Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2488 lines
72 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Sample Code
  4. **
  5. ** main.c
  6. **
  7. ** This file contains initialization functions which are WinMain,
  8. ** WndProc, and OutlineApp_InitalizeMenu.
  9. **
  10. ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
  11. **
  12. *************************************************************************/
  13. #include "outline.h"
  14. #if defined( USE_STATUSBAR )
  15. #include "status.h"
  16. #endif
  17. #if !defined( WIN32 )
  18. #if defined( USE_CTL3D )
  19. #include "ctl3d.h"
  20. #endif // USE_CTL3D
  21. #endif // !WIN32
  22. #include "initguid.h" // forces our GUIDs to be initialized
  23. #include "defguid.h"
  24. // OLETEST driver window handler
  25. HWND g_hwndDriver;
  26. #if defined( OLE_CNTR )
  27. //*************************************************************************
  28. #if defined( INPLACE_CNTR )
  29. OLEDBGDATA_MAIN("ICNTR")
  30. #else
  31. OLEDBGDATA_MAIN("CNTR")
  32. #endif
  33. CONTAINERAPP g_OutlineApp; // Global App object maintains app instance state
  34. /* Global interface Vtbl's
  35. * OLE2NOTE: we only need one copy of each Vtbl. When an object which
  36. * exposes an interface is instantiated, its lpVtbl is intialized
  37. * to point to one of these global Vtbl's.
  38. */
  39. IUnknownVtbl g_OleApp_UnknownVtbl;
  40. IClassFactoryVtbl g_OleApp_ClassFactoryVtbl;
  41. IMessageFilterVtbl g_OleApp_MessageFilterVtbl;
  42. IUnknownVtbl g_OleDoc_UnknownVtbl;
  43. IPersistFileVtbl g_OleDoc_PersistFileVtbl;
  44. IOleItemContainerVtbl g_OleDoc_OleItemContainerVtbl;
  45. IExternalConnectionVtbl g_OleDoc_ExternalConnectionVtbl;
  46. IDataObjectVtbl g_OleDoc_DataObjectVtbl;
  47. #if defined( USE_DRAGDROP )
  48. IDropSourceVtbl g_OleDoc_DropSourceVtbl;
  49. IDropTargetVtbl g_OleDoc_DropTargetVtbl;
  50. #endif // USE_DRAGDROP
  51. IOleUILinkContainerVtbl g_CntrDoc_OleUILinkContainerVtbl;
  52. IOleClientSiteVtbl g_CntrLine_UnknownVtbl;
  53. IOleClientSiteVtbl g_CntrLine_OleClientSiteVtbl;
  54. IAdviseSinkVtbl g_CntrLine_AdviseSinkVtbl;
  55. #if defined( INPLACE_CNTR )
  56. IOleInPlaceSiteVtbl g_CntrLine_OleInPlaceSiteVtbl;
  57. IOleInPlaceFrameVtbl g_CntrApp_OleInPlaceFrameVtbl;
  58. BOOL g_fInsideOutContainer = FALSE; // default to outside-in activation
  59. #endif // INPLACE_CNTR
  60. //*************************************************************************
  61. #endif // OLE_CNTR
  62. #if defined( OLE_SERVER )
  63. //*************************************************************************
  64. #if defined( INPLACE_SVR )
  65. OLEDBGDATA_MAIN("ISVR")
  66. #else
  67. OLEDBGDATA_MAIN("SVR")
  68. #endif
  69. SERVERAPP g_OutlineApp; // Global App object maintains app instance state
  70. /* Global interface Vtbl's
  71. * OLE2NOTE: we only need one copy of each Vtbl. When an object which
  72. * exposes an interface is instantiated, its lpVtbl is intialized
  73. * to point to one of these global Vtbl's.
  74. */
  75. IUnknownVtbl g_OleApp_UnknownVtbl;
  76. IClassFactoryVtbl g_OleApp_ClassFactoryVtbl;
  77. IMessageFilterVtbl g_OleApp_MessageFilterVtbl;
  78. IUnknownVtbl g_OleDoc_UnknownVtbl;
  79. IPersistFileVtbl g_OleDoc_PersistFileVtbl;
  80. IOleItemContainerVtbl g_OleDoc_OleItemContainerVtbl;
  81. IExternalConnectionVtbl g_OleDoc_ExternalConnectionVtbl;
  82. IDataObjectVtbl g_OleDoc_DataObjectVtbl;
  83. #if defined( USE_DRAGDROP )
  84. IDropSourceVtbl g_OleDoc_DropSourceVtbl;
  85. IDropTargetVtbl g_OleDoc_DropTargetVtbl;
  86. #endif // USE_DRAGDROP
  87. IOleObjectVtbl g_SvrDoc_OleObjectVtbl;
  88. IPersistStorageVtbl g_SvrDoc_PersistStorageVtbl;
  89. #if defined( SVR_TREATAS )
  90. IStdMarshalInfoVtbl g_SvrDoc_StdMarshalInfoVtbl;
  91. #endif // SVR_TREATAS
  92. #if defined( INPLACE_SVR )
  93. IOleInPlaceObjectVtbl g_SvrDoc_OleInPlaceObjectVtbl;
  94. IOleInPlaceActiveObjectVtbl g_SvrDoc_OleInPlaceActiveObjectVtbl;
  95. #endif // INPLACE_SVR
  96. IUnknownVtbl g_PseudoObj_UnknownVtbl;
  97. IOleObjectVtbl g_PseudoObj_OleObjectVtbl;
  98. IDataObjectVtbl g_PseudoObj_DataObjectVtbl;
  99. //*************************************************************************
  100. #endif // OLE_SVR
  101. #if !defined( OLE_VERSION )
  102. OLEDBGDATA_MAIN("OUTL")
  103. OUTLINEAPP g_OutlineApp; // Global App object maintains app instance state
  104. #endif
  105. LPOUTLINEAPP g_lpApp=(LPOUTLINEAPP)&g_OutlineApp; // ptr to global app obj
  106. RECT g_rectNull = {0, 0, 0, 0};
  107. UINT g_uMsgHelp = 0; // help msg from ole2ui dialogs
  108. BOOL g_fAppActive = FALSE;
  109. /* WinMain
  110. ** -------
  111. ** Main routine for the Windows application.
  112. */
  113. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  114. LPSTR lpszCmdLine, int nCmdShow)
  115. {
  116. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  117. MSG msg; /* MSG structure to store your messages */
  118. LPSTR pszTemp;
  119. #if defined( OLE_VERSION )
  120. /* OLE2NOTE: it is recommended that all OLE applications to set
  121. ** their message queue size to 96. this improves the capacity
  122. ** and performance of OLE's LRPC mechanism.
  123. */
  124. int cMsg = 96; // recommend msg queue size for OLE
  125. while (cMsg && ! SetMessageQueue(cMsg)) // take largest size we can get.
  126. cMsg -= 8;
  127. if (! cMsg)
  128. return -1; // ERROR: we got no message queue
  129. #endif
  130. #if defined( USE_CTL3D )
  131. Ctl3dRegister(hInstance);
  132. Ctl3dAutoSubclass(hInstance);
  133. #endif
  134. if(! hPrevInstance) {
  135. /* register window classes if first instance of application */
  136. if(! OutlineApp_InitApplication(lpOutlineApp, hInstance))
  137. return 0;
  138. }
  139. /* Create App Frame window */
  140. if (! OutlineApp_InitInstance(lpOutlineApp, hInstance, nCmdShow))
  141. return 0;
  142. if( (pszTemp = strstr(lpszCmdLine, "-driver")) )
  143. {
  144. //we were launched by the test driver
  145. g_hwndDriver = (HWND)strtoul(pszTemp+8, &lpszCmdLine, 10);
  146. }
  147. else
  148. {
  149. g_hwndDriver = NULL;
  150. }
  151. if (! OutlineApp_ParseCmdLine(lpOutlineApp, lpszCmdLine, nCmdShow))
  152. return 0;
  153. lpOutlineApp->m_hAccelApp = LoadAccelerators(hInstance, APPACCEL);
  154. lpOutlineApp->m_hAccelFocusEdit = LoadAccelerators(hInstance,
  155. FB_EDIT_ACCEL);
  156. lpOutlineApp->m_hAccel = lpOutlineApp->m_hAccelApp;
  157. lpOutlineApp->m_hWndAccelTarget = lpOutlineApp->m_hWndApp;
  158. if( g_hwndDriver )
  159. {
  160. PostMessage(g_hwndDriver, WM_TESTREG,
  161. (WPARAM)lpOutlineApp->m_hWndApp, 0);
  162. }
  163. // Main message loop
  164. while(GetMessage(&msg, NULL, 0, 0)) { /* Until WM_QUIT message */
  165. if(!MyTranslateAccelerator(&msg)) {
  166. TranslateMessage(&msg);
  167. DispatchMessage(&msg);
  168. }
  169. }
  170. #if defined( OLE_VERSION )
  171. OleApp_TerminateApplication((LPOLEAPP)lpOutlineApp);
  172. #else
  173. /* OLE2NOTE: CoInitialize() is called in OutlineApp_InitInstance
  174. ** and therefore we need to uninitialize it when exit.
  175. */
  176. CoUninitialize();
  177. #endif
  178. #if defined( USE_CTL3D )
  179. Ctl3dUnregister(hInstance);
  180. #endif
  181. return msg.wParam;
  182. } /* End of WinMain */
  183. BOOL MyTranslateAccelerator(LPMSG lpmsg)
  184. {
  185. // if it's not a keystroke it can not be an accelerator
  186. if (lpmsg->message < WM_KEYFIRST || lpmsg->message > WM_KEYLAST)
  187. return FALSE;
  188. if (g_lpApp->m_hWndAccelTarget &&
  189. TranslateAccelerator(g_lpApp->m_hWndAccelTarget,
  190. g_lpApp->m_hAccel,lpmsg))
  191. return TRUE;
  192. #if defined( INPLACE_SVR )
  193. /* OLE2NOTE: if we are in-place active and we did not translate the
  194. ** accelerator, we need to give the top-level (frame) in-place
  195. ** container a chance to translate the accelerator.
  196. ** we ONLY need to call OleTranslateAccelerator API if the
  197. ** message is a keyboard message. otherwise it is harmless but
  198. ** unnecessary.
  199. **
  200. ** NOTE: even a in-place server that does NOT have any
  201. ** Accelerators must still call OleTranslateAccelerator for all
  202. ** keyboard messages so that the server's OWN menu mneumonics
  203. ** (eg. &Edit -- Alt-e) function properly.
  204. **
  205. ** NOTE: an in-place server MUST check that the accelerator is
  206. ** NOT one of its own accelerators BEFORE calling
  207. ** OleTranslateAccelerator which tries to see if it is a
  208. ** container accelerator. if this is a server accelerator that
  209. ** was not translateed because the associated menu command was
  210. ** disabled, we MUST NOT call OleTranslateAccelerator. The
  211. ** IsAccelerator helper API has been added to assist with this
  212. ** check.
  213. */
  214. if (g_OutlineApp.m_lpIPData &&
  215. !IsAccelerator(g_lpApp->m_hAccel,
  216. GetAccelItemCount(g_lpApp->m_hAccel), lpmsg,NULL) &&
  217. OleTranslateAccelerator(g_OutlineApp.m_lpIPData->lpFrame,
  218. (LPOLEINPLACEFRAMEINFO)&g_OutlineApp.m_lpIPData->frameInfo,
  219. lpmsg) == NOERROR) {
  220. return TRUE;
  221. }
  222. #endif
  223. return FALSE;
  224. }
  225. /************************************************************************/
  226. /* */
  227. /* Main Window Procedure */
  228. /* */
  229. /* This procedure provides service routines for the Windows events */
  230. /* (messages) that Windows sends to the window, as well as the user */
  231. /* initiated events (messages) that are generated when the user selects */
  232. /* the action bar and pulldown menu controls or the corresponding */
  233. /* keyboard accelerators. */
  234. /* */
  235. /************************************************************************/
  236. LRESULT FAR PASCAL AppWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
  237. {
  238. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)GetWindowLong(hWnd, 0);
  239. LPOUTLINEDOC lpOutlineDoc = NULL;
  240. #if defined( OLE_VERSION )
  241. LPOLEAPP lpOleApp = (LPOLEAPP)lpOutlineApp;
  242. #endif
  243. #if defined( OLE_CNTR )
  244. LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOutlineApp;
  245. #endif
  246. HWND hWndDoc = NULL;
  247. #if defined( USE_FRAMETOOLS )
  248. LPFRAMETOOLS lptb = OutlineApp_GetFrameTools(lpOutlineApp);
  249. #endif
  250. if (lpOutlineApp) {
  251. lpOutlineDoc = OutlineApp_GetActiveDoc(lpOutlineApp);
  252. if (lpOutlineDoc)
  253. hWndDoc = OutlineDoc_GetWindow(lpOutlineDoc);
  254. }
  255. switch (Message) {
  256. case WM_TEST1:
  257. StartClipboardTest1(lpOutlineApp);
  258. break;
  259. case WM_TEST2:
  260. ContinueClipboardTest1(lpOutlineApp);
  261. break;
  262. case WM_COMMAND:
  263. {
  264. #ifdef WIN32
  265. WORD wID = LOWORD(wParam);
  266. #else
  267. WORD wID = wParam;
  268. #endif
  269. #if defined( INPLACE_CNTR )
  270. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  271. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  272. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
  273. ** m_fMenuHelpMode flag is set when F1 is pressed when a
  274. ** menu item is selected. this flag is set in
  275. ** IOleInPlaceFrame::ContextSensitveHelp method.
  276. ** m_fCSHelpMode flag is set when SHIFT-F1 context
  277. ** sensitive help is entered. this flag is set in
  278. ** IOleInPlaceSite::ContextSensitiveHelp method.
  279. ** if either of these flags are set then the WM_COMMAND
  280. ** message is received then, the corresponding command
  281. ** should NOT executed; help can be given (if desired).
  282. ** also the context sensitve help mode should be exited.
  283. ** the two different cases have their own way to exit
  284. ** the mode (please refer to the technote).
  285. */
  286. if (lpOleDoc &&
  287. (lpContainerApp->m_fMenuHelpMode||lpOleDoc->m_fCSHelpMode) &&
  288. (wID > IDM_FILE) /* min wID for app command */ &&
  289. (wID!=IDM_FB_EDIT) /* special wID to control FormulaBar */ ) {
  290. if ((lpContainerApp->m_fMenuHelpMode)) {
  291. LPOLEINPLACEACTIVEOBJECT lpIPActiveObj =
  292. lpContainerApp->m_lpIPActiveObj;
  293. lpContainerApp->m_fMenuHelpMode = FALSE;
  294. // inform the in-place active object that we handled the
  295. // menu help mode (F1) selection.
  296. if (lpIPActiveObj) {
  297. OLEDBG_BEGIN2("IOleInPlaceActiveObject::ContextSensitiveHelp(FALSE) called\r\n")
  298. lpIPActiveObj->lpVtbl->ContextSensitiveHelp(
  299. lpIPActiveObj, FALSE);
  300. OLEDBG_END2
  301. }
  302. }
  303. if ((lpOleDoc->m_fCSHelpMode)) {
  304. LPOLEINPLACEOBJECT lpIPObj;
  305. LPCONTAINERLINE lpLastIpActiveLine =
  306. lpContainerDoc->m_lpLastIpActiveLine;
  307. lpOleDoc->m_fCSHelpMode = FALSE;
  308. /* inform immediate in-place container parent and,
  309. ** if we were a container/server, immediate
  310. ** in-place object children that we handled the
  311. ** context sensitive help mode.
  312. */
  313. if (lpLastIpActiveLine &&
  314. (lpIPObj=lpLastIpActiveLine->m_lpOleIPObj)!=NULL){
  315. OLEDBG_BEGIN2("IOleInPlaceObject::ContextSensitiveHelp(FALSE) called\r\n")
  316. lpIPObj->lpVtbl->ContextSensitiveHelp(lpIPObj, FALSE);
  317. OLEDBG_END2
  318. }
  319. }
  320. // if we provided help, we would do it here...
  321. // remove context sensitive help cursor
  322. SetCursor(LoadCursor(NULL,IDC_ARROW));
  323. return 0L;
  324. }
  325. #endif // INPLACE_CNTR
  326. switch (wID) {
  327. case IDM_F_NEW:
  328. OleDbgIndent(-2); // Reset debug output indent level
  329. OleDbgOutNoPrefix2("\r\n");
  330. OLEDBG_BEGIN3("OutlineApp_NewCommand\r\n")
  331. OutlineApp_NewCommand(lpOutlineApp);
  332. OLEDBG_END3
  333. #if defined( OLE_CNTR )
  334. /* OLE2NOTE: this call will attempt to recover
  335. ** resources by unloading DLL's that were loaded
  336. ** by OLE and are no longer being used. it is a
  337. ** good idea to call this API now and then if
  338. ** your app tends to run for a long time.
  339. ** otherwise these DLL's will be unloaded when
  340. ** the app exits. some apps may want to call
  341. ** this as part of idle-time processing. this
  342. ** call is optional.
  343. */
  344. OLEDBG_BEGIN2("CoFreeUnusedLibraries called\r\n")
  345. CoFreeUnusedLibraries();
  346. OLEDBG_END2
  347. #endif
  348. #if defined( USE_FRAMETOOLS )
  349. OutlineDoc_UpdateFrameToolButtons(
  350. OutlineApp_GetActiveDoc(lpOutlineApp));
  351. #endif
  352. break;
  353. case IDM_F_OPEN:
  354. OleDbgOutNoPrefix2("\r\n");
  355. OLEDBG_BEGIN3("OutlineApp_OpenCommand\r\n")
  356. OutlineApp_OpenCommand(lpOutlineApp);
  357. OLEDBG_END3
  358. #if defined( OLE_CNTR )
  359. /* OLE2NOTE: this call will attempt to recover
  360. ** resources by unloading DLL's that were loaded
  361. ** by OLE and are no longer being used. it is a
  362. ** good idea to call this API now and then if
  363. ** your app tends to run for a long time.
  364. ** otherwise these DLL's will be unloaded when
  365. ** the app exits. some apps may want to call
  366. ** this as part of idle-time processing. this
  367. ** call is optional.
  368. */
  369. OLEDBG_BEGIN2("CoFreeUnusedLibraries called\r\n")
  370. CoFreeUnusedLibraries();
  371. OLEDBG_END2
  372. #endif
  373. #if defined( USE_FRAMETOOLS )
  374. OutlineDoc_UpdateFrameToolButtons(
  375. OutlineApp_GetActiveDoc(lpOutlineApp));
  376. #endif
  377. break;
  378. case IDM_F_SAVE:
  379. OleDbgOutNoPrefix2("\r\n");
  380. OLEDBG_BEGIN3("OutlineApp_SaveCommand\r\n")
  381. OutlineApp_SaveCommand(lpOutlineApp);
  382. OLEDBG_END3
  383. break;
  384. case IDM_F_SAVEAS:
  385. OleDbgOutNoPrefix2("\r\n");
  386. OLEDBG_BEGIN3("OutlineApp_SaveAsCommand\r\n")
  387. OutlineApp_SaveAsCommand(lpOutlineApp);
  388. OLEDBG_END3
  389. break;
  390. case IDM_F_PRINT:
  391. OleDbgOutNoPrefix2("\r\n");
  392. OLEDBG_BEGIN3("OutlineApp_PrintCommand\r\n")
  393. OutlineApp_PrintCommand(lpOutlineApp);
  394. OLEDBG_END3
  395. break;
  396. case IDM_F_PRINTERSETUP:
  397. OleDbgOutNoPrefix2("\r\n");
  398. OLEDBG_BEGIN3("OutlineApp_PrinterSetupCommand\r\n")
  399. OutlineApp_PrinterSetupCommand(lpOutlineApp);
  400. OLEDBG_END3
  401. break;
  402. case IDM_F_EXIT:
  403. SendMessage(hWnd, WM_CLOSE, 0, 0L);
  404. break;
  405. case IDM_H_ABOUT:
  406. OutlineApp_AboutCommand(lpOutlineApp);
  407. break;
  408. #if defined( INPLACE_CNTR )
  409. case IDM_ESCAPE:
  410. {
  411. /* ESCAPE key pressed */
  412. LPCONTAINERDOC lpContainerDoc =
  413. (LPCONTAINERDOC)lpOutlineDoc;
  414. /* OLE2NOTE: The standard OLE 2.0 UI convention
  415. ** is to have ESCAPE key exit in-place
  416. ** activation (ie. UIDeactivate). If
  417. ** possible it is recommended for both
  418. ** in-place servers AND in-place containers
  419. ** to take responsibility to handle the
  420. ** ESCAPE key accelerator. The server has
  421. ** the first crack at handling accelerator
  422. ** keys and normally the server should do
  423. ** the UIDeactivation. It is a good idea for
  424. ** in-place containers, in order to
  425. ** guarantee consistent behavior, to also
  426. ** handle the ESCAPE key and UIDeactivate
  427. ** the object in case the object does not do
  428. ** it itself. normally this should be
  429. ** unnecessary.
  430. */
  431. if (lpContainerDoc->m_lpLastUIActiveLine &&
  432. lpContainerDoc->m_lpLastUIActiveLine->m_fUIActive)
  433. {
  434. ContainerLine_UIDeactivate(
  435. lpContainerDoc->m_lpLastUIActiveLine);
  436. }
  437. break;
  438. }
  439. #endif // INPLACE_CNTR
  440. default:
  441. // forward message to document window
  442. if (hWndDoc) {
  443. return DocWndProc(hWndDoc, Message,wParam,lParam);
  444. }
  445. }
  446. break; /* End of WM_COMMAND */
  447. }
  448. case WM_INITMENU:
  449. OutlineApp_InitMenu(lpOutlineApp, lpOutlineDoc, (HMENU)wParam);
  450. break;
  451. #if defined( OLE_VERSION )
  452. /* OLE2NOTE: WM_INITMENUPOPUP is trapped primarily for the Edit
  453. ** menu. We didn't update the Edit menu until it is popped
  454. ** up to avoid the overheads of the OLE calls which are
  455. ** required to initialize some Edit menu items.
  456. */
  457. case WM_INITMENUPOPUP:
  458. {
  459. HMENU hMenuEdit = GetSubMenu(lpOutlineApp->m_hMenuApp, 1);
  460. #if defined( INPLACE_CNTR )
  461. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  462. /* OLE2NOTE: we must check if there is an object currently
  463. ** in-place UIActive. if so, then our edit menu is not
  464. ** on the menu; we do not want to bother updating the
  465. ** edit menu when it is not even there.
  466. */
  467. if (lpContainerDoc && lpContainerDoc->m_lpLastUIActiveLine &&
  468. lpContainerDoc->m_lpLastUIActiveLine->m_fUIActive)
  469. break; // an object is in-place UI active
  470. #endif
  471. if ((HMENU)wParam == hMenuEdit &&
  472. (LOWORD(lParam) == POS_EDITMENU) &&
  473. OleDoc_GetUpdateEditMenuFlag((LPOLEDOC)lpOutlineDoc)) {
  474. OleApp_UpdateEditMenu(lpOleApp, lpOutlineDoc, hMenuEdit);
  475. }
  476. break;
  477. }
  478. #endif // OLE_VERSION
  479. case WM_SIZE:
  480. if (wParam != SIZE_MINIMIZED)
  481. OutlineApp_ResizeWindows(lpOutlineApp);
  482. break;
  483. case WM_ACTIVATEAPP:
  484. #if defined (OLE_CNTR)
  485. if (g_fAppActive = (BOOL) wParam)
  486. OleApp_QueryNewPalette(lpOleApp);
  487. #endif
  488. #if defined( INPLACE_CNTR )
  489. {
  490. BOOL fActivate = (BOOL)wParam;
  491. LPOLEINPLACEACTIVEOBJECT lpIPActiveObj =
  492. lpContainerApp->m_lpIPActiveObj;
  493. /* OLE2NOTE: the in-place container MUST inform the
  494. ** inner most in-place active object (this is NOT
  495. ** necessarily our immediate child if there are
  496. ** nested levels of embedding) of the WM_ACTIVATEAPP
  497. ** status.
  498. */
  499. if (lpIPActiveObj) {
  500. #if defined( _DEBUG )
  501. OLEDBG_BEGIN2((fActivate ?
  502. "IOleInPlaceActiveObject::OnFrameWindowActivate(TRUE) called\r\n" :
  503. "IOleInPlaceActiveObject::OnFrameWindowActivate(FALSE) called\r\n"))
  504. #endif // _DEUBG
  505. lpIPActiveObj->lpVtbl->OnFrameWindowActivate(
  506. lpIPActiveObj, fActivate);
  507. OLEDBG_END2
  508. }
  509. }
  510. #endif // INPLACE_CNTR
  511. // OLE2NOTE: We can't call OutlineDoc_UpdateFrameToolButtons
  512. // right away which
  513. // would generate some OLE calls and eventually
  514. // WM_ACTIVATEAPP and a loop was formed. Therefore, we
  515. // should delay the frame tool initialization until
  516. // WM_ACTIVATEAPP is finished by posting a message
  517. // to ourselves.
  518. // we want to ignore the WM_ACTIVATEAPP that comes
  519. // as we bring up a modal dialog.
  520. /* Update enable/disable state of buttons in toolbar */
  521. if (wParam
  522. #if defined( OLE_VERSION )
  523. && lpOleApp->m_cModalDlgActive == 0
  524. #endif
  525. ) {
  526. PostMessage(hWnd, WM_U_INITFRAMETOOLS, 0, 0L);
  527. }
  528. return 0L;
  529. case WM_SETFOCUS:
  530. SetFocus(hWndDoc);
  531. break;
  532. #if defined( OLE_CNTR )
  533. case WM_QUERYNEWPALETTE:
  534. if (!g_fAppActive)
  535. return 0L;
  536. return OleApp_QueryNewPalette(lpOleApp);
  537. case WM_PALETTECHANGED:
  538. {
  539. HWND hWndPalChg = (HWND) wParam;
  540. static BOOL fInPaletteChanged = FALSE;
  541. if (fInPaletteChanged) // Guard against recursion
  542. return 0L;
  543. fInPaletteChanged = TRUE;
  544. if (hWnd != hWndPalChg)
  545. wSelectPalette(hWnd, lpOleApp->m_hStdPal,TRUE/*fBackground*/);
  546. #if defined( INPLACE_CNTR )
  547. /* OLE2NOTE: always forward the WM_PALETTECHANGED message (via
  548. ** SendMessage) to any in-place objects that currently have
  549. ** their window visible. this gives these objects the chance
  550. ** to select their palettes. this is
  551. ** REQUIRED by all in-place containers independent of
  552. ** whether they use color palettes themselves--their objects
  553. ** may use color palettes.
  554. ** (see ContainerDoc_ForwardPaletteChangedMsg for more info)
  555. */
  556. if (lpOutlineDoc){
  557. ContainerDoc_ForwardPaletteChangedMsg(
  558. (LPCONTAINERDOC)lpOutlineDoc, hWndPalChg);
  559. }
  560. #endif // INPLACE_CNTR
  561. fInPaletteChanged = FALSE;
  562. return 0L;
  563. }
  564. #endif // OLE_CNTR
  565. case WM_DESTROY:
  566. PostQuitMessage(0);
  567. break;
  568. case WM_CLOSE: /* close the window */
  569. /* Close all active documents. if successful, then exit */
  570. OleDbgOutNoPrefix2("\r\n");
  571. OutlineApp_CloseAllDocsAndExitCommand(lpOutlineApp, FALSE);
  572. break;
  573. case WM_QUERYENDSESSION:
  574. {
  575. #if defined( OLE_CNTR )
  576. /* OLE2NOTE: we are not able to make OLE LRPC calls when
  577. ** WM_QUERYENDSESSION is recieved (this is a
  578. ** SendMessage). this means, for example, that we are
  579. ** NOT able to ask objects to save. thus the most we can
  580. ** do is ask the user if he wants to exit with
  581. ** discarding changes or else abort shutting down.
  582. */
  583. int nResponse = MessageBox(
  584. hWnd,
  585. "Discard changes?",
  586. APPNAME,
  587. MB_ICONQUESTION | MB_OKCANCEL
  588. );
  589. if(nResponse == IDOK)
  590. return 1L; /* can terminate */
  591. #endif
  592. #if defined( OLE_SERVER )
  593. /* OLE2NOTE: an embedded object should never prompt whether
  594. ** it should be saved (according the OLE 2.0 User
  595. ** Model). therefore, an embedded object will never
  596. ** complain that it needs to be saved. it will always
  597. ** allow the QueryEndSession to proceed.
  598. */
  599. if (lpOutlineApp->m_lpDoc->m_docInitType == DOCTYPE_EMBEDDED)
  600. return 1L; /* can terminate */
  601. else
  602. #endif
  603. {
  604. /* this is not an embedded object; it is a user
  605. ** document. we will prompt if the user wants to
  606. ** save the document now in WM_QUERYENDSESSION. if
  607. ** the user cancels then that would abort the
  608. ** shutdown. if the user does not abort, then later
  609. ** in WM_ENDSESSION the document will be actually
  610. ** closed.
  611. **
  612. ** Because this is an SDI app, there is only one
  613. ** document. An MDI would need to loop through all
  614. ** open documents.
  615. */
  616. DWORD dwSaveOption = OLECLOSE_PROMPTSAVE;
  617. if (OutlineDoc_CheckSaveChanges(
  618. lpOutlineApp->m_lpDoc, &dwSaveOption))
  619. return 1L; /* can terminate */
  620. }
  621. /* else: can't terminate now */
  622. break;
  623. }
  624. #if defined( OLE_VERSION)
  625. case WM_ENDSESSION:
  626. {
  627. BOOL fEndSession = (BOOL)wParam;
  628. if (fEndSession) {
  629. OutlineApp_CloseAllDocsAndExitCommand(lpOutlineApp, TRUE);
  630. return 0L;
  631. }
  632. }
  633. break;
  634. #endif // OLE_VERSION
  635. #if defined( USE_STATUSBAR )
  636. case WM_MENUSELECT:
  637. {
  638. LPSTR lpszMessage;
  639. #ifdef WIN32
  640. UINT fuFlags = (UINT)HIWORD(wParam);
  641. UINT uItem = (UINT)LOWORD(wParam);
  642. #else
  643. UINT fuFlags = (UINT)LOWORD(lParam);
  644. UINT uItem = (UINT)wParam;
  645. #endif
  646. if (uItem == 0 && fuFlags == (UINT)-1) {
  647. GetControlMessage(STATUS_READY, &lpszMessage);
  648. OutlineApp_SetStatusText(lpOutlineApp, lpszMessage);
  649. }
  650. else if (fuFlags & MF_POPUP) {
  651. #ifdef WIN32
  652. HMENU hMainMenu = (HMENU)lParam;
  653. HMENU hPopupMenu = GetSubMenu(hMainMenu,uItem);
  654. #else
  655. HMENU hPopupMenu = (HMENU)wParam;
  656. #endif
  657. GetPopupMessage(hPopupMenu, &lpszMessage);
  658. OutlineApp_SetStatusText(lpOutlineApp, lpszMessage);
  659. }
  660. else if (fuFlags & MF_SYSMENU) {
  661. GetSysMenuMessage(uItem, &lpszMessage);
  662. OutlineApp_SetStatusText(lpOutlineApp, lpszMessage);
  663. }
  664. else if (uItem != 0) { // Command Item
  665. GetItemMessage(uItem, &lpszMessage);
  666. OutlineApp_SetStatusText(lpOutlineApp, lpszMessage);
  667. }
  668. else {
  669. GetControlMessage(STATUS_BLANK, &lpszMessage);
  670. OutlineApp_SetStatusText(lpOutlineApp, lpszMessage);
  671. }
  672. break;
  673. }
  674. #endif // USE_STATUSBAR
  675. #if defined( USE_FRAMETOOLS )
  676. case WM_U_INITFRAMETOOLS:
  677. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  678. break;
  679. #endif
  680. default:
  681. /* For any message for which you don't specifically provide a */
  682. /* service routine, you should return the message to Windows */
  683. /* for default message processing. */
  684. return DefWindowProc(hWnd, Message, wParam, lParam);
  685. }
  686. return (LRESULT)0;
  687. } /* End of AppWndProc */
  688. /************************************************************************/
  689. /* */
  690. /* Document Window Procedure */
  691. /* */
  692. /* The Document Window is the parent of the OwnerDraw Listbox which */
  693. /* maintains the list of lines in the current document. This window */
  694. /* receives the ownerdraw callback messages from the list box. */
  695. /************************************************************************/
  696. LRESULT FAR PASCAL DocWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
  697. {
  698. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  699. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)GetWindowLong(hWnd, 0);
  700. LPLINELIST lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
  701. LPSCALEFACTOR lpscale = OutlineDoc_GetScaleFactor(lpOutlineDoc);
  702. #if defined( OLE_VERSION )
  703. LPOLEAPP lpOleApp = (LPOLEAPP)lpOutlineApp;
  704. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  705. #if defined( OLE_CNTR )
  706. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  707. #endif
  708. #if defined( OLE_SERVER )
  709. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  710. #endif
  711. #if defined( INPLACE_CNTR )
  712. LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOutlineApp;
  713. #endif
  714. #endif // OLE_VERSION
  715. switch(Message) {
  716. #if defined( INPLACE_SVR )
  717. /* OLE2NOTE: ISVROTL doesn't use color palettes. The inplace objects
  718. ** that use color palettes must implement the following
  719. ** lines of code.
  720. **
  721. case WM_QUERYNEWPALETTE:
  722. return wSelectPalette(hWnd, hPal, FALSE); // foreground
  723. case WM_PALETTECHANGED:
  724. if (hWnd != (HWND) wParam)
  725. wSelectPalette(hWnd, hPal, TRUE); // background
  726. break;
  727. **
  728. **
  729. **
  730. */
  731. #endif
  732. case WM_MEASUREITEM:
  733. {
  734. LPMEASUREITEMSTRUCT lpmis = ((LPMEASUREITEMSTRUCT)lParam);
  735. switch (wParam) {
  736. case IDC_LINELIST:
  737. {
  738. HDC hDC = LineList_GetDC(lpLL);
  739. UINT uHeight;
  740. uHeight=Line_GetHeightInHimetric((LPLINE)lpmis->itemData);
  741. uHeight = XformHeightInHimetricToPixels(hDC, uHeight);
  742. uHeight = (UINT) (uHeight * lpscale->dwSyN /
  743. lpscale->dwSyD);
  744. if (uHeight >LISTBOX_HEIGHT_LIMIT)
  745. uHeight = LISTBOX_HEIGHT_LIMIT;
  746. lpmis->itemHeight = uHeight;
  747. LineList_ReleaseDC(lpLL, hDC);
  748. break;
  749. }
  750. case IDC_NAMETABLE:
  751. {
  752. // NOTE: NameTable is never made visible. do nothing.
  753. break;
  754. }
  755. #if defined( USE_HEADING )
  756. case IDC_ROWHEADING:
  757. {
  758. UINT uHeight;
  759. uHeight = LOWORD(lpmis->itemData);
  760. uHeight = (UINT) (uHeight * lpscale->dwSyN /
  761. lpscale->dwSyD);
  762. if (uHeight >LISTBOX_HEIGHT_LIMIT)
  763. uHeight = LISTBOX_HEIGHT_LIMIT;
  764. lpmis->itemHeight = uHeight;
  765. break;
  766. }
  767. case IDC_COLHEADING:
  768. {
  769. UINT uHeight;
  770. uHeight = LOWORD(lpmis->itemData);
  771. uHeight = (UINT) (uHeight * lpscale->dwSyN /
  772. lpscale->dwSyD);
  773. if (uHeight > LISTBOX_HEIGHT_LIMIT)
  774. uHeight = LISTBOX_HEIGHT_LIMIT;
  775. lpmis->itemHeight = uHeight;
  776. break;
  777. }
  778. #endif // USE_HEADING
  779. }
  780. return (LRESULT)TRUE;
  781. }
  782. case WM_DRAWITEM:
  783. {
  784. LPDRAWITEMSTRUCT lpdis = ((LPDRAWITEMSTRUCT)lParam);
  785. switch (lpdis->CtlID) {
  786. case IDC_LINELIST:
  787. {
  788. RECT rcClient;
  789. RECT rcDevice;
  790. HWND hWndLL = LineList_GetWindow(lpLL);
  791. LPLINE lpLine = (LPLINE)lpdis->itemData;
  792. // NOTE: When itemID == -1, the listbox is empty.
  793. // We are supposed to draw focus rect only
  794. // But it is not done in this app. If this line is
  795. // removed, the app will crash in Line_DrawToScreen
  796. // because of invalid lpLine.
  797. if (lpdis->itemID == -1)
  798. break;
  799. GetClientRect(hWndLL, &rcClient);
  800. rcDevice = lpdis->rcItem;
  801. // shift the item rect to account for horizontal scrolling
  802. rcDevice.left += rcClient.right - lpdis->rcItem.right;
  803. #if defined( OLE_CNTR )
  804. /* we need to remember the horizontal scroll offset
  805. ** needed for the in-place object's window.
  806. ** (this is specific to ICNTROTL)
  807. */
  808. if(lpdis->itemAction & ODA_DRAWENTIRE) {
  809. if (Line_GetLineType(lpLine) == CONTAINERLINETYPE)
  810. ((LPCONTAINERLINE)lpLine)->m_nHorizScrollShift =
  811. rcDevice.left;
  812. }
  813. #endif // OLE_CNTR
  814. // shift rect for left margin
  815. rcDevice.left += (int)(XformWidthInHimetricToPixels(NULL,
  816. LOWORD(OutlineDoc_GetMargin(lpOutlineDoc))) *
  817. lpscale->dwSxN / lpscale->dwSxD);
  818. rcDevice.right = rcDevice.left +
  819. (int)(XformWidthInHimetricToPixels(lpdis->hDC,
  820. Line_GetWidthInHimetric(lpLine)) *
  821. lpscale->dwSxN / lpscale->dwSxD);
  822. Line_DrawToScreen(
  823. lpLine,
  824. lpdis->hDC,
  825. &lpdis->rcItem,
  826. lpdis->itemAction,
  827. lpdis->itemState,
  828. &rcDevice
  829. );
  830. #if defined( USE_FRAMETOOLS )
  831. if (lpdis->itemState & ODS_FOCUS)
  832. OutlineDoc_SetFormulaBarEditText(lpOutlineDoc,lpLine);
  833. #endif
  834. break;
  835. }
  836. case IDC_NAMETABLE:
  837. {
  838. // NOTE: NameTable is never made visible. do nothing
  839. break;
  840. }
  841. #if defined( USE_HEADING )
  842. case IDC_ROWHEADING:
  843. {
  844. LPHEADING lphead;
  845. // Last dummy item shouldn't be drawn
  846. if (lpdis->itemID == (UINT)LineList_GetCount(lpLL))
  847. break;
  848. // only DrawEntire need be trapped as window is disabled
  849. if (lpdis->itemAction == ODA_DRAWENTIRE) {
  850. lphead = OutlineDoc_GetHeading(lpOutlineDoc);
  851. Heading_RH_Draw(lphead, lpdis);
  852. }
  853. break;
  854. }
  855. case IDC_COLHEADING:
  856. {
  857. RECT rect;
  858. RECT rcDevice;
  859. RECT rcLogical;
  860. LPHEADING lphead;
  861. // only DrawEntire need be trapped as window is disabled
  862. if (lpdis->itemAction == ODA_DRAWENTIRE) {
  863. lphead = OutlineDoc_GetHeading(lpOutlineDoc);
  864. GetClientRect(lpdis->hwndItem, &rect);
  865. rcDevice = lpdis->rcItem;
  866. // shift the item rect to account for
  867. // horizontal scrolling
  868. rcDevice.left = -(rcDevice.right - rect.right);
  869. // shift rect for left margin
  870. rcDevice.left += (int)(XformWidthInHimetricToPixels(
  871. NULL,
  872. LOWORD(OutlineDoc_GetMargin(lpOutlineDoc))) *
  873. lpscale->dwSxN / lpscale->dwSxD);
  874. rcDevice.right = rcDevice.left + (int)lpscale->dwSxN;
  875. rcLogical.left = 0;
  876. rcLogical.bottom = 0;
  877. rcLogical.right = (int)lpscale->dwSxD;
  878. rcLogical.top = LOWORD(lpdis->itemData);
  879. Heading_CH_Draw(lphead, lpdis, &rcDevice, &rcLogical);
  880. }
  881. break;
  882. }
  883. #endif // USE_HEADING
  884. }
  885. return (LRESULT)TRUE;
  886. }
  887. case WM_SETFOCUS:
  888. if (lpLL)
  889. SetFocus(LineList_GetWindow(lpLL));
  890. break;
  891. #if !defined( OLE_VERSION )
  892. case WM_RENDERFORMAT:
  893. {
  894. LPOUTLINEDOC lpClipboardDoc = lpOutlineApp->m_lpClipboardDoc;
  895. if (lpClipboardDoc)
  896. OutlineDoc_RenderFormat(lpClipboardDoc, wParam);
  897. break;
  898. }
  899. case WM_RENDERALLFORMATS:
  900. {
  901. LPOUTLINEDOC lpClipboardDoc = lpOutlineApp->m_lpClipboardDoc;
  902. if (lpClipboardDoc)
  903. OutlineDoc_RenderAllFormats(lpClipboardDoc);
  904. break;
  905. }
  906. case WM_DESTROYCLIPBOARD:
  907. if (g_lpApp->m_lpClipboardDoc) {
  908. OutlineDoc_Destroy(g_lpApp->m_lpClipboardDoc);
  909. g_lpApp->m_lpClipboardDoc = NULL;
  910. }
  911. break;
  912. #endif // OLE_VERSION
  913. #if defined( OLE_CNTR )
  914. case WM_U_UPDATEOBJECTEXTENT:
  915. {
  916. /* Update the extents of any OLE object that is marked that
  917. ** its size may have changed. when an
  918. ** IAdviseSink::OnViewChange notification is received,
  919. ** the corresponding ContainerLine is marked
  920. ** (m_fDoGetExtent==TRUE) and a message
  921. ** (WM_U_UPDATEOBJECTEXTENT) is posted to the document
  922. ** indicating that there are dirty objects.
  923. */
  924. ContainerDoc_UpdateExtentOfAllOleObjects(lpContainerDoc);
  925. break;
  926. }
  927. #endif // OLE_CNTR
  928. #if defined( INPLACE_SVR ) || defined( INPLACE_CNTR )
  929. /* OLE2NOTE: Any window that is used during in-place activation
  930. ** must handle the WM_SETCURSOR message or else the cursor
  931. ** of the in-place parent will be used. if WM_SETCURSOR is
  932. ** not handled, then DefWindowProc sends the message to the
  933. ** window's parent.
  934. **
  935. ** see context sensitive help technote (CSHELP.DOC).
  936. ** m_fCSHelpMode flag is set when SHIFT-F1 context
  937. ** sensitive help is entered.
  938. ** if this flag is set then the context sensitive help
  939. ** cursor should be shown.
  940. */
  941. case WM_SETCURSOR:
  942. if (lpOleDoc->m_fCSHelpMode)
  943. SetCursor(UICursorLoad(IDC_CONTEXTHELP));
  944. else
  945. SetCursor(LoadCursor(NULL, IDC_ARROW) );
  946. return (LRESULT)TRUE;
  947. #endif // INPLACE_SVR || INPLACE_CNTR
  948. #if defined( INPLACE_SVR )
  949. /* OLE2NOTE: when the in-place active, our in-place server
  950. ** document window (passed to IOleInPlaceFrame::SetMenu)
  951. ** will receive the WM_INITMENU and WM_INITMENUPOPUP messages.
  952. */
  953. case WM_INITMENU:
  954. OutlineApp_InitMenu(lpOutlineApp, lpOutlineDoc, (HMENU)wParam);
  955. break;
  956. /* OLE2NOTE: WM_INITMENUPOPUP is trapped primarily for the Edit
  957. ** menu. We didn't update the Edit menu until it is popped
  958. ** up to avoid the overheads of the OLE calls which are
  959. ** required to initialize some Edit menu items.
  960. */
  961. case WM_INITMENUPOPUP:
  962. {
  963. HMENU hMenuEdit = GetSubMenu(lpOutlineApp->m_hMenuApp, 1);
  964. if ((HMENU)wParam == hMenuEdit &&
  965. (LOWORD(lParam) == POS_EDITMENU) &&
  966. OleDoc_GetUpdateEditMenuFlag((LPOLEDOC)lpOutlineDoc)) {
  967. OleApp_UpdateEditMenu(
  968. (LPOLEAPP)lpOutlineApp, lpOutlineDoc, hMenuEdit);
  969. }
  970. break;
  971. }
  972. #endif // INPLACE_SVR
  973. #if defined( INPLACE_SVR ) && defined( USE_STATUSBAR )
  974. /* OLE2NOTE: when the server is in-place active the
  975. ** WM_MENUSELECT message is sent to the object's window and
  976. ** not the server app's frame window. processing this
  977. ** message allows there in-place server to give status bar
  978. ** help text for menu commands.
  979. */
  980. case WM_MENUSELECT:
  981. {
  982. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOleDoc;
  983. LPSTR lpszMessage;
  984. #ifdef WIN32
  985. UINT fuFlags = (UINT)HIWORD(wParam);
  986. UINT uItem = (UINT)LOWORD(wParam);
  987. #else
  988. UINT fuFlags = (UINT)LOWORD(lParam);
  989. UINT uItem = (UINT)wParam;
  990. #endif
  991. if (uItem == 0 && fuFlags == (UINT)-1) {
  992. GetControlMessage(STATUS_READY, &lpszMessage);
  993. ServerDoc_SetStatusText(lpServerDoc, lpszMessage);
  994. }
  995. else if (fuFlags & MF_POPUP) {
  996. #ifdef WIN32
  997. HMENU hMainMenu = (HMENU)lParam;
  998. HMENU hPopupMenu = GetSubMenu(hMainMenu,uItem);
  999. #else
  1000. HMENU hPopupMenu = (HMENU)wParam;
  1001. #endif
  1002. GetPopupMessage(hPopupMenu, &lpszMessage);
  1003. ServerDoc_SetStatusText(lpServerDoc, lpszMessage);
  1004. }
  1005. else if (uItem != 0) { // Command Item
  1006. GetItemMessage(uItem, &lpszMessage);
  1007. ServerDoc_SetStatusText(lpServerDoc, lpszMessage);
  1008. }
  1009. else {
  1010. GetControlMessage(STATUS_BLANK, &lpszMessage);
  1011. ServerDoc_SetStatusText(lpServerDoc, lpszMessage);
  1012. }
  1013. break;
  1014. }
  1015. #endif // INPLACE_SVR && USE_STATUSBAR
  1016. #if defined( INPLACE_SVR ) && defined( USE_FRAMETOOLS )
  1017. case WM_U_INITFRAMETOOLS:
  1018. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1019. break;
  1020. #endif // INPLACE_SVR && USE_FRAMETOOLS
  1021. case WM_COMMAND:
  1022. {
  1023. #ifdef WIN32
  1024. WORD wNotifyCode = HIWORD(wParam);
  1025. WORD wID = LOWORD(wParam);
  1026. HWND hwndCtl = (HWND) lParam;
  1027. #else
  1028. WORD wNotifyCode = HIWORD(lParam);
  1029. WORD wID = wParam;
  1030. HWND hwndCtl = (HWND) LOWORD(lParam);
  1031. #endif
  1032. #if defined( INPLACE_SVR )
  1033. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
  1034. ** m_fMenuHelpMode flag is set when F1 is pressed when a
  1035. ** menu item is selected. this flag is set in
  1036. ** IOleInPlaceActiveObject::ContextSensitveHelp method.
  1037. ** m_fCSHelpMode flag is set when SHIFT-F1 context
  1038. ** sensitive help is entered. this flag is set in
  1039. ** IOleInPlaceObject::ContextSensitiveHelp method.
  1040. ** if either of these flags are set then the WM_COMMAND
  1041. ** message is received then, the corresponding command
  1042. ** should NOT executed; help can be given (if desired).
  1043. ** also the context sensitve help mode should be exited.
  1044. ** the two different cases have their own way to exit
  1045. ** the mode (please refer to the technote).
  1046. */
  1047. if (lpOleDoc &&
  1048. (lpServerDoc->m_fMenuHelpMode||lpOleDoc->m_fCSHelpMode) &&
  1049. (wID > IDM_FILE) /* min wID for app command */ &&
  1050. (wID!=IDM_FB_EDIT) /* special wID to control FormulaBar */ ) {
  1051. if ((lpServerDoc->m_fMenuHelpMode)) {
  1052. LPOLEINPLACEFRAME lpFrame;
  1053. lpServerDoc->m_fMenuHelpMode = FALSE;
  1054. // inform top-level frame that we handled the
  1055. // menu help mode (F1) selection.
  1056. if (lpServerDoc->m_lpIPData &&
  1057. (lpFrame=lpServerDoc->m_lpIPData->lpFrame)!=NULL){
  1058. OLEDBG_BEGIN2("IOleInPlaceFrame::ContextSensitiveHelp(FALSE) called\r\n")
  1059. lpFrame->lpVtbl->ContextSensitiveHelp(lpFrame, FALSE);
  1060. OLEDBG_END2
  1061. }
  1062. }
  1063. if ((lpOleDoc->m_fCSHelpMode)) {
  1064. LPOLEINPLACESITE lpSite;
  1065. lpOleDoc->m_fCSHelpMode = FALSE;
  1066. /* inform immediate in-place container parent and,
  1067. ** if we were a container/server, immediate
  1068. ** in-place object children that we handled the
  1069. ** context sensitive help mode.
  1070. */
  1071. if (lpServerDoc->m_lpIPData &&
  1072. (lpSite=lpServerDoc->m_lpIPData->lpSite) !=NULL) {
  1073. OLEDBG_BEGIN2("IOleInPlaceSite::ContextSensitiveHelp(FALSE) called\r\n")
  1074. lpSite->lpVtbl->ContextSensitiveHelp(lpSite, FALSE);
  1075. OLEDBG_END2
  1076. }
  1077. }
  1078. // if we provided help, we would do it here...
  1079. // remove context sensitive help cursor
  1080. SetCursor(LoadCursor(NULL,IDC_ARROW));
  1081. return 0L;
  1082. }
  1083. #endif // INPLACE_SVR
  1084. #if defined( INPLACE_CNTR )
  1085. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
  1086. ** m_fMenuHelpMode flag is set when F1 is pressed when a
  1087. ** menu item is selected. this flag is set in
  1088. ** IOleInPlaceFrame::ContextSensitveHelp method.
  1089. ** m_fCSHelpMode flag is set when SHIFT-F1 context
  1090. ** sensitive help is entered. this flag is set in
  1091. ** IOleInPlaceSite::ContextSensitiveHelp method.
  1092. ** if either of these flags are set then the WM_COMMAND
  1093. ** message is received then, the corresponding command
  1094. ** should NOT executed; help can be given (if desired).
  1095. ** also the context sensitve help mode should be exited.
  1096. ** the two different cases have their own way to exit
  1097. ** the mode (please refer to the technote).
  1098. */
  1099. if (lpOleDoc &&
  1100. (lpContainerApp->m_fMenuHelpMode||lpOleDoc->m_fCSHelpMode) &&
  1101. (wID > IDM_FILE) /* min wID for app command */ &&
  1102. (wID!=IDM_FB_EDIT) /* special wID to control FormulaBar */ ) {
  1103. if ((lpContainerApp->m_fMenuHelpMode)) {
  1104. LPOLEINPLACEACTIVEOBJECT lpIPActiveObj =
  1105. lpContainerApp->m_lpIPActiveObj;
  1106. lpContainerApp->m_fMenuHelpMode = FALSE;
  1107. // inform the in-place active object that we handled the
  1108. // menu help mode (F1) selection.
  1109. if (lpIPActiveObj) {
  1110. OLEDBG_BEGIN2("IOleInPlaceActiveObject::ContextSensitiveHelp(FALSE) called\r\n")
  1111. lpIPActiveObj->lpVtbl->ContextSensitiveHelp(
  1112. lpIPActiveObj, FALSE);
  1113. OLEDBG_END2
  1114. }
  1115. }
  1116. if ((lpOleDoc->m_fCSHelpMode)) {
  1117. LPOLEINPLACEOBJECT lpIPObj;
  1118. LPCONTAINERLINE lpLastIpActiveLine =
  1119. lpContainerDoc->m_lpLastIpActiveLine;
  1120. lpOleDoc->m_fCSHelpMode = FALSE;
  1121. /* inform immediate in-place container parent and,
  1122. ** if we were a container/server, immediate
  1123. ** in-place object children that we handled the
  1124. ** context sensitive help mode.
  1125. */
  1126. if (lpLastIpActiveLine &&
  1127. (lpIPObj=lpLastIpActiveLine->m_lpOleIPObj)!=NULL){
  1128. OLEDBG_BEGIN2("IOleInPlaceObject::ContextSensitiveHelp(FALSE) called\r\n")
  1129. lpIPObj->lpVtbl->ContextSensitiveHelp(lpIPObj, FALSE);
  1130. OLEDBG_END2
  1131. }
  1132. }
  1133. // if we provided help, we would do it here...
  1134. // remove context sensitive help cursor
  1135. SetCursor(LoadCursor(NULL,IDC_ARROW));
  1136. return 0L;
  1137. }
  1138. #endif // INPLACE_CNTR
  1139. switch (wID) {
  1140. /*********************************************************
  1141. ** File new, open, save and print as well as Help about
  1142. ** are duplicated in this switch statement and they are
  1143. ** used to trap the message from the toolbar
  1144. **
  1145. *********************************************************/
  1146. case IDM_F_NEW:
  1147. OleDbgIndent(-2); // Reset debug output indent level
  1148. OleDbgOutNoPrefix2("\r\n");
  1149. OLEDBG_BEGIN3("OutlineApp_NewCommand\r\n")
  1150. OutlineApp_NewCommand(lpOutlineApp);
  1151. OLEDBG_END3
  1152. #if defined( OLE_CNTR )
  1153. /* OLE2NOTE: this call will attempt to recover
  1154. ** resources by unloading DLL's that were loaded
  1155. ** by OLE and are no longer being used. it is a
  1156. ** good idea to call this API now and then if
  1157. ** your app tends to run for a long time.
  1158. ** otherwise these DLL's will be unloaded when
  1159. ** the app exits. some apps may want to call
  1160. ** this as part of idle-time processing. this
  1161. ** call is optional.
  1162. */
  1163. OLEDBG_BEGIN2("CoFreeUnusedLibraries called\r\n")
  1164. CoFreeUnusedLibraries();
  1165. OLEDBG_END2
  1166. #endif
  1167. #if defined( USE_FRAMETOOLS )
  1168. OutlineDoc_UpdateFrameToolButtons(
  1169. OutlineApp_GetActiveDoc(lpOutlineApp));
  1170. #endif
  1171. break;
  1172. case IDM_F_OPEN:
  1173. OleDbgOutNoPrefix2("\r\n");
  1174. OLEDBG_BEGIN3("OutlineApp_OpenCommand\r\n")
  1175. OutlineApp_OpenCommand(lpOutlineApp);
  1176. OLEDBG_END3
  1177. #if defined( OLE_CNTR )
  1178. /* OLE2NOTE: this call will attempt to recover
  1179. ** resources by unloading DLL's that were loaded
  1180. ** by OLE and are no longer being used. it is a
  1181. ** good idea to call this API now and then if
  1182. ** your app tends to run for a long time.
  1183. ** otherwise these DLL's will be unloaded when
  1184. ** the app exits. some apps may want to call
  1185. ** this as part of idle-time processing. this
  1186. ** call is optional.
  1187. */
  1188. OLEDBG_BEGIN2("CoFreeUnusedLibraries called\r\n")
  1189. CoFreeUnusedLibraries();
  1190. OLEDBG_END2
  1191. #endif
  1192. #if defined( USE_FRAMETOOLS )
  1193. OutlineDoc_UpdateFrameToolButtons(
  1194. OutlineApp_GetActiveDoc(lpOutlineApp));
  1195. #endif
  1196. break;
  1197. case IDM_F_SAVE:
  1198. OleDbgOutNoPrefix2("\r\n");
  1199. OLEDBG_BEGIN3("OutlineApp_SaveCommand\r\n")
  1200. OutlineApp_SaveCommand(lpOutlineApp);
  1201. OLEDBG_END3
  1202. break;
  1203. case IDM_F_PRINT:
  1204. OleDbgOutNoPrefix2("\r\n");
  1205. OLEDBG_BEGIN3("OutlineApp_PrintCommand\r\n")
  1206. OutlineApp_PrintCommand(lpOutlineApp);
  1207. OLEDBG_END3
  1208. break;
  1209. case IDM_E_UNDO:
  1210. // SORRY. NOT IMPLEMENTED
  1211. break;
  1212. case IDM_E_CUT:
  1213. OleDbgOutNoPrefix2("\r\n");
  1214. OLEDBG_BEGIN3("OutlineDoc_CutCommand\r\n")
  1215. OutlineDoc_CutCommand(lpOutlineDoc);
  1216. OLEDBG_END3
  1217. #if defined( USE_FRAMETOOLS )
  1218. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1219. #endif
  1220. break;
  1221. case IDM_E_COPY:
  1222. OleDbgOutNoPrefix2("\r\n");
  1223. OLEDBG_BEGIN3("OutlineDoc_CopyCommand\r\n")
  1224. OutlineDoc_CopyCommand(lpOutlineDoc);
  1225. OLEDBG_END3
  1226. #if defined( USE_FRAMETOOLS )
  1227. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1228. #endif
  1229. break;
  1230. case IDM_E_PASTE:
  1231. OleDbgOutNoPrefix2("\r\n");
  1232. OLEDBG_BEGIN3("OutlineDoc_PasteCommand\r\n")
  1233. OutlineDoc_PasteCommand(lpOutlineDoc);
  1234. OLEDBG_END3
  1235. #if defined( USE_FRAMETOOLS )
  1236. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1237. #endif
  1238. break;
  1239. #if defined( OLE_VERSION )
  1240. case IDM_E_PASTESPECIAL:
  1241. OleDbgOutNoPrefix2("\r\n");
  1242. OLEDBG_BEGIN3("OleDoc_PasteSpecialCommand\r\n")
  1243. OleDoc_PasteSpecialCommand((LPOLEDOC)lpOutlineDoc);
  1244. OLEDBG_END3
  1245. #if defined( USE_FRAMETOOLS )
  1246. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1247. #endif
  1248. break;
  1249. #endif // OLE_VERSION
  1250. case IDM_E_CLEAR:
  1251. OleDbgOutNoPrefix2("\r\n");
  1252. OLEDBG_BEGIN3("OutlineDoc_ClearCommand\r\n")
  1253. OutlineDoc_ClearCommand(lpOutlineDoc);
  1254. OLEDBG_END3
  1255. #if defined( OLE_CNTR )
  1256. /* OLE2NOTE: this call will attempt to recover
  1257. ** resources by unloading DLL's that were loaded
  1258. ** by OLE and are no longer being used. it is a
  1259. ** good idea to call this API now and then if
  1260. ** your app tends to run for a long time.
  1261. ** otherwise these DLL's will be unloaded when
  1262. ** the app exits. some apps may want to call
  1263. ** this as part of idle-time processing. this
  1264. ** call is optional.
  1265. */
  1266. OLEDBG_BEGIN2("CoFreeUnusedLibraries called\r\n")
  1267. CoFreeUnusedLibraries();
  1268. OLEDBG_END2
  1269. #endif
  1270. #if defined( USE_FRAMETOOLS )
  1271. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1272. #endif
  1273. break;
  1274. case IDM_L_ADDLINE:
  1275. OleDbgOutNoPrefix2("\r\n");
  1276. OLEDBG_BEGIN3("OutlineDoc_AddTextLineCommand\r\n")
  1277. OutlineDoc_AddTextLineCommand(lpOutlineDoc);
  1278. OLEDBG_END3
  1279. #if defined( USE_FRAMETOOLS )
  1280. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1281. SetFocus(LineList_GetWindow(lpLL));
  1282. #endif
  1283. break;
  1284. case IDM_L_EDITLINE:
  1285. OleDbgOutNoPrefix2("\r\n");
  1286. OLEDBG_BEGIN3("OutlineDoc_EditLineCommand\r\n")
  1287. OutlineDoc_EditLineCommand(lpOutlineDoc);
  1288. OLEDBG_END3
  1289. SetFocus(LineList_GetWindow(lpLL));
  1290. break;
  1291. case IDM_L_INDENTLINE:
  1292. OleDbgOutNoPrefix2("\r\n");
  1293. OLEDBG_BEGIN3("OutlineDoc_IndentCommand\r\n")
  1294. OutlineDoc_IndentCommand(lpOutlineDoc);
  1295. OLEDBG_END3
  1296. break;
  1297. case IDM_L_UNINDENTLINE:
  1298. OleDbgOutNoPrefix2("\r\n");
  1299. OLEDBG_BEGIN3("OutlineDoc_UnindentCommand\r\n")
  1300. OutlineDoc_UnindentCommand(lpOutlineDoc);
  1301. OLEDBG_END3
  1302. break;
  1303. case IDM_L_SETLINEHEIGHT:
  1304. OleDbgOutNoPrefix2("\r\n");
  1305. OLEDBG_BEGIN3("OutlineDoc_SetLineHeight\r\n")
  1306. OutlineDoc_SetLineHeightCommand(lpOutlineDoc);
  1307. OLEDBG_END3
  1308. break;
  1309. case IDM_E_SELECTALL:
  1310. OleDbgOutNoPrefix2("\r\n");
  1311. OLEDBG_BEGIN3("OutlineDoc_SelectAllCommand\r\n")
  1312. OutlineDoc_SelectAllCommand(lpOutlineDoc);
  1313. OLEDBG_END3
  1314. break;
  1315. #if defined( OLE_CNTR )
  1316. case IDM_E_INSERTOBJECT:
  1317. OleDbgOutNoPrefix2("\r\n");
  1318. OLEDBG_BEGIN3("ContainerDoc_InsertOleObjectCommand\r\n")
  1319. ContainerDoc_InsertOleObjectCommand(lpContainerDoc);
  1320. OLEDBG_END3
  1321. #if defined( USE_FRAMETOOLS )
  1322. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1323. #endif
  1324. break;
  1325. case IDM_E_EDITLINKS:
  1326. OleDbgOutNoPrefix2("\r\n");
  1327. OLEDBG_BEGIN3("ContainerDoc_EditLinksCommand\r\n")
  1328. ContainerDoc_EditLinksCommand(lpContainerDoc);
  1329. OLEDBG_END3
  1330. break;
  1331. case IDM_E_CONVERTVERB:
  1332. OleDbgOutNoPrefix2("\r\n");
  1333. OLEDBG_BEGIN3("ContainerDoc_ConvertCommand\r\n")
  1334. ContainerDoc_ConvertCommand(
  1335. lpContainerDoc, FALSE /*fMustActivate*/);
  1336. OLEDBG_END3
  1337. break;
  1338. case IDM_E_PASTELINK:
  1339. OleDbgOutNoPrefix2("\r\n");
  1340. OLEDBG_BEGIN3("ContainerDoc_PasteLinkCommand\r\n")
  1341. ContainerDoc_PasteLinkCommand(lpContainerDoc);
  1342. OLEDBG_END3
  1343. #if defined( USE_FRAMETOOLS )
  1344. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1345. #endif
  1346. break;
  1347. #endif // OLE_CNTR
  1348. case IDM_N_DEFINENAME:
  1349. OleDbgOutNoPrefix2("\r\n");
  1350. OLEDBG_BEGIN3("OutlineDoc_DefineNameCommand\r\n")
  1351. OutlineDoc_DefineNameCommand(lpOutlineDoc);
  1352. OLEDBG_END3
  1353. break;
  1354. case IDM_N_GOTONAME:
  1355. OleDbgOutNoPrefix2("\r\n");
  1356. OLEDBG_BEGIN3("OutlineDoc_GotoNameCommand\r\n")
  1357. OutlineDoc_GotoNameCommand(lpOutlineDoc);
  1358. OLEDBG_END3
  1359. break;
  1360. #if defined( USE_FRAMETOOLS )
  1361. case IDM_O_BB_TOP:
  1362. FrameTools_BB_SetState(
  1363. lpOutlineDoc->m_lpFrameTools, BARSTATE_TOP);
  1364. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1365. break;
  1366. case IDM_O_BB_BOTTOM:
  1367. FrameTools_BB_SetState(
  1368. lpOutlineDoc->m_lpFrameTools, BARSTATE_BOTTOM);
  1369. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1370. break;
  1371. case IDM_O_BB_POPUP:
  1372. FrameTools_BB_SetState(
  1373. lpOutlineDoc->m_lpFrameTools, BARSTATE_POPUP);
  1374. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1375. break;
  1376. case IDM_O_BB_HIDE:
  1377. FrameTools_BB_SetState(
  1378. lpOutlineDoc->m_lpFrameTools, BARSTATE_HIDE);
  1379. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1380. break;
  1381. case IDM_O_FB_TOP:
  1382. FrameTools_FB_SetState(
  1383. lpOutlineDoc->m_lpFrameTools, BARSTATE_TOP);
  1384. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1385. break;
  1386. case IDM_O_FB_BOTTOM:
  1387. FrameTools_FB_SetState(
  1388. lpOutlineDoc->m_lpFrameTools, BARSTATE_BOTTOM);
  1389. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1390. break;
  1391. case IDM_O_FB_POPUP:
  1392. FrameTools_FB_SetState(
  1393. lpOutlineDoc->m_lpFrameTools, BARSTATE_POPUP);
  1394. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1395. break;
  1396. case IDM_FB_EDIT:
  1397. switch (wNotifyCode) {
  1398. case EN_SETFOCUS:
  1399. OutlineDoc_SetFormulaBarEditFocus(
  1400. lpOutlineDoc, TRUE);
  1401. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1402. break;
  1403. case EN_KILLFOCUS:
  1404. OutlineDoc_SetFormulaBarEditFocus(
  1405. lpOutlineDoc, FALSE);
  1406. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1407. break;
  1408. }
  1409. break;
  1410. case IDM_FB_CANCEL:
  1411. SetFocus(hWnd);
  1412. break;
  1413. case IDM_F2:
  1414. SendMessage(hWnd, WM_COMMAND, (WPARAM)IDM_FB_EDIT,
  1415. MAKELONG(0, EN_SETFOCUS));
  1416. break;
  1417. #endif // USE_FRAMETOOLS
  1418. case IDM_ESCAPE:
  1419. /* ESCAPE key pressed */
  1420. #if defined( USE_FRAMETOOLS )
  1421. if (OutlineDoc_IsEditFocusInFormulaBar(lpOutlineDoc))
  1422. SendMessage(
  1423. hWnd, WM_COMMAND,(WPARAM)IDM_FB_CANCEL,(LPARAM)0);
  1424. #endif // USE_FRAMETOOLS
  1425. #if defined( INPLACE_SVR )
  1426. else {
  1427. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1428. /* OLE2NOTE: The standard OLE 2.0 UI convention
  1429. ** is to have ESCAPE key exit in-place
  1430. ** activation (ie. UIDeactivate). If
  1431. ** possible it is recommended for both
  1432. ** in-place servers AND in-place containers
  1433. ** to take responsibility to handle the
  1434. ** ESCAPE key accelerator. The server has
  1435. ** the first crack at handling accelerator
  1436. ** keys and normally the server should do
  1437. ** the UIDeactivation.
  1438. */
  1439. if (lpServerDoc->m_fUIActive) {
  1440. SvrDoc_IPObj_UIDeactivate( (LPOLEINPLACEOBJECT)&
  1441. lpServerDoc->m_OleInPlaceObject);
  1442. }
  1443. }
  1444. #endif // INPLACE_SVR
  1445. break;
  1446. #if defined( USE_HEADING )
  1447. case IDC_BUTTON:
  1448. if (wNotifyCode == BN_CLICKED) {
  1449. SendMessage(hWnd, WM_COMMAND, IDM_E_SELECTALL, 0L);
  1450. SetFocus(hWnd);
  1451. }
  1452. break;
  1453. case IDM_O_HEAD_SHOW:
  1454. OutlineDoc_ShowHeading(lpOutlineDoc, TRUE);
  1455. break;
  1456. case IDM_O_HEAD_HIDE:
  1457. OutlineDoc_ShowHeading(lpOutlineDoc, FALSE);
  1458. break;
  1459. #endif // USE_HEADING
  1460. #if defined( OLE_CNTR )
  1461. case IDM_O_SHOWOBJECT:
  1462. {
  1463. LPCONTAINERDOC lpContainerDoc =
  1464. (LPCONTAINERDOC)lpOutlineDoc;
  1465. BOOL fShowObject;
  1466. fShowObject = !ContainerDoc_GetShowObjectFlag(
  1467. lpContainerDoc);
  1468. ContainerDoc_SetShowObjectFlag(
  1469. lpContainerDoc, fShowObject);
  1470. LineList_ForceRedraw(lpLL, TRUE);
  1471. break;
  1472. }
  1473. #endif // OLE_CNTR
  1474. #if !defined( OLE_CNTR )
  1475. // Container does not allow zoom factors > 100%
  1476. case IDM_V_ZOOM_400:
  1477. case IDM_V_ZOOM_300:
  1478. case IDM_V_ZOOM_200:
  1479. #endif // !OLE_CNTR
  1480. case IDM_V_ZOOM_100:
  1481. case IDM_V_ZOOM_75:
  1482. case IDM_V_ZOOM_50:
  1483. case IDM_V_ZOOM_25:
  1484. OutlineDoc_SetCurrentZoomCommand(lpOutlineDoc, wID);
  1485. break;
  1486. case IDM_V_SETMARGIN_0:
  1487. case IDM_V_SETMARGIN_1:
  1488. case IDM_V_SETMARGIN_2:
  1489. case IDM_V_SETMARGIN_3:
  1490. case IDM_V_SETMARGIN_4:
  1491. OutlineDoc_SetCurrentMarginCommand(lpOutlineDoc, wID);
  1492. break;
  1493. case IDM_V_ADDTOP_1:
  1494. case IDM_V_ADDTOP_2:
  1495. case IDM_V_ADDTOP_3:
  1496. case IDM_V_ADDTOP_4:
  1497. {
  1498. UINT nHeightInHimetric;
  1499. switch (wID) {
  1500. case IDM_V_ADDTOP_1:
  1501. nHeightInHimetric = 1000;
  1502. break;
  1503. case IDM_V_ADDTOP_2:
  1504. nHeightInHimetric = 2000;
  1505. break;
  1506. case IDM_V_ADDTOP_3:
  1507. nHeightInHimetric = 3000;
  1508. break;
  1509. case IDM_V_ADDTOP_4:
  1510. nHeightInHimetric = 4000;
  1511. break;
  1512. }
  1513. OutlineDoc_AddTopLineCommand(
  1514. lpOutlineDoc, nHeightInHimetric);
  1515. break;
  1516. }
  1517. case IDM_H_ABOUT:
  1518. OutlineApp_AboutCommand(lpOutlineApp);
  1519. break;
  1520. case IDM_D_DEBUGLEVEL:
  1521. SetDebugLevelCommand();
  1522. break;
  1523. #if defined( OLE_VERSION )
  1524. case IDM_D_INSTALLMSGFILTER:
  1525. InstallMessageFilterCommand();
  1526. break;
  1527. case IDM_D_REJECTINCOMING:
  1528. RejectIncomingCommand();
  1529. break;
  1530. #endif // OLE_VERSION
  1531. #if defined( INPLACE_CNTR )
  1532. case IDM_D_INSIDEOUT:
  1533. g_fInsideOutContainer = !g_fInsideOutContainer;
  1534. // force all object to unload so they can start new
  1535. // activation behavior.
  1536. ContainerDoc_UnloadAllOleObjectsOfClass(
  1537. (LPCONTAINERDOC)lpOutlineDoc,
  1538. &CLSID_NULL,
  1539. OLECLOSE_SAVEIFDIRTY
  1540. );
  1541. OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
  1542. break;
  1543. #endif // INPLACE_CNTR
  1544. #if defined( OLE_CNTR )
  1545. case IDC_LINELIST: {
  1546. if (wNotifyCode == LBN_DBLCLK) {
  1547. /* OLE2NOTE: a container should execute the
  1548. ** OLEIVERB_PRIMARY verb on an OLE object
  1549. ** when the user DBLCLK's the object.
  1550. */
  1551. int nIndex = LineList_GetFocusLineIndex(lpLL);
  1552. LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
  1553. if (lpLine &&
  1554. Line_GetLineType(lpLine)==CONTAINERLINETYPE) {
  1555. MSG msg;
  1556. _fmemset((LPMSG)&msg,0,sizeof(msg));
  1557. msg.hwnd = hWnd;
  1558. msg.message = Message;
  1559. msg.wParam = wParam;
  1560. msg.lParam = lParam;
  1561. ContainerLine_DoVerb(
  1562. (LPCONTAINERLINE)lpLine,
  1563. OLEIVERB_PRIMARY,
  1564. (LPMSG)&msg,
  1565. TRUE,
  1566. TRUE
  1567. );
  1568. }
  1569. #if defined( INPLACE_CNTR )
  1570. { // BEGIN BLOCK
  1571. LPCONTAINERDOC lpContainerDoc =
  1572. (LPCONTAINERDOC) lpOutlineDoc;
  1573. if (lpContainerDoc->m_fAddMyUI) {
  1574. /* OLE2NOTE: fAddMyUI is TRUE when
  1575. ** there was previously an in-place
  1576. ** active object which got
  1577. ** UIDeactivated as a result of this
  1578. ** DBLCLK AND the DBLCLK did NOT
  1579. ** result in in-place activating
  1580. ** another object.
  1581. ** (see IOleInPlaceSite::OnUIActivate and
  1582. ** IOleInPlaceSite::OnUIDeactivate
  1583. ** methods).
  1584. */
  1585. /* OLE2NOTE: You need to generate
  1586. ** QueryNewPalette only if you own
  1587. ** the top level frame (ie. you are
  1588. ** a top-level inplace container).
  1589. */
  1590. OleApp_QueryNewPalette((LPOLEAPP)g_lpApp);
  1591. #if defined( USE_DOCTOOLS )
  1592. ContainerDoc_AddDocLevelTools(lpContainerDoc);
  1593. #endif
  1594. #if defined( USE_FRAMETOOLS )
  1595. ContainerDoc_AddFrameLevelUI(lpContainerDoc);
  1596. #endif
  1597. lpContainerDoc->m_fAddMyUI = FALSE;
  1598. }
  1599. } // END BLOCK
  1600. #endif // INPLACE_CNTR
  1601. }
  1602. break;
  1603. }
  1604. #endif // OLE_CNTR
  1605. default:
  1606. #if defined( OLE_CNTR )
  1607. if (wID >= IDM_E_OBJECTVERBMIN) {
  1608. OleDbgOutNoPrefix2("\r\n");
  1609. OLEDBG_BEGIN3("ContainerDoc_ContainerLineDoVerbCommand\r\n")
  1610. ContainerDoc_ContainerLineDoVerbCommand(
  1611. (LPCONTAINERDOC)lpOutlineDoc,
  1612. (LONG)(wID-IDM_E_OBJECTVERBMIN)
  1613. );
  1614. OLEDBG_END3
  1615. break;
  1616. }
  1617. #endif // OLE_CNTR
  1618. return DefWindowProc(hWnd, Message, wParam, lParam);
  1619. }
  1620. break; /* End of WM_COMMAND */
  1621. }
  1622. default:
  1623. if (Message == g_uMsgHelp) {
  1624. /* Handle OLE2UI dialog's help messages.
  1625. ** We get the hDlg of the dialog that called us in the wParam
  1626. ** and the dialog type in the LOWORD of the lParam,
  1627. ** so we pass this along to our help function.
  1628. */
  1629. OutlineDoc_DialogHelp((HWND)wParam, LOWORD(lParam));
  1630. break;
  1631. }
  1632. /* For any message for which you don't specifically provide a */
  1633. /* service routine, you should return the message to Windows */
  1634. /* for default message processing. */
  1635. return DefWindowProc(hWnd, Message, wParam, lParam);
  1636. }
  1637. return (LRESULT)0;
  1638. } /* End of DocWndProc */
  1639. //***********************************************************************
  1640. //*
  1641. //* LineListWndProc() Drag and Drop Listbox Window Proc Sub-Class
  1642. //*
  1643. //* Sub Class the Ownerdraw list box in order to activate the drag drop.
  1644. //***********************************************************************
  1645. LRESULT FAR PASCAL LineListWndProc(
  1646. HWND hWnd,
  1647. UINT Message,
  1648. WPARAM wParam,
  1649. LPARAM lParam
  1650. )
  1651. {
  1652. HWND hwndParent = GetParent ( hWnd );
  1653. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1654. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC) GetWindowLong( hwndParent, 0 );
  1655. LPLINELIST lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
  1656. #if defined( OLE_VERSION )
  1657. LPOLEAPP lpOleApp = (LPOLEAPP)lpOutlineApp;
  1658. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1659. #endif // OLE_VERSION
  1660. #if defined( INPLACE_SVR )
  1661. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1662. static BOOL fUIActivateClick = FALSE;
  1663. static BOOL fInWinPosChged = FALSE;
  1664. #endif // INPLACE_SVR
  1665. #if defined( INPLACE_CNTR )
  1666. LPCONTAINERAPP lpContainerApp=(LPCONTAINERAPP)lpOutlineApp;
  1667. LPCONTAINERDOC lpContainerDoc=(LPCONTAINERDOC)lpOutlineDoc;
  1668. #endif // INPLACE_CNTR
  1669. switch (Message) {
  1670. case WM_KILLFOCUS:
  1671. /* OLE2NOTE: when our window looses focus we
  1672. ** should not display any active selection
  1673. */
  1674. #if defined( INPLACE_CNTR )
  1675. if (! lpContainerApp->m_fPendingUIDeactivate)
  1676. #endif // INPLACE_CNTR
  1677. LineList_RemoveSel(lpLL);
  1678. break;
  1679. case WM_SETFOCUS:
  1680. #if defined( INPLACE_CNTR )
  1681. {
  1682. HWND hWndObj=ContainerDoc_GetUIActiveWindow(lpContainerDoc);
  1683. /* OLE2NOTE: if there is a UIActive in-place object, we must
  1684. ** forward focus to its window as long as there is
  1685. ** not a pending UIDeactivate. if the mouse is
  1686. ** clicked outside of the object and the object is
  1687. ** about to be deactivated then we do NOT want to
  1688. ** forward focus to the object. we do NOT want it to
  1689. ** restore its selection feedback.
  1690. */
  1691. if (lpContainerApp->m_fPendingUIDeactivate)
  1692. break;
  1693. else if (hWndObj) {
  1694. SetFocus(hWndObj);
  1695. break; // do not restore containers selection state
  1696. }
  1697. }
  1698. #endif // INPLACE_CNTR
  1699. /* OLE2NOTE: when our window gains focus we
  1700. ** should restore the previous selection
  1701. */
  1702. LineList_RestoreSel(lpLL);
  1703. break;
  1704. #if defined( INPLACE_SVR )
  1705. case WM_MOUSEACTIVATE:
  1706. {
  1707. if (lpServerDoc->m_fInPlaceActive && !lpServerDoc->m_fUIActive) {
  1708. fUIActivateClick = TRUE;
  1709. };
  1710. break;
  1711. }
  1712. #endif // INPLACE_SVR
  1713. #if defined( USE_FRAMETOOLS )
  1714. case WM_CHAR:
  1715. {
  1716. OutlineDoc_SetFormulaBarEditFocus(lpOutlineDoc, TRUE);
  1717. FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, NULL);
  1718. FrameTools_FB_SendMessage(
  1719. lpOutlineDoc->m_lpFrameTools,
  1720. IDM_FB_EDIT,
  1721. Message,
  1722. wParam,
  1723. lParam
  1724. );
  1725. return (LRESULT)0; // don't do default listbox processing
  1726. }
  1727. #endif // USE_FRAMETOOLS
  1728. #if defined( INPLACE_CNTR )
  1729. case WM_VSCROLL:
  1730. {
  1731. if (wParam == SB_ENDSCROLL) {
  1732. /* OLE2NOTE: after scrolling finishes, update position of
  1733. ** in-place visible windows.
  1734. ** (ICNTROTL specific) we first let the ListBox
  1735. ** perform it normal processing with the EndScroll
  1736. ** message. also we let the ListBox handle all other
  1737. ** scroll messages.
  1738. */
  1739. LRESULT lResult = CallWindowProc(
  1740. (WNDPROC)lpOutlineApp->m_ListBoxWndProc,
  1741. hWnd,
  1742. Message,
  1743. wParam,
  1744. lParam
  1745. );
  1746. ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, 0);
  1747. return lResult;
  1748. }
  1749. break;
  1750. }
  1751. #endif // INPLACR_CNTR
  1752. #if defined( USE_HEADING )
  1753. case WM_HSCROLL:
  1754. {
  1755. LPHEADING lphead = OutlineDoc_GetHeading(lpOutlineDoc);
  1756. Heading_CH_SendMessage(lphead, Message, wParam, lParam);
  1757. break;
  1758. }
  1759. /* NOTE: WM_PAINT trapped in order to track vertical scrolling
  1760. ** that has taken place so the row headings can be
  1761. ** coordinated with the LineList. we wanted to trap instead
  1762. ** but it is not generated from scrolling without using
  1763. ** scroll bar (e.g. use keyboard).
  1764. */
  1765. case WM_PAINT:
  1766. {
  1767. Heading_RH_Scroll(OutlineDoc_GetHeading(lpOutlineDoc), hWnd);
  1768. break;
  1769. }
  1770. #endif // USE_HEADING
  1771. case WM_LBUTTONUP:
  1772. {
  1773. #if defined( USE_DRAGDROP )
  1774. if (lpOleDoc->m_fPendingDrag) {
  1775. /* ButtonUP came BEFORE distance/time threshholds were
  1776. ** exceeded. clear fPendingDrag state.
  1777. */
  1778. ReleaseCapture();
  1779. KillTimer(hWnd, 1);
  1780. lpOleDoc->m_fPendingDrag = FALSE;
  1781. }
  1782. #endif // USE_DRAGDROP
  1783. #if defined( INPLACE_SVR )
  1784. if (fUIActivateClick) {
  1785. fUIActivateClick = FALSE;
  1786. ServerDoc_UIActivate((LPSERVERDOC) lpOleDoc);
  1787. }
  1788. #endif // INPLACE_SVR
  1789. #if defined( INPLACE_CNTR )
  1790. {
  1791. /* check if a UIDeactivate is pending.
  1792. ** (see comment in WM_LBUTTONDOWN)
  1793. */
  1794. if ( lpContainerApp->m_fPendingUIDeactivate ) {
  1795. ContainerLine_UIDeactivate(
  1796. lpContainerDoc->m_lpLastUIActiveLine);
  1797. lpContainerApp->m_fPendingUIDeactivate = FALSE;
  1798. }
  1799. }
  1800. #endif // INPLACE_CNTR
  1801. break;
  1802. }
  1803. case WM_LBUTTONDOWN:
  1804. {
  1805. POINT pt;
  1806. pt.x = (int)(short)LOWORD (lParam );
  1807. pt.y = (int)(short)HIWORD (lParam );
  1808. #if defined( INPLACE_SVR ) || defined( INPLACE_CNTR )
  1809. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
  1810. ** m_fCSHelpMode flag is set when SHIFT-F1 context
  1811. ** sensitive help is entered.
  1812. ** if this flag is set then the button click should not
  1813. ** cause any action. if the application implements a
  1814. ** help system, then context sensitive help should be
  1815. ** given for the location clicked by the user.
  1816. */
  1817. if (lpOleDoc->m_fCSHelpMode) {
  1818. return (LRESULT)0; // eat the button click because we do
  1819. // not give any help.
  1820. }
  1821. #endif // INPLACE_SVR || INPLACE_CNTR
  1822. #if defined( INPLACE_CNTR )
  1823. {
  1824. /* OLE2NOTE: both inside-out and outside-in style
  1825. ** containers must check if the mouse click is
  1826. ** outside of the current UIActive object (if
  1827. ** any). If so, then set the flag indicating that
  1828. ** there is a pending UIDeactivate needed. We do NOT
  1829. ** want to do it now,
  1830. ** because that would result in un-wanted movement of
  1831. ** the data on the screen as frame adornments (eg.
  1832. ** toolbar) and/or object adornments (eg. ruler) would
  1833. ** be removed from the screen. we want to defer the
  1834. ** UIDeactivate till the mouse up event. The listbox's
  1835. ** default processing captures the mouse on button down
  1836. ** so that it is sure to get the button up message.
  1837. **
  1838. ** SPECIAL NOTE: there is potential interaction here
  1839. ** with Drag/Drop. if this button down event actually
  1840. ** starts a Drag/Drop operation, then OLE does the mouse
  1841. ** capture. in this situation we will NOT get our button
  1842. ** up event. we must instead perform the UIDeactivate
  1843. ** when the drop operation finishes
  1844. */
  1845. lpContainerApp->m_fPendingUIDeactivate =
  1846. ContainerDoc_IsUIDeactivateNeeded(lpContainerDoc, pt);
  1847. }
  1848. #endif // INPLACE_CNTR
  1849. #if defined( USE_DRAGDROP )
  1850. /* OLE2NOTE: check if this is a button down on the region
  1851. ** that is a handle to start a drag operation. for us,
  1852. ** this this the top/bottom border of the selection.
  1853. ** do NOT want to start a drag immediately; we want to
  1854. ** wait until the mouse moves a certain threshold. if
  1855. ** LButtonUp comes before mouse move to start drag, then
  1856. ** the fPendingDrag state is cleared. we must capture
  1857. ** the mouse to ensure the modal state is handled
  1858. ** properly.
  1859. */
  1860. if ( OleDoc_QueryDrag(lpOleDoc, pt.y) ) {
  1861. lpOleDoc->m_fPendingDrag = TRUE;
  1862. lpOleDoc->m_ptButDown = pt;
  1863. SetTimer(hWnd, 1, lpOleApp->m_nDragDelay, NULL);
  1864. SetCapture(hWnd);
  1865. /* We do NOT want to do the listbox's default
  1866. ** processing which would be to capture the mouse
  1867. ** and enter a modal multiple selection state until
  1868. ** a mouse up occurs. we have just finished a modal
  1869. ** drag/drop operation where OLE has captured the
  1870. ** mouse. thus by now the mouse up has already occured.
  1871. */
  1872. return (LRESULT)0; // don't do default listbox processing
  1873. }
  1874. #endif // USE_DRAGDROP
  1875. break;
  1876. }
  1877. case WM_MOUSEMOVE: {
  1878. #if defined( USE_DRAGDROP )
  1879. int x = (int)(short)LOWORD (lParam );
  1880. int y = (int)(short)HIWORD (lParam );
  1881. POINT pt = lpOleDoc->m_ptButDown;
  1882. int nDragMinDist = lpOleApp->m_nDragMinDist;
  1883. if (lpOleDoc->m_fPendingDrag) {
  1884. if (! ( ((pt.x - nDragMinDist) <= x)
  1885. && (x <= (pt.x + nDragMinDist))
  1886. && ((pt.y - nDragMinDist) <= y)
  1887. && (y <= (pt.y + nDragMinDist)) ) ) {
  1888. DWORD dwEffect;
  1889. // mouse moved beyond threshhold to start drag
  1890. ReleaseCapture();
  1891. KillTimer(hWnd, 1);
  1892. lpOleDoc->m_fPendingDrag = FALSE;
  1893. // perform the modal drag/drop operation.
  1894. dwEffect = OleDoc_DoDragDrop( lpOleDoc );
  1895. #if defined( INPLACE_CNTR )
  1896. {
  1897. /* if necessary UIDeactive the in-place object.
  1898. ** this applies to outside-in style
  1899. ** container only.
  1900. ** (see comment above)
  1901. */
  1902. if (lpContainerApp->m_fPendingUIDeactivate) {
  1903. lpContainerApp->m_fPendingUIDeactivate = FALSE;
  1904. // do not UIDeactivate if drag/drop was canceled
  1905. if (dwEffect != DROPEFFECT_NONE)
  1906. ContainerLine_UIDeactivate(
  1907. lpContainerDoc->m_lpLastUIActiveLine
  1908. );
  1909. }
  1910. }
  1911. #endif // INPLACE_CNTR
  1912. return (LRESULT)0; // don't do default listbox process
  1913. }
  1914. else {
  1915. /* cursor did not move from initial mouse down
  1916. ** (pending drag) point.
  1917. */
  1918. return (LRESULT)0; // don't do default listbox process
  1919. }
  1920. }
  1921. #endif // USE_DRAGDROP
  1922. #if defined( INPLACE_CNTR )
  1923. { // BEGIN BLOCK
  1924. if (lpContainerDoc->m_fAddMyUI) {
  1925. /* OLE2NOTE: fAddMyUI is TRUE when
  1926. ** there was previously an in-place
  1927. ** active object which got
  1928. ** UIDeactivated as a result of a
  1929. ** DBLCLK AND the DBLCLK did NOT
  1930. ** result in in-place activating
  1931. ** another object.
  1932. ** (see IOleInPlaceSite::OnUIActivate and
  1933. ** IOleInPlaceSite::OnUIDeactivate
  1934. ** methods).
  1935. */
  1936. #if defined( USE_DOCTOOLS )
  1937. ContainerDoc_AddDocLevelTools(lpContainerDoc);
  1938. #endif
  1939. #if defined( USE_FRAMETOOLS )
  1940. ContainerDoc_AddFrameLevelUI(lpContainerDoc);
  1941. #endif
  1942. lpContainerDoc->m_fAddMyUI = FALSE;
  1943. }
  1944. } // END BLOCK
  1945. #endif // INPLACE_CNTR
  1946. break;
  1947. }
  1948. #if defined( USE_DRAGDROP )
  1949. case WM_TIMER:
  1950. {
  1951. DWORD dwEffect;
  1952. // drag time delay threshhold exceeded -- start drag
  1953. ReleaseCapture();
  1954. KillTimer(hWnd, 1);
  1955. lpOleDoc->m_fPendingDrag = FALSE;
  1956. // perform the modal drag/drop operation.
  1957. dwEffect = OleDoc_DoDragDrop( lpOleDoc );
  1958. #if defined( INPLACE_CNTR )
  1959. /* if necessary UIDeactive the in-place object.
  1960. ** this applies to outside-in style
  1961. ** container only.
  1962. ** (see comment above)
  1963. */
  1964. if (lpContainerApp->m_fPendingUIDeactivate) {
  1965. lpContainerApp->m_fPendingUIDeactivate = FALSE;
  1966. // do not UIDeactivate if drag/drop was canceled
  1967. if (dwEffect != DROPEFFECT_NONE)
  1968. ContainerLine_UIDeactivate(
  1969. lpContainerDoc->m_lpLastUIActiveLine);
  1970. }
  1971. #endif // INPLACE_CNTR
  1972. break;
  1973. }
  1974. #endif // USE_DRAGDROP
  1975. case WM_SETCURSOR:
  1976. {
  1977. RECT rc;
  1978. POINT ptCursor;
  1979. #if defined( INPLACE_SVR ) || defined( INPLACE_CNTR )
  1980. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
  1981. ** m_fCSHelpMode flag is set when SHIFT-F1 context
  1982. ** sensitive help is entered.
  1983. ** if this flag is set then the context sensitive help
  1984. ** cursor should be shown.
  1985. */
  1986. if (lpOleDoc->m_fCSHelpMode) {
  1987. SetCursor(UICursorLoad(IDC_CONTEXTHELP));
  1988. return (LRESULT)TRUE;
  1989. }
  1990. #endif // INPLACE_SVR || INPLACE_CNTR
  1991. GetCursorPos((POINT FAR*)&ptCursor);
  1992. ScreenToClient(hWnd, (POINT FAR*)&ptCursor);
  1993. GetClientRect(hWnd, (LPRECT)&rc);
  1994. // use arrow cursor if in scroll bar
  1995. if (! PtInRect((LPRECT)&rc, ptCursor) )
  1996. SetCursor(LoadCursor(NULL, IDC_ARROW) );
  1997. #if defined( USE_DRAGDROP )
  1998. // use arrow cursor if on drag handle (top/bottom of selection)
  1999. else if ( OleDoc_QueryDrag ( lpOleDoc, ptCursor.y) )
  2000. SetCursor(LoadCursor(NULL, IDC_ARROW) );
  2001. #endif // USE_DRAGDROP
  2002. else
  2003. SetCursor(lpOutlineApp->m_hcursorSelCur);
  2004. return (LRESULT)TRUE;
  2005. }
  2006. #if defined( INPLACE_SVR )
  2007. /* The handling of WM_WINDOWPOSCHANGED message is ISVROTL
  2008. ** application specific. The nature of the owner-draw list
  2009. ** box used by the ISVROTL application causes a recursive
  2010. ** call to this message in some situations when in-place
  2011. ** active. in order not to crash this recursive call must be
  2012. ** guarded.
  2013. */
  2014. case WM_WINDOWPOSCHANGED:
  2015. {
  2016. WINDOWPOS FAR* lpWinPos = (WINDOWPOS FAR*) lParam;
  2017. LRESULT lResult;
  2018. // guard against recursive call
  2019. if (fInWinPosChged)
  2020. return (LRESULT)0;
  2021. fInWinPosChged = TRUE;
  2022. lResult = CallWindowProc(
  2023. (WNDPROC)lpOutlineApp->m_ListBoxWndProc,
  2024. hWnd,
  2025. Message,
  2026. wParam,
  2027. lParam
  2028. );
  2029. fInWinPosChged = FALSE;
  2030. return lResult;
  2031. }
  2032. #endif // INPLACE_SVR
  2033. }
  2034. return CallWindowProc(
  2035. (WNDPROC)lpOutlineApp->m_ListBoxWndProc,
  2036. hWnd,
  2037. Message,
  2038. wParam,
  2039. lParam
  2040. );
  2041. }
  2042. // Utility function to count the number of accelerator items in an
  2043. // accelerator table. A number of OLE APIs need this count, so
  2044. // this can be quite handy.
  2045. // (code shamelessly stolen from the Microsoft Foundation Classes)
  2046. int GetAccelItemCount(HACCEL hAccel)
  2047. {
  2048. #if defined( WIN32 )
  2049. return CopyAcceleratorTable(hAccel, NULL, 0);
  2050. #else
  2051. #pragma pack(1)
  2052. typedef struct tagACCELERATOR
  2053. {
  2054. BYTE fFlags;
  2055. WORD wEvent;
  2056. WORD wID;
  2057. } ACCELERATOR;
  2058. #pragma pack()
  2059. // attempt to lock down the accelerator resource
  2060. ACCELERATOR FAR* pAccel;
  2061. int cAccelItems = 1;
  2062. if (hAccel == NULL ||
  2063. (pAccel = (ACCELERATOR FAR*)LockResource((HGLOBAL)hAccel)) == NULL)
  2064. {
  2065. // NULL accerator table or LockResource failed on the HACCEL,
  2066. // no accelerators
  2067. return 0;
  2068. }
  2069. // otherwise, count them -- last entry in accel table has 0x80 bit set
  2070. while ((pAccel->fFlags & 0x80) == 0)
  2071. {
  2072. ++cAccelItems;
  2073. ++pAccel;
  2074. }
  2075. UnlockResource((HGLOBAL)hAccel);
  2076. return cAccelItems;
  2077. #endif
  2078. }
  2079.