home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / w3_prog / ddjwin.arj / PROPVIEW.LZH / PROPVIEW.C < prev    next >
Text File  |  1991-07-08  |  40KB  |  2,163 lines

  1. /*****************************************************************************
  2.  
  3.     PROGRAM        : PropView (c) 1991 All rights reserved
  4.     AUTHOR        : Mike Klein
  5.     VERSION        : 1.5
  6.     FILE        : propview.exe
  7.     FINISHED    : 07-08-91
  8.  
  9.     REQUIREMENTS: Windows 3.x
  10.  
  11.     PURPOSE        : Point to any window on screen and view info/properties, and
  12.                   send messages to window too.
  13.  
  14. *****************************************************************************/
  15.  
  16.  
  17. #define NOCOMM                                                                                      
  18.  
  19. #include <windows.h>
  20. #include <direct.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. #include "propview.h"
  26.  
  27. static HWND        hDlgPropView;
  28. static HANDLE    hInstPropView;
  29. static HWND        hDlgActive;
  30. static HWND        hWndTarget;
  31. static HWND     hDlgChildren;
  32. static HWND     hDlgProperties;
  33. static HWND     hDlgSendMsg;
  34. static HWND     hDlgExtraData;
  35. static HWND     hDlgStyles;
  36.  
  37. static BYTE Text[100];
  38.  
  39. static BOOL Capturing = FALSE;
  40.  
  41. static FARPROC lpEnumWindowPropsProc;
  42. static FARPROC lpEnumChildrenProc;
  43.  
  44. static BOOL ShowHex            = TRUE;
  45. static BOOL ShowScreenCoord    = TRUE;
  46.  
  47.  
  48. //
  49. // Some internally used functions
  50. //
  51.  
  52. VOID PASCAL ExamineWindow(HWND);
  53. VOID PASCAL DrawIcons(VOID);
  54. VOID PASCAL OutlineWindow(HWND);
  55. VOID PASCAL UpdatePos(VOID);
  56.  
  57.  
  58. /*****************************************************************************
  59.  
  60.     FUNCTION: WinMain
  61.  
  62.     PURPOSE : Calls initialization function, processes message loop
  63.  
  64. *****************************************************************************/
  65.  
  66. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
  67.     int nCmdShow)
  68. {
  69.     WNDCLASS    wc;
  70.     MSG            msg;
  71.  
  72.     int ChildTabs[3];
  73.     int PropTab;
  74.  
  75.     int            hFile;
  76.     BYTE        Msg[81];
  77.     BYTE        Hex[5];
  78.     OFSTRUCT    OFstruct;
  79.  
  80.     //
  81.     // See if a version of Propview is already running
  82.     //
  83.  
  84.     if(!hPrevInstance)
  85.     {
  86.         hInstPropView = hInstance;
  87.  
  88.         //
  89.         // Fill in window class structure with parameters that describe the
  90.         // main window.
  91.         //
  92.  
  93.         wc.lpszClassName = (LPSTR) "PropView";
  94.         wc.lpfnWndProc   = MainWndProc;
  95.         wc.hInstance     = hInstPropView;
  96.         wc.lpszMenuName  = (LPSTR) "PropView";
  97.         wc.style         = CS_DBLCLKS;
  98.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  99.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  100.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  101.         wc.cbClsExtra    = 0;
  102.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  103.  
  104.         if(!RegisterClass((LPWNDCLASS) &wc))
  105.         {
  106.             return(FALSE);
  107.         }
  108.  
  109.         //
  110.         // Fill in window class structure with parameters that describe the
  111.         // single-listbox window.
  112.         //
  113.  
  114.         wc.lpszClassName = (LPSTR) "SingleViewer";
  115.         wc.lpfnWndProc   = GenericViewerWndProc;
  116.         wc.hInstance     = hInstPropView;
  117.         wc.lpszMenuName  = NULL;
  118.         wc.style         = CS_DBLCLKS;
  119.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  120.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  121.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  122.         wc.cbClsExtra    = 0;
  123.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  124.  
  125.         if(!RegisterClass((LPWNDCLASS) &wc))
  126.         {
  127.             return(FALSE);
  128.         }
  129.  
  130.         //
  131.         // Fill in window class structure with parameters that describe the
  132.         // double-listbox window.
  133.         //
  134.  
  135.         wc.lpszClassName = (LPSTR) "DoubleViewer";
  136.         wc.lpfnWndProc   = GenericViewerWndProc;
  137.         wc.hInstance     = hInstPropView;
  138.         wc.lpszMenuName  = NULL;
  139.         wc.style         = CS_DBLCLKS;
  140.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  141.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  142.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  143.         wc.cbClsExtra    = 0;
  144.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  145.  
  146.         if(!RegisterClass((LPWNDCLASS) &wc))
  147.         {
  148.             return(FALSE);
  149.         }
  150.  
  151.         //
  152.         // Fill in window class structure with parameters that describe the
  153.         // message sending window.
  154.         //
  155.  
  156.         wc.lpszClassName = (LPSTR) "SendMsg";
  157.         wc.lpfnWndProc   = SendMsgWndProc;
  158.         wc.hInstance     = hInstPropView;
  159.         wc.lpszMenuName  = NULL;
  160.         wc.style         = CS_DBLCLKS;
  161.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  162.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  163.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  164.         wc.cbClsExtra    = 0;
  165.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  166.  
  167.         if(!RegisterClass((LPWNDCLASS) &wc))
  168.         {
  169.             return(FALSE);
  170.         }
  171.  
  172.         //
  173.         // Create the main window PropView
  174.         //
  175.  
  176.         CreateDialog
  177.         (
  178.             hInstPropView,
  179.             "PropView",
  180.             NULL,
  181.             NULL
  182.         );
  183.  
  184.         //
  185.         // Make procedure instances for enum functions
  186.         //
  187.  
  188.         if((lpEnumWindowPropsProc =
  189.             MakeProcInstance(EnumWindowPropsProc, hInstPropView)) == NULL)
  190.         {
  191.             return(FALSE);
  192.         }
  193.  
  194.         if((lpEnumChildrenProc =
  195.             MakeProcInstance(EnumChildrenProc, hInstPropView)) == NULL)
  196.         {
  197.             return(FALSE);
  198.         }
  199.  
  200.         //
  201.         // Create the Children window & set caption
  202.         //
  203.  
  204.         if((hDlgChildren = CreateDialog
  205.         (
  206.             hInstPropView,
  207.             "SingleViewer",
  208.             hDlgPropView,
  209.             0L
  210.         )) == NULL)
  211.         {
  212.             return(FALSE);
  213.         }
  214.  
  215.         SetWindowText(hDlgChildren, (LPSTR) "No Children");
  216.         SetDlgItemText
  217.         (
  218.             hDlgChildren,
  219.             IDC_STATIC,
  220.             (LPSTR) "Class\t\tCtrlID\thWnd\tCaption"
  221.         );
  222.  
  223.         //
  224.         // Create the Properties window & set caption
  225.         //
  226.  
  227.         if((hDlgProperties = CreateDialog
  228.         (
  229.             hInstPropView,
  230.             "SingleViewer",
  231.             hDlgPropView,
  232.             0L
  233.         )) == NULL)
  234.         {
  235.             return(FALSE);
  236.         }
  237.  
  238.         SetWindowText(hDlgProperties, (LPSTR) "No Properties");
  239.         SetDlgItemText(hDlgProperties, IDC_STATIC, (LPSTR) "Property\tValue");
  240.  
  241.         //
  242.         // Set tabs for children and properties list boxes
  243.         //
  244.  
  245.         ChildTabs[0] = 53;
  246.         ChildTabs[1] = 82;
  247.         ChildTabs[2] = 111;
  248.  
  249.         SendDlgItemMessage
  250.         (
  251.             hDlgChildren,
  252.             IDC_LISTBOX,
  253.             LB_SETTABSTOPS,
  254.             3,
  255.             (LONG) (LPINT) &ChildTabs
  256.         );
  257.  
  258.         PropTab = 50;
  259.  
  260.         SendDlgItemMessage
  261.         (
  262.             hDlgProperties,
  263.             IDC_LISTBOX,
  264.             LB_SETTABSTOPS,
  265.             1,
  266.             (LONG) (LPINT) &PropTab
  267.         );
  268.  
  269.         //
  270.         // Create the Data window
  271.         //
  272.  
  273.         if((hDlgExtraData = CreateDialog
  274.         (
  275.             hInstPropView,
  276.             "DoubleViewer",
  277.             hDlgPropView,
  278.             0L
  279.         )) == NULL)
  280.         {
  281.             return(FALSE);
  282.         }
  283.  
  284.         SetWindowText(hDlgExtraData, (LPSTR) "Extra Data");
  285.  
  286.         //
  287.         // Create the Styles window
  288.         //
  289.  
  290.         if((hDlgStyles = CreateDialog
  291.         (
  292.             hInstPropView,
  293.             "DoubleViewer",
  294.             hDlgPropView,
  295.             0L
  296.         )) == NULL)
  297.         {
  298.             return(FALSE);
  299.         }
  300.  
  301.         SetWindowText(hDlgStyles, (LPSTR) "Styles");
  302.  
  303.         //
  304.         // Create the SendMsg window
  305.         //
  306.  
  307.         if((hDlgSendMsg = CreateDialog
  308.         (
  309.             hInstPropView,
  310.             "SendMsg",
  311.             hDlgPropView,
  312.             0L
  313.         )) == NULL)
  314.         {
  315.             return(FALSE);
  316.         }
  317.  
  318.         //
  319.         // Fill the msgs combobox in SendMsg dialog
  320.         //
  321.  
  322.         hFile = OpenFile("wm.msg", (LPOFSTRUCT) &OFstruct, OF_READ);
  323.  
  324.         if(hFile != -1)
  325.         {
  326.             FILE *fp = fdopen(hFile, "r");
  327.  
  328.             while(fscanf(fp,"%22s%4s", Msg, Hex) != EOF )
  329.             {
  330.                 if(Msg[0] != 'W')
  331.                 {
  332.                     break;
  333.                 }
  334.  
  335.                 wsprintf((LPSTR) Text, "%-35.35s %s", (LPSTR) &Msg[3], (LPSTR) Hex);
  336.  
  337.                 SendDlgItemMessage
  338.                 (
  339.                     hDlgSendMsg,
  340.                     IDC_MESSAGES,
  341.                     CB_ADDSTRING,
  342.                     0,
  343.                     (LONG) (LPSTR) Text
  344.                 );
  345.             }
  346.  
  347.             fclose(fp);
  348.         }
  349.  
  350.         //
  351.         // Check some radiobutton defaults
  352.         //
  353.  
  354.         CheckRadioButton(hDlgPropView, IDC_HEX, IDC_DEC, IDC_HEX);
  355.         CheckRadioButton(hDlgPropView, IDC_SCREEN, IDC_DIALOG, IDC_SCREEN);
  356.     }
  357.     else
  358.     {
  359.         //
  360.         // If there was another instance of PropView running, then switch to
  361.         // it by finding any window of class = "PropView". Then, if it's an
  362.         // icon, open the window, otherwise just make it active.
  363.         //
  364.  
  365.         if(hDlgPropView = FindWindow("PropView", NULL))
  366.         {
  367.             if(IsIconic(hDlgPropView))
  368.             {
  369.                 ShowWindow(hDlgPropView, SW_SHOWNORMAL);
  370.             }
  371.  
  372.             SetActiveWindow(hDlgPropView);
  373.         }
  374.         return(FALSE);
  375.     }
  376.  
  377.     //
  378.     // Acquire and dispatch messages until a WM_QUIT message is received.
  379.     // The window handle hDlgActive points to the currently active window,
  380.     // and is used to identify and process keystrokes going to any modeless
  381.     // dialog box.
  382.     //
  383.  
  384.     while(GetMessage((LPMSG) &msg, NULL, NULL, NULL))
  385.     {
  386.         if(hDlgActive != NULL)
  387.         {
  388.             if(!IsDialogMessage(hDlgActive, (LPMSG) &msg))
  389.             {
  390.                 TranslateMessage((LPMSG) &msg);
  391.                 DispatchMessage((LPMSG) &msg);
  392.             }
  393.         }
  394.         else
  395.         {
  396.             TranslateMessage((LPMSG) &msg);
  397.             DispatchMessage((LPMSG) &msg);
  398.         }
  399.     }
  400.  
  401.     FreeProcInstance(lpEnumWindowPropsProc);
  402.     FreeProcInstance(lpEnumChildrenProc);
  403. }
  404.  
  405.  
  406. /*****************************************************************************
  407.  
  408.     FUNCTION: MainWndProc
  409.  
  410.     PURPOSE : Processes messages for PropView dialog box
  411.  
  412. *****************************************************************************/
  413.  
  414. LONG FAR PASCAL MainWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  415. {
  416.     HWND    hWndTemp;
  417.     POINT    Point;
  418.  
  419.     FARPROC lpProc;
  420.  
  421.     //
  422.     // Switch stmt for acting on msgs
  423.     //
  424.  
  425.     switch(wMsg)
  426.     {
  427.         case WM_CREATE :
  428.  
  429.             hDlgPropView = hWnd;
  430.             break;
  431.  
  432.         case WM_MOUSEMOVE :
  433.  
  434.             //
  435.             // Check to see if we're capturing or not
  436.             //
  437.  
  438.             if(!Capturing)
  439.             {
  440.                 return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  441.             }
  442.  
  443.             //
  444.             // Find out the window to query. Abort if same as last hWnd
  445.             //
  446.  
  447.             GetCursorPos((LPPOINT) &Point);
  448.  
  449.             if((hWndTemp = WindowFromPoint(Point)) == NULL)
  450.             {
  451.                 break;
  452.             }
  453.  
  454.             //
  455.             // Screen out if same window
  456.             //
  457.  
  458.             if
  459.             (
  460.                 (hWndTemp != hWndTarget) &&
  461.                 (hWndTemp != hDlgPropView) &&
  462.                 (GetParent(hWndTemp) != hDlgPropView)
  463.             )
  464.             {
  465.                 ExamineWindow(hWndTemp);
  466.             }
  467.  
  468.             UpdatePos();
  469.             break;
  470.  
  471.         case WM_LBUTTONDOWN :
  472.         case WM_MBUTTONDOWN :
  473.         case WM_RBUTTONDOWN :
  474.  
  475.             //
  476.             // Any mouse button press cancels capture mode
  477.             //
  478.  
  479.             if(Capturing)
  480.             {
  481.                 Capturing = FALSE;
  482.                 ReleaseCapture();
  483.             }
  484.  
  485.             break;
  486.  
  487.         case WM_COMMAND :
  488.  
  489.             switch(wParam)
  490.             {
  491.                 case IDOK     :
  492.                 case IDCANCEL :
  493.  
  494.                     SendMessage(hWnd, WM_CLOSE, 0, 0L);
  495.                     break;
  496.  
  497.                 case IDC_HEX :
  498.  
  499.                     ShowHex = TRUE;
  500.                     ExamineWindow(hWndTarget);
  501.                     UpdatePos();
  502.                     return(0L);
  503.  
  504.                 case IDC_DEC :
  505.  
  506.                     ShowHex = FALSE;
  507.                     ExamineWindow(hWndTarget);
  508.                     UpdatePos();
  509.                     return(0L);
  510.  
  511.                 case IDC_SCREEN :
  512.  
  513.                     ShowScreenCoord = TRUE;
  514.                     ExamineWindow(hWndTarget);
  515.                     UpdatePos();
  516.                     return(0L);
  517.  
  518.                 case IDC_DIALOG :
  519.  
  520.                     ShowScreenCoord = FALSE;
  521.                     ExamineWindow(hWndTarget);
  522.                     UpdatePos();
  523.                     return(0L);
  524.  
  525.                 case IDC_SPY :
  526.  
  527.                     //
  528.                     // Run a copy of Spy
  529.                     //
  530.  
  531.                     WinExec("spy", SW_SHOWNORMAL);
  532.                     return(0L);
  533.  
  534.                 case IDC_CHILDREN :
  535.  
  536.                     //
  537.                     // Show/hide the "children" window
  538.                     //
  539.  
  540.                     if(IsWindowVisible(hDlgChildren))
  541.                     {
  542.                         ShowWindow(hDlgChildren, SW_HIDE);
  543.                     }
  544.                     else
  545.                     {
  546.                         ShowWindow(hDlgChildren, SW_SHOWNORMAL);
  547.                     }
  548.                     return(0L);
  549.  
  550.                 case IDC_SENDMSG :
  551.  
  552.                     //
  553.                     // Show/hide the "SendMsg" dialog
  554.                     //
  555.  
  556.                     if(IsWindowVisible(hDlgSendMsg))
  557.                     {
  558.                         ShowWindow(hDlgSendMsg, SW_HIDE);
  559.                     }
  560.                     else
  561.                     {
  562.                         ShowWindow(hDlgSendMsg, SW_SHOWNORMAL);
  563.                     }
  564.                     return(0L);
  565.  
  566.                 case IDC_DATA :
  567.  
  568.                     //
  569.                     // Show/hide the window/class data dialog
  570.                     //
  571.  
  572.                     if(IsWindowVisible(hDlgExtraData))
  573.                     {
  574.                         ShowWindow(hDlgExtraData, SW_HIDE);
  575.                     }
  576.                     else
  577.                     {
  578.                         ShowWindow(hDlgExtraData, SW_SHOWNORMAL);
  579.                     }
  580.                     return(0L);
  581.  
  582.                 case IDC_STYLES :
  583.  
  584.                     //
  585.                     // Show/hide the window/class data dialog
  586.                     //
  587.  
  588.                     if(IsWindowVisible(hDlgStyles))
  589.                     {
  590.                         ShowWindow(hDlgStyles, SW_HIDE);
  591.                     }
  592.                     else
  593.                     {
  594.                         ShowWindow(hDlgStyles, SW_SHOWNORMAL);
  595.                     }
  596.                     return(0L);
  597.  
  598.                 case IDC_PROPERTIES :
  599.  
  600.                     //
  601.                     // Show/hide the window properties dialog
  602.                     //
  603.  
  604.                     if(IsWindowVisible(hDlgProperties))
  605.                     {
  606.                         ShowWindow(hDlgProperties, SW_HIDE);
  607.                     }
  608.                     else
  609.                     {
  610.                         ShowWindow(hDlgProperties, SW_SHOWNORMAL);
  611.                     }
  612.                     return(0L);
  613.  
  614.                 case IDM_ABOUT :
  615.  
  616.                     //
  617.                     // Bring up the modal About dialog box
  618.                     //
  619.  
  620.                     lpProc = MakeProcInstance(About, hInstPropView);
  621.                     DialogBox(hInstPropView, "About", hWnd, lpProc);
  622.                     FreeProcInstance(lpProc);
  623.                     return(0L);
  624.  
  625.                 case IDM_EXIT :
  626.  
  627.                     SendMessage(hWnd, WM_CLOSE, 0, 0L);
  628.                     return(0L);
  629.  
  630.                 case IDM_GO :
  631.  
  632.                     Capturing = TRUE;
  633.                     SetCapture(hWnd);
  634.                     return(0L);
  635.  
  636.                 default :
  637.  
  638.                     break;
  639.             }
  640.  
  641.             break;
  642.  
  643.         case WM_PAINT :
  644.  
  645.             if(hWndTarget != NULL)
  646.             {
  647.                 DrawIcons();
  648.  
  649.                 //
  650.                 // Validate areas we just painted so WM_PAINT doesn't
  651.                 //
  652.  
  653.                 ValidateRect(GetDlgItem(hDlgPropView, IDC_HWNDICON), NULL);
  654.                 ValidateRect(GetDlgItem(hDlgPropView, IDC_PARENTICON), NULL);
  655.             }
  656.  
  657.             break;
  658.  
  659.         case WM_CLOSE                :
  660.  
  661.             DestroyWindow(hWnd);
  662.             return(0L);
  663.  
  664.         case WM_ACTIVATE             :
  665.  
  666.             hDlgActive = (wParam == NULL) ? NULL : hWnd;
  667.             break;
  668.  
  669.         case WM_DESTROY              :
  670.  
  671.             PostQuitMessage(0);
  672.             return(0L);
  673.  
  674.         default                      :
  675.  
  676.             break;
  677.     }
  678.  
  679.     return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  680. }
  681.  
  682.  
  683. /*****************************************************************************
  684.  
  685.     FUNCTION: GenericViewerWndProc
  686.  
  687.     PURPOSE : Processes messages for generic listbox display window
  688.  
  689. *****************************************************************************/
  690.  
  691. LONG FAR PASCAL GenericViewerWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  692. {
  693.     BYTE Entry[50];
  694.     BYTE *ptr;
  695.     HWND hWndTemp;
  696.  
  697.     int Index;
  698.  
  699.     //
  700.     // Switch stmt for acting on msgs
  701.     //
  702.  
  703.     switch(wMsg)
  704.     {
  705.         case WM_COMMAND :
  706.  
  707.             switch(wParam)
  708.             {
  709.                 case IDC_LISTBOX :
  710.  
  711.                     if(HIWORD(lParam) == LBN_DBLCLK)
  712.                     {
  713.                         //
  714.                         // Get index of entry in listbox clicked on
  715.                         //
  716.  
  717.                         if((Index = (int) SendDlgItemMessage
  718.                         (
  719.                             hWnd,
  720.                             IDC_LISTBOX,
  721.                             LB_GETCURSEL,
  722.                             0,
  723.                             0L
  724.                         )) == LB_ERR)
  725.                         {
  726.                             break;
  727.                         }
  728.  
  729.                         //
  730.                         // Get entry text
  731.                         //
  732.  
  733.                         SendDlgItemMessage
  734.                         (
  735.                             hWnd,
  736.                             IDC_LISTBOX,
  737.                             LB_GETTEXT,
  738.                             Index,
  739.                             (LONG) (LPSTR) Entry
  740.                         );
  741.  
  742.                         if(hDlgChildren == hWnd)
  743.                         {
  744.                             if(Entry[0] == '\"')
  745.                             {
  746.                                 //
  747.                                 // This is when parent entry of ".." was
  748.                                 // selected
  749.                                 //
  750.  
  751.                                 ExamineWindow(GetParent(hWndTarget));
  752.                             }
  753.                             else
  754.                             {
  755.                                 //
  756.                                 // Pull out the hWnd field of the child
  757.                                 // window we want to examine.
  758.                                 //
  759.  
  760.                                 if(ptr = strrchr(Entry, '\t'))
  761.                                 {
  762.                                     if(*(ptr + 1) == '\"')
  763.                                     {
  764.                                         while(--ptr)
  765.                                         {
  766.                                             if(*ptr == '\t')
  767.                                             {
  768.                                                 break;
  769.                                             }
  770.                                         }
  771.                                     }
  772.                                     else
  773.                                     {
  774.                                         ++ptr;
  775.                                     }
  776.  
  777.                                     if(ShowHex)
  778.                                     {
  779.                                         sscanf(ptr, "%x", &hWndTemp);
  780.                                     }
  781.                                     else
  782.                                     {
  783.                                         sscanf(ptr, "%d", &hWndTemp);
  784.                                     }
  785.  
  786.                                     ExamineWindow(hWndTemp);
  787.                                 }
  788.                             }
  789.                         }
  790.                     }
  791.  
  792.                     return(0L);
  793.  
  794.                 default :
  795.  
  796.                     break;
  797.             }
  798.  
  799.             break;
  800.  
  801.         case WM_CLOSE :
  802.  
  803.             if(IsWindowVisible(hWnd))
  804.             {
  805.                 ShowWindow(hWnd, SW_HIDE);
  806.             }
  807.             else
  808.             {
  809.                 ShowWindow(hWnd, SW_SHOWNORMAL);
  810.             }
  811.             return(0L);
  812.  
  813.         case WM_SIZE :
  814.  
  815.             if(wParam != SIZEICONIC)
  816.             {
  817.                 if
  818.                 (
  819.                     hWnd == hDlgChildren ||
  820.                     hWnd == hDlgProperties
  821.                 )
  822.                 {
  823.                     //
  824.                     // For SingleViewer dialogs...
  825.                     //
  826.                     // Resize the static text ctrl & list box ctrl so
  827.                     // that they fill the size of the resized dialog
  828.                     //
  829.  
  830.                     if(GetDlgItem(hWnd, IDC_STATIC))
  831.                     {
  832.                         MoveWindow
  833.                         (
  834.                             GetDlgItem(hWnd, IDC_STATIC),
  835.                             0,
  836.                             0,
  837.                             LOWORD(lParam),
  838.                             12,
  839.                             TRUE
  840.                         );
  841.                     }
  842.  
  843.                     if(GetDlgItem(hWnd, IDC_LISTBOX))
  844.                     {
  845.                         MoveWindow
  846.                         (
  847.                             GetDlgItem(hWnd, IDC_LISTBOX),
  848.                             0,
  849.                             12,
  850.                             LOWORD(lParam),
  851.                             HIWORD(lParam) - 12,
  852.                             TRUE
  853.                         );
  854.                     }
  855.                     InvalidateRect(GetDlgItem(hWnd, IDC_STATIC), NULL, TRUE);
  856.                 }
  857.                 else
  858.                 {
  859.                     WORD Width    = LOWORD(lParam);
  860.                     WORD Height    = HIWORD(lParam);
  861.  
  862.                     //
  863.                     // For DoubleViewer dialogs...
  864.                     //
  865.                     // Resize both of the static text ctrls & list box
  866.                     // ctrls so that they fill the size of the resized
  867.                     // dialog.
  868.                     //
  869.  
  870.                     if(GetDlgItem(hWnd, IDC_WNDTEXT))
  871.                     {
  872.                         MoveWindow
  873.                         (
  874.                             GetDlgItem(hWnd, IDC_WNDTEXT),
  875.                             4,
  876.                             4,
  877.                             Width / 2 - 8,
  878.                             12,
  879.                             TRUE
  880.                         );
  881.                     }
  882.  
  883.                     if(GetDlgItem(hWnd, IDC_CLSTEXT))
  884.                     {
  885.                         MoveWindow
  886.                         (
  887.                             GetDlgItem(hWnd, IDC_CLSTEXT),
  888.                             Width / 2 + 2,
  889.                             4,
  890.                             Width / 2 - 8,
  891.                             12,
  892.                             TRUE
  893.                         );
  894.                     }
  895.  
  896.                     if(GetDlgItem(hWnd, IDC_WNDLIST))
  897.                     {
  898.                         MoveWindow
  899.                         (
  900.                             GetDlgItem(hWnd, IDC_WNDLIST),
  901.                             4,
  902.                             19,
  903.                             Width / 2 - 8,
  904.                             Height - (18 + 4),
  905.                             TRUE
  906.                         );
  907.                     }
  908.  
  909.                     if(GetDlgItem(hWnd, IDC_CLSLIST))
  910.                     {
  911.                         MoveWindow
  912.                         (
  913.                             GetDlgItem(hWnd, IDC_CLSLIST),
  914.                             Width / 2 + 2,
  915.                             19,
  916.                             Width / 2 - 8,
  917.                             Height - (18 + 4),
  918.                             TRUE
  919.                         );
  920.                     }
  921.  
  922.                     InvalidateRect(GetDlgItem(hWnd, IDC_WNDTEXT), NULL, TRUE);
  923.                     InvalidateRect(GetDlgItem(hWnd, IDC_CLSTEXT), NULL, TRUE);
  924.                 }
  925.             }
  926.             break;
  927.  
  928.         case WM_ACTIVATE :
  929.  
  930.             hDlgActive = (wParam == NULL) ? NULL : hWnd;
  931.             break;
  932.  
  933.         default :
  934.             
  935.             break;
  936.     }
  937.  
  938.     return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  939. }
  940.  
  941.  
  942. /*****************************************************************************
  943.  
  944.     FUNCTION: SendMsgWndProc
  945.  
  946.     PURPOSE : Processes messages for message sending dialog
  947.  
  948. *****************************************************************************/
  949.  
  950. LONG FAR PASCAL SendMsgWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  951. {
  952.     BYTE hWndText[7];
  953.     BYTE MsgText[50];
  954.     BYTE Msg[81];
  955.     BYTE wParamText[5];
  956.     BYTE lParamText[10];
  957.  
  958.     //
  959.     // Switch stmt for acting on msgs
  960.     //
  961.  
  962.     switch(wMsg)
  963.     {
  964.         case WM_COMMAND :
  965.  
  966.             switch(wParam)
  967.             {
  968.                 case IDOK :
  969.  
  970.                     SendMessage(hWnd, WM_CLOSE, 0, 0L);
  971.                     return(0L);
  972.  
  973.                 case IDC_SEND :
  974.  
  975.                     //
  976.                     // Send message to target window
  977.                     //
  978.  
  979.                     GetDlgItemText
  980.                     (
  981.                         hWnd,
  982.                         IDC_HWNDTOSEND,
  983.                         (LPSTR) hWndText,
  984.                         sizeof(hWndText)
  985.                     );
  986.                     GetDlgItemText
  987.                     (
  988.                         hWnd,
  989.                         IDC_MESSAGES,
  990.                         (LPSTR) MsgText,
  991.                         sizeof(MsgText)
  992.                     );
  993.                     GetDlgItemText
  994.                     (
  995.                         hWnd,
  996.                         IDC_WPARAM,
  997.                         (LPSTR) wParamText,
  998.                         sizeof(wParamText)
  999.                     );
  1000.                     GetDlgItemText
  1001.                     (
  1002.                         hWnd,
  1003.                         IDC_LPARAM,
  1004.                         (LPSTR) lParamText,
  1005.                         sizeof(lParamText)
  1006.                     );
  1007.  
  1008.                     //
  1009.                     // Check for parms not filled in or null window handle
  1010.                     //
  1011.  
  1012.                     if
  1013.                     (
  1014.                         hWndText[0] == '\0' ||
  1015.                         MsgText[0] == '\0' ||
  1016.                         wParamText[0] == '\0' ||
  1017.                         lParamText[0] == '\0' ||
  1018.                         !IsWindow(hWndTarget)
  1019.                     )
  1020.                     {
  1021.                         return(0L);;
  1022.                     }
  1023.  
  1024.                     lstrcpy((LPSTR) Msg, (LPSTR) &MsgText[36]);
  1025.  
  1026.                     if(ShowHex)
  1027.                     {
  1028.                         hWnd    = (HWND) strtol(hWndText, NULL, 16);
  1029.                         wMsg    = (WORD) strtol(Msg, NULL, 16);
  1030.                         wParam    = (WORD) strtol(wParamText, NULL, 16);
  1031.                         lParam    = (DWORD) strtol(lParamText, NULL, 16);
  1032.                     }
  1033.                     else
  1034.                     {
  1035.                         hWnd    = (HWND) strtol(hWndText, NULL, 10);
  1036.                         wMsg    = (WORD) strtol(Msg, NULL, 10);
  1037.                         wParam    = (WORD) strtol(wParamText, NULL, 10);
  1038.                         lParam    = (DWORD) strtol(lParamText, NULL, 10);
  1039.                     }
  1040.  
  1041.                     if(PostMessage(hWnd, wMsg, wParam, lParam) == FALSE)
  1042.                        {
  1043.                         MessageBeep(0);
  1044.                            MessageBox
  1045.                         (
  1046.                             hDlgSendMsg,
  1047.                             "PostMessage() failed",
  1048.                             "ERROR",
  1049.                             MB_ICONEXCLAMATION | MB_OK
  1050.                         );
  1051.                     }
  1052.  
  1053.                     SetActiveWindow(hDlgSendMsg);
  1054.                     return(0L);
  1055.  
  1056.                 default :
  1057.  
  1058.                     break;
  1059.             }
  1060.  
  1061.             break;
  1062.  
  1063.         case WM_CLOSE :
  1064.  
  1065.             if(IsWindowVisible(hWnd))
  1066.             {
  1067.                 ShowWindow(hWnd, SW_HIDE);
  1068.             }
  1069.             else
  1070.             {
  1071.                 ShowWindow(hWnd, SW_SHOWNORMAL);
  1072.             }
  1073.             return(0L);
  1074.  
  1075.         case WM_ACTIVATE :
  1076.  
  1077.             hDlgActive = (wParam == NULL) ? NULL : hWnd;
  1078.             break;
  1079.  
  1080.         default :
  1081.             
  1082.             break;
  1083.     }
  1084.  
  1085.     return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  1086. }
  1087.  
  1088.  
  1089. /*****************************************************************************
  1090.  
  1091.     FUNCTION: UpdatePos
  1092.  
  1093.     PURPOSE : Updates cursor information in dialog
  1094.  
  1095. *****************************************************************************/
  1096.  
  1097. VOID PASCAL UpdatePos(VOID)
  1098. {
  1099.     POINT    Point;
  1100.     POINT    Client;
  1101.  
  1102.     if(hWndTarget == NULL)
  1103.     {
  1104.         return;
  1105.     }
  1106.  
  1107.     //
  1108.     // Get some cursor information
  1109.     //
  1110.  
  1111.     GetCursorPos((LPPOINT) &Point);
  1112.  
  1113.     if(ShowScreenCoord == FALSE)
  1114.     {
  1115.         LONG Units = GetDialogBaseUnits();
  1116.         WORD Xamt = LOWORD(Units);
  1117.         WORD Yamt = HIWORD(Units);
  1118.  
  1119.         Point.x    = (Point.x * 4 ) / Xamt;
  1120.         Point.y    = (Point.y * 4 ) / Yamt;
  1121.     }
  1122.  
  1123.     if((hWndTarget != NULL) && (GetParent(hWndTarget) != NULL))
  1124.     {
  1125.         Client.x = Point.x;
  1126.         Client.y = Point.y;
  1127.  
  1128.         ScreenToClient(hWndTarget, (LPPOINT) &Client);
  1129.     }
  1130.     else
  1131.     {
  1132.         Client.x = 0;
  1133.         Client.y = 0;
  1134.     }
  1135.  
  1136.     if(ShowHex)
  1137.     {
  1138.         wsprintf
  1139.         (
  1140.             (LPSTR) Text,
  1141.             "Cursor = (0x%04x, 0x%04x), (0x%04x, 0x%04x)",
  1142.             Point.x,
  1143.             Point.y,
  1144.             Client.x,
  1145.             Client.y
  1146.         );
  1147.     }
  1148.     else
  1149.     {
  1150.         wsprintf
  1151.         (
  1152.             (LPSTR) Text,
  1153.             "Cursor = (%d, %d), (%d, %d)",
  1154.             Point.x,
  1155.             Point.y,
  1156.             Client.x,
  1157.             Client.y
  1158.         );
  1159.     }
  1160.  
  1161.     SetDlgItemText(hDlgPropView, IDC_POS, (LPSTR) Text);
  1162. }
  1163.  
  1164.  
  1165. /*****************************************************************************
  1166.  
  1167.     FUNCTION: ExamineWindow
  1168.  
  1169.     PURPOSE : Shows info on selected window (ie. children, parent, properties)
  1170.  
  1171. *****************************************************************************/
  1172.  
  1173. VOID PASCAL ExamineWindow(HWND hWnd)
  1174. {
  1175.     #define NUMCLASSSTYLES    11
  1176.     #define NUMWNDSTYLES    29
  1177.  
  1178.     HWND    hWndParent;
  1179.     BYTE    ModuleFileName[30];
  1180.     BYTE    ClassName[30];
  1181.     BYTE    hWndText[7];
  1182.     RECT    Rect;
  1183.     int        i;
  1184.     HANDLE    hInst;
  1185.  
  1186.     LONG    WndStyle;
  1187.     WORD    ClassStyle;
  1188.     WORD    WndExtraData;
  1189.     WORD    ClsExtraData;
  1190.  
  1191.     static struct
  1192.     {
  1193.         WORD    Style;
  1194.         LPSTR    Text;
  1195.     }
  1196.     ClassStyles[NUMCLASSSTYLES] =
  1197.     {
  1198.         {CS_BYTEALIGNCLIENT,    "CS_BYTEALIGNCLIENT"},
  1199.         {CS_BYTEALIGNWINDOW,    "CS_BYTEALIGNWINDOW"},
  1200.         {CS_CLASSDC,            "CS_CLASSDC"},
  1201.         {CS_DBLCLKS,            "CS_DBLCLKS"},
  1202.         {CS_GLOBALCLASS,        "CS_GLOBALCLASS"},
  1203.         {CS_HREDRAW,            "CS_HREDRAW"},
  1204.         {CS_NOCLOSE,            "CS_NOCLOSE"},
  1205.         {CS_OWNDC,                "CS_OWNDC"},
  1206.         {CS_PARENTDC,            "CS_PARENTDC"},
  1207.         {CS_SAVEBITS,            "CS_SAVEBITS"},
  1208.         {CS_VREDRAW,            "CS_VREDRAW"}
  1209.     };
  1210.  
  1211.     static struct
  1212.     {
  1213.         LONG    Style;
  1214.         LPSTR    Text;
  1215.     }
  1216.     WndStyles[NUMWNDSTYLES] =
  1217.     {
  1218.         {WS_POPUP,                "WS_POPUP"},
  1219.         {WS_OVERLAPPED,            "WS_OVERLAPPED"},
  1220.         {WS_CHILD,                "WS_CHILD"},
  1221.         {WS_MINIMIZE,            "WS_MINIMIZE"},
  1222.         {WS_VISIBLE,            "WS_VISIBLE"},
  1223.         {WS_DISABLED,            "WS_DISABLED"},
  1224.         {WS_CLIPSIBLINGS,        "WS_CLIPSIBLINGS"},
  1225.         {WS_CLIPCHILDREN,        "WS_CLIPCHILDREN"},
  1226.         {WS_MAXIMIZE,            "WS_MAXIMIZE"},
  1227.         {WS_CAPTION,            "WS_CAPTION"},
  1228.         {WS_BORDER,                "WS_BORDER"},
  1229.         {WS_DLGFRAME,            "WS_DLGFRAME"},
  1230.         {WS_VSCROLL,            "WS_VSCROLL"},
  1231.         {WS_HSCROLL,            "WS_HSCROLL"},
  1232.         {WS_SYSMENU,            "WS_SYSMENU"},
  1233.         {WS_THICKFRAME,            "WS_THICKFRAME"},
  1234.         {WS_GROUP,                "WS_GROUP"},
  1235.         {WS_TABSTOP,            "WS_TABSTOP"},
  1236.         {WS_MINIMIZEBOX,        "WS_MINIMIZEBOX"},
  1237.         {WS_MAXIMIZEBOX,        "WS_MAXIMIZEBOX"},
  1238.         {WS_EX_DLGMODALFRAME,    "WS_EX_DLGMODALFRAME"},
  1239.         {WS_EX_NOPARENTNOTIFY,    "WS_EX_NOPARENTNOTIFY"}
  1240.     };
  1241.  
  1242.     //
  1243.     // Check for NULL hWnd
  1244.     //
  1245.  
  1246.     if((hWnd == NULL) || !IsWindow(hWnd))
  1247.     {
  1248.         return;
  1249.     }
  1250.  
  1251.     //
  1252.     // We have a new target window
  1253.     //
  1254.  
  1255.     hWndTarget = hWnd;
  1256.  
  1257.     //
  1258.     // DRAW ICONS
  1259.     //
  1260.  
  1261.     DrawIcons();
  1262.  
  1263.     //
  1264.     // Turn on outline of target window
  1265.     //
  1266.  
  1267.     OutlineWindow(hWndTarget);
  1268.  
  1269.     //
  1270.     // Update the hWnd in the SendMsg dialog
  1271.     //
  1272.  
  1273.     if(ShowHex)
  1274.     {
  1275.         wsprintf(hWndText, "0x%04x", hWndTarget);
  1276.     }    
  1277.     else
  1278.     {
  1279.         wsprintf(hWndText, "%d", hWndTarget);
  1280.     }    
  1281.  
  1282.     SetDlgItemText(hDlgSendMsg, IDC_HWNDTOSEND, (LPSTR) hWndText);
  1283.  
  1284.     //
  1285.     // Display different window stats
  1286.     //
  1287.  
  1288.     GetClassName(hWnd, (LPSTR) ClassName, sizeof(ClassName));
  1289.  
  1290.     if(ShowHex)
  1291.     {
  1292.         wsprintf
  1293.         (
  1294.             (LPSTR) Text,
  1295.             "= 0x%04x (0x%04x), %s",
  1296.             hWnd,
  1297.             GetDlgCtrlID(hWnd),
  1298.             (LPSTR) ClassName
  1299.         );
  1300.     }
  1301.     else
  1302.     {
  1303.         wsprintf
  1304.         (
  1305.             (LPSTR) Text,
  1306.             "= %d (%d), %s",
  1307.             hWnd,
  1308.             GetDlgCtrlID(hWnd),
  1309.             (LPSTR) ClassName
  1310.         );
  1311.     }
  1312.  
  1313.     SetDlgItemText(hDlgPropView, IDC_HWND, (LPSTR) Text);
  1314.  
  1315.     if(!GetWindowText(hWnd, (LPSTR) Text, sizeof(Text)))
  1316.     {
  1317.         Text[0] = '\0';
  1318.     }
  1319.  
  1320.     SetDlgItemText(hDlgPropView, IDC_CAPTION, (LPSTR) Text);
  1321.  
  1322.     if((hWndParent = GetParent(hWnd)) != NULL)
  1323.     {
  1324.         GetClassName(hWndParent, (LPSTR) ClassName, sizeof(ClassName));
  1325.  
  1326.         if(ShowHex)
  1327.         {
  1328.             wsprintf
  1329.             (
  1330.                 (LPSTR) Text,
  1331.                 "= 0x%04x (0x%04x), %s",
  1332.                 hWndParent,
  1333.                 GetDlgCtrlID(hWndParent),
  1334.                 (LPSTR) ClassName
  1335.             );
  1336.         }
  1337.         else
  1338.         {
  1339.             wsprintf
  1340.             (
  1341.                 (LPSTR) Text,
  1342.                 "= %d (%d), %s",
  1343.                 hWndParent,
  1344.                 GetDlgCtrlID(hWndParent),
  1345.                 (LPSTR) ClassName
  1346.             );
  1347.         }
  1348.  
  1349.         SetDlgItemText(hDlgPropView, IDC_HWNDPARENT, (LPSTR) Text);
  1350.  
  1351.         if(!GetWindowText(hWndParent, (LPSTR) Text, sizeof(Text)))
  1352.         {
  1353.             Text[0] = '\0';
  1354.         }
  1355.  
  1356.         SetDlgItemText(hDlgPropView, IDC_PARENTCAPTION, (LPSTR) Text);
  1357.     }
  1358.     else
  1359.     {
  1360.         SetDlgItemText(hDlgPropView, IDC_HWNDPARENT, (LPSTR) "=");
  1361.         SetDlgItemText(hDlgPropView, IDC_PARENTCAPTION, (LPSTR) "");
  1362.     }
  1363.  
  1364.     //
  1365.     // Get and display INSTANCE information
  1366.     //
  1367.  
  1368.     hInst = GetWindowWord(hWnd, GWW_HINSTANCE);
  1369.     GetModuleFileName(hInst, (LPSTR) ModuleFileName, sizeof(ModuleFileName));
  1370.  
  1371.     if(ShowHex)
  1372.     {
  1373.         wsprintf
  1374.         (
  1375.             (LPSTR) Text,
  1376.             "hInst = 0x%04x, %s",
  1377.             hInst,
  1378.             (LPSTR) ModuleFileName
  1379.         );
  1380.     }
  1381.     else
  1382.     {
  1383.         wsprintf
  1384.         (
  1385.             (LPSTR) Text,
  1386.             "hInst = %d, %s",
  1387.             hInst,
  1388.             (LPSTR) ModuleFileName
  1389.         );
  1390.     }
  1391.     SetDlgItemText(hDlgPropView, IDC_HINST, (LPSTR) Text);
  1392.  
  1393.     //
  1394.     // Get & display RECT of window
  1395.     //
  1396.  
  1397.     GetWindowRect(hWnd, (LPRECT) &Rect);
  1398.  
  1399.     if(ShowScreenCoord == FALSE)
  1400.     {
  1401.         LONG Units = GetDialogBaseUnits();
  1402.         WORD Xamt = LOWORD(Units);
  1403.         WORD Yamt = HIWORD(Units);
  1404.  
  1405.         Rect.left    = (Rect.left * Xamt) / 4;
  1406.         Rect.right    = (Rect.right * Xamt) / 4;
  1407.         Rect.top    = (Rect.top * Yamt) / 4;
  1408.         Rect.bottom    = (Rect.bottom * Yamt) / 4;
  1409.     }
  1410.  
  1411.     if(ShowHex)
  1412.     {
  1413.         wsprintf
  1414.         (
  1415.             (LPSTR) Text,
  1416.             "Rect = (0x%04x, 0x%04x)-(0x%04x, 0x%04x)",
  1417.             Rect.left,
  1418.             Rect.top,
  1419.             Rect.right,
  1420.             Rect.bottom
  1421.         );
  1422.     }
  1423.     else
  1424.     {
  1425.         wsprintf
  1426.         (
  1427.             (LPSTR) Text,
  1428.             "Rect = (%d, %d)-(%d, %d)",
  1429.             Rect.left,
  1430.             Rect.top,
  1431.             Rect.right,
  1432.             Rect.bottom
  1433.         );
  1434.     }
  1435.     SetDlgItemText(hDlgPropView, IDC_RECT, (LPSTR) Text);
  1436.  
  1437.     //
  1438.     // Get & display CHILDREN & PROPERTY information
  1439.     //
  1440.  
  1441.     SendDlgItemMessage(hDlgChildren, IDC_LISTBOX, WM_SETREDRAW, 0, 0L);
  1442.     SendDlgItemMessage(hDlgProperties, IDC_LISTBOX, WM_SETREDRAW, 0, 0L);
  1443.  
  1444.     SendDlgItemMessage(hDlgProperties, IDC_LISTBOX, LB_RESETCONTENT, 0, 0L);
  1445.     SendDlgItemMessage(hDlgChildren, IDC_LISTBOX, LB_RESETCONTENT, 0, 0L);
  1446.  
  1447.     EnumChildWindows(hWndTarget, lpEnumChildrenProc, NULL);
  1448.  
  1449.     if
  1450.     (
  1451.         !(i = (int) SendDlgItemMessage
  1452.         (
  1453.             hDlgChildren,
  1454.             IDC_LISTBOX,
  1455.             LB_GETCOUNT,
  1456.             0,
  1457.             0L
  1458.         ))
  1459.     )
  1460.     {
  1461.         SetWindowText(hDlgChildren, "No children");
  1462.     }
  1463.     else
  1464.     {
  1465.         if(i == 1)
  1466.         {
  1467.             SetWindowText(hDlgChildren, "One child");
  1468.         }
  1469.         else
  1470.         {
  1471.             wsprintf(Text, "%d Children", i);
  1472.             SetWindowText(hDlgChildren, Text);
  1473.         }
  1474.     }
  1475.  
  1476.     if(GetParent(hWndTarget))
  1477.     {
  1478.         SendDlgItemMessage
  1479.         (
  1480.             hDlgChildren,
  1481.             IDC_LISTBOX,
  1482.             LB_ADDSTRING,
  1483.             0,
  1484.             (LONG) (LPSTR) "\"..\" (parent)"
  1485.         );
  1486.     }
  1487.  
  1488.     EnumProps(hWndTarget, lpEnumWindowPropsProc);
  1489.  
  1490.     if
  1491.     (
  1492.         !(i = (int) SendDlgItemMessage
  1493.         (
  1494.             hDlgProperties,
  1495.             IDC_LISTBOX,
  1496.             LB_GETCOUNT,
  1497.             0,
  1498.             0L
  1499.         ))
  1500.     )
  1501.     {
  1502.         SetWindowText(hDlgProperties, "No properties");
  1503.     }
  1504.     else
  1505.     {
  1506.         if(i == 1)
  1507.         {
  1508.             SetWindowText(hDlgProperties, "One property");
  1509.         }
  1510.         else
  1511.         {
  1512.             wsprintf(Text, "%d Properties", i);
  1513.             SetWindowText(hDlgProperties, Text);
  1514.         }
  1515.     }
  1516.  
  1517.     //
  1518.     // Now, turn redrawing for both listbox windows back on, invalidating their
  1519.     // areas, and sending a WM_PAINT.
  1520.     //
  1521.  
  1522.     SendDlgItemMessage(hDlgChildren, IDC_LISTBOX, WM_SETREDRAW, 1, 0L);
  1523.     SendDlgItemMessage(hDlgProperties, IDC_LISTBOX, WM_SETREDRAW, 1, 0L);
  1524.  
  1525.     InvalidateRect(GetDlgItem(hDlgChildren, IDC_LISTBOX), NULL, TRUE);
  1526.     InvalidateRect(GetDlgItem(hDlgProperties, IDC_LISTBOX), NULL, TRUE);
  1527.  
  1528.     UpdateWindow(GetDlgItem(hDlgChildren, IDC_LISTBOX));
  1529.     UpdateWindow(GetDlgItem(hDlgProperties, IDC_LISTBOX));
  1530.  
  1531.     //
  1532.     // Update the Data window
  1533.     //
  1534.  
  1535.     SendDlgItemMessage(hDlgExtraData, IDC_WNDLIST, WM_SETREDRAW, 0, 0L);
  1536.     SendDlgItemMessage(hDlgExtraData, IDC_CLSLIST, WM_SETREDRAW, 0, 0L);
  1537.     SendDlgItemMessage(hDlgExtraData, IDC_WNDLIST, LB_RESETCONTENT, 0, 0L);
  1538.     SendDlgItemMessage(hDlgExtraData, IDC_CLSLIST, LB_RESETCONTENT, 0, 0L);
  1539.  
  1540.     WndExtraData = GetClassWord(hWndTarget, GCW_CBWNDEXTRA);
  1541.     ClsExtraData = GetClassWord(hWndTarget, GCW_CBCLSEXTRA);
  1542.  
  1543.     if(ShowHex)
  1544.     {
  1545.         wsprintf
  1546.         (
  1547.             (LPSTR) Text,
  1548.             "Window = 0x%04x bytes",
  1549.             WndExtraData
  1550.         );
  1551.     }
  1552.     else
  1553.     {
  1554.         wsprintf
  1555.         (
  1556.             (LPSTR) Text,
  1557.             "Window = %d bytes",
  1558.             WndExtraData
  1559.         );
  1560.     }
  1561.     SetDlgItemText(hDlgExtraData, IDC_WNDTEXT, (LPSTR) Text);
  1562.  
  1563.     for(i = 0; i < (int) WndExtraData; i += 2)
  1564.     {
  1565.         BYTE Byte[5];
  1566.  
  1567.         if(ShowHex)
  1568.         {
  1569.             wsprintf(Byte, "0x%04x", GetWindowWord(hWndTarget, i));
  1570.         }
  1571.         else
  1572.         {
  1573.             wsprintf(Byte, "%d", GetWindowWord(hWndTarget, i));
  1574.         }
  1575.  
  1576.         SendDlgItemMessage
  1577.         (
  1578.             hDlgExtraData,
  1579.             IDC_WNDLIST,
  1580.             LB_ADDSTRING,
  1581.             0,
  1582.             (LONG) (LPSTR) Byte
  1583.         );
  1584.     }
  1585.  
  1586.     //
  1587.     // Reset, and then fill the class bytes listbox
  1588.     //
  1589.  
  1590.     if(ShowHex)
  1591.     {
  1592.         wsprintf
  1593.         (
  1594.             (LPSTR) Text,
  1595.             "Class = 0x%04x bytes",
  1596.             ClsExtraData
  1597.         );
  1598.     }
  1599.     else
  1600.     {
  1601.         wsprintf
  1602.         (
  1603.             (LPSTR) Text,
  1604.             "Class = %d bytes",
  1605.             ClsExtraData
  1606.         );
  1607.     }
  1608.     SetDlgItemText(hDlgExtraData, IDC_CLSTEXT, (LPSTR) Text);
  1609.  
  1610.     for(i = 0; i < (int) ClsExtraData; i += 2)
  1611.     {
  1612.         BYTE Byte[7];
  1613.  
  1614.         if(ShowHex)
  1615.         {
  1616.             wsprintf(Byte, "0x%04x", GetClassWord(hWndTarget, i));
  1617.         }
  1618.         else
  1619.         {
  1620.             wsprintf(Byte, "%d", GetClassWord(hWndTarget, i));
  1621.         }
  1622.  
  1623.         SendDlgItemMessage
  1624.         (
  1625.             hDlgExtraData,
  1626.             IDC_CLSLIST,
  1627.             LB_ADDSTRING,
  1628.             0,
  1629.             (LONG) (LPSTR) Byte
  1630.         );
  1631.     }
  1632.  
  1633.     SendDlgItemMessage(hDlgExtraData, IDC_CLSLIST, WM_SETREDRAW, 1, 0L);
  1634.     SendDlgItemMessage(hDlgExtraData, IDC_WNDLIST, WM_SETREDRAW, 1, 0L);
  1635.     InvalidateRect(GetDlgItem(hDlgExtraData, IDC_CLSLIST), NULL, TRUE);
  1636.     InvalidateRect(GetDlgItem(hDlgExtraData, IDC_WNDLIST), NULL, TRUE);
  1637.     UpdateWindow(GetDlgItem(hDlgExtraData, IDC_CLSLIST));
  1638.     UpdateWindow(GetDlgItem(hDlgExtraData, IDC_WNDLIST));
  1639.  
  1640.     //
  1641.     // Update the Styles window
  1642.     //
  1643.  
  1644.     SendDlgItemMessage(hDlgStyles, IDC_WNDLIST, WM_SETREDRAW, 0, 0L);
  1645.     SendDlgItemMessage(hDlgStyles, IDC_CLSLIST, WM_SETREDRAW, 0, 0L);
  1646.     SendDlgItemMessage(hDlgStyles, IDC_WNDLIST, LB_RESETCONTENT, 0, 0L);
  1647.     SendDlgItemMessage(hDlgStyles, IDC_CLSLIST, LB_RESETCONTENT, 0, 0L);
  1648.  
  1649.     WndStyle    = GetWindowLong(hWndTarget, GWL_STYLE);
  1650.     ClassStyle    = GetClassWord(hWndTarget, GCW_STYLE);
  1651.  
  1652.     if(ShowHex)
  1653.     {
  1654.         wsprintf
  1655.         (
  1656.             (LPSTR) Text,
  1657.             "Wnd Style = 0x%08lx",
  1658.             WndStyle
  1659.         );
  1660.     }
  1661.     else
  1662.     {
  1663.         wsprintf
  1664.         (
  1665.             (LPSTR) Text,
  1666.             "Wnd Style = %ld",
  1667.             WndStyle
  1668.         );
  1669.     }
  1670.     SetDlgItemText(hDlgStyles, IDC_WNDTEXT, (LPSTR) Text);
  1671.  
  1672.     //
  1673.     // Check to see if the window is a popup. If so, don't throw in
  1674.     // WS_OVERLAPPED attribute.
  1675.     //
  1676.  
  1677.     if(WndStyle & WndStyles[0].Style)
  1678.     {
  1679.         SendDlgItemMessage
  1680.         (
  1681.             hDlgStyles,
  1682.             IDC_WNDLIST,
  1683.             LB_ADDSTRING,
  1684.             0,
  1685.             (LONG) (LPSTR) WndStyles[1].Text
  1686.         );
  1687.     }
  1688.     else
  1689.     {
  1690.         if(WndStyle & WndStyles[1].Style)
  1691.         {
  1692.             SendDlgItemMessage
  1693.             (
  1694.                 hDlgStyles,
  1695.                 IDC_WNDLIST,
  1696.                 LB_ADDSTRING,
  1697.                 0,
  1698.                 (LONG) (LPSTR) WndStyles[0].Text
  1699.             );
  1700.         }
  1701.     }
  1702.  
  1703.     for(i = 2; i < NUMWNDSTYLES; ++i)
  1704.     {
  1705.         if(WndStyle & WndStyles[i].Style)
  1706.         {
  1707.             SendDlgItemMessage
  1708.             (
  1709.                 hDlgStyles,
  1710.                 IDC_WNDLIST,
  1711.                 LB_ADDSTRING,
  1712.                 0,
  1713.                 (LONG) (LPSTR) WndStyles[i].Text
  1714.             );
  1715.         }
  1716.     }
  1717.  
  1718.     //
  1719.     // Reset, and then fill the class styles combo box
  1720.     //
  1721.  
  1722.     if(ShowHex)
  1723.     {
  1724.         wsprintf
  1725.         (
  1726.             (LPSTR) Text,
  1727.             "Class Style = 0x%04x",
  1728.             ClassStyle
  1729.         );
  1730.     }
  1731.     else
  1732.     {
  1733.         wsprintf
  1734.         (
  1735.             (LPSTR) Text,
  1736.             "Class Style = %d",
  1737.             ClassStyle
  1738.         );
  1739.     }
  1740.     SetDlgItemText(hDlgStyles, IDC_CLSTEXT, (LPSTR) Text);
  1741.  
  1742.     for(i = 0; i < NUMCLASSSTYLES; ++i)
  1743.     {
  1744.         if(ClassStyle & ClassStyles[i].Style)
  1745.         {
  1746.             SendDlgItemMessage
  1747.             (
  1748.                 hDlgStyles,
  1749.                 IDC_CLSLIST,
  1750.                 LB_ADDSTRING,
  1751.                 0,
  1752.                 (LONG) (LPSTR) ClassStyles[i].Text
  1753.             );
  1754.         }
  1755.     }
  1756.  
  1757.     //
  1758.     // Turn off outline of target window
  1759.     //
  1760.  
  1761.     OutlineWindow(hWndTarget);
  1762.  
  1763.     //
  1764.     // Turn redrawing back on and repaint all listboxes
  1765.     //
  1766.  
  1767.     SendDlgItemMessage(hDlgStyles, IDC_WNDLIST, WM_SETREDRAW, 1, 0L);
  1768.     SendDlgItemMessage(hDlgStyles, IDC_CLSLIST, WM_SETREDRAW, 1, 0L);
  1769.     InvalidateRect(GetDlgItem(hDlgStyles, IDC_WNDLIST), NULL, TRUE);
  1770.     InvalidateRect(GetDlgItem(hDlgStyles, IDC_CLSLIST), NULL, TRUE);
  1771.     UpdateWindow(GetDlgItem(hDlgStyles, IDC_WNDLIST));
  1772.     UpdateWindow(GetDlgItem(hDlgStyles, IDC_CLSLIST));
  1773. }
  1774.  
  1775.  
  1776. /*****************************************************************************
  1777.  
  1778.     FUNCTION: EnumWindowPropsProc
  1779.  
  1780.     PURPOSE : Enumerates properties for window under mouse
  1781.  
  1782. *****************************************************************************/
  1783.  
  1784. int FAR PASCAL EnumWindowPropsProc(HWND hWnd, LPSTR lpString, HANDLE hData)
  1785. {
  1786.     //
  1787.     // Check the passed property name to see if it's a string or an atom
  1788.     //
  1789.  
  1790.     if(HIWORD(lpString))
  1791.     {
  1792.         if(ShowHex)
  1793.         {
  1794.             wsprintf(Text, "%s\t= 0x%04x", (LPSTR) lpString, hData);
  1795.         }
  1796.         else
  1797.         {
  1798.             wsprintf(Text, "%s\t= %d", (LPSTR) lpString, hData);
  1799.         }
  1800.     }
  1801.     else
  1802.     {
  1803.         if(ShowHex)
  1804.         {
  1805.             wsprintf(Text, "0x%04x, 0x%04x", LOWORD((DWORD) lpString), hData);
  1806.         }
  1807.         else
  1808.         {
  1809.             wsprintf(Text, "%d, %d", LOWORD((DWORD) lpString), hData);
  1810.         }
  1811.     }
  1812.  
  1813.     SendDlgItemMessage
  1814.     (
  1815.         hDlgProperties,
  1816.         IDC_LISTBOX,
  1817.         LB_ADDSTRING,
  1818.         0,
  1819.         (LONG) (LPSTR) Text
  1820.     );
  1821.  
  1822.     return(1);
  1823. }
  1824.  
  1825.  
  1826. /*****************************************************************************
  1827.  
  1828.     FUNCTION: DrawIcons
  1829.  
  1830.     PURPOSE : Draws the target and parent class icons
  1831.  
  1832. *****************************************************************************/
  1833.  
  1834. VOID PASCAL DrawIcons(VOID)
  1835. {
  1836.     HWND    hWndParent;
  1837.     HDC        hDC;
  1838.     HFONT    hFont;
  1839.     HICON    hIcon;
  1840.     BYTE    ClassName[30];
  1841.  
  1842.     if(hWndTarget == NULL)
  1843.     {
  1844.         return;
  1845.     }
  1846.  
  1847.     //
  1848.     // Setup small prop helv font for icon titles
  1849.     //
  1850.  
  1851.     hFont = CreateFont
  1852.     (
  1853.         12, 0,
  1854.         0, 0,
  1855.         FW_NORMAL,
  1856.         FALSE,
  1857.         FALSE,
  1858.         FALSE,
  1859.         ANSI_CHARSET,
  1860.         OUT_DEFAULT_PRECIS,
  1861.         CLIP_DEFAULT_PRECIS,
  1862.         DEFAULT_QUALITY,
  1863.         VARIABLE_PITCH | FF_SWISS,
  1864.         "Helv"
  1865.     );
  1866.  
  1867.     //
  1868.     // Get window class name & draw icon
  1869.     //
  1870.  
  1871.     if(!GetClassName(hWndTarget, (LPSTR) ClassName, sizeof(ClassName)))
  1872.     {
  1873.         ClassName[0] = '\0';
  1874.     }
  1875.  
  1876.     if((hIcon = GetClassWord(hWndTarget, GCW_HICON)) == NULL)
  1877.     {
  1878.         if(!lstrcmpi((LPSTR) ClassName, "listbox"))
  1879.         {
  1880.             hIcon = LoadIcon(hInstPropView, "listbox");
  1881.         }
  1882.         else
  1883.         {
  1884.             if(!lstrcmpi((LPSTR) ClassName, "combobox"))
  1885.             {
  1886.                 hIcon = LoadIcon(hInstPropView, "combobox");
  1887.             }
  1888.             else
  1889.             {
  1890.                 if(!lstrcmpi((LPSTR) ClassName, "button"))
  1891.                 {
  1892.                     hIcon = LoadIcon(hInstPropView, "button");
  1893.                 }
  1894.                 else
  1895.                 {
  1896.                     if(!lstrcmpi((LPSTR) ClassName, "edit") ||
  1897.                         !lstrcmpi((LPSTR) ClassName, "static"))
  1898.                     {
  1899.                         hIcon = LoadIcon(hInstPropView, "editcontrol");
  1900.                     }
  1901.                 }
  1902.             }
  1903.         }
  1904.     }
  1905.  
  1906.     //
  1907.     // Get DC, draw icon, and release DC
  1908.     //
  1909.  
  1910.     hDC = GetDC(GetDlgItem(hDlgPropView, IDC_HWNDICON));
  1911.  
  1912.     if((hIcon == NULL) && IsIconic(hWndTarget) && IsWindowVisible(hWndTarget))
  1913.     {
  1914.         HDC hDCTarget = GetWindowDC(hWndTarget);
  1915.         BitBlt(hDC, 0, 0, 36, 36, hDCTarget, 0, 0, SRCCOPY);
  1916.         ReleaseDC(hWndTarget, hDCTarget);
  1917.     }
  1918.     else
  1919.     {
  1920.         BitBlt(hDC, 0, 0, 36, 36, hDC, 0, 0, WHITENESS);
  1921.         DrawIcon(hDC, 0, 0, hIcon);
  1922.     }
  1923.  
  1924.     ReleaseDC(GetDlgItem(hDlgPropView, IDC_HWNDICON), hDC);
  1925.  
  1926.     if((hWndParent = GetParent(hWndTarget)) != NULL)
  1927.     {
  1928.         HICON hIcon;
  1929.  
  1930.         //
  1931.         // Get DC, draw icon, and release DC
  1932.         //
  1933.  
  1934.         hDC = GetDC(GetDlgItem(hDlgPropView, IDC_PARENTICON));
  1935.  
  1936.         if
  1937.         (
  1938.             ((hIcon = GetClassWord(hWndParent, GCW_HICON)) == NULL) &&
  1939.             IsIconic(hWndParent) && IsWindowVisible(hWndTarget)
  1940.         )
  1941.         {
  1942.             HDC hDCTarget = GetWindowDC(hWndParent);
  1943.             BitBlt(hDC, 0, 0, 36, 36, hDCTarget, 0, 0, SRCCOPY);
  1944.             ReleaseDC(hWndParent, hDCTarget);
  1945.         }
  1946.         else
  1947.         {
  1948.             BitBlt(hDC, 0, 0, 36, 36, hDC, 0, 0, WHITENESS);
  1949.             DrawIcon(hDC, 0, 0, hIcon);
  1950.         }
  1951.  
  1952.         ReleaseDC(GetDlgItem(hDlgPropView, IDC_PARENTICON), hDC);
  1953.     }
  1954.     else
  1955.     {
  1956.         //
  1957.         // Get DC, draw icon, and release DC
  1958.         //
  1959.  
  1960.         hDC = GetDC(GetDlgItem(hDlgPropView, IDC_PARENTICON));
  1961.         BitBlt(hDC, 0, 0, 36, 36, hDC, 0, 0, WHITENESS);
  1962.         ReleaseDC(GetDlgItem(hDlgPropView, IDC_PARENTICON), hDC);
  1963.     }
  1964.  
  1965.     //
  1966.     // Do usual cleanup
  1967.     //
  1968.  
  1969.     DeleteObject(hFont);
  1970. }
  1971.  
  1972.  
  1973. /*****************************************************************************
  1974.  
  1975.     FUNCTION: EnumChildrenProc
  1976.  
  1977.     PURPOSE : Enumerates children of window under mouse
  1978.  
  1979. *****************************************************************************/
  1980.  
  1981. int FAR PASCAL EnumChildrenProc(HWND hWnd, DWORD lParam)
  1982. {
  1983.     BYTE Text[100];
  1984.     BYTE Caption[100];
  1985.     BYTE ClassName[30];
  1986.  
  1987.     //
  1988.     // Get the child window's caption and class name
  1989.     //
  1990.  
  1991.     GetWindowText(hWnd, (LPSTR) Caption, sizeof(Caption));
  1992.     GetClassName(hWnd, (LPSTR) ClassName, sizeof(ClassName));
  1993.  
  1994.     //
  1995.     // Format and add the entry to the child list box
  1996.     //
  1997.  
  1998.     if(Caption[0] != '\0')
  1999.     {
  2000.         if(ShowHex)
  2001.         {
  2002.             wsprintf
  2003.             (
  2004.                 (LPSTR) Text,
  2005.                 "%s\t0x%04x\t0x%04x\t\"%s\"",
  2006.                 (LPSTR) ClassName,
  2007.                 GetDlgCtrlID(hWnd),
  2008.                 hWnd,
  2009.                 (LPSTR) Caption
  2010.             );
  2011.         }
  2012.         else
  2013.         {
  2014.             wsprintf
  2015.             (
  2016.                 (LPSTR) Text,
  2017.                 "%s\t%d\t%d\t\"%s\"",
  2018.                 (LPSTR) ClassName,
  2019.                 GetDlgCtrlID(hWnd),
  2020.                 hWnd,
  2021.                 (LPSTR) Caption
  2022.             );
  2023.         }
  2024.     }
  2025.     else
  2026.     {
  2027.         if(ShowHex)
  2028.         {
  2029.             wsprintf
  2030.             (
  2031.                 (LPSTR) Text,
  2032.                 "%s\t0x%04x\t0x%04x",
  2033.                 (LPSTR) ClassName,
  2034.                 GetDlgCtrlID(hWnd),
  2035.                 hWnd
  2036.             );
  2037.         }
  2038.         else
  2039.         {
  2040.             wsprintf
  2041.             (
  2042.                 (LPSTR) Text,
  2043.                 "%s\t%d\t%d",
  2044.                 (LPSTR) ClassName,
  2045.                 GetDlgCtrlID(hWnd),
  2046.                 hWnd
  2047.             );
  2048.         }
  2049.     }
  2050.  
  2051.     SendDlgItemMessage
  2052.     (
  2053.         hDlgChildren,
  2054.         IDC_LISTBOX,
  2055.         LB_ADDSTRING,
  2056.         0,
  2057.         (LONG) (LPSTR) Text
  2058.     );
  2059.  
  2060.     return(1);
  2061. }
  2062.  
  2063.  
  2064. /*****************************************************************************
  2065.  
  2066.     FUNCTION: About
  2067.  
  2068.     PURPOSE : Processes messages for About box
  2069.  
  2070. *****************************************************************************/
  2071.  
  2072. BOOL FAR PASCAL About(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  2073. {
  2074.     switch(wMsg)
  2075.     {
  2076.         case WM_INITDIALOG :
  2077.  
  2078.             return(TRUE);
  2079.  
  2080.         case WM_COMMAND    :
  2081.  
  2082.             if(wParam == IDOK || wParam == IDCANCEL)
  2083.             {
  2084.                 EndDialog(hWnd, TRUE);
  2085.                 return(TRUE);
  2086.             }
  2087.             break;
  2088.  
  2089.         default            :
  2090.  
  2091.             break;
  2092.     }
  2093.     return(FALSE);
  2094. }
  2095.  
  2096.  
  2097. /*****************************************************************************
  2098.  
  2099.     FUNCTION: OutlineWindow
  2100.  
  2101.     PURPOSE : Outlines window with a rectangle
  2102.  
  2103. *****************************************************************************/
  2104.  
  2105. VOID PASCAL OutlineWindow(HWND hWnd)
  2106. {
  2107.     RECT    Rect;
  2108.     HDC        hDC;
  2109.     HPEN    hPen;
  2110.     HPEN    hPenOld;
  2111.     HANDLE    hBrush;
  2112.     HANDLE    hBrushOld;
  2113.     int        OldROP2Mode;
  2114.  
  2115.     //
  2116.     // Check for valid window handle and pen thickness
  2117.     //
  2118.  
  2119.     if(!IsWindow(hWnd))
  2120.     {
  2121.         return;
  2122.     }
  2123.  
  2124.     //
  2125.     // Set up parms to draw rectangle
  2126.     //
  2127.  
  2128.     hBrush    = GetStockObject(NULL_BRUSH);
  2129.     hPen    = CreatePen(PS_SOLID, 6, RGB(0, 0, 0));
  2130.  
  2131.     //
  2132.     // Get DC for window and it's dimensions
  2133.     //
  2134.  
  2135.     hDC = GetWindowDC(hWnd);
  2136.     GetWindowRect(hWnd, (LPRECT) &Rect);
  2137.  
  2138.     //
  2139.     // Set drawing mode parameters
  2140.     //
  2141.  
  2142.     hBrushOld    = SelectObject(hDC, hBrush);
  2143.     hPenOld        = SelectObject(hDC, hPen);
  2144.     OldROP2Mode    = SetROP2(hDC, R2_NOT);
  2145.  
  2146.     //
  2147.     // Draw the rectangle and release the DC
  2148.     //
  2149.  
  2150.     Rectangle(hDC, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top);
  2151.  
  2152.     //
  2153.     // Be a good boy and reset the old context attributes
  2154.     //
  2155.  
  2156.     SelectObject(hDC, hBrushOld);
  2157.     SelectObject(hDC, hPenOld);
  2158.     DeleteObject(hPen);
  2159.     SetROP2(hDC, OldROP2Mode);
  2160.  
  2161.     ReleaseDC(hWnd, hDC);
  2162. }
  2163.