home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xray10.zip / source.zip / xraydll.c < prev    next >
Text File  |  1996-12-28  |  9KB  |  225 lines

  1. /**
  2. File:   xraydll.c
  3. Notes:  xray hook dll - contains the hook procs
  4.         This sample code provided by CodeSmith Software. Use as you wish.
  5. **/
  6.  
  7. #define INCL_WIN
  8. #define INCL_DOSMODULEMGR
  9.  
  10. #include <os2.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #include "xray.h"
  16. #include "xrayrc.h"
  17.  
  18. BOOL Hooked;            // flag set when hooks are enabled
  19. HMODULE hmXrayDll;      // handle to the dll module
  20. HAB habXray;            // anchor block of our process
  21. HWND hwndXrayClient;    // handle to our client proc in xray.c
  22. HATOMTBL hatomtblSystem;// handle to system atom table
  23. GLOBALS Global;         // global data in the dll
  24.                         // we sent a pointer to it in XrayInit()
  25.  
  26. // #define TESTHOOK     // define this to test hooks only within our process
  27.                         // or comment out to use hooks system wide
  28.  
  29. #ifndef TESTHOOK
  30.   HMQ hmqType = NULLHANDLE;     // use NULLHANDLE for system wide hooks
  31. #else
  32.   HMQ hmqType = HMQ_CURRENT;    // use HMQ_CURRENT for current thread only
  33. #endif
  34.  
  35.                     // ConvertClass takes a predefined class on input (eg "#1")
  36.                     // and converts it into English (eg. "Frame")
  37. VOID ConvertClass(CHAR *class)
  38. {
  39.     INT i;
  40.     static struct {
  41.         CHAR *number;
  42.         CHAR *desc;
  43.     } cl[] = {
  44.          "#1",  "Frame(#1)",
  45.          "#2",  "Combobox(#2)",
  46.          "#3",  "Button(#3)",
  47.          "#4",  "Menu(#4)",
  48.          "#5",  "Static(#5)",
  49.          "#6",  "EntryField(#6)",
  50.          "#7",  "Listbox(#7)",
  51.          "#8",  "ScrollBar(#8)",
  52.          "#9",  "TitleBar(#9)",
  53.          "#10",  "MultilineEntry(#10)",
  54.          "#16", "AppStat(#16)",
  55.          "#17",  "KbdStat(#17)",
  56.          "#18",  "Pecic(#18)",
  57.          "#19",  "DBEkkpopup(#19)",
  58.          "#32",  "SpinButton(#32)",
  59.          "#37",  "Container(#37)",
  60.          "#38",  "Slider(#38)",
  61.          "#39",  "ValueSet(#39)",
  62.          "#40",  "NoteBook(#40)",
  63.          "#41",  "PenFirst(#41)",
  64.          "#44",  "PenLast(#44)",
  65.          "#64",  "MMPMFirst(#64)",
  66.          "#65",  "CircularSlider(#65)",
  67.          "#79",  "MMPMLast(#79)",
  68.          "#32766", "Desktop(#32766)",
  69.          0, 0
  70.     };
  71.  
  72.     for(i = 0; cl[i].number; i++)
  73.         if(strcmp(cl[i].number, class) == 0) {
  74.             strcpy(class, cl[i].desc);
  75.             break;
  76.         }
  77. }
  78.                 // converts any new line characters into a space
  79. VOID ConvertNewlines(CHAR *buf)
  80. {
  81.     while(*buf) {
  82.         if(*buf == '\n' || *buf == '\r')
  83.             *buf = ' ';
  84.         buf++;
  85.     }
  86. }
  87.  
  88.         // UpdateDisplay takes the input window hwnd, and extracts the info
  89.         // from it (title, class, etc). We then post a msg to our client proc
  90.         // to display this info, stored in a global string variable.
  91. VOID UpdateDisplay(HWND hwnd, HAB habCurrent)
  92. {
  93.     CHAR title[24], class[32], p_class[32], menuId[24] = " ";
  94.     HWND p_hwnd = WinQueryWindow(hwnd, QW_PARENT);
  95.     HPS hps;
  96.     RECTL rcl;
  97.     PID pid, p_pid;
  98.     TID tid, p_tid;
  99.  
  100.     if(habCurrent == habXray)       // if attempt to look at Xrays windows
  101.         sprintf(Global.winInfo, " Right mouse button for menu.  Atoms used: wmu_UpdateDisplay=%X  wmu_FloatToTop=%X",Global.wmu_UpdateDisplay, Global.wmu_FloatToTop);
  102.     else {
  103.         if(WinQueryWindowText(hwnd, sizeof(title), title) == 0)
  104.             strcpy(title,"(none)");
  105.         else
  106.             ConvertNewlines(title);
  107.         WinQueryClassName(hwnd, sizeof(class), class);
  108.         if(memcmp(class, "#4", 3) == 0)         // if a menu, get selected id
  109.             sprintf(menuId, "ItemID:%X  ", WinSendMsg(hwnd, MM_QUERYSELITEMID, MPFROMSHORT(TRUE), 0));
  110.  
  111.         ConvertClass(class);
  112.         WinQueryClassName(p_hwnd, sizeof(p_class), p_class);
  113.         ConvertClass(p_class);
  114.         WinQueryWindowProcess(hwnd, &pid, &tid);
  115.         WinQueryWindowProcess(p_hwnd, &p_pid, &p_tid);
  116.         sprintf(Global.winInfo, "TITLE:%s  CLASS:%s  ID:%X %sHwnd:%X  Style:%X  Pid,Tid:%X,%X  PARENT CLASS:%s  Hwnd:%X  Pid,Tid:%X,%X",
  117.                     title, class, WinQueryWindowUShort(hwnd, QWS_ID), menuId, hwnd, WinQueryWindowULong(hwnd,QWL_STYLE),
  118.                     pid, tid, p_class, p_hwnd, p_pid, p_tid);
  119.     }
  120.     WinInvalidateRect(hwndXrayClient, NULL, FALSE);      // refresh our window
  121. }
  122.  
  123.             // Post message hook. If you want to process the message here,
  124.             // return TRUE. If you want the message to be passed on, return FALSE.
  125.  
  126. BOOL EXPENTRY XrayHookInput(HAB hab, PQMSG pQmsg, USHORT fs)
  127. {
  128.     static HWND hwndLast;
  129.     static BOOL first = 1;
  130.  
  131.     switch(pQmsg->msg) {
  132.  
  133.         case WM_MOUSEMOVE:
  134.                         // When an app is first loaded, it always receives a
  135.                         // WM_MOUSEMOVE, even if the mouse doesn't move. This
  136.                         // allows setting a custom mouse pointer.
  137.                         // Here we just display a startup msg.
  138.                     if(first) {
  139.                         first = 0;
  140.                         sprintf(Global.winInfo, "  X·RAY  Version:%s    Press right mouse button over this window for menu", VERSION);
  141.                         WinInvalidateRect(hwndXrayClient, NULL, FALSE);      // refresh our window
  142.                         break;
  143.                     }
  144.                         // if mouse over a new window, display its info
  145.                     if(pQmsg->hwnd != hwndLast) {
  146.                         hwndLast = pQmsg->hwnd;
  147.                         UpdateDisplay(pQmsg->hwnd, hab);
  148.                     }
  149.                     break;                  // pass this msg on
  150.  
  151.         default:                    // if this is our custom msg, then mp1 = window handle; mp2 = hab
  152.                                     // to double check this is our msg, match client hwnds and verify params
  153.                     if(pQmsg->msg == Global.wmu_UpdateDisplay && pQmsg->hwnd == hwndXrayClient && WinIsWindow((HAB)pQmsg->mp2, (HWND)pQmsg->mp1) == TRUE) {
  154.                         UpdateDisplay((HWND)pQmsg->mp1, (HAB)pQmsg->mp2);
  155.                         return TRUE;        // msg processed, return TRUE
  156.                     }
  157.                     break;
  158.     }
  159.     return FALSE;                           // msg not processed if FALSE
  160. }
  161.  
  162.         // Send Message hook. Don't do any processing in here, especially calling
  163.         // WinSendMsg(). Simply post a msg to yourself, for processing either
  164.         // in your client proc, or in the input hook.
  165.  
  166. VOID EXPENTRY XrayHookSendMsg(HAB habAnchor, PSMHSTRUCT psmh, BOOL fInterTask)
  167. {
  168.     switch(psmh->msg) {
  169.         case WM_MENUSELECT:
  170.                         // When a menu selection is changed (via keyboard), we
  171.                         // want to display the menu id of the new selection.
  172.                         // We simply pass the menu hwnd (mp2) for processing
  173.                         // in the input hook proc
  174.                     WinPostMsg(hwndXrayClient, Global.wmu_UpdateDisplay, psmh->mp2, (MPARAM)habAnchor);
  175.                     return;
  176.         case WM_WINDOWPOSCHANGED:
  177.                         // When any window changes position , we notify our client
  178.                         // proc to move itself to the top of all windows
  179.                     if(Global.floatOnTop)
  180.                         WinPostMsg(hwndXrayClient, Global.wmu_FloatToTop, 0, 0);
  181.                     return;
  182.     }
  183.     return;
  184. }
  185.  
  186.         // next 3 routines are called from the exe, so we need to export them
  187.  
  188. GLOBALS * EXPENTRY EXPORT XraySetGlobals(void)
  189. {
  190.     return &Global;   // allow client access to the dlls global data
  191. }
  192.  
  193. BOOL EXPENTRY EXPORT XrayInit(HWND hwnd)       // enable hooks
  194. {
  195.     hwndXrayClient = hwnd;      // save client hwnd so we can post msgs to it
  196.     if(!Hooked) {
  197.                                 // create unique message ids (can't use WM_USER in hooks)
  198.         hatomtblSystem = WinQuerySystemAtomTable();
  199.         srand((UINT)hwnd);
  200.         sprintf(Global.szUpdateDisplay,"XrayUpdateDisplay%d",rand());
  201.         sprintf(Global.szFloatToTop,"XrayFloatToTop%d",rand());
  202.         Global.wmu_UpdateDisplay = WinAddAtom(hatomtblSystem, Global.szUpdateDisplay);
  203.         Global.wmu_FloatToTop = WinAddAtom(hatomtblSystem, Global.szFloatToTop);
  204.         if(DosQueryModuleHandle("xraydll", &hmXrayDll))
  205.             return FALSE;
  206.         habXray = WinQueryAnchorBlock(hwnd);
  207.         WinSetHook(habXray, hmqType, HK_INPUT, (PFN)XrayHookInput, hmXrayDll);
  208.         WinSetHook(habXray, hmqType, HK_SENDMSG, (PFN)XrayHookSendMsg, hmXrayDll);
  209.         Hooked = 1;
  210.     }
  211.     return TRUE;
  212. }
  213.  
  214. BOOL EXPENTRY EXPORT XrayKill()        // disable hooks
  215. {
  216.     if(Hooked) {
  217.         WinReleaseHook(habXray, hmqType, HK_INPUT, (PFN)XrayHookInput, hmXrayDll);
  218.         WinReleaseHook(habXray, hmqType, HK_SENDMSG, (PFN)XrayHookSendMsg, hmXrayDll);
  219.         WinDeleteAtom(hatomtblSystem, Global.wmu_UpdateDisplay);
  220.         WinDeleteAtom(hatomtblSystem, Global.wmu_FloatToTop);
  221.         Hooked = 0;
  222.     }
  223.     return TRUE;
  224. }
  225.