home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / v / v12n3.zip / RCLICK.ZIP / RCLSRC.ZIP / RCHOOK.C next >
C/C++ Source or Header  |  1992-11-11  |  10KB  |  338 lines

  1. //========================================================================
  2. // 
  3. //  RCHook.C - The Message Hook DLL for RClick
  4. //
  5. //  (c) Douglas Boling 1993
  6. //
  7. //  For better readability, set tab stops to every 3 characters.
  8. //
  9. //========================================================================
  10.  
  11. #define  WINVER      0x0300
  12. #define    MAXWINDOWS    128
  13.  
  14. #include <windows.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "rchook.h"
  18. //
  19. //Structures
  20. //
  21. typedef struct {
  22.     LONG    lParam;
  23.     int    wParam;
  24.     UINT  uMsg;
  25.     HWND  hWnd;
  26. } CALLHOOKDATA;
  27. typedef CALLHOOKDATA far *LPCALLHOOKDATA;
  28. //
  29. // Function prototypes
  30. //
  31. long FAR PASCAL    WndProc (HWND, WORD, WORD, LONG);
  32. BOOL FAR PASCAL AboutDlgProc (HWND, WORD, WORD, LONG);
  33. BOOL FAR PASCAL ConfigDlgProc (HWND, WORD, WORD, LONG);
  34. void SetHook (BOOL);
  35. void CopyMenuBitmap (HMENU, UINT, UINT);
  36. void CopyMenu (HMENU, HMENU);
  37.  
  38. char     szDllName[] = "RCHook";
  39.  
  40. HANDLE    hInst;
  41. FARPROC    lpfnNextHook;
  42. FARPROC    lpfnNextHook1;
  43. int        sHooked = 0;
  44. char        szStr[64];
  45.  
  46. int      sNumNoPopProgs;
  47. char        szNoPopPrograms[MAXWINDOWS][12];
  48.  
  49. HMENU        hMenu, hProgMenu;
  50. HWND        hwndMyWin, hwndTarg;
  51. BOOL        bMenuUp, bGetCMD;
  52. //=======================================================================
  53. //
  54. // Library initialization and terminataion functions
  55. //
  56. //=======================================================================
  57. //------------------------------------------------------------------------
  58. // LibMain - DLL initialization routine
  59. //------------------------------------------------------------------------
  60. int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
  61.                          LPSTR lpszCmdLine) {
  62.     hInst = hInstance;
  63.     bMenuUp = FALSE;
  64.     bGetCMD = FALSE;
  65.     sNumNoPopProgs = 0;
  66.  
  67.     if (sHooked == 0) SetHook (TRUE);
  68.     return 1;
  69. }
  70. //------------------------------------------------------------------------
  71. // WEP - DLL termination routine
  72. //------------------------------------------------------------------------
  73. int FAR PASCAL WEP (int nParameter) {
  74.    
  75.     if (sHooked) SetHook (FALSE);
  76.    if (bMenuUp) {
  77.       DestroyMenu (hMenu);
  78.    }   
  79.     return 1;
  80. }
  81. //===================================================================
  82. // Local procedures
  83. //===================================================================
  84. //-------------------------------------------------------------------
  85. // SetHook - Sets or Clears the message queue hook
  86. //-------------------------------------------------------------------
  87. void SetHook (BOOL bEnable) {
  88.     if (bEnable) {
  89.         if (sHooked == 0) {
  90.             lpfnNextHook = SetWindowsHook (WH_GETMESSAGE, 
  91.                                        GetProcAddress (hInst, "MsgHookProc"));
  92.  
  93.             lpfnNextHook1 = SetWindowsHook (WH_CALLWNDPROC,
  94.                                        GetProcAddress (hInst, "CallHookProc"));
  95.             sHooked++;
  96.         }
  97.     } else {
  98.         if (sHooked) {
  99.              UnhookWindowsHook (WH_GETMESSAGE,
  100.                                GetProcAddress (hInst, "MsgHookProc"));
  101.  
  102.              UnhookWindowsHook (WH_CALLWNDPROC,
  103.                                GetProcAddress (hInst, "CallHookProc"));
  104.         sHooked--;
  105.         }
  106.     }
  107.     return;
  108. }
  109.  
  110. //-------------------------------------------------------------------
  111. // CopyMenuBitmap - Copys a bitmap menu item
  112. //-------------------------------------------------------------------
  113. void CopyMenuBitmap (HMENU hPopMenu, UINT usMenuState, UINT usMenuID) {
  114.    
  115.     usMenuState &= ~MF_BITMAP;            
  116.     switch (usMenuID) {
  117.        case 0xf120:
  118.            AppendMenu (hPopMenu, usMenuState, usMenuID, "Restore");
  119.            break;
  120.         default:
  121.             AppendMenu (hPopMenu, usMenuState, usMenuID, "Bitmap");
  122.             break;
  123.     }
  124.     return;
  125. }    
  126.  
  127. //-------------------------------------------------------------------
  128. // CopyMenu - Copys the menu from a window to the popup menu
  129. //-------------------------------------------------------------------
  130. void CopyMenu (HMENU hPopMenu, HMENU hSrcMenu) {
  131.    int    i, sMenuItems;
  132.    UINT    usMenuID, usMenuState;
  133.    HMENU    hSubMenu;
  134.    
  135.     sMenuItems = GetMenuItemCount (hSrcMenu);
  136.     for (i = 0; i < sMenuItems; i++) {
  137.         usMenuID = GetMenuItemID (hSrcMenu, i);
  138.         usMenuState = GetMenuState (hSrcMenu, i, MF_BYPOSITION);
  139.        if (usMenuID == 0xffff) {
  140.           hSubMenu = CreatePopupMenu ();
  141.           CopyMenu (hSubMenu, GetSubMenu (hSrcMenu, i));
  142.          if (usMenuState & MF_BITMAP) {
  143.             CopyMenuBitmap (hPopMenu, MF_POPUP, hSubMenu);
  144.             } else {
  145.                 GetMenuString (hSrcMenu, i, szStr, sizeof (szStr),
  146.                                MF_BYPOSITION);
  147.                 AppendMenu (hPopMenu, MF_POPUP, hSubMenu, szStr);
  148.             }
  149.        } else {  
  150.          if (usMenuState & MF_BITMAP) {
  151.             CopyMenuBitmap (hPopMenu, usMenuState, usMenuID);
  152.          } else {   
  153.                GetMenuString (hSrcMenu, i, szStr, sizeof (szStr),
  154.                               MF_BYPOSITION);
  155.                AppendMenu (hPopMenu, usMenuState, usMenuID, szStr);
  156.             }   
  157.        }                
  158.    }
  159. }
  160.  
  161. //===================================================================
  162. // Send Message Hook function
  163. //===================================================================
  164. LRESULT FAR PASCAL CallHookProc (int code, WORD wParam, LONG lParam) {
  165.  
  166.     LPCALLHOOKDATA    lpmMsg;
  167.  
  168.     lpmMsg = (LPCALLHOOKDATA) lParam;
  169.  
  170.     if (code < 0) 
  171.        return DefHookProc (code, wParam, lParam, &lpfnNextHook1);
  172.  
  173.     if (bMenuUp && (lpmMsg->uMsg == WM_COMMAND)) {
  174.        bGetCMD = FALSE;
  175.  
  176.         if (lpmMsg->wParam == 0x7fff) {
  177.             PostMessage (hwndMyWin, RBM_SHOWABOUTDLG, hwndTarg, 0);
  178.           lpmMsg->uMsg = WM_NULL;
  179.        }
  180.         if (lpmMsg->wParam == 0x7ffe) {
  181.             hwndTarg  = lpmMsg->hWnd;
  182.             PostMessage (hwndMyWin, RBM_SHOWCONFIGDLG, hwndTarg, 0);
  183.           lpmMsg->uMsg = WM_NULL;
  184.         }
  185.     }
  186.     return DefHookProc (code, wParam, lParam, &lpfnNextHook1);
  187.    
  188. }   
  189. //===================================================================
  190. // Post Message Hook function
  191. //===================================================================
  192. LRESULT FAR PASCAL MsgHookProc (int code, WORD wParam, LONG lParam) {
  193.  
  194.     int        i;
  195.     LPMSG        lpmMsg;
  196.     HMENU        hWinMenu;
  197.     char         *pszModuleName;
  198.  
  199.     if (code < 0) 
  200.        return DefHookProc (code, wParam, lParam, &lpfnNextHook);
  201.     
  202.     lpmMsg = (LPMSG) lParam;
  203.  
  204.     //
  205.     //Check for Right Button Down
  206.     //
  207.     if (lpmMsg->message == WM_RBUTTONDOWN && !bMenuUp) {
  208.  
  209.        hwndTarg = lpmMsg->hwnd;
  210.        while (GetParent (hwndTarg) != GetDesktopWindow() && 
  211.                GetParent (hwndTarg) != 0)
  212.           hwndTarg = GetParent(hwndTarg);
  213.       
  214.         if (hWinMenu = GetMenu (hwndTarg)) {
  215.             bMenuUp = TRUE;
  216.             GetModuleFileName (GetWindowWord (hwndTarg, GWW_HINSTANCE),
  217.                                szStr, sizeof (szStr));
  218.  
  219.             pszModuleName = strrchr(szStr, '\\')+1;
  220.            for (i = 0; i < sNumNoPopProgs; i++) {
  221.               if (strcmp (pszModuleName, szNoPopPrograms[i]) == 0) {
  222.                  bMenuUp = FALSE;
  223.                  break;
  224.               }
  225.            }  
  226.            if (bMenuUp && (i = GetMenuItemCount (hWinMenu))) {
  227.                 if (hMenu = CreatePopupMenu()) {
  228.                    
  229.                    CopyMenu (hMenu, hWinMenu);
  230.                     hProgMenu = CreatePopupMenu();
  231.  
  232.                    AppendMenu (hProgMenu, MF_ENABLED,
  233.                        0x7ffe, (LPSTR) "Configure Rclick...");
  234.                    AppendMenu (hProgMenu, MF_ENABLED,
  235.                        0x7fff, (LPSTR) "About RClick...");
  236.                    
  237.                    AppendMenu (hMenu, MF_SEPARATOR, 0, 0);
  238.                    AppendMenu (hMenu, MF_POPUP, hProgMenu, (LPSTR) "RClick");
  239.  
  240.                   bGetCMD = TRUE;                   
  241.                     TrackPopupMenu (hMenu, 0, lpmMsg->pt.x-10, 
  242.                                     lpmMsg->pt.y-5, 0, hwndTarg, 0);
  243.                   DestroyMenu (hMenu);
  244.                   lpmMsg->message = WM_NULL;
  245.                 }
  246.             }
  247.           bMenuUp = FALSE;
  248.             return 0;
  249.         } 
  250.     }
  251.     //
  252.     //Check for WM_COMMAND
  253.     //
  254.     if (bGetCMD && (lpmMsg->message == WM_COMMAND)) {
  255.        bGetCMD = FALSE;
  256.  
  257.         if (lpmMsg->wParam == 0x7fff) {
  258.             PostMessage (hwndMyWin, RBM_SHOWABOUTDLG, hwndTarg, 
  259.                          MAKELONG (lpmMsg->pt.y, lpmMsg->pt.x));
  260.           lpmMsg->message = WM_NULL;
  261.        }
  262.         if (lpmMsg->wParam == 0x7ffe) {
  263.             hwndTarg  = lpmMsg->hwnd;
  264.             PostMessage (hwndMyWin, RBM_SHOWCONFIGDLG, hwndTarg, 
  265.                          MAKELONG (lpmMsg->pt.y, lpmMsg->pt.x));
  266.           lpmMsg->message = WM_NULL;
  267.         }
  268.  
  269.     }
  270.    return DefHookProc (code, wParam, lParam, &lpfnNextHook);
  271. }
  272.  
  273. //===================================================================
  274. // Library exported functions
  275. //===================================================================
  276. //-------------------------------------------------------------------
  277. // GetStatus - Returns Status information
  278. //-------------------------------------------------------------------
  279. VOID FAR PASCAL GetStatus (PHOOKSTAT phsStatus){
  280.  
  281.     phsStatus -> hwndMyWin = hwndMyWin;
  282.     phsStatus -> sNoPopCnt = sNumNoPopProgs;
  283.     if (sHooked)
  284.         phsStatus -> bEnabled = TRUE;
  285.     else 
  286.         phsStatus -> bEnabled = FALSE;
  287.      return;
  288. }
  289. //-------------------------------------------------------------------
  290. // SetStatus - Returns Status information
  291. //-------------------------------------------------------------------
  292. VOID FAR PASCAL SetStatus (PHOOKSTAT phsStatus){
  293.  
  294.     hwndMyWin = phsStatus -> hwndMyWin;
  295.     if (phsStatus -> bEnabled)
  296.        SetHook (TRUE);
  297.     else 
  298.        SetHook (FALSE);
  299.      return;
  300. }
  301. //-------------------------------------------------------------------
  302. // GetNoPop - Returns the name in no pop list
  303. //-------------------------------------------------------------------
  304. VOID FAR PASCAL GetNoPop (int sIndex, LPSTR lpszNoPopName) {
  305.  
  306.     if (sIndex < sNumNoPopProgs) {
  307.        lstrcpy (lpszNoPopName, szNoPopPrograms[sIndex]);
  308.     }   
  309.     return;
  310. }
  311. //-------------------------------------------------------------------
  312. // SetNoPop - Adds program name to no pop list
  313. //-------------------------------------------------------------------
  314. VOID FAR PASCAL SetNoPop (LPSTR lpszNoPopName) {
  315.  
  316.     if (sNumNoPopProgs < MAXWINDOWS - 1) {
  317.        lstrcpy (szNoPopPrograms[sNumNoPopProgs++], lpszNoPopName);
  318.     }
  319.     return;
  320. }    
  321. //-------------------------------------------------------------------
  322. // RemoveNoPop - Removes a program name from the no pop list
  323. //-------------------------------------------------------------------
  324. VOID FAR PASCAL RemoveNoPop (LPSTR lpszNoPopName) {
  325.  
  326.     int    i, j;
  327.     
  328.    for (i = 0; i < sNumNoPopProgs; i++) {
  329.       if (lstrcmp (lpszNoPopName, (LPSTR) szNoPopPrograms[i]) == 0) {
  330.             for (j = i; j < sNumNoPopProgs - 1; j++) 
  331.                strcpy (szNoPopPrograms[j], szNoPopPrograms[j+1]);
  332.          break;
  333.       }
  334.    }
  335.    sNumNoPopProgs--;
  336.     return;
  337. }
  338.