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.

1451 lines
43 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Server Sample Code
  4. **
  5. ** svrinpl.c
  6. **
  7. ** This file contains all interfaces, methods and related support
  8. ** functions for an In-Place Object (Server) application (aka. Visual
  9. ** Editing). The in-place Object application includes the following
  10. ** implementation objects:
  11. **
  12. ** ServerDoc Object
  13. ** exposed interfaces:
  14. ** IOleInPlaceObject
  15. ** IOleInPlaceActiveObject
  16. **
  17. ** ServerApp Object
  18. ** exposed interfaces:
  19. ** IUnknown
  20. **
  21. ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
  22. **
  23. *************************************************************************/
  24. #include "outline.h"
  25. OLEDBGDATA
  26. extern LPOUTLINEAPP g_lpApp;
  27. /* OLE2NOTE: the object should compose a string that is used by
  28. ** in-place containers to be used for the window titles. this string
  29. ** is passed to the container application via
  30. ** IOleInPlaceUIWindow::SetActiveObject. the string should have the
  31. ** following form:
  32. ** <application name> - <object short type name>
  33. ** SDI containers can use the string directly to display in the
  34. ** frame window title. the container would concatenate the string
  35. ** " in <container doc name>".
  36. ** an MDI container with the MDI child window maximized can do the
  37. ** same as the SDI container. an MDI container with the MDI child
  38. ** windows NOT maximized can look for the " - " in the string from
  39. ** the object. the first part of the string (app name) would be put
  40. ** as the frame window title; the second part would be composed with
  41. ** " in <container doc name>" and used as the MDI child window
  42. ** title.
  43. */
  44. // REVIEW: should use string resource for messages
  45. char g_szIPObjectTitle[] = APPNAME " - " SHORTUSERTYPENAME;
  46. extern RECT g_rectNull;
  47. /*************************************************************************
  48. ** ServerDoc::IOleInPlaceObject interface implementation
  49. *************************************************************************/
  50. // IOleInPlaceObject::QueryInterface method
  51. STDMETHODIMP SvrDoc_IPObj_QueryInterface(
  52. LPOLEINPLACEOBJECT lpThis,
  53. REFIID riid,
  54. LPVOID FAR * lplpvObj
  55. )
  56. {
  57. LPSERVERDOC lpServerDoc =
  58. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  59. return OleDoc_QueryInterface((LPOLEDOC)lpServerDoc, riid, lplpvObj);
  60. }
  61. // IOleInPlaceObject::AddRef method
  62. STDMETHODIMP_(ULONG) SvrDoc_IPObj_AddRef(LPOLEINPLACEOBJECT lpThis)
  63. {
  64. LPSERVERDOC lpServerDoc =
  65. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  66. OleDbgAddRefMethod(lpThis, "IOleInPlaceObject");
  67. return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
  68. }
  69. // IOleInPlaceObject::Release method
  70. STDMETHODIMP_(ULONG) SvrDoc_IPObj_Release(LPOLEINPLACEOBJECT lpThis)
  71. {
  72. LPSERVERDOC lpServerDoc =
  73. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  74. OleDbgReleaseMethod(lpThis, "IOleInPlaceObject");
  75. return OleDoc_Release((LPOLEDOC)lpServerDoc);
  76. }
  77. // IOleInPlaceObject::GetWindow method
  78. STDMETHODIMP SvrDoc_IPObj_GetWindow(
  79. LPOLEINPLACEOBJECT lpThis,
  80. HWND FAR* lphwnd
  81. )
  82. {
  83. LPSERVERDOC lpServerDoc =
  84. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  85. OLEDBG_BEGIN2("SvrDoc_IPObj_GetWindow\r\n")
  86. *lphwnd = ((LPOUTLINEDOC)lpServerDoc)->m_hWndDoc;
  87. OLEDBG_END2
  88. return S_OK;
  89. }
  90. // IOleInPlaceObject::ContextSensitiveHelp method
  91. STDMETHODIMP SvrDoc_IPObj_ContextSensitiveHelp(
  92. LPOLEINPLACEOBJECT lpThis,
  93. BOOL fEnable
  94. )
  95. {
  96. LPOLEDOC lpOleDoc =
  97. (LPOLEDOC)((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  98. OleDbgOut2("SvrDoc_IPObj_ContextSensitiveHelp\r\n");
  99. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC).
  100. ** This method is called when SHIFT-F1 context sensitive help is
  101. ** entered. the cursor should then change to a question mark
  102. ** cursor and the app should enter a modal state where the next
  103. ** mouse click does not perform its normal action but rather
  104. ** gives help corresponding to the location clicked. if the app
  105. ** does not implement a help system, it should at least eat the
  106. ** click and do nothing.
  107. */
  108. lpOleDoc->m_fCSHelpMode = fEnable;
  109. return S_OK;
  110. }
  111. // IOleInPlaceObject::InPlaceDeactivate method
  112. STDMETHODIMP SvrDoc_IPObj_InPlaceDeactivate(LPOLEINPLACEOBJECT lpThis)
  113. {
  114. LPSERVERDOC lpServerDoc =
  115. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  116. HRESULT hrErr;
  117. OLEDBG_BEGIN2("SvrDoc_IPObj_InPlaceDeactivate\r\n")
  118. hrErr = ServerDoc_DoInPlaceDeactivate(lpServerDoc);
  119. OLEDBG_END2
  120. return hrErr;
  121. }
  122. // IOleInPlaceObject::UIDeactivate method
  123. STDMETHODIMP SvrDoc_IPObj_UIDeactivate(LPOLEINPLACEOBJECT lpThis)
  124. {
  125. LPSERVERDOC lpServerDoc =
  126. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  127. LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
  128. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  129. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  130. LPLINELIST lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpServerDoc)->m_LineList;
  131. HWND hWndApp = OutlineApp_GetWindow(g_lpApp);
  132. OLEDBG_BEGIN2("SvrDoc_IPObj_UIDeactivate\r\n");
  133. if (!lpServerDoc->m_fUIActive) {
  134. OLEDBG_END2
  135. return NOERROR;
  136. }
  137. lpServerDoc->m_fUIActive = FALSE;
  138. // Clip the hatch window to the size of pos rect so, that the object
  139. // adornments and hatch border will not be visible.
  140. ServerDoc_ResizeInPlaceWindow(lpServerDoc,
  141. (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect),
  142. (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect)
  143. );
  144. if (lpIPData->lpDoc)
  145. lpIPData->lpDoc->lpVtbl->SetActiveObject(lpIPData->lpDoc, NULL, NULL);
  146. if (lpIPData->lpFrame) {
  147. lpIPData->lpFrame->lpVtbl->SetActiveObject(
  148. lpIPData->lpFrame,
  149. NULL,
  150. NULL
  151. );
  152. }
  153. #if defined( USE_FRAMETOOLS )
  154. /* OLE2NOTE: we must hide our frame tools here but NOT call
  155. ** IOleInPlaceFrame::SetBorderSpace(NULL) or SetMenu(NULL).
  156. ** we must hide our tools BEFORE calling
  157. ** IOleInPlaceSite::OnUIDeactivate. the container will put
  158. ** his menus and tools back when OnUIDeactivate is called.
  159. */
  160. ServerDoc_RemoveFrameLevelTools(lpServerDoc);
  161. #endif
  162. OLEDBG_BEGIN2("IOleInPlaceSite::OnUIDeactivate called\r\n");
  163. lpIPData->lpSite->lpVtbl->OnUIDeactivate(lpIPData->lpSite, FALSE);
  164. OLEDBG_END2
  165. /* Reset to use our normal app's accelerator table */
  166. g_lpApp->m_hAccelApp = lpServerApp->m_hAccelBaseApp;
  167. g_lpApp->m_hAccel = lpServerApp->m_hAccelBaseApp;
  168. g_lpApp->m_hWndAccelTarget = hWndApp;
  169. OLEDBG_END2
  170. #if !defined( SVR_INSIDEOUT )
  171. /* OLE2NOTE: an "outside-in" style in-place server would hide its
  172. ** window here. an "inside-out" style server leaves its window
  173. ** visible when it is UIDeactivated. it would only hide its
  174. ** window when InPlaceDeactivated. this app is an "inside-out"
  175. ** style server. it is recommended for most server to support
  176. ** inside-out behavior if possible.
  177. */
  178. ServerDoc_DoInPlaceHide(lpServerDoc);
  179. #endif // INSIEDOUT
  180. return NOERROR;
  181. }
  182. // IOleInPlaceObject::SetObjectRects method
  183. STDMETHODIMP SvrDoc_IPObj_SetObjectRects(
  184. LPOLEINPLACEOBJECT lpThis,
  185. LPCRECT lprcPosRect,
  186. LPCRECT lprcClipRect
  187. )
  188. {
  189. LPSERVERDOC lpServerDoc =
  190. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  191. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  192. LPLINELIST lpLL = OutlineDoc_GetLineList((LPOUTLINEDOC)lpServerDoc);
  193. OLEDBG_BEGIN2("SvrDoc_IPObj_SetObjectRects\r\n")
  194. #if defined( _DEBUG )
  195. OleDbgOutRect3("SvrDoc_IPObj_SetObjectRects (PosRect)",
  196. (LPRECT)lprcPosRect);
  197. OleDbgOutRect3("SvrDoc_IPObj_SetObjectRects (ClipRect)",
  198. (LPRECT)lprcClipRect);
  199. #endif
  200. // save the current PosRect and ClipRect
  201. lpIPData->rcPosRect = *lprcPosRect;
  202. lpIPData->rcClipRect = *lprcClipRect;
  203. if (! lpServerDoc->m_fUIActive) // hatch and adornaments must not be drawn
  204. lprcClipRect = lprcPosRect;
  205. ServerDoc_ResizeInPlaceWindow(
  206. lpServerDoc, (LPRECT)lprcPosRect, (LPRECT)lprcClipRect);
  207. OLEDBG_END2
  208. return NOERROR;
  209. }
  210. // IOleInPlaceObject::ReactivateAndUndo method
  211. STDMETHODIMP SvrDoc_IPObj_ReactivateAndUndo(LPOLEINPLACEOBJECT lpThis)
  212. {
  213. OLEDBG_BEGIN2("SvrDoc_IPObj_ReactivateAndUndo\r\n")
  214. // We do not support support UNDO.
  215. /* REVIEW: for debugging purposes it would be useful to give a
  216. ** message box indicating that this method has been called.
  217. */
  218. OLEDBG_END2
  219. return NOERROR;
  220. }
  221. /*************************************************************************
  222. ** ServerDoc::IOleInPlaceActiveObject interface implementation
  223. *************************************************************************/
  224. // IOleInPlaceActiveObject::QueryInterface method
  225. STDMETHODIMP SvrDoc_IPActiveObj_QueryInterface(
  226. LPOLEINPLACEACTIVEOBJECT lpThis,
  227. REFIID riid,
  228. LPVOID FAR * lplpvObj
  229. )
  230. {
  231. SCODE sc = E_NOINTERFACE;
  232. LPSERVERDOC lpServerDoc =
  233. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  234. /* The container should not be able to access the other interfaces
  235. ** of our object by doing QI on this interface.
  236. */
  237. *lplpvObj = NULL;
  238. if (IsEqualIID(riid, &IID_IUnknown) ||
  239. IsEqualIID(riid, &IID_IOleWindow) ||
  240. IsEqualIID(riid, &IID_IOleInPlaceActiveObject)) {
  241. OleDbgOut4("OleDoc_QueryInterface: IOleInPlaceActiveObject* RETURNED\r\n");
  242. *lplpvObj = lpThis;
  243. OleDoc_AddRef((LPOLEDOC)lpServerDoc);
  244. sc = NOERROR;
  245. }
  246. OleDbgQueryInterfaceMethod(*lplpvObj);
  247. return ResultFromScode(sc);
  248. }
  249. // IOleInPlaceActiveObject::AddRef method
  250. STDMETHODIMP_(ULONG) SvrDoc_IPActiveObj_AddRef(
  251. LPOLEINPLACEACTIVEOBJECT lpThis
  252. )
  253. {
  254. LPSERVERDOC lpServerDoc =
  255. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  256. OleDbgAddRefMethod(lpThis, "IOleInPlaceActiveObject");
  257. return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
  258. }
  259. // IOleInPlaceActiveObject::Release method
  260. STDMETHODIMP_(ULONG) SvrDoc_IPActiveObj_Release(
  261. LPOLEINPLACEACTIVEOBJECT lpThis
  262. )
  263. {
  264. LPSERVERDOC lpServerDoc =
  265. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  266. OleDbgReleaseMethod(lpThis, "IOleInPlaceActiveObject");
  267. return OleDoc_Release((LPOLEDOC)lpServerDoc);
  268. }
  269. // IOleInPlaceActiveObject::GetWindow method
  270. STDMETHODIMP SvrDoc_IPActiveObj_GetWindow(
  271. LPOLEINPLACEACTIVEOBJECT lpThis,
  272. HWND FAR* lphwnd
  273. )
  274. {
  275. LPSERVERDOC lpServerDoc =
  276. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  277. OLEDBG_BEGIN2("SvrDoc_IPActiveObj_GetWindow\r\n")
  278. *lphwnd = ((LPOUTLINEDOC)lpServerDoc)->m_hWndDoc;
  279. OLEDBG_END2
  280. return NOERROR;
  281. }
  282. // IOleInPlaceActiveObject::ContextSensitiveHelp method
  283. STDMETHODIMP SvrDoc_IPActiveObj_ContextSensitiveHelp(
  284. LPOLEINPLACEACTIVEOBJECT lpThis,
  285. BOOL fEnterMode
  286. )
  287. {
  288. LPSERVERDOC lpServerDoc =
  289. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  290. OleDbgOut2("SvrDoc_IPActiveObj_ContextSensitiveHelp\r\n");
  291. /* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
  292. ** This method is called when F1 is pressed when a menu item is
  293. ** selected. this tells the in-place server application to give
  294. ** help rather than execute the next menu command. at a minimum,
  295. ** even if the in-place server application does not implement a
  296. ** help system, it should NOT execute the next command when
  297. ** fEnable==TRUE. We set the active object's m_fMenuMode flag here.
  298. ** later, in WM_COMMAND processing in the DocWndProc, if this
  299. ** flag is set then the command is NOT executed (and help could
  300. ** be given if we had a help system....but we don't.)
  301. */
  302. lpServerDoc->m_fMenuHelpMode = fEnterMode;
  303. #if !defined( HACK )
  304. ((LPOLEDOC)lpServerDoc)->m_fCSHelpMode = fEnterMode;
  305. #endif
  306. return NOERROR;
  307. }
  308. // IOleInPlaceActiveObject::TranslateAccelerator method
  309. STDMETHODIMP SvrDoc_IPActiveObj_TranslateAccelerator(
  310. LPOLEINPLACEACTIVEOBJECT lpThis,
  311. LPMSG lpmsg
  312. )
  313. {
  314. // This will never be called because this server is implemented as an EXE
  315. return NOERROR;
  316. }
  317. // IOleInPlaceActiveObject::OnFrameWindowActivate method
  318. STDMETHODIMP SvrDoc_IPActiveObj_OnFrameWindowActivate(
  319. LPOLEINPLACEACTIVEOBJECT lpThis,
  320. BOOL fActivate
  321. )
  322. {
  323. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)
  324. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  325. HWND hWndDoc = OutlineDoc_GetWindow(lpOutlineDoc);
  326. #if defined( _DEBUG )
  327. if (fActivate)
  328. OleDbgOut2("SvrDoc_IPActiveObj_OnFrameWindowActivate(TRUE)\r\n");
  329. else
  330. OleDbgOut2("SvrDoc_IPActiveObj_OnFrameWindowActivate(FALSE)\r\n");
  331. #endif // _DEBUG
  332. /* OLE2NOTE: this is a notification of the container application's
  333. ** WM_ACTIVATEAPP status. some applications may find this
  334. ** important. we need to update the enable/disable status of our
  335. ** tool bar buttons.
  336. */
  337. // OLE2NOTE: We can't call OutlineDoc_UpdateFrameToolButtons
  338. // right away which
  339. // would generate some OLE calls and eventually
  340. // WM_ACTIVATEAPP and a loop was formed. Therefore, we
  341. // should delay the frame tool initialization until
  342. // WM_ACTIVATEAPP is finished by posting a message
  343. // to ourselves.
  344. /* Update enable/disable state of buttons in toolbar */
  345. if (fActivate)
  346. PostMessage(hWndDoc, WM_U_INITFRAMETOOLS, 0, 0L);
  347. return NOERROR;
  348. }
  349. // IOleInPlaceActiveObject::OnDocWindowActivate method
  350. STDMETHODIMP SvrDoc_IPActiveObj_OnDocWindowActivate(
  351. LPOLEINPLACEACTIVEOBJECT lpThis,
  352. BOOL fActivate
  353. )
  354. {
  355. LPSERVERDOC lpServerDoc =
  356. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  357. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  358. #if defined( _DEBUG )
  359. if (fActivate)
  360. OleDbgOut2("SvrDoc_IPActiveObj_OnDocWindowActivate(TRUE)\r\n");
  361. else
  362. OleDbgOut2("SvrDoc_IPActiveObj_OnDocWindowActivate(FALSE)\r\n");
  363. #endif
  364. if (fActivate) {
  365. ServerDoc_AddFrameLevelUI(lpServerDoc);
  366. }
  367. else {
  368. #if defined( USE_FRAMETOOLS )
  369. /* OLE2NOTE: we must NOT call IOleInPlaceFrame::SetBorderSpace(NULL)
  370. ** or SetMenu(NULL) here. we should simply hide our tools.
  371. */
  372. ServerDoc_RemoveFrameLevelTools(lpServerDoc);
  373. #endif
  374. }
  375. OLEDBG_END2
  376. return NOERROR;
  377. }
  378. // IOleInPlaceActiveObject::ResizeBorder method
  379. STDMETHODIMP SvrDoc_IPActiveObj_ResizeBorder(
  380. LPOLEINPLACEACTIVEOBJECT lpThis,
  381. LPCRECT lprectBorder,
  382. LPOLEINPLACEUIWINDOW lpIPUiWnd,
  383. BOOL fFrameWindow
  384. )
  385. {
  386. LPSERVERDOC lpServerDoc =
  387. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  388. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  389. OLEDBG_BEGIN2("SvrDoc_IPActiveObj_ResizeBorder\r\n")
  390. #if defined( USE_FRAMETOOLS )
  391. if (fFrameWindow) {
  392. FrameTools_NegotiateForSpaceAndShow(
  393. lpOutlineDoc->m_lpFrameTools,
  394. (LPRECT)lprectBorder,
  395. (LPOLEINPLACEFRAME)lpIPUiWnd
  396. );
  397. }
  398. #endif
  399. OLEDBG_END2
  400. return NOERROR;
  401. }
  402. // IOleInPlaceActiveObject::EnableModeless method
  403. STDMETHODIMP SvrDoc_IPActiveObj_EnableModeless(
  404. LPOLEINPLACEACTIVEOBJECT lpThis,
  405. BOOL fEnable
  406. )
  407. {
  408. #if defined( USE_FRAMETOOLS )
  409. LPSERVERDOC lpServerDoc =
  410. ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
  411. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  412. LPFRAMETOOLS lptb;
  413. /* OLE2NOTE: we must enable/disable mouse and keyboard input to our
  414. ** floating tool palette
  415. */
  416. if (lpOutlineDoc) {
  417. lptb = lpOutlineDoc->m_lpFrameTools;
  418. if (lptb)
  419. FrameTools_EnableWindow(lptb, fEnable);
  420. }
  421. #endif // USE_FRAMETOOLS
  422. #if defined( _DEBUG )
  423. if (fEnable)
  424. OleDbgOut2("SvrDoc_IPActiveObj_EnableModeless(TRUE)\r\n");
  425. else
  426. OleDbgOut2("SvrDoc_IPActiveObj_EnableModeless(FALSE)\r\n");
  427. #endif // _DEBUG
  428. /* OLE2NOTE: this method is called when the top-level, in-place
  429. ** container puts up a modal dialog. it tells the UIActive
  430. ** object to disable it modeless dialogs for the duration that
  431. ** the container is displaying a modal dialog.
  432. **
  433. ** ISVROTL does not use any modeless dialogs, thus we can
  434. ** ignore this method.
  435. */
  436. return NOERROR;
  437. }
  438. /*************************************************************************
  439. ** Support Functions
  440. *************************************************************************/
  441. HRESULT ServerDoc_DoInPlaceActivate(
  442. LPSERVERDOC lpServerDoc,
  443. LONG lVerb,
  444. LPMSG lpmsg,
  445. LPOLECLIENTSITE lpActiveSite
  446. )
  447. {
  448. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  449. LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
  450. LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
  451. SCODE sc = E_FAIL;
  452. RECT rcPos;
  453. RECT rcClip;
  454. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  455. LPOUTLINEDOC lpOutlineDoc=(LPOUTLINEDOC)lpServerDoc;
  456. HWND hWndDoc = lpOutlineDoc->m_hWndDoc;
  457. HWND hWndHatch = lpServerDoc->m_hWndHatch;
  458. HRESULT hrErr;
  459. LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
  460. LPOLEINPLACESITE lpIPSite = NULL;
  461. /* OLE2NOTE: lpActiveSite should be used only for InPlace PLAYing.
  462. ** This app does not do inplace PLAYing, so it never uses
  463. ** lpActiveSite.
  464. */
  465. /* InPlace activation can only be done if the ClientSite is non-NULL. */
  466. if (! lpServerDoc->m_lpOleClientSite)
  467. return NOERROR;
  468. if (! lpServerDoc->m_fInPlaceActive) {
  469. // if the object is in open mode then we do not want to do inplace
  470. // activation.
  471. if (IsWindowVisible(lpOutlineDoc->m_hWndDoc))
  472. return NOERROR;
  473. lpIPSite = (LPOLEINPLACESITE)OleStdQueryInterface(
  474. (LPUNKNOWN)lpServerDoc->m_lpOleClientSite,
  475. &IID_IOleInPlaceSite
  476. );
  477. if (! lpIPSite)
  478. goto errActivate;
  479. OLEDBG_BEGIN2("IOleInPlaceSite::CanInPlaceActivate called\r\n");
  480. hrErr = lpIPSite->lpVtbl->CanInPlaceActivate(lpIPSite);
  481. OLEDBG_END2
  482. if (hrErr != NOERROR)
  483. goto errActivate;
  484. lpServerDoc->m_fInPlaceActive = TRUE;
  485. OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceActivate called\r\n");
  486. hrErr = lpIPSite->lpVtbl->OnInPlaceActivate(lpIPSite);
  487. OLEDBG_END2
  488. if (hrErr != NOERROR)
  489. goto errActivate;
  490. if (! ServerDoc_AllocInPlaceData(lpServerDoc)) {
  491. sc = E_OUTOFMEMORY;
  492. OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceDeactivate called\r\n");
  493. lpIPSite->lpVtbl->OnInPlaceDeactivate(lpIPSite);
  494. OLEDBG_END2
  495. goto errActivate;
  496. }
  497. (lpIPData = lpServerDoc->m_lpIPData)->lpSite = lpIPSite;
  498. goto InPlaceActive;
  499. errActivate:
  500. lpServerDoc->m_fInPlaceActive = FALSE;
  501. if (lpIPSite)
  502. OleStdRelease((LPUNKNOWN)lpIPSite);
  503. return ResultFromScode(sc);
  504. }
  505. InPlaceActive:
  506. if (! lpServerDoc->m_fInPlaceVisible) {
  507. lpServerDoc->m_fInPlaceVisible = TRUE;
  508. OLEDBG_BEGIN2("IOleInPlaceSite::GetWindow called\r\n");
  509. hrErr = lpIPData->lpSite->lpVtbl->GetWindow(
  510. lpIPData->lpSite, &lpServerDoc->m_hWndParent);
  511. OLEDBG_END2
  512. if (hrErr != NOERROR) {
  513. sc = GetScode(hrErr);
  514. goto errRtn;
  515. }
  516. if (! lpServerDoc->m_hWndParent)
  517. goto errRtn;
  518. /* OLE2NOTE: The server should fill in the "cb" field so that the
  519. ** container can tell what size structure the server is
  520. ** expecting. this enables this structure to be easily extended
  521. ** in future releases of OLE. the container should check this
  522. ** field so that it doesn't try to use fields that do not exist
  523. ** since the server may be using an old structure definition.
  524. */
  525. _fmemset(
  526. (LPOLEINPLACEFRAMEINFO)&lpIPData->frameInfo,
  527. 0,
  528. sizeof(OLEINPLACEFRAMEINFO)
  529. );
  530. lpIPData->frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  531. OLEDBG_BEGIN2("IOleInPlaceSite::GetWindowContext called\r\n");
  532. hrErr = lpIPData->lpSite->lpVtbl->GetWindowContext(lpIPData->lpSite,
  533. (LPOLEINPLACEFRAME FAR*) &lpIPData->lpFrame,
  534. (LPOLEINPLACEUIWINDOW FAR*)&lpIPData->lpDoc,
  535. (LPRECT)&rcPos,
  536. (LPRECT)&rcClip,
  537. (LPOLEINPLACEFRAMEINFO)&lpIPData->frameInfo);
  538. OLEDBG_END2
  539. if (hrErr != NOERROR) {
  540. sc = GetScode(hrErr);
  541. goto errRtn;
  542. }
  543. lpServerApp->m_lpIPData = lpIPData;
  544. ShowWindow(hWndDoc, SW_HIDE); // make sure we are hidden
  545. /* OLE2NOTE: reparent in-place server document's window to the
  546. ** special in-place hatch border window. set the in-place site's
  547. ** window as the parent of the hatch window. position the
  548. ** in-place and hatch border windows using the PosRect and
  549. ** ClipRect.
  550. ** it is important to properly parent and position the in-place
  551. ** server window BEFORE calling IOleInPlaceFrame::SetMenu and
  552. ** SetBorderSpace.
  553. */
  554. ShowWindow(lpServerDoc->m_hWndHatch, SW_SHOW);
  555. // make sure App busy/blocked dialogs are parented to our
  556. // new hWndFrame
  557. OleStdMsgFilter_SetParentWindow(
  558. lpOleApp->m_lpMsgFilter,lpIPData->frameInfo.hwndFrame);
  559. SetParent(lpServerDoc->m_hWndHatch, lpServerDoc->m_hWndParent);
  560. SetParent(hWndDoc, lpServerDoc->m_hWndHatch);
  561. #if defined( _DEBUG )
  562. OleDbgOutRect3("IOleInPlaceSite::GetWindowContext (PosRect)",
  563. (LPRECT)&rcPos);
  564. OleDbgOutRect3("IOleInPlaceSite::GetWindowContext (ClipRect)",
  565. (LPRECT)&rcClip);
  566. #endif
  567. // save the current PosRect and ClipRect
  568. lpIPData->rcPosRect = rcPos;
  569. lpIPData->rcClipRect = rcClip;
  570. /* OLE2NOTE: build the shared menu for the in-place container and
  571. ** the server.
  572. */
  573. if (ServerDoc_AssembleMenus (lpServerDoc) != NOERROR)
  574. goto errRtn;
  575. #if defined( SVR_INSIDEOUT )
  576. if (lVerb == OLEIVERB_INPLACEACTIVATE) {
  577. // Clip the hatch window to the size of pos rect so, that
  578. // hatch and object adornments will not be visible.
  579. ServerDoc_ResizeInPlaceWindow(lpServerDoc,
  580. (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect),
  581. (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect)
  582. );
  583. }
  584. #endif // SVR_INSIDEOUT
  585. }
  586. #if defined( SVR_INSIDEOUT )
  587. // OLE2NOTE: if verb is OLEIVERB_INPLACEACTIVATE we do NOT want to
  588. // show our UI
  589. if (lVerb == OLEIVERB_INPLACEACTIVATE) {
  590. return NOERROR;
  591. }
  592. #endif // SVR_INSIDEOUT
  593. if (! lpServerDoc->m_fUIActive) {
  594. lpServerDoc->m_fUIActive = TRUE;
  595. OLEDBG_BEGIN2("IOleInPlaceSite::OnUIActivate called\r\n");
  596. hrErr = lpIPData->lpSite->lpVtbl->OnUIActivate(lpIPData->lpSite);
  597. OLEDBG_END2
  598. if (hrErr != NOERROR) {
  599. lpServerDoc->m_fUIActive = FALSE;
  600. goto errRtn;
  601. }
  602. SetFocus(hWndDoc);
  603. // Show the object adornments and hacth border around them.
  604. ServerDoc_ResizeInPlaceWindow(lpServerDoc,
  605. (LPRECT)&lpIPData->rcPosRect,
  606. (LPRECT)&lpIPData->rcClipRect
  607. );
  608. /* OLE2NOTE: IOleInPlaceFrame::SetActiveObject must be called BEFORE
  609. ** IOleInPlaceFrame::SetMenu.
  610. */
  611. OLEDBG_BEGIN2("IOleInPlaceSite::SetActiveObject called\r\n");
  612. CallIOleInPlaceUIWindowSetActiveObjectA(
  613. (struct IOleInPlaceUIWindow *) lpIPData->lpFrame,
  614. (LPOLEINPLACEACTIVEOBJECT) &lpServerDoc->m_OleInPlaceActiveObject,
  615. (LPSTR)g_szIPObjectTitle
  616. );
  617. OLEDBG_END2
  618. /* OLE2NOTE: If the container wants to give ownership of the
  619. ** palette then he would sendmessage WM_QUEYNEWPALETTE to
  620. ** the object window proc, before returning from
  621. ** IOleInPlaceFrame::SetActiveObject. Those objects which
  622. ** want to be edited inplace only if they have the ownership of
  623. ** the palette, can check at this point in the code whether
  624. ** they got WM_QUERYNEWPALETTE or not. If they didn't get
  625. ** the message, then they can inplace deactivate and do open
  626. ** editing instead.
  627. */
  628. if (lpIPData->lpDoc) {
  629. CallIOleInPlaceUIWindowSetActiveObjectA(
  630. lpIPData->lpDoc,
  631. (LPOLEINPLACEACTIVEOBJECT)&lpServerDoc->m_OleInPlaceActiveObject,
  632. (LPSTR)g_szIPObjectTitle
  633. );
  634. }
  635. /* OLE2NOTE: install the menu and frame-level tools on the in-place
  636. ** frame.
  637. */
  638. ServerDoc_AddFrameLevelUI(lpServerDoc);
  639. }
  640. return NOERROR;
  641. errRtn:
  642. ServerDoc_DoInPlaceDeactivate(lpServerDoc);
  643. return ResultFromScode(sc);
  644. }
  645. HRESULT ServerDoc_DoInPlaceDeactivate(LPSERVERDOC lpServerDoc)
  646. {
  647. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  648. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  649. if (!lpServerDoc->m_fInPlaceActive)
  650. return S_OK;
  651. lpServerDoc->m_fInPlaceActive = FALSE;
  652. SvrDoc_IPObj_UIDeactivate(
  653. (LPOLEINPLACEOBJECT)&lpServerDoc->m_OleInPlaceObject);
  654. /* OLE2NOTE: an inside-out style in-place server will
  655. ** NOT hide its window in UIDeactive (an outside-in
  656. ** style object will hide its window in UIDeactivate).
  657. ** thus, an inside-out server must explicitly hide
  658. ** its window in InPlaceDeactivate. it is ALSO important for an
  659. ** outside-in style object to call ServerDoc_DoInPlaceHide here
  660. ** BEFORE freeing the InPlaceData structure. it will be common
  661. ** for in-place containers to call IOleInPlaceObject::
  662. ** InPlaceDeactivate in their IOleInPlaceSite::OnUIDeactiate
  663. ** implementation.
  664. */
  665. ServerDoc_DoInPlaceHide(lpServerDoc);
  666. OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceDeactivate called\r\n");
  667. lpIPData->lpSite->lpVtbl->OnInPlaceDeactivate(lpIPData->lpSite);
  668. OLEDBG_END2
  669. OleStdRelease((LPUNKNOWN)lpIPData->lpSite);
  670. lpIPData->lpSite = NULL;
  671. ServerDoc_FreeInPlaceData(lpServerDoc);
  672. return NOERROR;
  673. }
  674. HRESULT ServerDoc_DoInPlaceHide(LPSERVERDOC lpServerDoc)
  675. {
  676. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  677. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  678. LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
  679. HWND hWndApp = OutlineApp_GetWindow(g_lpApp);
  680. if (! lpServerDoc->m_fInPlaceVisible)
  681. return NOERROR;
  682. // Set the parent back to server app's window
  683. OleDoc_HideWindow((LPOLEDOC)lpServerDoc, FALSE /* fShutdown */);
  684. /* we need to enusure that our window is set to normal 100% zoom.
  685. ** if the window is next shown in open mode it should start out
  686. ** at normal zoom factor. our window may have been set to a
  687. ** different zoom factor while it was in-place active.
  688. */
  689. OutlineDoc_SetCurrentZoomCommand(lpOutlineDoc,IDM_V_ZOOM_100);
  690. lpServerDoc->m_fInPlaceVisible = FALSE;
  691. lpServerDoc->m_hWndParent = hWndApp;
  692. SetParent(
  693. lpOutlineDoc->m_hWndDoc,
  694. lpServerDoc->m_hWndParent
  695. );
  696. // make sure App busy/blocked dialogs are parented to our own hWndApp
  697. OleStdMsgFilter_SetParentWindow(lpOleApp->m_lpMsgFilter, hWndApp);
  698. // Hide the in-place hatch border window.
  699. ShowWindow(lpServerDoc->m_hWndHatch, SW_HIDE);
  700. ServerDoc_DisassembleMenus(lpServerDoc);
  701. /* we no longer need the IOleInPlaceFrame* or the doc's
  702. ** IOleInPlaceWindow* interface pointers.
  703. */
  704. if (lpIPData->lpDoc) {
  705. OleStdRelease((LPUNKNOWN)lpIPData->lpDoc);
  706. lpIPData->lpDoc = NULL;
  707. }
  708. if (lpIPData->lpFrame) {
  709. OleStdRelease((LPUNKNOWN)lpIPData->lpFrame);
  710. lpIPData->lpFrame = NULL;
  711. }
  712. ((LPSERVERAPP)g_lpApp)->m_lpIPData = NULL;
  713. return NOERROR;
  714. }
  715. BOOL ServerDoc_AllocInPlaceData(LPSERVERDOC lpServerDoc)
  716. {
  717. LPINPLACEDATA lpIPData;
  718. if (!(lpIPData = (LPINPLACEDATA) New(sizeof(INPLACEDATA))))
  719. return FALSE;
  720. lpIPData->lpFrame = NULL;
  721. lpIPData->lpDoc = NULL;
  722. lpIPData->lpSite = NULL;
  723. lpIPData->hOlemenu = NULL;
  724. lpIPData->hMenuShared = NULL;
  725. lpServerDoc->m_lpIPData = lpIPData;
  726. return TRUE;
  727. }
  728. void ServerDoc_FreeInPlaceData(LPSERVERDOC lpServerDoc)
  729. {
  730. Delete(lpServerDoc->m_lpIPData);
  731. lpServerDoc->m_lpIPData = NULL;
  732. }
  733. HRESULT ServerDoc_AssembleMenus(LPSERVERDOC lpServerDoc)
  734. {
  735. HMENU hMenuShared;
  736. LONG FAR* lpWidths;
  737. UINT uPosition;
  738. UINT uPositionStart;
  739. LPSERVERAPP lpServerApp = (LPSERVERAPP) g_lpApp;
  740. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  741. HRESULT hresult;
  742. BOOL fNoError = TRUE;
  743. lpWidths = lpIPData->menuGroupWidths.width;
  744. hMenuShared = CreateMenu();
  745. if (hMenuShared &&
  746. (hresult = lpIPData->lpFrame->lpVtbl->InsertMenus(
  747. lpIPData->lpFrame, hMenuShared,
  748. &lpIPData->menuGroupWidths)) == NOERROR) {
  749. /* Insert EDIT group menus */
  750. uPosition = (UINT)lpWidths[0]; /* # of menus in the FILE group */
  751. uPositionStart = uPosition;
  752. fNoError &= InsertMenu(
  753. hMenuShared,
  754. (UINT)uPosition,
  755. (UINT)(MF_BYPOSITION | MF_POPUP),
  756. (UINT)lpServerApp->m_hMenuEdit,
  757. (LPCSTR)"&Edit"
  758. );
  759. uPosition++;
  760. lpWidths[1] = uPosition - uPositionStart;
  761. /* Insert OBJECT group menus */
  762. uPosition += (UINT)lpWidths[2];
  763. uPositionStart = uPosition;
  764. fNoError &= InsertMenu(
  765. hMenuShared,
  766. (UINT)uPosition,
  767. (UINT)(MF_BYPOSITION | MF_POPUP),
  768. (UINT)lpServerApp->m_hMenuLine,
  769. (LPCSTR)"&Line"
  770. );
  771. uPosition++;
  772. fNoError &= InsertMenu(
  773. hMenuShared,
  774. (UINT)uPosition,
  775. (UINT)(MF_BYPOSITION | MF_POPUP),
  776. (UINT)lpServerApp->m_hMenuName,
  777. (LPCSTR)"&Name"
  778. );
  779. uPosition++;
  780. fNoError &= InsertMenu(
  781. hMenuShared,
  782. (UINT)uPosition,
  783. (UINT)(MF_BYPOSITION | MF_POPUP),
  784. (UINT)lpServerApp->m_hMenuOptions,
  785. (LPCSTR)"&Options"
  786. );
  787. uPosition++;
  788. fNoError &= InsertMenu(
  789. hMenuShared,
  790. (UINT)uPosition,
  791. (UINT)(MF_BYPOSITION | MF_POPUP),
  792. (UINT)lpServerApp->m_hMenuDebug,
  793. (LPCSTR)"DbgI&Svr"
  794. );
  795. uPosition++;
  796. lpWidths[3] = uPosition - uPositionStart;
  797. /* Insert HELP group menus */
  798. uPosition += (UINT) lpWidths[4]; /* # of menus in WINDOW group */
  799. uPositionStart = uPosition;
  800. fNoError &= InsertMenu(
  801. hMenuShared,
  802. (UINT)uPosition,
  803. (UINT)(MF_BYPOSITION | MF_POPUP),
  804. (UINT)lpServerApp->m_hMenuHelp,
  805. (LPCSTR)"&Help"
  806. );
  807. uPosition++;
  808. lpWidths[5] = uPosition - uPositionStart;
  809. OleDbgAssert(fNoError == TRUE);
  810. } else {
  811. /* In-place container does not allow us to add menus to the
  812. ** frame.
  813. ** OLE2NOTE: even when the in-place container does NOT allow
  814. ** the building of a merged menu bar, it is CRITICAL that
  815. ** the in-place server still call OleCreateMenuDescriptor
  816. ** passing NULL for hMenuShared.
  817. */
  818. if (hMenuShared) {
  819. DestroyMenu(hMenuShared);
  820. hMenuShared = NULL;
  821. }
  822. }
  823. lpIPData->hMenuShared = hMenuShared;
  824. if (!(lpIPData->hOlemenu = OleCreateMenuDescriptor(hMenuShared,
  825. &lpIPData->menuGroupWidths)))
  826. return ResultFromScode(E_OUTOFMEMORY);
  827. return NOERROR;
  828. }
  829. void ServerDoc_DisassembleMenus(LPSERVERDOC lpServerDoc)
  830. {
  831. UINT uCount;
  832. UINT uGroup;
  833. UINT uDeleteAt;
  834. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  835. LONG FAR* lpWidths = lpIPData->menuGroupWidths.width;
  836. BOOL fNoError = TRUE;
  837. /* OLE2NOTE: even when hMenuShared is NULL (ie. the server has no
  838. ** Menu), there is still an hOleMenu created that must be destroyed.
  839. */
  840. if (lpIPData->hOlemenu) {
  841. OleDestroyMenuDescriptor (lpIPData->hOlemenu);
  842. lpIPData->hOlemenu = NULL;
  843. }
  844. if (! lpIPData->hMenuShared)
  845. return; // no menus to be destroyed
  846. /* Remove server group menus. */
  847. uDeleteAt = 0;
  848. for (uGroup = 0; uGroup < 6; uGroup++) {
  849. uDeleteAt += (UINT)lpWidths[uGroup++];
  850. for (uCount = 0; uCount < (UINT)lpWidths[uGroup]; uCount++)
  851. fNoError &= RemoveMenu(lpIPData->hMenuShared, uDeleteAt,
  852. MF_BYPOSITION);
  853. }
  854. /* Remove container group menus */
  855. fNoError &= (lpIPData->lpFrame->lpVtbl->RemoveMenus(
  856. lpIPData->lpFrame,
  857. lpIPData->hMenuShared) == NOERROR);
  858. OleDbgAssert(fNoError == TRUE);
  859. DestroyMenu(lpIPData->hMenuShared);
  860. lpIPData->hMenuShared = NULL;
  861. }
  862. /* ServerDoc_UpdateInPlaceWindowOnExtentChange
  863. ** -------------------------------------------
  864. ** The size of the in-place window needs to be changed.
  865. ** calculate the size required in Client coordinates (taking into
  866. ** account the current scale factor imposed by the in-place
  867. ** container) and ask our in-place container to allow us to resize.
  868. ** our container must call us back via
  869. ** IOleInPlaceObject::SetObjectRects for the actual sizing to take
  870. ** place.
  871. **
  872. ** OLE2NOTE: the rectangle that we ask for from our in-place
  873. ** container is always the rectangle required for the object display
  874. ** itself (in our case the size of the LineList contents). it does
  875. ** NOT include the space we require for object frame adornments.
  876. */
  877. void ServerDoc_UpdateInPlaceWindowOnExtentChange(LPSERVERDOC lpServerDoc)
  878. {
  879. SIZEL sizelHim;
  880. SIZEL sizelPix;
  881. RECT rcPosRect;
  882. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  883. LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
  884. HWND hWndLL = lpLL->m_hWndListBox;
  885. LPSCALEFACTOR lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
  886. if (!lpServerDoc->m_fInPlaceActive)
  887. return;
  888. OleDoc_GetExtent((LPOLEDOC)lpServerDoc, (LPSIZEL)&sizelHim);
  889. // apply current scale factor
  890. sizelHim.cx = sizelHim.cx * lpscale->dwSxN / lpscale->dwSxD;
  891. sizelHim.cy = sizelHim.cy * lpscale->dwSxN / lpscale->dwSxD;
  892. XformSizeInHimetricToPixels(NULL, (LPSIZEL)&sizelHim, (LPSIZEL)&sizelPix);
  893. GetWindowRect(hWndLL, (LPRECT)&rcPosRect);
  894. ScreenToClient(lpServerDoc->m_hWndParent, (POINT FAR *)&rcPosRect);
  895. rcPosRect.right = rcPosRect.left + (int) sizelPix.cx;
  896. rcPosRect.bottom = rcPosRect.top + (int) sizelPix.cy;
  897. OleDbgOutRect3("ServerDoc_UpdateInPlaceWindowOnExtentChange: (PosRect)", (LPRECT)&rcPosRect);
  898. OLEDBG_BEGIN2("IOleInPlaceSite::OnPosRectChange called\r\n");
  899. lpServerDoc->m_lpIPData->lpSite->lpVtbl->OnPosRectChange(
  900. lpServerDoc->m_lpIPData->lpSite,
  901. (LPRECT) &rcPosRect
  902. );
  903. OLEDBG_END2
  904. }
  905. /* ServerDoc_CalcInPlaceWindowPos
  906. * ------------------------------
  907. *
  908. * Move (and re-scale) the ServerDoc to the specified rectangle.
  909. *
  910. * Parameters:
  911. * lprcListBox - rect in client coordinate in which the listbox will fit
  912. * lprcDoc - corresponding size of the Doc in client coordinate
  913. *
  914. */
  915. void ServerDoc_CalcInPlaceWindowPos(
  916. LPSERVERDOC lpServerDoc,
  917. LPRECT lprcListBox,
  918. LPRECT lprcDoc,
  919. LPSCALEFACTOR lpscale
  920. )
  921. {
  922. SIZEL sizelHim;
  923. SIZEL sizelPix;
  924. LPLINELIST lpLL;
  925. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  926. LPHEADING lphead;
  927. if (!lpServerDoc || !lprcListBox || !lprcDoc)
  928. return;
  929. lphead = (LPHEADING)&lpOutlineDoc->m_heading;
  930. lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
  931. OleDoc_GetExtent((LPOLEDOC)lpServerDoc, (LPSIZEL)&sizelHim);
  932. XformSizeInHimetricToPixels(NULL, &sizelHim, &sizelPix);
  933. if (sizelHim.cx == 0 || sizelPix.cx == 0) {
  934. lpscale->dwSxN = 1;
  935. lpscale->dwSxD = 1;
  936. } else {
  937. lpscale->dwSxN = lprcListBox->right - lprcListBox->left;
  938. lpscale->dwSxD = sizelPix.cx;
  939. }
  940. if (sizelHim.cy == 0 || sizelPix.cy == 0) {
  941. lpscale->dwSyN = 1;
  942. lpscale->dwSyD = 1;
  943. } else {
  944. lpscale->dwSyN = lprcListBox->bottom - lprcListBox->top;
  945. lpscale->dwSyD = sizelPix.cy;
  946. }
  947. lprcDoc->left = lprcListBox->left - Heading_RH_GetWidth(lphead,lpscale);
  948. lprcDoc->right = lprcListBox->right;
  949. lprcDoc->top = lprcListBox->top - Heading_CH_GetHeight(lphead,lpscale);
  950. lprcDoc->bottom = lprcListBox->bottom;
  951. }
  952. /* ServerDoc_ResizeInPlaceWindow
  953. ** -----------------------------
  954. ** Actually resize the in-place ServerDoc windows according to the
  955. ** PosRect and ClipRect allowed by our in-place container.
  956. **
  957. ** OLE2NOTE: the PosRect rectangle that our in-place container tells
  958. ** us is always the rectangle required for the object display
  959. ** itself (in our case the size of the LineList contents). it does
  960. ** NOT include the space we require for object frame adornments.
  961. */
  962. void ServerDoc_ResizeInPlaceWindow(
  963. LPSERVERDOC lpServerDoc,
  964. LPCRECT lprcPosRect,
  965. LPCRECT lprcClipRect
  966. )
  967. {
  968. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  969. LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
  970. SCALEFACTOR scale;
  971. RECT rcDoc;
  972. POINT ptOffset;
  973. /* OLE2NOTE: calculate the space needed for our object frame
  974. ** adornments. our in-place container tells us the size that our
  975. ** object should take in window client coordinates
  976. ** (lprcPosRect). the rectangle cooresponds to the size that our
  977. ** LineList ListBox should be. our Doc window must the correct
  978. ** amount larger to accomodate our row/column headings.
  979. ** then move all windows into position.
  980. */
  981. ServerDoc_CalcInPlaceWindowPos(
  982. lpServerDoc,
  983. (LPRECT)lprcPosRect,
  984. (LPRECT)&rcDoc,
  985. (LPSCALEFACTOR)&scale
  986. );
  987. /* OLE2NOTE: we need to honor the lprcClipRect specified by our
  988. ** in-place container. we must NOT draw outside of the ClipRect.
  989. ** in order to achieve this, we will size the hatch window to be
  990. ** exactly the size that should be visible (rcVisRect). the
  991. ** rcVisRect is defined as the intersection of the full size of
  992. ** the in-place server window and the lprcClipRect.
  993. ** the ClipRect could infact clip the HatchRect on the
  994. ** right/bottom and/or on the top/left. if it is clipped on the
  995. ** right/bottom then it is sufficient to simply resize the hatch
  996. ** window. but if the HatchRect is clipped on the top/left then
  997. ** we must "move" the ServerDoc window (child of HatchWindow) by
  998. ** the delta that was clipped. the window origin of the
  999. ** ServerDoc window will then have negative coordinates relative
  1000. ** to its parent HatchWindow.
  1001. */
  1002. SetHatchWindowSize(
  1003. lpServerDoc->m_hWndHatch,
  1004. (LPRECT)&rcDoc,
  1005. (LPRECT)lprcClipRect,
  1006. (LPPOINT)&ptOffset
  1007. );
  1008. // shift Doc window to account for hatch frame being drawn
  1009. OffsetRect((LPRECT)&rcDoc, ptOffset.x, ptOffset.y);
  1010. // move/size/set scale factor of ServerDoc window.
  1011. OutlineDoc_SetScaleFactor(
  1012. lpOutlineDoc, (LPSCALEFACTOR)&scale, (LPRECT)&rcDoc);
  1013. /* reset the horizontal extent of the listbox. this makes
  1014. ** the listbox realize that a scroll bar is not needed.
  1015. */
  1016. SendMessage(
  1017. lpLL->m_hWndListBox,
  1018. LB_SETHORIZONTALEXTENT,
  1019. (int) 0,
  1020. 0L
  1021. );
  1022. SendMessage(
  1023. lpLL->m_hWndListBox,
  1024. LB_SETHORIZONTALEXTENT,
  1025. (int) (lprcPosRect->right - lprcPosRect->left),
  1026. 0L
  1027. );
  1028. }
  1029. /* ServerDoc_SetStatusText
  1030. ** Tell the active in-place frame to display a status message.
  1031. */
  1032. void ServerDoc_SetStatusText(LPSERVERDOC lpServerDoc, LPSTR lpszMessage)
  1033. {
  1034. if (lpServerDoc && lpServerDoc->m_fUIActive &&
  1035. lpServerDoc->m_lpIPData != NULL) {
  1036. OLEDBG_BEGIN2("IOleInPlaceFrame::SetStatusText called\r\n")
  1037. CallIOleInPlaceFrameSetStatusTextA
  1038. (lpServerDoc->m_lpIPData->lpFrame, lpszMessage);
  1039. OLEDBG_END2
  1040. }
  1041. }
  1042. /* ServerDoc_GetTopInPlaceFrame
  1043. ** ----------------------------
  1044. ** returns NON-AddRef'ed pointer to Top In-Place Frame interface
  1045. */
  1046. LPOLEINPLACEFRAME ServerDoc_GetTopInPlaceFrame(LPSERVERDOC lpServerDoc)
  1047. {
  1048. if (lpServerDoc->m_lpIPData)
  1049. return lpServerDoc->m_lpIPData->lpFrame;
  1050. else
  1051. return NULL;
  1052. }
  1053. void ServerDoc_GetSharedMenuHandles(
  1054. LPSERVERDOC lpServerDoc,
  1055. HMENU FAR* lphSharedMenu,
  1056. HOLEMENU FAR* lphOleMenu
  1057. )
  1058. {
  1059. if (lpServerDoc->m_lpIPData) {
  1060. *lphSharedMenu = lpServerDoc->m_lpIPData->hMenuShared;
  1061. *lphOleMenu = lpServerDoc->m_lpIPData->hOlemenu;
  1062. } else {
  1063. *lphSharedMenu = NULL;
  1064. *lphOleMenu = NULL;
  1065. }
  1066. }
  1067. void ServerDoc_AddFrameLevelUI(LPSERVERDOC lpServerDoc)
  1068. {
  1069. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1070. LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
  1071. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  1072. LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
  1073. HMENU hSharedMenu; // combined obj/cntr menu
  1074. HOLEMENU hOleMenu; // returned by OleCreateMenuDesc.
  1075. ServerDoc_GetSharedMenuHandles(
  1076. lpServerDoc,
  1077. &hSharedMenu,
  1078. &hOleMenu
  1079. );
  1080. lpTopIPFrame->lpVtbl->SetMenu(
  1081. lpTopIPFrame,
  1082. hSharedMenu,
  1083. hOleMenu,
  1084. lpOutlineDoc->m_hWndDoc
  1085. );
  1086. // save normal accelerator table
  1087. lpServerApp->m_hAccelBaseApp = lpOutlineApp->m_hAccelApp;
  1088. // install accelerator table for UIActive server (w/ active editor cmds)
  1089. lpOutlineApp->m_hAccel = lpServerApp->m_hAccelIPSvr;
  1090. lpOutlineApp->m_hAccelApp = lpServerApp->m_hAccelIPSvr;
  1091. lpOutlineApp->m_hWndAccelTarget = lpOutlineDoc->m_hWndDoc;
  1092. #if defined( USE_FRAMETOOLS )
  1093. ServerDoc_AddFrameLevelTools(lpServerDoc);
  1094. // update toolbar button enable states
  1095. OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
  1096. #endif
  1097. }
  1098. void ServerDoc_AddFrameLevelTools(LPSERVERDOC lpServerDoc)
  1099. {
  1100. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1101. LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
  1102. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  1103. LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
  1104. #if defined( USE_FRAMETOOLS )
  1105. HWND hWndFrame;
  1106. FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, TRUE);
  1107. // if not in-place UI active, add our tools to our own frame.
  1108. if (! lpServerDoc->m_fUIActive) {
  1109. OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
  1110. return;
  1111. }
  1112. if ((hWndFrame = OutlineApp_GetFrameWindow(lpOutlineApp)) == NULL) {
  1113. /* we could NOT get a valid frame window, so POP our tools up. */
  1114. /* OLE2NOTE: since we are poping up our tools, we MUST inform
  1115. ** the top in-place frame window that we need NO tool space
  1116. ** BUT that it should NOT put its own tools up. if we were
  1117. ** to pass NULL instead of (0,0,0,0), then the container
  1118. ** would have the option to leave its own tools up.
  1119. */
  1120. lpTopIPFrame->lpVtbl->SetBorderSpace(
  1121. lpTopIPFrame,
  1122. (LPCBORDERWIDTHS)&g_rectNull
  1123. );
  1124. FrameTools_PopupTools(lpOutlineDoc->m_lpFrameTools);
  1125. } else {
  1126. /* OLE2NOTE: we need to negotiate for space and attach our frame
  1127. ** level tools to the top-level in-place container's frame window.
  1128. */
  1129. FrameTools_AttachToFrame(lpOutlineDoc->m_lpFrameTools, hWndFrame);
  1130. FrameTools_NegotiateForSpaceAndShow(
  1131. lpOutlineDoc->m_lpFrameTools,
  1132. NULL,
  1133. lpTopIPFrame
  1134. );
  1135. }
  1136. #else // ! USE_FRAMETOOLS
  1137. /* OLE2NOTE: if you do NOT use frame tools, you MUST inform the top
  1138. ** in-place frame window so that it can put back its own tools.
  1139. */
  1140. lpTopIPFrame->lpVtbl->SetBorderSpace(lpIPData->lpFrame, NULL);
  1141. #endif // ! USE_FRAMETOOLS
  1142. }
  1143. #if defined( USE_FRAMETOOLS )
  1144. void ServerDoc_RemoveFrameLevelTools(LPSERVERDOC lpServerDoc)
  1145. {
  1146. LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
  1147. OleDbgAssert(lpOutlineDoc->m_lpFrameTools != NULL);
  1148. // Reparent our tools back to one of our own windows
  1149. FrameTools_AttachToFrame(lpOutlineDoc->m_lpFrameTools,g_lpApp->m_hWndApp);
  1150. FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, FALSE);
  1151. }
  1152. #endif // USE_FRAMETOOLS
  1153. void ServerDoc_UIActivate (LPSERVERDOC lpServerDoc)
  1154. {
  1155. if (lpServerDoc->m_fInPlaceActive && !lpServerDoc->m_fUIActive) {
  1156. ServerDoc_DoInPlaceActivate(lpServerDoc,
  1157. OLEIVERB_UIACTIVATE,
  1158. NULL /*lpmsg*/,
  1159. lpServerDoc->m_lpOleClientSite
  1160. );
  1161. OutlineDoc_ShowWindow((LPOUTLINEDOC)lpServerDoc);
  1162. }
  1163. }