home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / BOCOLE.PAK / BOLEHELP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  7.4 KB  |  238 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.5  $
  6. //
  7. // Implements message hooks for catching F1 in the dialogs
  8. //----------------------------------------------------------------------------
  9. #include "BOle.h"
  10. #include "BOleSvc.h"
  11.  
  12. extern "C" {
  13.   #include "Ole2UI.h"
  14. }
  15.  
  16.  
  17. // BOleHelpNotify is a C function which is exposed to the OLE2UI dialog
  18. // boxes (but not to other DLLs) for them to call back to get help from 
  19. // the application.
  20. //
  21. // 2 minor hacks are used here to solve the language differences between
  22. // the Bolero header files (C++ only) and OLE2UI (C, and I don't have the 
  23. // time to convert it to C++)
  24. //
  25. // 1. We're using the resource IDs of the dialog boxes to identify which 
  26. //    dialog box to provide help on since OLE2UI can't compile the 
  27. //    BOleDialogHelp enum.
  28. //
  29. // 2. The pCastToApp parameter is used because OLE2UI can't compile the
  30. //    class definition for IBApplication.
  31. //
  32. extern "C" void BOleHelpNotify (DWORD pCastToApp, int dialogResId)
  33. {
  34.     BOleDialogHelp helpCode;
  35.     switch (dialogResId) {
  36.         case IDD_INSERTCONTROL: helpCode = BOLE_HELP_BROWSECONTROL;   break;
  37.         case IDD_INSERTOBJECT : helpCode = BOLE_HELP_BROWSE;          break;
  38.         case IDD_PASTESPECIAL : helpCode = BOLE_HELP_BROWSECLIPBOARD; break;
  39.         case IDD_CONVERT      : helpCode = BOLE_HELP_CONVERT;         break;
  40.         case IDD_EDITLINKS    : helpCode = BOLE_HELP_BROWSELINKS;     break;
  41.         case IDD_CHANGEICON   : helpCode = BOLE_HELP_CHANGEICON;      break;
  42.         case IDD_INSERTFILEBROWSE
  43.                               : helpCode = BOLE_HELP_FILEOPEN;        break;
  44.         case IDD_CHANGESOURCE : helpCode = BOLE_HELP_SOURCESET;       break;
  45.         case IDD_CHANGEICONBROWSE
  46.                               : helpCode = BOLE_HELP_ICONFILEOPEN;    break;
  47.         default               : return;
  48.     }
  49.  
  50.     PIBApplication pIApp = (PIBApplication) pCastToApp;
  51.     pIApp->DialogHelpNotify (helpCode);
  52. }
  53.  
  54.  
  55. #ifndef WIN32    // help for old nonMS OLEUI  (MS_OLEUI_DEF)
  56.  
  57. extern "C" {
  58.   #include "Common.h"
  59. }
  60.  
  61. // GetBOleHook -- Examine the parameters to our hook proc and determine if 
  62. //                it's a message we should handle. If so, return the hook 
  63. //                out of the window properties
  64. //
  65. HHOOK GetBOleHook (int code, WPARAM wParam, LPARAM lParam)
  66. {
  67.     HHOOK hHook = NULL;
  68.  
  69.     // Make sure the message is one we should handle
  70.     //
  71.     if (code != MSGF_DIALOGBOX                 || 
  72.         ((LPMSG) lParam)->message != WM_KEYDOWN ||
  73.         ((LPMSG) lParam)->wParam != VK_F1)
  74.          return hHook; 
  75.  
  76.     // The window property "Structure" contains the private part of the
  77.     // dialog struct (INSERTOBJECT is private, OLEUIINSERTOBJECT is public)
  78.     //
  79.     HWND hwnd = GetParent (((LPMSG) lParam)->hwnd);
  80.     HANDLE hOleUIStd = GetProp (hwnd, TEXT(STRUCTUREPROP));
  81.     if (!hOleUIStd)
  82.         return hHook;
  83.  
  84.     // The data model in OLE2UI is limiting here. If we want to get the
  85.     // pointer to the public part of a dialog struct, there's nothing to
  86.     // cast this pointer to. OleUIStandard doesn't have the pointer in the
  87.     // beginning like the private declarations of the dialog box structs!
  88.     //
  89.     LPOLEUISTANDARD pOleUIStd = (LPOLEUISTANDARD) ((LPLONG) GlobalLock (hOleUIStd))[0];
  90.     if (!pOleUIStd)
  91.         return hHook;
  92.  
  93.     // If we're a system-wide hook, make sure this hook was installed in
  94.     // this task before returning it.
  95.     //
  96.  
  97.     hHook = pOleUIStd->hHook;
  98.     
  99.     GlobalUnlock (hOleUIStd);
  100.     return hHook;
  101. }
  102.  
  103. // MyHookProc is a MessageProc callback for SetWindowsHookEx which allows
  104. // us to catch messages during our dialog boxes. We're looking for F1
  105. // keystrokes which would otherwise be eaten by the control with focus.
  106. //
  107. extern "C" LRESULT _loadds CALLBACK MyHookProc (int code, WPARAM wParam, LPARAM lParam)
  108. {
  109.     HHOOK hHook = GetBOleHook (code, wParam, lParam);
  110.     if (hHook) {
  111.  
  112.         // The window which really gets the message is the control, so the
  113.         // dialog is its parent
  114.         //
  115.         HWND w = GetParent (((LPMSG) lParam)->hwnd);
  116.         ::PostMessage(w, RegisterWindowMessage(HELPMSGSTRING), 0, 0);
  117.         return ::CallNextHookEx (hHook, code, wParam, lParam);
  118.     }
  119.     return 0; 
  120. }
  121.  
  122. // EnterBOleDialog has two basic jobs:
  123. // 1. Install and remove the Windows hook which allows us to catch
  124. //    F1 keystrokes while we're running a BOleUI dialog box.
  125. // 2. Make sure we do the right enabling of modeless dialogs around
  126. //    the system
  127. //
  128. void BOleService::ExitBOleDialog ()
  129. {
  130.     // If we're closing this dialog box, remove the Windows hook 
  131.     ::UnhookWindowsHook (WH_MSGFILTER, MyHookProc);
  132.     OnModalDialog (FALSE);
  133.     return;
  134. }
  135.  
  136. void BOleService::EnterBOleDialog (HWND hwndOwner, HHOOK *hHook, HTASK *hTask)
  137. {
  138.     BOOL  fHookSuccess = TRUE;
  139.   HHOOK hook;
  140.  
  141.     // Find the address of the callback for the Windows hook
  142.     //
  143.     HOOKPROC hookProc = (HOOKPROC)MyHookProc; 
  144.     if (!hookProc) 
  145.         fHookSuccess = FALSE;
  146.  
  147.     // Install the Windows hook
  148.     //
  149.     if (fHookSuccess) {
  150.         hook = ::SetWindowsHook (WH_MSGFILTER, hookProc);
  151.         if (!(hook)) 
  152.             fHookSuccess = FALSE;
  153.  
  154.     if (fHookSuccess && hHook)
  155.       *hHook = hook;
  156.  
  157.         // Pass back the current "task"
  158.         //
  159.     if (hTask)
  160.           *hTask = GetCurrentTask();
  161.     }
  162.  
  163.     // Use the same thing Bolero clients do to en/disable modeless dialogs
  164.     //
  165.     OnModalDialog (TRUE);
  166. }
  167.  
  168.  
  169. #else  // WIN32   HELP for OLEUI standard dlgs
  170.  
  171.  
  172. const TCHAR selectorPtr[] = TEXT("UnlikelyNameClash_HelpSelectorPtr");
  173. const TCHAR offsetPtr[] = TEXT("UnlikelyNameClash_HelpOffsetPtr");
  174.  
  175.  
  176. BOOL GetBOleHook (UINT msg, WPARAM wParam, LPARAM lParam)
  177. {
  178.     if (msg == RegisterWindowMessage (SZOLEUI_MSG_HELP)) {
  179.          return TRUE; 
  180.   } else 
  181.      return FALSE;
  182. }
  183.  
  184. // MyWndProc is a MessageProc callback for hWndOwner to monitor for
  185. // help messages for OleUI dialogs.
  186. //
  187. extern "C" LRESULT _loadds CALLBACK MyWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  188. {
  189.     WORD sel = (WORD)GetProp (hwnd, selectorPtr);
  190.     WORD off = (WORD)GetProp (hwnd, offsetPtr);
  191.     BOleService *pSvc = (BOleService *) MAKELONG(off,sel);
  192.  
  193.     if (GetBOleHook (msg, wParam, lParam)) 
  194.     BOleHelpNotify ((DWORD) pSvc->GetApplication(), lParam);
  195.  
  196.   return ::CallWindowProc(pSvc->lpfnHelpWndProc, hwnd, msg, wParam, lParam);
  197. }
  198.  
  199. // EnterBOleDialog has two basic jobs:
  200. // 1. Install and remove the Windows hook which allows us to catch
  201. //    F1 keystrokes while we're running a BOleUI dialog box.
  202. // 2. Make sure we do the right enabling of modeless dialogs around
  203. //    the system
  204. //
  205. void BOleService::ExitBOleDialog ()
  206. {
  207.     // If we're closing this dialog box, remove the Windows hook 
  208.  
  209.   SetWindowLong (helpWnd, GWL_WNDPROC, (LONG)lpfnHelpWndProc);
  210.     RemoveProp (helpWnd, selectorPtr);
  211.     RemoveProp (helpWnd, offsetPtr);
  212.   lpfnHelpWndProc = NULL;
  213.   helpWnd = NULL;
  214.     OnModalDialog (FALSE);
  215.     return;
  216. }
  217.  
  218. void BOleService::EnterBOleDialog (HWND hwndOwner, HHOOK *hHook, HTASK *hTask)
  219. {
  220.   if (lpfnHelpWndProc == NULL) {
  221.        UINT    helpMsg = RegisterWindowMessage(SZOLEUI_MSG_HELP);
  222.      WNDPROC wndProc = (WNDPROC)MyWndProc; 
  223.      helpWnd = hwndOwner;
  224.  
  225.      SetProp (helpWnd, selectorPtr, (HANDLE)HIWORD((DWORD)this));     //SELECTOROF(this));
  226.      SetProp (helpWnd, offsetPtr, (HANDLE)LOWORD((DWORD)this));        //OFFSETOF(this));
  227.  
  228.      lpfnHelpWndProc =  (WNDPROC)GetWindowLong (helpWnd, GWL_WNDPROC);
  229.      SetWindowLong (helpWnd, GWL_WNDPROC, (LONG)wndProc);
  230.   }
  231.  
  232.     // Use the same thing Bolero clients do to en/disable modeless dialogs
  233.     //
  234.     OnModalDialog (TRUE);
  235. }
  236. #endif  // WIN32
  237.  
  238.