|
|
1.1 root 1: /****************************** Module Header ******************************\
2: * Module Name: window.c - Spy Window dialog functions.
3: *
4: * Created: Microsoft, IBM Corporation 1990
5: *
6: \***************************************************************************/
7:
8: #define INCL_WIN
9: #define INCL_WINSYS
10: #define INCL_DOSPROCESS
11: #include <os2.h>
12: #include <stdio.h>
13: #include <string.h>
14: #include "spy.h"
15: #include "spyhk32.h"
16: #include <time.h>
17: #include <stdlib.h>
18:
19:
20: /************* GLOBAL VARIABLES */
21:
22:
23:
24:
25: /************* PROCEDURE DECLARATIONS */
26:
27: void InitWindowList(HWND, HWND, int);
28: void BuildWindowWatchList(void);
29: void DisplayWindowInfo(HWND, HWND);
30:
31:
32: void SelectWindowFromText(HWND);
33: SHORT DumpWindowInfo(HWND, SHORT);
34: int _cdecl CompareHwnds(const void *, const void *);
35:
36:
37:
38:
39: /**************************** Public Function ******************************\
40: * MRESULT EXPENTRY SpyWindowsDlgProc(hwnd, msg, mp1, mp2)
41: *
42: * Effects: The Spy Windows Dialog procedure
43: *
44: * Return value: none
45: \***************************************************************************/
46: MRESULT EXPENTRY SpyWindowsDlgProc(hwnd, msg, mp1, mp2)
47: HWND hwnd;
48: USHORT msg;
49: MPARAM mp1;
50: MPARAM mp2;
51: {
52: BOOL fSelect = TRUE;
53: SHORT cWindows;
54: HWND hwndPoint;
55: HWND hwndItem; /* from handle of list item */
56: USHORT iItemFocus; /* Index to item that has the focus */
57:
58: switch (msg) {
59:
60: case WM_INITDLG:
61: /* Initialize the dialog items */
62: hwndWindowLB = WinWindowFromID(hwnd, DID_WINDOWLIST);
63: InitWindowList(hwnd, HWND_DESKTOP, 0);
64: InitWindowList(hwnd, HWND_OBJECT, -10);
65: hwndWinDlgDisp = NULL;
66: fTrackingListBox = TRUE;
67: break;
68:
69: case WM_CHAR:
70: /*
71: * Handle VK_ENTER and VK_NEWLINE if our Edit control has
72: * the focus and it is a keydown
73: */
74: if (!(SHORT1FROMMP(mp1) & KC_KEYUP) &&
75: (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) &&
76: ( (SHORT2FROMMP(mp2) == VK_ENTER) ||
77: (SHORT2FROMMP(mp2) == VK_NEWLINE) )) {
78:
79:
80: if (WinQueryFocus(HWND_DESKTOP, FALSE) ==
81: WinWindowFromID(hwnd, DID_WHANDLE)) {
82: SelectWindowFromText(hwnd);
83: break;
84: }
85: }
86:
87: /* Normaly pass to dialog procedure to handle message */
88: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
89: break;
90:
91: case WM_COMMAND:
92: switch (SHORT1FROMMP(mp1)) {
93: case DID_OK:
94: BuildWindowWatchList();
95: case DID_CANCEL:
96: /* Now dismiss the dialog */
97: WinDismissDlg(hwnd, SHORT1FROMMP(mp1));
98: break;
99: case DID_WUNSELALL:
100: fSelect = FALSE;
101: case DID_WSELALL:
102: cWindows = (SHORT) WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT,
103: 0L, 0L);
104:
105: fTrackingListBox = FALSE;
106: while (cWindows) {
107: /* Loop through all windows, selecting or unselcting all */
108: WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)--cWindows,
109: (MPARAM)fSelect);
110: }
111: fTrackingListBox = TRUE;
112: break;
113:
114: case DID_WSELMOUSE:
115: /* Call function to track mouse, returns window handle */
116: hwndPoint = HwndSelWinWithMouse(hwnd, DisplayWindowInfo, FALSE);
117: if (hwndPoint == NULL)
118: break; /* No window to process */
119:
120: /*
121: * Now find the window in the list, Make the item visible
122: * and set the item as selected.
123: */
124: cWindows = (SHORT) WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT,
125: 0L, 0L);
126:
127: while (cWindows) {
128: /*
129: * Loop through all windows until we wind the right
130: * one with the correct window handle
131: */
132: hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
133: (MPARAM)--cWindows, 0L);
134:
135: if (hwndItem == hwndPoint) {
136: /* found the right item, move it to top */
137: WinSendMsg(hwndWindowLB, LM_SETTOPINDEX, (MPARAM)cWindows, 0L);
138: WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)cWindows,
139: (MPARAM)TRUE);
140: break;
141: }
142: }
143: break;
144:
145: }
146: break;
147:
148:
149: default:
150: /*
151: * Default is to see if the listbox has changed its focus
152: * item number. If it has, then we want to display the information
153: * about the window that the listbox cursor is over. There is no
154: * legal way to do this, One approach appears to temporary set the
155: * listbox to be a single selection listbox, then query its selection
156: * and set it back into multiple selection mode.
157: */
158: if (fTrackingListBox && hwndWindowLB != NULL) {
159:
160: WinSetWindowBits(hwndWindowLB, QWL_STYLE, 0L, LS_MULTIPLESEL);
161: iItemFocus = (USHORT)WinSendMsg(hwndWindowLB, LM_QUERYSELECTION,
162: (MPARAM)LIT_FIRST, 0L);
163: WinSetWindowBits(hwndWindowLB, QWL_STYLE, LS_MULTIPLESEL,
164: LS_MULTIPLESEL);
165:
166: if (iItemFocus != iCurItemFocus) {
167: iCurItemFocus = iItemFocus;
168: if (iItemFocus != (USHORT)-1) {
169:
170: hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
171: (MPARAM)iItemFocus, 0L);
172: DisplayWindowInfo(hwnd, hwndItem);
173: }
174: }
175: }
176: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
177: }
178: return 0L;
179: }
180:
181:
182:
183:
184: /***************************** Private Function ****************************\
185: * void SelectWindowFromText(hwndDlg)
186: *
187: * Effects:
188: * Updates the text that is displayed in the message text line
189: *
190: * History:
191: * 27-September-1988 KurtE
192: \***************************************************************************/
193: void SelectWindowFromText(hwndDlg)
194: HWND hwndDlg;
195: {
196: char szTemp[80];
197: HWND hwndSelect;
198: SHORT cItems;
199: SHORT i;
200:
201:
202: /* First get the edit text from the string */
203: WinQueryDlgItemText(hwndDlg, DID_WHANDLE, sizeof(szTemp),
204: (PSZ)szTemp);
205:
206: hwndSelect = (HWND)UConvertStringToNum(szTemp);
207:
208: cItems = (SHORT)WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT,
209: 0L, 0L);
210:
211: for (i=0; i < cItems; i++) {
212: if ((HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
213: (MPARAM)i, 0L) == hwndSelect)
214: break; /* found it */
215: }
216:
217: if (i < cItems) {
218: /*
219: * found the hwnd, bring to top, and select it
220: */
221: WinSendMsg(hwndWindowLB, LM_SETTOPINDEX,
222: MPFROMSHORT(i), (MPARAM)0L);
223:
224: /* Always set it on */
225: WinSendMsg(hwndWindowLB, LM_SELECTITEM,
226: MPFROMSHORT(i), MPFROMSHORT(TRUE));
227:
228: } else {
229: WinAlarm(HWND_DESKTOP, WA_WARNING);
230: WinSetDlgItemText(hwndDlg, DID_WHANDLE, (PSZ)"");
231: }
232:
233: }
234:
235:
236: /**************************** Private Function ******************************\
237: * InitWindowList (hwndDialog, hwnd, level)
238: *
239: * Effects: Builds the list of windows displayed in the windows dialog
240: *
241: *
242: * Return value:
243: \***************************************************************************/
244: void InitWindowList(hwndDialog, hwnd, level)
245: HWND hwndDialog;
246: HWND hwnd;
247: int level;
248: {
249: char szTemp[30];
250: char szId[20];
251: HWND hwndT;
252: USHORT item;
253: USHORT id;
254: int i;
255:
256: /*
257: * We will first add this item to our list of
258: * items in the listbox, If the item is in our list of hwnds,
259: * set the item selected. To keep from getting into endless loops
260: * will not add spywindow client, and descendants.
261: */
262: if (hwnd != hwndSpy) {
263: id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID);
264: sprintf(szId, "ID: %x", id);
265:
266: for (i = 0; i < cToName; i++) {
267: if (id == rgidtoname[i].id) {
268: strcpy (szId, rgidtoname[i].szIdName);
269: break;
270: }
271: }
272:
273: sprintf(szTemp, "%04x(%d) - %s", (USHORT)hwnd, level, szId);
274: item = (USHORT)WinSendMsg(hwndWindowLB, LM_INSERTITEM,
275: (MPARAM)LIT_END, (MPARAM)(PSZ)szTemp);
276:
277: /* Set the item handle to the handle of the window */
278: WinSendMsg(hwndWindowLB, LM_SETITEMHANDLE, (MPARAM)item,
279: (MPARAM)hwnd);
280:
281: if (SpyFWindowInList(hwnd, TRUE))
282: WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)item,
283: (MPARAM)TRUE);
284:
285: /*
286: * Then we recurse with all of our children
287: */
288: if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL)
289: InitWindowList(hwndDialog, hwndT, level+1);
290: }
291:
292: /*
293: * Then go to our next sibling
294: */
295: if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL)
296: InitWindowList(hwndDialog, hwndT, level);
297: }
298:
299:
300:
301: /**************************** Private Function *****************************\
302: * BuildWindowWatchList()
303: *
304: * Effects: Updates the list of windows to be watched from the listbox
305: *
306: *
307: * Return value:
308: \***************************************************************************/
309: void BuildWindowWatchList()
310: {
311:
312: USHORT itemPrevious;
313: USHORT item;
314: HWND hwnd;
315:
316: SHORT chwnd;
317: HWND rghwnd[MAXHWNDS];
318:
319: /*
320: * Simply loop through asking for the next selected item in the
321: * list. Make sure not to overrun our list.
322: */
323: itemPrevious = (USHORT)LIT_FIRST;
324: chwnd = 0;
325:
326: while ((item = (USHORT)WinSendMsg(hwndWindowLB, LM_QUERYSELECTION,
327: (MPARAM)itemPrevious, 0L)) != (USHORT)LIT_NONE) {
328: /*
329: * Get the items handle, which has the value of the window handle
330: */
331: hwnd = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
332: (MPARAM)item, 0L);
333:
334: /* Make sure it still is a valid window */
335: if (WinIsWindow(hab, hwnd)) {
336: rghwnd[chwnd++] = hwnd;
337: if (chwnd >= MAXHWNDS)
338: break; /* Dont overflow array */
339: }
340:
341: itemPrevious = item; /* Where to cointinue the search */
342: }
343:
344: SpySetWindowList (chwnd, rghwnd);
345: }
346:
347:
348: /**************************** Public Function ******************************\
349: * HWND HwndSelWinWithMouse(HWND hwnd, void (*pfnDisplayInfo)(HWND, HWND),
350: * BOOL fFrameOnly)
351: *
352: * Effects: This function is used to allow the user to select a window with
353: * the mouse. If fDisplayInfo is TRUE, it will update the
354: * information in the dialog box, about the window that the
355: * mouse is currently over.
356: *
357: * Return value: none
358: \***************************************************************************/
359: HWND HwndSelWinWithMouse(hwnd, pfnDisplayInfo, fFrameOnly)
360: HWND hwnd;
361: void (*pfnDisplayInfo)(HWND, HWND);
362: BOOL fFrameOnly;
363: {
364:
365: QMSG qmsg;
366: HWND hwndPoint;
367: char szClassName[50]; /* Class name of window */
368: CLASSINFO classinfo; /* Information about class */
369:
370:
371: /*
372: * First set the capture to the specified window
373: */
374: WinSetCapture(HWND_DESKTOP, hwnd);
375: WinSetPointer (HWND_DESKTOP, hptrSelWin);
376:
377: /*
378: * Now loop through all of the messages that are sent, until
379: * we get our mouse 1 down message. We will also filter out
380: * the WM_MOVE message, else we will dispatch the messages.
381: */
382: while (WinGetMsg(hab, &qmsg, NULL, 0, 0)) {
383: if (qmsg.msg == WM_MOUSEMOVE) {
384: if (pfnDisplayInfo != NULL) {
385: hwndPoint = WinWindowFromPoint(HWND_DESKTOP,
386: &qmsg.ptl, TRUE, FALSE);
387: (*pfnDisplayInfo)(hwnd, hwndPoint);
388: }
389: }
390: else if (qmsg.msg == WM_BUTTON1DOWN)
391: break;
392: else
393: WinDispatchMsg(hab, &qmsg);
394: }
395:
396: WinSetPointer (HWND_DESKTOP, hptrArrow);
397: WinSetCapture(HWND_DESKTOP, NULL);
398:
399:
400: /*
401: * Map the point to the window, If the CTRL-Key is down,
402: * we will go up through the parent chain until we get to
403: * a frame window or desktop. Dont let hwndSpy through!!!
404: */
405: hwndPoint = WinWindowFromPoint(HWND_DESKTOP,
406: &qmsg.ptl, TRUE, FALSE);
407: if (fFrameOnly || WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) {
408: /* Asked for frame window */
409: for (;;) {
410: if (hwndPoint == NULL)
411: return (NULL); /* No frames available */
412: /* See if frame class */
413: WinQueryClassName(hwndPoint, sizeof(szClassName),
414: (PSZ)szClassName);
415: if (WinQueryClassInfo(hab, (PSZ)szClassName, &classinfo) &&
416: (classinfo.flClassStyle & CS_FRAME))
417: break; /* We have our frame */
418:
419: /* Not frame, go back to parent */
420: hwndPoint = WinQueryWindow(hwndPoint, QW_PARENT, FALSE);
421: }
422: }
423:
424: if (pfnDisplayInfo != NULL)
425: (*pfnDisplayInfo)(hwnd, hwndPoint);
426:
427: if (WinIsChild(hwndPoint, hwndSpy))
428: return (NULL); /* Dont want to get in endless loops */
429:
430: return (hwndPoint);
431: }
432:
433:
434:
435: /**************************** Private Function *****************************\
436: * DisplayWindowInfo(HWND hwndDialog, HWND hwnd)
437: *
438: * Effects: Displays the information about the selected window in the dialog
439: *
440: *
441: * Return value:
442: \***************************************************************************/
443: void DisplayWindowInfo(hwndDlg, hwnd)
444: HWND hwndDlg;
445: HWND hwnd;
446: {
447: HWND hwndT;
448: HWND hwndParent;
449: char szTemp[50];
450: char szTemp2[10];
451: CLASSINFO classinfo;
452: RECTL rcl;
453: USHORT id;
454: ULONG ul;
455: USHORT us1;
456: USHORT us2;
457: USHORT us3;
458: USHORT us4;
459: PID pidWindow;
460: TID tidWindow;
461:
462:
463: if (hwnd != hwndWinDlgDisp)
464: {
465: hwndWinDlgDisp = hwnd;
466:
467: /* This could be table driven */
468: sprintf(szTemp, "%p", hwnd);
469: WinSetDlgItemText(hwndDlg, DID_WHANDLE, (PSZ)szTemp);
470:
471: /*
472: * Make sure the window has not been deleted
473: */
474: if (WinIsWindow(hab, hwnd)) {
475: WinQueryClassName(hwnd, sizeof(szTemp), (PSZ)szTemp);
476: if (!WinQueryClassInfo(hab, (PSZ)szTemp, &classinfo)) {
477: classinfo.flClassStyle = -1; /* Let know error conditon */
478: classinfo.cbWindowData = 0; /* Make sure we dont dump */
479: }
480:
481: WinSetDlgItemText(hwndDlg, DID_WCLASS, (PSZ)szTemp);
482:
483:
484: /*
485: * Warning, we only query the text if the window is not an object
486: * window. If it is an object window, the message queue may not
487: * be processing messages, which could hang us
488: */
489: if (WinIsChild(hwnd, HWND_OBJECT))
490: szTemp[0] = '\0'; /* No text available */
491: else
492: WinQueryWindowText(hwnd, sizeof(szTemp), (PSZ)szTemp);
493: WinSetDlgItemText(hwndDlg, DID_WTEXT, (PSZ)szTemp);
494:
495: hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE);
496: sprintf(szTemp, "%p", hwndParent);
497: WinSetDlgItemText(hwndDlg, DID_WPARENT, (PSZ)szTemp);
498:
499: hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE);
500: sprintf(szTemp, "%p", hwndT);
501: WinSetDlgItemText(hwndDlg, DID_WCHILD, (PSZ)szTemp);
502:
503: hwndT = WinQueryWindow(hwnd, QW_OWNER, FALSE);
504: sprintf(szTemp, "%p", hwndT);
505: WinSetDlgItemText(hwndDlg, DID_WOWNER, (PSZ)szTemp);
506:
507: WinQueryWindowRect(hwnd, &rcl);
508: WinMapWindowPoints(hwnd, hwndParent, (PPOINTL)&rcl, 2);
509: sprintf(szTemp, "(%d, %d), (%d, %d)", (SHORT)rcl.xLeft,
510: (SHORT)rcl.yBottom, (SHORT)rcl.xRight, (SHORT)rcl.yTop);
511: WinSetDlgItemText(hwndDlg, DID_WRECT, (PSZ)szTemp);
512:
513: id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID);
514: sprintf(szTemp, "0x%04x", id);
515: WinSetDlgItemText(hwndDlg, DID_WID, (PSZ)szTemp);
516:
517: ul = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE);
518: sprintf(szTemp, "0x%08lx", ul);
519: WinSetDlgItemText(hwndDlg, DID_WSTYLE, (PSZ)szTemp);
520:
521: sprintf(szTemp, "0x%08lx", classinfo.flClassStyle);
522: WinSetDlgItemText(hwndDlg, DID_WCSTYLE, (PSZ)szTemp);
523:
524: ul = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP);
525: sprintf(szTemp, "%p", ul);
526: WinSetDlgItemText(hwndDlg, DID_WPFNWP, (PSZ)szTemp);
527:
528: ul = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ);
529: sprintf(szTemp, "0x%04x", (SHORT)ul);
530: WinSetDlgItemText(hwndDlg, DID_WHMQ, (PSZ)szTemp);
531:
532: WinQueryWindowProcess(hwnd, &pidWindow, &tidWindow);
533: sprintf(szTemp, "%d", pidWindow);
534: WinSetDlgItemText(hwndDlg, DID_WPID, (PSZ)szTemp);
535: sprintf(szTemp, "%d", tidWindow);
536: WinSetDlgItemText(hwndDlg, DID_WTID, (PSZ)szTemp);
537:
538: /*
539: * We have four General purpose lines left, used only for
540: * frames now
541: */
542: if ((classinfo.flClassStyle & CS_FRAME) &&
543: (classinfo.cbWindowData > QWL_HWNDFOCUSSAVE)) {
544: ul = (ULONG)WinQueryWindowULong(hwnd, QWL_HWNDFOCUSSAVE);
545: sprintf(szTemp, "Frame Focus: %p",ul);
546: WinSetDlgItemText(hwndDlg, DID_WOLINE1, (PSZ)szTemp);
547:
548: us1 = (USHORT)WinQueryWindowUShort(hwnd, QWS_FLAGS);
549: us2 = (USHORT)WinQueryWindowUShort(hwnd, QWS_RESULT);
550: sprintf(szTemp, "Flags: 0x%04x Rslt: 0x%04x", us1, us2);
551: WinSetDlgItemText(hwndDlg, DID_WOLINE2, (PSZ)szTemp);
552:
553: us1 = (USHORT)WinQueryWindowUShort(hwnd, QWS_XRESTORE);
554: us2 = (USHORT)WinQueryWindowUShort(hwnd, QWS_YRESTORE);
555: us3 = (USHORT)WinQueryWindowUShort(hwnd, QWS_CXRESTORE);
556: us4 = (USHORT)WinQueryWindowUShort(hwnd, QWS_CYRESTORE);
557: sprintf(szTemp, "Restore: (%d, %d, %d, %d)",us1, us2, us3, us4);
558: WinSetDlgItemText(hwndDlg, DID_WOLINE3, (PSZ)szTemp);
559:
560: us1 = (USHORT)WinQueryWindowUShort(hwnd, QWS_XMINIMIZE);
561: us2 = (USHORT)WinQueryWindowUShort(hwnd, QWS_YMINIMIZE);
562: sprintf(szTemp, "Minimize: (%d, %d)",us1, us2);
563: WinSetDlgItemText(hwndDlg, DID_WOLINE4, (PSZ)szTemp);
564: } else {
565: /*
566: * Nothing special to output for this window type, so lets
567: * dump the window extra words.
568: * Note: This code is sh.ty
569: */
570: us1 = 0; /* Word offset */
571: for (id=DID_WOLINE1; id <= DID_WOLINE4; id++) {
572: szTemp[0] = '\0';
573: for (us2 = 0; us2 < 4; us2++) {
574: if (us1 >= classinfo.cbWindowData)
575: break;
576: us3 = (USHORT)WinQueryWindowUShort(hwnd, us1);
577: sprintf(szTemp2, "%04x ", us3);
578: strcat(szTemp, szTemp2);
579: us1 += 2; /* Setup for next word */
580: }
581:
582: /* output this line */
583: WinSetDlgItemText(hwndDlg, id, (PSZ)szTemp);
584: }
585: }
586: } else {
587: /*
588: * Window was deleted, Show the window text as deleted, and
589: * clear out the remaining fields.
590: */
591: WinSetDlgItemText(hwndDlg, DID_WTEXT, (PSZ)"*** Deleted ***");
592: szTemp[0] = '\0';
593: for (id=DID_WCLASS; id <= DID_WOLINE4; id++) {
594: WinSetDlgItemText(hwndDlg, id, (PSZ)szTemp);
595: }
596: }
597: }
598: }
599:
600:
601:
602:
603: /**************************** Public Function ******************************\
604: * DumpOneWindowInfo()
605: *
606: * Effects: Dump the information about one window to the current outputs
607: *
608: * Return value: none
609: \***************************************************************************/
610: void DumpOneWindowInfo()
611: {
612: HWND hwndPoint;
613: HWND hwndT;
614: SHORT wLevel;
615:
616: hwndPoint = HwndSelWinWithMouse(hwndSpy, NULL, FALSE);
617: if (hwndPoint == NULL)
618: return; /* No window selected */
619:
620: /* Now see what level the window is at */
621: wLevel = 0;
622: hwndT = hwndPoint;
623: while (hwndT != NULL) {
624: wLevel++;
625: hwndT = WinQueryWindow(hwndT, QW_PARENT, FALSE);
626: };
627:
628:
629: DumpWindowInfo(hwndPoint, wLevel);
630: }
631:
632:
633: /**************************** Private Function ******************************\
634: * DumpAllWIndowsInfo (HWND hwnd, WORD wLevel)
635: *
636: * Effects: Dumps the complet window list out to the current output units.
637: *
638: *
639: * Return value:
640: \***************************************************************************/
641: SHORT DumpAllWindowsInfo(hwnd, wLevel)
642: HWND hwnd;
643: SHORT wLevel;
644: {
645: HWND hwndT;
646: SPWD *pspwdT;
647: SHORT cWindowBytes;
648:
649: pspwdT = pspwd + wDumpCount;
650:
651: cWindowBytes = DumpWindowInfo(hwnd, wLevel);
652:
653: pspwdT->hwnd = hwnd;
654: pspwdT->index = wDumpCount;
655:
656:
657: /*
658: * Then we recurse with all of our children
659: */
660: if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL)
661: cWindowBytes += DumpAllWindowsInfo(hwndT, wLevel+1);
662:
663: /*
664: * Then go to our next sibling
665: */
666: if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL)
667: cWindowBytes += DumpAllWindowsInfo(hwndT, wLevel);
668:
669: return (cWindowBytes);
670: }
671:
672:
673:
674: /**************************** Private Function ******************************\
675: * DumpWindowIndex (void)
676: *
677: * Effects: Dump a sorted list of Hwnds and index into other list
678: * This function works like sh.t
679: *
680: *
681: * Return value:
682: \***************************************************************************/
683: void DumpWindowIndex(cBytes)
684: SHORT cBytes;
685: {
686: SHORT cch;
687: char szTemp[20];
688: char szOutput[100];
689: SPWD *pspwdT;
690: SHORT i;
691:
692: /* Sort the hwnds first */
693: qsort((void *)pspwd, wDumpCount, sizeof(SPWD), CompareHwnds);
694: pspwdT = pspwd;
695:
696: strcpy (szOutput, "Index of Window Handles");
697: cch = strlen(szOutput);
698: for (i=0; i< wDumpCount; i++) {
699: if ((i & 3) == 0) {
700: /* 4 per row */
701: OutputString(szOutput, cch);
702: szOutput[0] = '\0';
703: cch = 0;
704: }
705:
706: cch += sprintf(szTemp, "%3d-%04x ",
707: pspwdT->index, (USHORT)pspwdT->hwnd);
708: strcat (szOutput, szTemp);
709: pspwdT++;
710: }
711:
712: OutputString(szOutput, cch);
713:
714: cch = sprintf(szOutput, "Number of Windows: %d, Approx heap size: %d",
715: wDumpCount, cBytes);
716: OutputString(szOutput, cch);
717:
718:
719: }
720:
721:
722: /**************************** Private Function ******************************\
723: * int CompareHwnds(SPWD *pspwd1, SPWD *pspwd2)
724: *
725: * Effects: Compares two window handles.
726: *
727: *
728: * Return value:
729: \***************************************************************************/
730: int _cdecl CompareHwnds(pspwd1, pspwd2)
731: const void *pspwd1;
732: const void *pspwd2;
733: {
734: return (((SPWD *)pspwd1)->hwnd < ((SPWD *)pspwd2)->hwnd)? -1 : 1;
735: }
736:
737:
738:
739:
740: /**************************** Private Function *****************************\
741: * DumpWindowInfo(HWND hwnd, SHORT wLevel)
742: *
743: * Effects: Displays the information about the selected window in the dialog
744: *
745: *
746: * Return value:
747: \***************************************************************************/
748: SHORT DumpWindowInfo(hwnd, wLevel)
749: HWND hwnd;
750: SHORT wLevel;
751: {
752: HWND hwndParent;
753: HWND hwndChild;
754: HWND hwndOwner;
755:
756: char szTemp[128];
757: char szTemp2[20];
758: SHORT cch;
759: char szClass[30];
760: RECTL rcl;
761: USHORT id;
762: ULONG ulStyle;
763: ULONG ulPFNWP;
764: ULONG ulHMQ;
765: SHORT wOffsetClassData;
766: SHORT wWindowWord;
767: PID pidWindow;
768: TID tidWindow;
769:
770: CLASSINFO classinfo;
771:
772: hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE);
773: hwndChild = WinQueryWindow(hwnd, QW_TOP, FALSE);
774: hwndOwner = WinQueryWindow(hwnd, QW_OWNER, FALSE);
775: id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID);
776:
777: cch = sprintf(szTemp,
778: "%d-H:%p(%d) P:%p C:%p O:%p ID:%04x",
779: ++wDumpCount, hwnd, wLevel, hwndParent,
780: hwndChild, hwndOwner, id);
781:
782: OutputString(szTemp, cch);
783:
784: ulHMQ = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ);
785: WinQueryWindowRect(hwnd, &rcl);
786: WinMapWindowPoints(hwnd, hwndParent, (PPOINTL)&rcl, 2);
787: ulStyle = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE);
788:
789: cch = sprintf(szTemp,
790: " MQ:%p St:%08lx Rect: (%d, %d) (%d, %d)",
791: ulHMQ, ulStyle,
792: (SHORT)rcl.xLeft, (SHORT)rcl.yBottom,
793: (SHORT)rcl.xRight, (SHORT)rcl.yTop);
794: OutputString(szTemp, cch);
795:
796: ulPFNWP = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP);
797: WinQueryClassName(hwnd, sizeof(szClass), (PSZ)szClass);
798: if (!WinQueryClassInfo(hab, (PSZ)szClass, &classinfo)) {
799: classinfo.flClassStyle = -1; /* Let know error conditon */
800: classinfo.cbWindowData = 0; /* Make sure we dont dump */
801: }
802:
803: WinQueryWindowProcess(hwnd, &pidWindow, &tidWindow);
804:
805: cch = sprintf(szTemp,
806: " PID:%d TID:%d Pfn:%p Cl:%s",
807: ulStyle, pidWindow, tidWindow, ulPFNWP, szClass);
808: OutputString(szTemp, cch);
809:
810: /*
811: * Dump the window extra words out also.
812: */
813: strcpy (szTemp, " ");
814: id = 8;
815: for (wOffsetClassData = 0; wOffsetClassData < classinfo.cbWindowData;
816: wOffsetClassData += 2) {
817:
818: wWindowWord = (USHORT)WinQueryWindowUShort(hwnd, wOffsetClassData);
819: sprintf(szTemp2, "%04x ", wWindowWord);
820: strcat(szTemp, szTemp2);
821: if (--id == 0) {
822: /* line full is full */
823: OutputString(szTemp, strlen(szTemp));
824: szTemp[10] = '\0';
825: id = 8;
826: }
827: }
828:
829: if (id != 8)
830: OutputString(szTemp, strlen(szTemp));
831:
832: /* Return the number of bytes associated with the window */
833: return ((SIZEOFWND + classinfo.cbWindowData + 3) & 0xfffc);
834: }
835:
836:
837: /**************************** Public Function ******************************\
838: * DumpFrameAcclTable()
839: *
840: * Effects: Dump the information about one window to the current outputs
841: *
842: * Return value: none
843: \***************************************************************************/
844: void DumpFrameAcclTable()
845: {
846: HWND hwndPoint;
847: HACCEL haccel;
848: ACCELTABLE *npAcclTbl;
849: SHORT cbAccel;
850: char szTemp[100];
851: char szFS[100];
852: SHORT cch;
853: ACCEL *npAccel;
854: PID pidHwnd;
855: TID tidHwnd;
856: PPIB ppib;
857: PTIB ptib;
858: SHORT i;
859: SHORT j;
860: char szChar[2];
861: char *pszChar;
862:
863: hwndPoint = HwndSelWinWithMouse(hwndSpy, NULL, TRUE);
864: if (hwndPoint == NULL)
865: return;
866:
867: // Now lets get the accel table for the frame window
868: haccel = WinQueryAccelTable(hab, hwndPoint);
869: if (haccel == NULL)
870: return;
871:
872: WinQueryWindowProcess(hwndPoint, &pidHwnd, &tidHwnd);
873: DosGetThreadInfo(&ptib, &ppib);
874: if (ppib->pib_ulpid == pidHwnd) {
875: // It is in our own process, so do it local
876: // Allocate memory for the Accel table. If over 4K to much anyway!
877: cbAccel = WinCopyAccelTable(haccel, (PACCELTABLE)NULL, 0);
878: npAcclTbl = (ACCELTABLE *)WinAllocMem(hHeap, cbAccel);
879: if (npAcclTbl == NULL)
880: return;
881: WinCopyAccelTable(haccel, npAcclTbl, cbAccel);
882: } else {
883: // Let the hook do it for us
884: /* Lets use the hook */
885: SpySetPIDIntercept(pidHwnd, PIT_ACCEL, (ULONG)haccel);
886:
887: /* HACK: Send message to frame known to send another message */
888: WinSendMsg(hwndPoint, WM_QUERYTASKFOCUS, 0L, 0L);
889:
890: // Ask for size
891: cbAccel = SpyGetPIDInterceptData(NULL, 0, NULL);
892: npAcclTbl = (ACCELTABLE *)WinAllocMem(hHeap, cbAccel);
893: if (npAcclTbl == NULL)
894: return;
895: SpyGetPIDInterceptData((char *)npAcclTbl, cbAccel, NULL);
896: }
897:
898: // Now Dump the Accel table header
899: cch = sprintf(szTemp,"HACCEL:%p for HWND:%p CP:%d CNT:%d",
900: haccel, hwndPoint, npAcclTbl->codepage, npAcclTbl->cAccel);
901: OutputString(szTemp, cch);
902:
903: // Now dump each of the items
904: npAccel = npAcclTbl->aaccel;
905: szChar[1] = '\0'; // Make it NULL TERMINATED
906: for (i=npAcclTbl->cAccel; i > 0; i--) {
907: pszChar = szChar;
908: if (npAccel->fs & AF_CHAR) {
909: if ((npAccel->key >= ' ') && (npAccel->key <= '~'))
910: szChar[0] = (char)npAccel->key;
911: else
912: szChar[0] = ' ';
913: } else if (npAccel->fs & AF_VIRTUALKEY) {
914: if ((npAccel->key >= ivktosMin) && (npAccel->key < cvktos))
915: pszChar = avktos[npAccel->key].szVkey;
916: else
917: szChar[0] = ' ';
918: }
919: szFS[0] = '\0';
920: for (j=0; j < caftos; j++) {
921: if (npAccel->fs & aaftos[j].usBit)
922: strcat(szFS, aaftos[j].szBit);
923: }
924:
925: cch=sprintf(szTemp, " fs:%x key:%x(%s) cmd:%x - %s",
926: npAccel->fs, npAccel->key, pszChar, npAccel->cmd, szFS);
927: OutputString(szTemp, cch);
928: npAccel++;
929: }
930:
931: // And free the memory we allocated
932: WinFreeMem(hHeap, (NPBYTE)npAcclTbl, cbAccel);
933: }
934:
935:
936: /**************************** Public Function ******************************\
937: * SelOrDeselWithMouse(BOOL fSelect)
938: *
939: * Effects: Fastway to add/or remove window from watch list
940: *
941: * Return value: none
942: \***************************************************************************/
943:
944: void SelOrDeselWithMouse(fSelect)
945: BOOL fSelect;
946: {
947: HWND rghwnd[MAXHWNDS];
948: HWND hwndPoint;
949: SHORT chwnd;
950: BOOL fWinCurInList;
951: SHORT i;
952:
953: /* First get the window of interest */
954: hwndPoint = HwndSelWinWithMouse(hwndSpy, NULL, FALSE);
955: if (hwndPoint == NULL)
956: return; /* No window selected */
957: fWinCurInList = SpyFWindowInList(hwndPoint, TRUE);
958:
959: if ((fWinCurInList && fSelect)
960: || (!fWinCurInList && !fSelect))
961: return; /* Alredy right state */
962:
963: chwnd = SpyGetWindowList(MAXHWNDS, (HWND FAR *)rghwnd);
964:
965: if (fSelect) {
966: /* Add window to end of list */
967: rghwnd[chwnd++] = hwndPoint;
968: } else {
969: /* find it in the list, and delete it out */
970: for (i=0; rghwnd[i] != hwndPoint; i++)
971: ;
972:
973: /* Now copy rest of them down */
974: chwnd--; /* One less item */
975: for (;i < chwnd; i++ ) {
976: rghwnd[i] = rghwnd[i+1];
977: }
978: }
979:
980: /* Now call to update the list */
981: SpySetWindowList(chwnd, (HWND FAR *)rghwnd);
982: }
983:
984:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.