|
|
1.1 root 1:
2: /******************************************************************************\
3: * This is a part of the Microsoft Source Code Samples.
4: * Copyright (C) 1993 Microsoft Corporation.
5: * All rights reserved.
6: * This source code is only intended as a supplement to
7: * Microsoft Development Tools and/or WinHelp documentation.
8: * See these sources for detailed information regarding the
9: * Microsoft samples programs.
10: \******************************************************************************/
11:
12: /*****************************************************************************\
13: *
14: * Module: spy.c
15: *
16: * Main module for the Windows debugging Spy SDK applet.
17: *
18: * Functions:
19: *
20: * WinMain()
21: * SpyWndProc()
22: * SpyInit()
23: * PutOptions()
24: * InitMenu()
25: * SpyCommand()
26: *
27: * Comments:
28: *
29: \*****************************************************************************/
30:
31: #include "spy.h"
32: #include <stdlib.h>
33:
34:
35: #define WM_EXECINSTANCE (WM_USER+100)
36:
37:
38: /*
39: * Macros to simplify working with menus.
40: */
41: #define MyEnableMenuItem(hMenu, wIDEnableItem, fEnable) \
42: EnableMenuItem((hMenu),(wIDEnableItem),(fEnable)?MF_ENABLED:MF_GRAYED)
43:
44: #define MyCheckMenuItem(hMenu, wIDCheckItem, fCheck) \
45: CheckMenuItem((hMenu),(wIDCheckItem),(fCheck)?MF_CHECKED:MF_UNCHECKED)
46:
47:
48: HANDLE ghInst;
49: HWND ghwndSpyApp;
50: HWND ghwndPrintf = NULL;
51: HANDLE ghHookThread = NULL;
52: HWND ghwndSpyHook = NULL;
53: HWND ghwndSpyingOn = NULL; // The window we are spying on.
54: HFONT ghfontPrintf;
55: INT gnLines;
56: BOOL gfSpyOn = FALSE;
57: BOOL gfSpyAll;
58: BOOL gfOutputWin;
59: BOOL gfOutputCom1;
60: BOOL gfOutputFile;
61: HFILE gfhFile;
62: CHAR gszFile[MAXSTRING];
63: INT gcxBorder;
64: INT gcyBorder;
65: BOOL gfMsgsUser; // TRUE to spy on all WM_USER messages.
66: BOOL gfMsgsUnknown; // TRUE to spy on all unknown msgs.
67: CHAR gszAppName[] = SPYAPPNAME;
68: WINDOWPLACEMENT gwndpl;
69:
70:
71: PRIVATE HANDLE ghaccelTbl; // Accelerator table handle.
72: PRIVATE CHAR gszSpyClassName[] = SPYCLASSNAME;
73:
74:
75: PRIVATE BOOL SpyInit(HANDLE hInstance, INT nCmdShow);
76: PRIVATE VOID PutOptions(VOID);
77: PRIVATE VOID InitMenu(HMENU hmenu);
78: PRIVATE LRESULT SpyCommand(HWND hwnd, INT nCmd, INT nNotifyCode);
79:
80:
81:
82: /*****************************************************************************\
83: * WinMain
84: *
85: * Main entry point for the Spy app.
86: *
87: \*****************************************************************************/
88:
89: INT WINAPI
90: WinMain(
91: HINSTANCE hInstance,
92: HINSTANCE hPrevInstance,
93: LPSTR lpCmdLine,
94: INT nCmdShow
95: )
96: {
97: MSG msg;
98:
99: if (!SpyInit(hInstance, nCmdShow))
100: return FALSE;
101:
102: if (!CreateHookThread())
103: goto closespy;
104:
105: /*
106: * Polling messages from event queue
107: */
108: while (GetMessage(&msg, NULL, 0, 0))
109: {
110: if (!TranslateAccelerator(ghwndSpyApp, ghaccelTbl, &msg))
111: {
112: TranslateMessage(&msg);
113: DispatchMessage(&msg);
114: }
115: }
116:
117: closespy:
118: if (IsWindow(ghwndSpyApp))
119: {
120: if (DestroyWindow(ghwndSpyApp))
121: {
122: ghwndSpyApp = NULL;
123: }
124: }
125:
126: if (IsWindow(ghwndPrintf))
127: {
128: if (DestroyWindow(ghwndPrintf))
129: {
130: ghwndPrintf = NULL;
131: }
132: }
133:
134: return (INT)msg.wParam;
135: }
136:
137:
138:
139: /*****************************************************************************\
140: * SpyInit
141: *
142: * Initializes the Spy application.
143: *
144: * Arguments:
145: * HANDLE hInstance - handle to the instance of SPY.
146: * INT nCmdShow - show the window?
147: *
148: * Returns:
149: * TRUE if successful, FALSE otherwise.
150: *
151: \*****************************************************************************/
152:
153: PRIVATE BOOL
154: SpyInit(
155: HANDLE hInstance,
156: INT nCmdShow
157: )
158: {
159: WNDCLASS wc;
160: HWND hwndT;
161: CHAR szClassName[40];
162: BOOL bFoundPrevSpy = FALSE;
163: INT i;
164: INT j;
165:
166: ghInst = hInstance;
167:
168: /*
169: * Loop through windows to find one of the spy class.
170: */
171: for (hwndT = GetWindow(GetDesktopWindow(), GW_CHILD); hwndT;
172: hwndT = GetWindow(hwndT, GW_HWNDNEXT))
173: {
174: if (GetClassName(hwndT, szClassName, 40))
175: {
176: if (!lstrcmpi(szClassName, gszSpyClassName))
177: {
178: bFoundPrevSpy = TRUE;
179: break;
180: }
181: }
182: }
183:
184: if (bFoundPrevSpy)
185: {
186: if (hwndT)
187: SendMessage(hwndT, WM_EXECINSTANCE, 0, 0);
188:
189: return FALSE;
190: }
191:
192: if (!(ghaccelTbl = LoadAccelerators(ghInst, "spy")))
193: return FALSE;
194:
195: ReadRegistry();
196:
197: gcxBorder = GetSystemMetrics(SM_CXBORDER);
198: gcyBorder = GetSystemMetrics(SM_CYBORDER);
199:
200: //
201: // Calculate the counts in the message groups. This is best
202: // done at run time to be safe.
203: //
204: for (i = 0; i < gcMessages; i++)
205: {
206: //
207: // If this message belongs to a message group,
208: // increment the total for that group.
209: //
210: for (j = 0; j < gcMsgGroups; j++)
211: {
212: if (gaMsgGroup[j].flMask & gaMsgs[i].Flags)
213: gaMsgGroup[j].cMsgs++;
214: }
215: }
216:
217: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
218: wc.hIcon = LoadIcon(hInstance, gszAppName);
219: wc.lpszMenuName = gszAppName;
220: wc.lpszClassName = gszSpyClassName;
221: wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
222: wc.hInstance = hInstance;
223: wc.style = CS_BYTEALIGNCLIENT;
224: wc.lpfnWndProc = SpyWndProc;
225: wc.cbWndExtra = 0;
226: wc.cbClsExtra = 0;
227:
228: if (!RegisterClass(&wc))
229: return FALSE;
230:
231: ghwndSpyApp = CreateWindow(gszSpyClassName, gszAppName,
232: WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
233: NULL, NULL, hInstance, NULL);
234:
235: if (!ghwndSpyApp)
236: return FALSE;
237:
238: if (nCmdShow != SW_SHOWNORMAL)
239: gwndpl.showCmd = nCmdShow;
240:
241: SetWindowPlacement(ghwndSpyApp, &gwndpl);
242:
243: return TRUE;
244: }
245:
246:
247:
248: /*****************************************************************************\
249: * SpyWndProc
250: *
251: * Main window procedure for the spy app.
252: *
253: * Arguments:
254: * HWND hwnd - handle to the spy window
255: * UINT msg - message
256: * WPARAM wParam - message parameter
257: * LPARAM lParam - message parameter
258: *
259: * Returns:
260: * The value that the window proc should return, based on the processing
261: * of the specific WM_COMMAND message received.
262: \*****************************************************************************/
263:
264: LRESULT CALLBACK
265: SpyWndProc(
266: HWND hwnd,
267: UINT msg,
268: WPARAM wParam,
269: LPARAM lParam
270: )
271: {
272: switch (msg)
273: {
274: case WM_CREATE:
275: MyCreatePrintfWin(hwnd);
276: return 0;
277:
278: case WM_INITMENU:
279: if (GetMenu(ghwndSpyApp) == (HMENU)wParam)
280: InitMenu((HMENU)wParam);
281:
282: break;
283:
284: case WM_COMMAND:
285: return SpyCommand(hwnd, LOWORD(wParam), HIWORD(wParam));
286:
287: case WM_ACTIVATE:
288: /*
289: * Set the focus to the printf window if we are being activated.
290: */
291: if (LOWORD(wParam))
292: SetFocus(ghwndPrintf);
293:
294: break;
295:
296: case WM_SIZE:
297: /*
298: * Size the printf window to fit into the new client area size.
299: */
300: MoveWindow(ghwndPrintf, -gcxBorder, -gcyBorder,
301: LOWORD(lParam) + (2 * gcxBorder),
302: HIWORD(lParam) + (2 * gcyBorder), TRUE);
303: break;
304:
305: case WM_CLOSE:
306: SetSpyHook(FALSE);
307:
308: if (gfhFile)
309: _lclose(gfhFile);
310:
311: SendMessage(ghwndSpyHook, WM_CLOSE, 0, 0);
312: WriteRegistry();
313: WaitForSingleObject(ghHookThread, INFINITE);
314: DestroyWindow(ghwndSpyApp);
315: break;
316:
317: case WM_DESTROY:
318: PostQuitMessage(0); /* Kill the main window */
319: ghwndSpyApp = NULL;
320: ghwndPrintf = NULL;
321: break;
322:
323: case WM_EXECINSTANCE:
324: /*
325: * another instance of spy has been started.
326: */
327: if (IsIconic(hwnd))
328: ShowWindow(hwnd,SW_SHOWNORMAL);
329:
330: SetForegroundWindow(hwnd);
331: BringWindowToTop(hwnd);
332:
333: break;
334:
335: default:
336: return DefWindowProc(hwnd, msg, wParam, lParam);
337: }
338:
339: return 0;
340: }
341:
342:
343:
344: /*****************************************************************************\
345: * InitMenu
346: *
347: * This function grays/enables and checks/unchecks the menu items
348: * appropriately for the given state.
349: *
350: * Arguments:
351: * HMENU hmenu - The menu handle.
352: *
353: * Returns:
354: * VOID
355: \*****************************************************************************/
356:
357: PRIVATE VOID
358: InitMenu(
359: HMENU hmenu
360: )
361: {
362: BOOL fEnable = !IsPrintfEmpty();
363:
364: MyEnableMenuItem(hmenu, MENU_EDIT_CUT, fEnable);
365: MyEnableMenuItem(hmenu, MENU_EDIT_COPY, fEnable);
366: MyEnableMenuItem(hmenu, MENU_EDIT_CLEAR, fEnable);
367: }
368:
369:
370:
371: /*****************************************************************************\
372: * SpyCommand
373: *
374: * Handles thw WM_COMMAND messages for the Spy app.
375: *
376: * Arguments:
377: * HWND hwnd - Window handle of the main app window.
378: * INT nCmd - Command value.
379: * INT nNotifyCode - The notify code.
380: *
381: * Returns:
382: * The value that the window proc should return, based on the processing
383: * of the specific WM_COMMAND message received.
384: \*****************************************************************************/
385:
386: PRIVATE LRESULT
387: SpyCommand(
388: HWND hwnd,
389: INT nCmd,
390: INT nNotifyCode
391: )
392: {
393: HMENU hmenu;
394:
395: switch (nCmd)
396: {
397: case MENU_SPY_SELECTWINDOW:
398: MyDialogBox(DID_SELECTWINDOW, SelectWindowDlgProc);
399: break;
400:
401: case MENU_SPY_ABOUT:
402: MyDialogBox(DID_ABOUT, AboutDlgProc);
403: break;
404:
405: case MENU_SPY_EXIT:
406: PostMessage(hwnd, WM_CLOSE, 0, 0);
407: break;
408:
409: case MENU_EDIT_CUT:
410: if (CopyToClipboard())
411: ClearPrintfWindow(ghwndPrintf);
412:
413: break;
414:
415: case MENU_EDIT_COPY:
416: CopyToClipboard();
417: break;
418:
419: case MENU_EDIT_CLEAR:
420: ClearPrintfWindow(ghwndPrintf);
421: break;
422:
423: case MENU_OPTIONS_MESSAGES:
424: MyDialogBox(DID_MESSAGES, MessagesDlgProc);
425: break;
426:
427: case MENU_OPTIONS_FONT:
428: SelectFont();
429: break;
430:
431: case MENU_OPTIONS_OUTPUT:
432: MyDialogBox(DID_OUTPUT, OutputDlgProc);
433: break;
434:
435: case MENU_START:
436: if (SetSpyHook(TRUE))
437: {
438: hmenu = GetMenu(hwnd);
439: ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING,
440: MENU_STOP, "&Stop!");
441: DrawMenuBar(hwnd);
442:
443: SetSpyCaption();
444: }
445:
446: break;
447:
448: case MENU_STOP:
449: if (SetSpyHook(FALSE))
450: {
451: hmenu = GetMenu(hwnd);
452: ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING,
453: MENU_START, "&Start!");
454: DrawMenuBar(hwnd);
455:
456: SetSpyCaption();
457: }
458:
459: break;
460: }
461:
462: return 0;
463: }
464:
465:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.