olecli2.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_OLE2_SEG
  12. #pragma code_seg(AFX_OLE2_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. /////////////////////////////////////////////////////////////////////////////
  20. // COleFrameHook Construction & Destruction
  21. COleFrameHook::COleFrameHook(CFrameWnd* pFrameWnd, COleClientItem* pItem)
  22. {
  23. ASSERT_VALID(pItem);
  24. ASSERT_VALID(pFrameWnd);
  25. m_lpActiveObject = NULL;
  26. m_pActiveItem = pItem;
  27. m_pFrameWnd = pFrameWnd;
  28. m_hWnd = pFrameWnd->m_hWnd;
  29. m_bToolBarHidden = FALSE;
  30. m_hAccelTable = NULL;
  31. m_bInModalState = FALSE;
  32. m_nModelessCount = 0;
  33. pFrameWnd->m_pNotifyHook = this; // assume start out hooked
  34. ASSERT_VALID(this);
  35. }
  36. COleFrameHook::~COleFrameHook()
  37. {
  38. if (m_pFrameWnd != NULL)
  39. {
  40. ASSERT_VALID(m_pFrameWnd);
  41. if (m_pFrameWnd->m_pNotifyHook == this)
  42. m_pFrameWnd->m_pNotifyHook = NULL;
  43. }
  44. ASSERT_VALID(this);
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. // COleFrameHook overrides
  48. void COleFrameHook::OnRecalcLayout()
  49. {
  50. ASSERT_VALID(this);
  51. if (m_lpActiveObject == NULL)
  52. return;
  53. // get current border size (without current server control bars)
  54. RECT rectBorder;
  55. m_pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderGet, &rectBorder);
  56. // allow server to resize/move its control bars
  57. m_lpActiveObject->ResizeBorder(&rectBorder, &m_xOleInPlaceFrame,
  58. m_pActiveItem->m_pInPlaceFrame == this);
  59. }
  60. BOOL COleFrameHook::OnDocActivate(BOOL bActive)
  61. {
  62. ASSERT_VALID(this);
  63. if (m_lpActiveObject == NULL)
  64. return TRUE;
  65. // allow server to do document activation related actions
  66. m_lpActiveObject->OnDocWindowActivate(bActive);
  67. // make sure window caption gets updated later
  68. COleFrameHook* pNotifyHook = m_pActiveItem->m_pInPlaceFrame;
  69. pNotifyHook->m_pFrameWnd->DelayUpdateFrameTitle();
  70. if (!bActive)
  71. {
  72. // clear border space
  73. pNotifyHook->m_xOleInPlaceFrame.SetBorderSpace(NULL);
  74. if (m_pActiveItem->m_pInPlaceDoc != NULL)
  75. m_pActiveItem->m_pInPlaceDoc->m_xOleInPlaceFrame.SetBorderSpace(NULL);
  76. // remove the menu hook when the doc is not active
  77. pNotifyHook->m_xOleInPlaceFrame.SetMenu(NULL, NULL, NULL);
  78. // unhook top-level frame if not needed
  79. if (pNotifyHook != this)
  80. {
  81. // shouldn't be removing some other hook
  82. ASSERT(pNotifyHook->m_pFrameWnd->m_pNotifyHook == pNotifyHook);
  83. pNotifyHook->m_pFrameWnd->m_pNotifyHook = NULL;
  84. }
  85. }
  86. else
  87. {
  88. // rehook top-level frame if necessary (no effect if top-level == doc-level)
  89. pNotifyHook->m_pFrameWnd->m_pNotifyHook = pNotifyHook;
  90. }
  91. // don't do default if activating
  92. return bActive;
  93. }
  94. BOOL COleFrameHook::OnContextHelp(BOOL bEnter)
  95. {
  96. ASSERT_VALID(this);
  97. if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
  98. return TRUE;
  99. // allow all servers to enter/exit context sensitive help mode
  100. return NotifyAllInPlace(bEnter, &COleFrameHook::DoContextSensitiveHelp);
  101. }
  102. /////////////////////////////////////////////////////////////////////////////
  103. // COleFrameHook callbacks for the top-level frame
  104. BOOL COleFrameHook::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
  105. {
  106. UNUSED_ALWAYS(nFlags);
  107. UNUSED_ALWAYS(nItemID);
  108. // if we're over a docobject item, we need to reflect messages
  109. COleDocObjectItem* pActiveDocObjectItem = DYNAMIC_DOWNCAST(COleDocObjectItem, m_pActiveItem);
  110. if (pActiveDocObjectItem != NULL)
  111. {
  112. CWnd* pWnd = pActiveDocObjectItem->GetInPlaceWindow();
  113. // if we're popping up a menu, figure out what menu is
  114. // apparing; if it's in the help menu and it's not the
  115. // first element, it's the object's menu.
  116. if (nFlags & MF_POPUP)
  117. {
  118. if (pActiveDocObjectItem->m_pHelpPopupMenu->GetSafeHmenu() ==
  119. hSysMenu)
  120. {
  121. pActiveDocObjectItem->m_bInHelpMenu = (nItemID != 0);
  122. if (pActiveDocObjectItem->m_bInHelpMenu && pWnd != NULL)
  123. {
  124. pWnd->SendMessage(WM_MENUSELECT,
  125. MAKEWPARAM(nItemID, nFlags), (LPARAM) hSysMenu);
  126. return TRUE;
  127. }
  128. }
  129. }
  130. else
  131. {
  132. if (pActiveDocObjectItem->m_bInHelpMenu && pWnd != NULL)
  133. {
  134. pWnd->SendMessage(WM_MENUSELECT,
  135. MAKEWPARAM(nItemID, nFlags), (LPARAM) hSysMenu);
  136. return TRUE;
  137. }
  138. }
  139. }
  140. return FALSE;
  141. }
  142. void COleFrameHook::OnInitMenu(CMenu* pMenu)
  143. {
  144. UNUSED_ALWAYS(pMenu);
  145. // reset the help menu flag when a new menu is opening
  146. COleDocObjectItem* pActiveDocObjectItem = DYNAMIC_DOWNCAST(COleDocObjectItem, m_pActiveItem);
  147. if (pActiveDocObjectItem != NULL)
  148. pActiveDocObjectItem->m_bInHelpMenu = FALSE;
  149. return;
  150. }
  151. BOOL COleFrameHook::OnInitMenuPopup(CMenu* pMenu, int nIndex, BOOL bSysMenu)
  152. {
  153. UNUSED_ALWAYS(nIndex);
  154. if (bSysMenu)
  155. return FALSE;
  156. COleDocObjectItem* pActiveDocObjectItem = DYNAMIC_DOWNCAST(COleDocObjectItem, m_pActiveItem);
  157. if (pActiveDocObjectItem == NULL)
  158. return FALSE;
  159. // if we're popping up a new menu, for the object,
  160. // reflect the message and don't let MFC handle it
  161. // with ON_COMMAND_UI stuff
  162. if (pActiveDocObjectItem->m_bInHelpMenu)
  163. {
  164. CWnd* pWnd = pActiveDocObjectItem->GetInPlaceWindow();
  165. if (pWnd != NULL)
  166. {
  167. pWnd->SendMessage(WM_INITMENUPOPUP, (WPARAM) pMenu->m_hMenu,
  168. MAKELPARAM(nIndex, bSysMenu));
  169. return TRUE;
  170. }
  171. }
  172. return FALSE;
  173. }
  174. BOOL COleFrameHook::OnPreTranslateMessage(MSG* pMsg)
  175. {
  176. ASSERT_VALID(this);
  177. if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
  178. return FALSE;
  179. // allow server to translate accelerators
  180. if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
  181. return m_lpActiveObject->TranslateAccelerator(pMsg) == S_OK;
  182. // if we've finally gotten a WM_COMMAND message, make sure
  183. // that it is appropriately reflected to the docobject
  184. if (pMsg->message == WM_COMMAND)
  185. {
  186. COleDocObjectItem* pActiveDocObjectItem = DYNAMIC_DOWNCAST(COleDocObjectItem, m_pActiveItem);
  187. if (pActiveDocObjectItem != NULL)
  188. {
  189. LRESULT lResult = 0;
  190. if (pActiveDocObjectItem->m_bInHelpMenu)
  191. {
  192. CWnd* pWnd = pActiveDocObjectItem->GetInPlaceWindow();
  193. if (pWnd != NULL)
  194. lResult = pWnd->SendMessage(WM_COMMAND, pMsg->wParam, pMsg->lParam);
  195. }
  196. return lResult;
  197. }
  198. }
  199. return FALSE;
  200. }
  201. void COleFrameHook::OnActivate(BOOL bActive)
  202. {
  203. ASSERT_VALID(this);
  204. if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
  205. return;
  206. if (m_pFrameWnd->IsWindowEnabled())
  207. {
  208. // allow active server to do frame level activation
  209. m_lpActiveObject->OnFrameWindowActivate(bActive);
  210. }
  211. }
  212. void COleFrameHook::OnEnableModeless(BOOL bEnable)
  213. {
  214. ASSERT_VALID(this);
  215. if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
  216. return;
  217. // allow server to disable/enable modeless dialogs
  218. NotifyAllInPlace(bEnable, &COleFrameHook::DoEnableModeless);
  219. }
  220. BOOL COleFrameHook::OnUpdateFrameTitle()
  221. {
  222. ASSERT_VALID(this);
  223. ASSERT_VALID(m_pActiveItem);
  224. if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
  225. return FALSE;
  226. return m_pActiveItem->OnUpdateFrameTitle();
  227. }
  228. void COleFrameHook::OnPaletteChanged(CWnd* pFocusWnd)
  229. {
  230. CWnd* pWnd = m_pActiveItem->GetInPlaceWindow();
  231. if (pWnd != NULL)
  232. pWnd->SendMessage(WM_PALETTECHANGED, (WPARAM)pFocusWnd->GetSafeHwnd());
  233. }
  234. BOOL COleFrameHook::OnQueryNewPalette()
  235. {
  236. CWnd* pWnd = m_pActiveItem->GetInPlaceWindow();
  237. if (pWnd != NULL)
  238. return pWnd->SendMessage(WM_QUERYNEWPALETTE);
  239. return FALSE;
  240. }
  241. /////////////////////////////////////////////////////////////////////////////
  242. // Helpers for notifications that have to affect all in-place windows
  243. BOOL COleFrameHook::NotifyAllInPlace(
  244. BOOL bParam, BOOL (COleFrameHook::*pNotifyFunc)(BOOL bParam))
  245. {
  246. ASSERT_VALID(this);
  247. HWND hWndFrame = m_hWnd;
  248. CWinApp* pApp = AfxGetApp();
  249. // no doc manager - no templates
  250. if (pApp->m_pDocManager == NULL)
  251. return TRUE;
  252. // walk all templates in the application
  253. CDocTemplate* pTemplate;
  254. POSITION pos = pApp->m_pDocManager->GetFirstDocTemplatePosition();
  255. while (pos != NULL)
  256. {
  257. pTemplate = pApp->m_pDocManager->GetNextDocTemplate(pos);
  258. ASSERT_VALID(pTemplate);
  259. ASSERT_KINDOF(CDocTemplate, pTemplate);
  260. // walk all documents in the template
  261. POSITION pos2 = pTemplate->GetFirstDocPosition();
  262. while (pos2)
  263. {
  264. COleDocument* pDoc = (COleDocument*)pTemplate->GetNextDoc(pos2);
  265. ASSERT_VALID(pDoc);
  266. if (pDoc->IsKindOf(RUNTIME_CLASS(COleDocument)))
  267. {
  268. // walk all COleClientItem objects in the document
  269. COleClientItem* pItem;
  270. POSITION pos3 = pDoc->GetStartPosition();
  271. while ((pItem = pDoc->GetNextClientItem(pos3)) != NULL)
  272. {
  273. if (pItem->m_pInPlaceFrame != NULL &&
  274. pItem->m_pInPlaceFrame->m_lpActiveObject != NULL &&
  275. pItem->m_pView != NULL &&
  276. AfxIsDescendant(hWndFrame, pItem->m_pView->m_hWnd))
  277. {
  278. // Whew! Found an in-place active item that is
  279. // part of this frame window hierarchy.
  280. COleFrameHook* pNotifyHook = pItem->m_pInPlaceFrame;
  281. if (!(pNotifyHook->*pNotifyFunc)(bParam))
  282. return FALSE;
  283. }
  284. }
  285. }
  286. }
  287. }
  288. return TRUE;
  289. }
  290. BOOL COleFrameHook::DoContextSensitiveHelp(BOOL bEnter)
  291. {
  292. ASSERT_VALID(this);
  293. ASSERT(m_lpActiveObject != NULL);
  294. return !FAILED(m_lpActiveObject->ContextSensitiveHelp(bEnter));
  295. }
  296. BOOL COleFrameHook::DoEnableModeless(BOOL bEnable)
  297. {
  298. ASSERT_VALID(this);
  299. ASSERT(m_lpActiveObject != NULL);
  300. // allow server to enable/disable any modeless windows
  301. if (!bEnable)
  302. {
  303. if (m_nModelessCount++ == 0)
  304. m_lpActiveObject->EnableModeless(FALSE);
  305. }
  306. else
  307. {
  308. if (m_nModelessCount != 0 && --m_nModelessCount == 0)
  309. m_lpActiveObject->EnableModeless(TRUE);
  310. }
  311. return TRUE;
  312. }
  313. /////////////////////////////////////////////////////////////////////////////
  314. // COleClientItem - default in-place activation implementation
  315. BOOL COleClientItem::CanActivate()
  316. {
  317. // don't allow in-place activations with iconic aspect items
  318. if (m_nDrawAspect == DVASPECT_ICON)
  319. return FALSE;
  320. // if no view has been set, attempt to find suitable one.
  321. // (necessary to get links to embeddings to work correctly)
  322. if (m_pView == NULL)
  323. {
  324. // only use pActivateView if this item is in same document
  325. _AFX_OLE_STATE* pOleState = _afxOleState;
  326. if (pOleState->m_pActivateView != NULL &&
  327. pOleState->m_pActivateView->GetDocument() != GetDocument())
  328. {
  329. pOleState->m_pActivateView = NULL; // not in same document
  330. }
  331. CView* pView = pOleState->m_pActivateView;
  332. if (pView == NULL)
  333. {
  334. // no routing view available - try to use the one with focus
  335. CWnd* pWnd = CWnd::GetFocus();
  336. while (pWnd != NULL && !pWnd->IsKindOf(RUNTIME_CLASS(CView)))
  337. pWnd = pWnd->GetParent();
  338. pView = STATIC_DOWNCAST(CView, pWnd);
  339. if (pView == NULL)
  340. {
  341. // still no routing view available - just use first one
  342. COleDocument* pDoc = GetDocument();
  343. POSITION pos = pDoc->GetFirstViewPosition();
  344. pView = pDoc->GetNextView(pos);
  345. }
  346. }
  347. m_pView = pView;
  348. }
  349. return m_pView->GetSafeHwnd() != NULL;
  350. }
  351. void COleClientItem::OnActivate()
  352. {
  353. ASSERT_VALID(this);
  354. // it is necessary to lock the object when it is in-place
  355. // (without this, a link to an embedding may disconnect unexpectedly)
  356. if (!m_bLocked)
  357. {
  358. OleLockRunning(m_lpObject, TRUE, FALSE);
  359. m_bLocked = TRUE;
  360. }
  361. // notify the item of the state change
  362. if (m_nItemState != activeState)
  363. {
  364. OnChange(OLE_CHANGED_STATE, (DWORD)activeState);
  365. m_nItemState = activeState;
  366. }
  367. }
  368. void COleClientItem::OnActivateUI()
  369. {
  370. ASSERT_VALID(this);
  371. // notify the item of the state change
  372. if (m_nItemState != activeUIState)
  373. {
  374. OnChange(OLE_CHANGED_STATE, (DWORD)activeUIState);
  375. m_nItemState = activeUIState;
  376. }
  377. // the container window must have WS_CLIPCHILDREN set
  378. ASSERT_VALID(m_pView);
  379. m_dwContainerStyle = m_pView->GetStyle();
  380. m_pView->ModifyStyle(0, WS_CLIPCHILDREN);
  381. // cache the server's HWND for later
  382. LPOLEINPLACEOBJECT lpInPlaceObject =
  383. QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
  384. ASSERT(lpInPlaceObject != NULL);
  385. // get the HWND for the in-place active object
  386. HWND hWnd;
  387. if (lpInPlaceObject->GetWindow(&hWnd) != S_OK)
  388. hWnd = NULL;
  389. lpInPlaceObject->Release();
  390. m_hWndServer = hWnd;
  391. // make sure top-level frame is hooked
  392. if (m_pInPlaceFrame != NULL)
  393. {
  394. ASSERT_VALID(m_pInPlaceFrame->m_pFrameWnd);
  395. m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook = m_pInPlaceFrame;
  396. }
  397. // make sure doc-level frame is hooked
  398. if (m_pInPlaceDoc != NULL)
  399. {
  400. ASSERT_VALID(m_pInPlaceDoc->m_pFrameWnd);
  401. m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook = m_pInPlaceDoc;
  402. }
  403. }
  404. BOOL COleClientItem::OnShowControlBars(CFrameWnd* pFrameWnd, BOOL bShow)
  405. {
  406. ASSERT_VALID(pFrameWnd);
  407. ASSERT_VALID(this);
  408. // show/hide all bars marked with CBRS_HIDE_INPLACE style
  409. BOOL bResult = FALSE;
  410. if (bShow)
  411. {
  412. POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
  413. while (pos)
  414. {
  415. CControlBar* pBar =
  416. (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
  417. ASSERT_VALID(pBar);
  418. if ((pBar->GetBarStyle() & CBRS_HIDE_INPLACE) &&
  419. (pBar->m_nStateFlags & CControlBar::tempHide))
  420. {
  421. pBar->m_nStateFlags &= ~CControlBar::tempHide;
  422. pFrameWnd->ShowControlBar(pBar, TRUE, TRUE);
  423. bResult = TRUE;
  424. }
  425. }
  426. }
  427. else
  428. {
  429. POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
  430. while (pos)
  431. {
  432. CControlBar* pBar =
  433. (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
  434. ASSERT_VALID(pBar);
  435. if (pBar->IsVisible() && (pBar->GetBarStyle() & CBRS_HIDE_INPLACE))
  436. {
  437. pBar->m_nStateFlags |= CControlBar::tempHide;
  438. pFrameWnd->ShowControlBar(pBar, FALSE, TRUE);
  439. bResult = TRUE;
  440. }
  441. }
  442. }
  443. return bResult;
  444. }
  445. BOOL COleClientItem::OnGetWindowContext(
  446. CFrameWnd** ppMainFrame, CFrameWnd** ppDocFrame,
  447. LPOLEINPLACEFRAMEINFO pFrameInfo)
  448. {
  449. ASSERT(AfxIsValidAddress(ppMainFrame, sizeof(CFrameWnd*)));
  450. ASSERT(AfxIsValidAddress(ppDocFrame, sizeof(CFrameWnd*)));
  451. ASSERT(pFrameInfo == NULL ||
  452. AfxIsValidAddress(pFrameInfo, sizeof(OLEINPLACEFRAMEINFO)));
  453. ASSERT_VALID(this);
  454. ASSERT_VALID(m_pView);
  455. // get main window of application
  456. *ppMainFrame = m_pView->GetTopLevelFrame();
  457. ASSERT_VALID(*ppMainFrame);
  458. ASSERT_KINDOF(CFrameWnd, *ppMainFrame);
  459. // get document window (if there is one)
  460. CFrameWnd* pDocFrame = m_pView->GetParentFrame();
  461. if (pDocFrame != *ppMainFrame)
  462. {
  463. *ppDocFrame = pDocFrame;
  464. ASSERT_VALID(*ppDocFrame);
  465. ASSERT_KINDOF(CFrameWnd, *ppDocFrame);
  466. }
  467. if (pFrameInfo != NULL)
  468. {
  469. // get accelerator table
  470. CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
  471. HACCEL hAccel = pTemplate != NULL ? pTemplate->m_hAccelInPlace : NULL;
  472. pFrameInfo->cAccelEntries =
  473. hAccel != NULL ? CopyAcceleratorTable(hAccel, NULL, 0) : 0;
  474. pFrameInfo->haccel = pFrameInfo->cAccelEntries != 0 ? hAccel : NULL;
  475. pFrameInfo->hwndFrame = (*ppMainFrame)->m_hWnd;
  476. pFrameInfo->fMDIApp = *ppDocFrame != NULL;
  477. }
  478. return TRUE;
  479. }
  480. BOOL COleClientItem::OnScrollBy(CSize sizeExtent)
  481. {
  482. ASSERT_VALID(this);
  483. ASSERT_VALID(m_pView);
  484. // scroll through splitter or view
  485. CSplitterWnd* pSplitter = CView::GetParentSplitter(m_pView, FALSE);
  486. BOOL bResult;
  487. if (pSplitter != NULL)
  488. bResult = pSplitter->DoScrollBy(m_pView, sizeExtent);
  489. else
  490. bResult = m_pView->OnScrollBy(sizeExtent);
  491. return bResult;
  492. }
  493. void COleClientItem::OnDeactivateUI(BOOL /*bUndoable*/)
  494. {
  495. ASSERT_VALID(this);
  496. // notify the item of the state change
  497. if (m_nItemState != activeState)
  498. {
  499. OnChange(OLE_CHANGED_STATE, (DWORD)activeState);
  500. m_nItemState = activeState;
  501. }
  502. if (m_pView != NULL && m_pDocument->GetFirstViewPosition())
  503. {
  504. // restore container window's WS_CLIPCHILDREN bit...
  505. ASSERT_VALID(m_pView);
  506. m_pView->ModifyStyle(WS_CLIPCHILDREN, m_dwContainerStyle & WS_CLIPCHILDREN);
  507. }
  508. // restore original user interface on the frame window
  509. CFrameWnd* pMainFrame;
  510. CFrameWnd* pDocFrame = NULL;
  511. if (OnGetWindowContext(&pMainFrame, &pDocFrame, NULL))
  512. {
  513. ASSERT_VALID(pMainFrame);
  514. pMainFrame->DelayUpdateFrameTitle();
  515. if (pMainFrame->NegotiateBorderSpace(CFrameWnd::borderSet, NULL))
  516. pMainFrame->DelayRecalcLayout();
  517. // restore original user interface on the document window
  518. if (pDocFrame != NULL)
  519. {
  520. pDocFrame->DelayUpdateFrameTitle();
  521. if (pDocFrame->NegotiateBorderSpace(CFrameWnd::borderSet, NULL))
  522. pDocFrame->DelayRecalcLayout();
  523. }
  524. }
  525. // cleanup frame interfaces allocated in GetWindowContext
  526. if (m_pInPlaceFrame != NULL)
  527. {
  528. OnShowControlBars(m_pInPlaceFrame->m_pFrameWnd, TRUE);
  529. // release OLE frame window hooks and allow menu update
  530. ::OleSetMenuDescriptor(NULL, m_pInPlaceFrame->m_pFrameWnd->m_hWnd,
  531. NULL, NULL, NULL);
  532. if (m_pInPlaceDoc != NULL)
  533. {
  534. ::OleSetMenuDescriptor(NULL, m_pInPlaceDoc->m_pFrameWnd->m_hWnd,
  535. NULL, NULL, NULL);
  536. }
  537. m_pInPlaceFrame->m_pFrameWnd->DelayUpdateFrameMenu(NULL);
  538. // unhook from frame window
  539. if (m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook == m_pInPlaceFrame)
  540. m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook = NULL;
  541. // cleanup document interfaces allocated in GetWindowContext
  542. if (m_pInPlaceDoc != NULL)
  543. {
  544. OnShowControlBars(m_pInPlaceDoc->m_pFrameWnd, TRUE);
  545. // unhook from frame window
  546. if (m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook == m_pInPlaceDoc)
  547. m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook = NULL;
  548. }
  549. }
  550. // reset server HWND -- no longer necessary
  551. m_hWndServer = NULL;
  552. CWnd* pWnd = AfxGetMainWnd();
  553. if (pWnd != NULL)
  554. {
  555. // set focus back to the container
  556. pWnd = pWnd->GetTopLevelParent();
  557. ASSERT_VALID(pWnd);
  558. if (::GetActiveWindow() == pWnd->m_hWnd)
  559. pWnd->SetFocus();
  560. }
  561. }
  562. void COleClientItem::OnDeactivate()
  563. {
  564. ASSERT_VALID(this);
  565. // notify the item of the state change
  566. if (m_nItemState != loadedState)
  567. {
  568. OnChange(OLE_CHANGED_STATE, (DWORD)loadedState);
  569. m_nItemState = loadedState;
  570. }
  571. // cleanup frame interfaces allocated in GetWindowContext
  572. if (m_pInPlaceFrame != NULL)
  573. {
  574. // release in place frame
  575. if (m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook == m_pInPlaceFrame)
  576. m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook = NULL;
  577. m_pInPlaceFrame->InternalRelease();
  578. m_pInPlaceFrame = NULL;
  579. // cleanup document interfaces allocated in GetWindowContext
  580. if (m_pInPlaceDoc != NULL)
  581. {
  582. // release in place document
  583. if (m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook == m_pInPlaceDoc)
  584. m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook = NULL;
  585. m_pInPlaceDoc->InternalRelease();
  586. m_pInPlaceDoc = NULL;
  587. }
  588. }
  589. // both frame-level and doc-level interfaces should be cleaned up
  590. ASSERT(m_pInPlaceFrame == NULL);
  591. ASSERT(m_pInPlaceDoc == NULL);
  592. // no longer need the container window
  593. m_pView = NULL;
  594. }
  595. void COleClientItem::OnDiscardUndoState()
  596. {
  597. ASSERT_VALID(this);
  598. // default does nothing
  599. }
  600. void COleClientItem::OnDeactivateAndUndo()
  601. {
  602. ASSERT_VALID(this);
  603. DeactivateUI(); // default is to UI deactivate
  604. }
  605. BOOL COleClientItem::OnChangeItemPosition(const CRect& rectPos)
  606. {
  607. if (!IsInPlaceActive())
  608. return FALSE;
  609. ASSERT_VALID(this);
  610. ASSERT(AfxIsValidAddress(&rectPos, sizeof(CRect), FALSE));
  611. ASSERT_VALID(m_pView);
  612. // determine the visible rect based on intersection between client rect
  613. CRect clipRect;
  614. OnGetClipRect(clipRect);
  615. CRect visRect;
  616. visRect.IntersectRect(clipRect, rectPos);
  617. // advise the server of the new visible rectangle
  618. if (!visRect.IsRectEmpty())
  619. return SetItemRects(&rectPos, &clipRect);
  620. return FALSE;
  621. }
  622. /////////////////////////////////////////////////////////////////////////////
  623. // IOleInPlaceFrame notifications (default implementation)
  624. void COleClientItem::OnInsertMenus(CMenu* pMenuShared,
  625. LPOLEMENUGROUPWIDTHS lpMenuWidths)
  626. {
  627. ASSERT_VALID(this);
  628. ASSERT_VALID(pMenuShared);
  629. ASSERT(AfxIsValidAddress(lpMenuWidths, sizeof(OLEMENUGROUPWIDTHS)));
  630. // initialize the group widths array
  631. lpMenuWidths->width[0] = 0;
  632. lpMenuWidths->width[2] = 0;
  633. lpMenuWidths->width[4] = 0;
  634. // get menu from document template
  635. CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
  636. HMENU hMenuOLE = pTemplate->m_hMenuInPlace;
  637. // only copy the popups if there is a menu loaded
  638. if (hMenuOLE == NULL)
  639. return;
  640. // insert our menu items and adjust group widths array
  641. AfxMergeMenus(pMenuShared->GetSafeHmenu(), hMenuOLE, &lpMenuWidths->width[0], 0);
  642. }
  643. void COleClientItem::OnSetMenu(CMenu* pMenuShared, HOLEMENU holemenu,
  644. HWND hwndActiveObject)
  645. {
  646. ASSERT_VALID(this);
  647. ASSERT(m_pInPlaceFrame != NULL);
  648. ASSERT(m_pInPlaceFrame->m_pFrameWnd != NULL);
  649. // don't set the doc is active
  650. CFrameWnd* pFrameWnd = m_pInPlaceFrame->m_pFrameWnd;
  651. ASSERT_VALID(pFrameWnd);
  652. if (m_pInPlaceDoc != NULL &&
  653. m_pInPlaceDoc->m_pFrameWnd != pFrameWnd->GetActiveFrame())
  654. {
  655. return;
  656. }
  657. // update the menu
  658. pFrameWnd->DelayUpdateFrameMenu(pMenuShared->GetSafeHmenu());
  659. // enable/disable the OLE command routing hook
  660. ::OleSetMenuDescriptor(holemenu, pFrameWnd->m_hWnd,
  661. hwndActiveObject, NULL, NULL);
  662. if (m_pInPlaceDoc != NULL)
  663. {
  664. pFrameWnd = m_pInPlaceDoc->m_pFrameWnd;
  665. ASSERT_VALID(pFrameWnd);
  666. ::OleSetMenuDescriptor(holemenu, pFrameWnd->m_hWnd,
  667. hwndActiveObject, NULL, NULL);
  668. }
  669. }
  670. void COleClientItem::OnRemoveMenus(CMenu* pMenuShared)
  671. {
  672. ASSERT_VALID(this);
  673. ASSERT_VALID(pMenuShared);
  674. // get menu from document template
  675. CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
  676. HMENU hMenuOLE = pTemplate->m_hMenuInPlace;
  677. if (hMenuOLE == NULL)
  678. return;
  679. // remove any menu popups originally added in OnInsertMenus
  680. AfxUnmergeMenus(pMenuShared->GetSafeHmenu(), hMenuOLE);
  681. }
  682. BOOL COleClientItem::OnUpdateFrameTitle()
  683. {
  684. ASSERT_VALID(this);
  685. return FALSE;
  686. }
  687. /////////////////////////////////////////////////////////////////////////////
  688. // In-place Activation operations
  689. void COleClientItem::Deactivate()
  690. {
  691. ASSERT_VALID(this);
  692. ASSERT(m_lpObject != NULL);
  693. ASSERT(IsInPlaceActive());
  694. // get IOleInPlaceObject interface
  695. LPOLEINPLACEOBJECT lpInPlaceObject =
  696. QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
  697. if (lpInPlaceObject == NULL)
  698. {
  699. Close(); // handle rare failure cases by calling Close
  700. return;
  701. }
  702. // call IOleInPlaceObject::InPlaceDeactivate
  703. m_scLast = lpInPlaceObject->InPlaceDeactivate();
  704. lpInPlaceObject->Release();
  705. if (FAILED(m_scLast))
  706. {
  707. Close(); // handle rare failure cases by calling Close
  708. return;
  709. }
  710. m_nItemState = loadedState; // just in case server has crashed
  711. }
  712. void COleClientItem::DeactivateUI()
  713. {
  714. ASSERT_VALID(this);
  715. ASSERT(m_lpObject != NULL);
  716. ASSERT(GetItemState() == activeUIState);
  717. // get IOleInPlaceObject interface
  718. LPOLEINPLACEOBJECT lpInPlaceObject =
  719. QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
  720. if (lpInPlaceObject == NULL)
  721. {
  722. Close(); // handle rare failure cases by calling Close
  723. return;
  724. }
  725. // call IOleInPlaceObject::UIDeactivate
  726. m_scLast = lpInPlaceObject->UIDeactivate();
  727. lpInPlaceObject->Release();
  728. if (FAILED(m_scLast))
  729. {
  730. Close(); // handle rare failure cases by calling Close
  731. return;
  732. }
  733. if (m_nItemState == activeUIState)
  734. m_nItemState = activeState; // just in case server has crashed
  735. }
  736. BOOL COleClientItem::SetItemRects(LPCRECT lpPosRect, LPCRECT lpClipRect)
  737. {
  738. ASSERT_VALID(this);
  739. ASSERT(m_lpObject != NULL);
  740. ASSERT(IsInPlaceActive());
  741. ASSERT(lpPosRect == NULL ||
  742. AfxIsValidAddress(lpPosRect, sizeof(RECT), FALSE));
  743. ASSERT(lpClipRect == NULL ||
  744. AfxIsValidAddress(lpClipRect, sizeof(RECT), FALSE));
  745. // get IOleInPlaceObject interface
  746. LPOLEINPLACEOBJECT lpInPlaceObject =
  747. QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
  748. if (lpInPlaceObject == NULL)
  749. return FALSE; // perhaps server crashed?
  750. // use OnGetPosRect if rectangle not specified
  751. CRect rectPos;
  752. if (lpPosRect == NULL)
  753. {
  754. ASSERT(lpClipRect == NULL);
  755. OnGetItemPosition(rectPos);
  756. lpPosRect = &rectPos;
  757. }
  758. // use OnGetClipRect if clipping rectangle not specified
  759. CRect rectClip;
  760. if (lpClipRect == NULL)
  761. {
  762. OnGetClipRect(rectClip);
  763. lpClipRect = &rectClip;
  764. }
  765. ASSERT(lpPosRect != NULL);
  766. ASSERT(lpClipRect != NULL);
  767. // notify the server of the new item rectangles
  768. m_scLast = lpInPlaceObject->SetObjectRects(lpPosRect, lpClipRect);
  769. lpInPlaceObject->Release();
  770. // remember position rectangle as cached position
  771. return !FAILED(m_scLast);
  772. }
  773. BOOL COleClientItem::ReactivateAndUndo()
  774. {
  775. ASSERT_VALID(this);
  776. ASSERT(m_lpObject != NULL);
  777. ASSERT(IsInPlaceActive());
  778. // get IOleInPlaceObject interface
  779. LPOLEINPLACEOBJECT lpInPlaceObject =
  780. QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
  781. if (lpInPlaceObject == NULL)
  782. {
  783. Close(); // handle rare failure cases by calling Close
  784. return FALSE;
  785. }
  786. // call IOleInPlaceObject::ReactivateAndUndo
  787. m_scLast = lpInPlaceObject->ReactivateAndUndo();
  788. lpInPlaceObject->Release();
  789. if (FAILED(m_scLast))
  790. {
  791. Close(); // handle rare failure cases by calling Close
  792. return FALSE;
  793. }
  794. return TRUE;
  795. }
  796. CWnd* COleClientItem::GetInPlaceWindow()
  797. {
  798. ASSERT_VALID(this);
  799. ASSERT(m_lpObject != NULL);
  800. // only inplace active items should be asking for the window handle
  801. if (GetItemState() != activeUIState)
  802. return NULL;
  803. // handle case of server that just disappears
  804. if (m_hWndServer != NULL && !::IsWindow(m_hWndServer))
  805. {
  806. Close();
  807. return NULL;
  808. }
  809. ASSERT(m_hWndServer == NULL || ::IsWindow(m_hWndServer));
  810. return CWnd::FromHandle(m_hWndServer);
  811. }
  812. /////////////////////////////////////////////////////////////////////////////
  813. // COleFrameHook OLE interface implementation
  814. BEGIN_INTERFACE_MAP(COleFrameHook, CCmdTarget)
  815. INTERFACE_PART(COleFrameHook, IID_IOleWindow, OleInPlaceFrame)
  816. INTERFACE_PART(COleFrameHook, IID_IOleInPlaceUIWindow, OleInPlaceFrame)
  817. INTERFACE_PART(COleFrameHook, IID_IOleInPlaceFrame, OleInPlaceFrame)
  818. #ifndef _AFXDLL
  819. INTERFACE_PART(COleFrameHook, IID_IOleCommandTarget, OleCommandTarget)
  820. #endif
  821. END_INTERFACE_MAP()
  822. /////////////////////////////////////////////////////////////////////////////
  823. // COleFrameHook::XOleCommandTarget implementation
  824. #ifdef _AFXDLL
  825. LPUNKNOWN COleFrameHook::GetInterfaceHook(const void* pIID)
  826. {
  827. ASSERT(m_pModuleState != NULL);
  828. if (m_pModuleState->m_dwVersion >= 0x423 &&
  829. *(IID*)pIID == IID_IOleCommandTarget)
  830. {
  831. return &m_xOleCommandTarget;
  832. }
  833. return NULL;
  834. }
  835. #endif
  836. STDMETHODIMP_(ULONG) COleFrameHook::XOleCommandTarget::AddRef()
  837. {
  838. METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
  839. return pThis->ExternalAddRef();
  840. }
  841. STDMETHODIMP_(ULONG) COleFrameHook::XOleCommandTarget::Release()
  842. {
  843. METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
  844. return pThis->ExternalRelease();
  845. }
  846. STDMETHODIMP COleFrameHook::XOleCommandTarget::QueryInterface(
  847. REFIID iid, LPVOID* ppvObj)
  848. {
  849. METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
  850. return pThis->ExternalQueryInterface(&iid, ppvObj);
  851. }
  852. STDMETHODIMP COleFrameHook::XOleCommandTarget::Exec(
  853. const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
  854. VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
  855. {
  856. HRESULT hResult = OLECMDERR_E_UNKNOWNGROUP;
  857. METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
  858. COleDocObjectItem* pActiveDocObjectItem =
  859. DYNAMIC_DOWNCAST(COleDocObjectItem, pThis->m_pActiveItem);
  860. if (pActiveDocObjectItem != NULL)
  861. {
  862. hResult = _AfxExecOleCommandHelper(pActiveDocObjectItem,
  863. pguidCmdGroup, nCmdID, nCmdExecOpt, pvarargIn, pvarargOut);
  864. }
  865. return hResult;
  866. }
  867. STDMETHODIMP COleFrameHook::XOleCommandTarget::QueryStatus(
  868. const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[],
  869. OLECMDTEXT* pcmdtext)
  870. {
  871. HRESULT hResult = OLECMDERR_E_UNKNOWNGROUP;
  872. METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
  873. COleDocObjectItem* pActiveDocObjectItem =
  874. DYNAMIC_DOWNCAST(COleDocObjectItem, pThis->m_pActiveItem);
  875. if (pActiveDocObjectItem != NULL)
  876. {
  877. hResult = _AfxQueryStatusOleCommandHelper(pActiveDocObjectItem,
  878. pguidCmdGroup, cCmds, rgCmds, pcmdtext);
  879. }
  880. return hResult;
  881. }
  882. /////////////////////////////////////////////////////////////////////////////
  883. // COleFrameHook::XOleInPlaceFrame implementation
  884. STDMETHODIMP_(ULONG) COleFrameHook::XOleInPlaceFrame::AddRef()
  885. {
  886. METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
  887. return pThis->ExternalAddRef();
  888. }
  889. STDMETHODIMP_(ULONG) COleFrameHook::XOleInPlaceFrame::Release()
  890. {
  891. METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
  892. return pThis->ExternalRelease();
  893. }
  894. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::QueryInterface(
  895. REFIID iid, LPVOID* ppvObj)
  896. {
  897. METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
  898. return pThis->ExternalQueryInterface(&iid, ppvObj);
  899. }
  900. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::GetWindow(
  901. HWND* lphwnd)
  902. {
  903. METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
  904. *lphwnd = pThis->m_hWnd;
  905. return *lphwnd != NULL ? S_OK : E_FAIL;
  906. }
  907. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::ContextSensitiveHelp(
  908. BOOL fEnterMode)
  909. {
  910. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  911. ASSERT_VALID(pThis);
  912. // document frame windows should not be put in help mode, so we get the
  913. // top-level frame window and check it first
  914. CFrameWnd* pFrameWnd = pThis->m_pFrameWnd->GetTopLevelFrame();
  915. ASSERT_VALID(pFrameWnd);
  916. if (fEnterMode)
  917. {
  918. if (!pFrameWnd->m_bHelpMode)
  919. {
  920. // check if help mode probable
  921. if (!pFrameWnd->CanEnterHelpMode())
  922. return E_UNEXPECTED;
  923. // attempt to enter context help
  924. if (!pThis->OnContextHelp(TRUE) ||
  925. !pFrameWnd->PostMessage(WM_COMMAND, ID_CONTEXT_HELP))
  926. {
  927. return E_UNEXPECTED;
  928. }
  929. }
  930. }
  931. else
  932. {
  933. // just exit help mode
  934. pFrameWnd->ExitHelpMode();
  935. }
  936. return S_OK;
  937. }
  938. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::GetBorder(LPRECT lpRectBorder)
  939. {
  940. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  941. ASSERT_VALID(pThis);
  942. COleClientItem* pItem = pThis->m_pActiveItem;
  943. ASSERT_VALID(pItem);
  944. CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
  945. ASSERT_VALID(pFrameWnd);
  946. // hide the control bars temporarily
  947. BOOL bHidden = pItem->OnShowControlBars(pFrameWnd, FALSE);
  948. // determine border space assuming that we'll remove our control bars
  949. CRect rectSave = pFrameWnd->m_rectBorder;
  950. pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderSet, NULL);
  951. pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderGet, lpRectBorder);
  952. pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderSet, &rectSave);
  953. // restore control bars
  954. if (bHidden)
  955. pItem->OnShowControlBars(pFrameWnd, TRUE);
  956. return S_OK;
  957. }
  958. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::RequestBorderSpace(
  959. LPCRECT lpRectWidths)
  960. {
  961. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  962. ASSERT_VALID(pThis);
  963. CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
  964. ASSERT_VALID(pFrameWnd);
  965. if (!pFrameWnd->NegotiateBorderSpace(
  966. CFrameWnd::borderRequest, (LPRECT)lpRectWidths))
  967. {
  968. return INPLACE_E_NOTOOLSPACE;
  969. }
  970. return S_OK;
  971. }
  972. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetBorderSpace(
  973. LPCRECT lpRectWidths)
  974. {
  975. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  976. ASSERT_VALID(pThis);
  977. CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
  978. if (pFrameWnd->NegotiateBorderSpace(
  979. CFrameWnd::borderSet, (LPRECT)lpRectWidths))
  980. {
  981. pFrameWnd->DelayRecalcLayout(FALSE);
  982. pFrameWnd->PostMessage(WM_KICKIDLE);
  983. }
  984. pThis->m_pActiveItem->OnShowControlBars(pFrameWnd, lpRectWidths == NULL);
  985. return S_OK;
  986. }
  987. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetActiveObject(
  988. LPOLEINPLACEACTIVEOBJECT lpActiveObject, LPCOLESTR lpszObjName)
  989. {
  990. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  991. ASSERT_VALID(pThis);
  992. SCODE sc = E_UNEXPECTED;
  993. TRY
  994. {
  995. // release the old active object
  996. RELEASE(pThis->m_lpActiveObject);
  997. // set the new active object
  998. pThis->m_lpActiveObject = lpActiveObject;
  999. if (lpActiveObject != NULL)
  1000. lpActiveObject->AddRef();
  1001. // update caption if necessary
  1002. pThis->m_strObjName.Empty();
  1003. if (lpszObjName != NULL && lpActiveObject != NULL)
  1004. {
  1005. pThis->m_strObjName = lpszObjName;
  1006. pThis->m_pActiveItem->OnUpdateFrameTitle();
  1007. }
  1008. sc = S_OK;
  1009. }
  1010. END_TRY
  1011. return sc;
  1012. }
  1013. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::InsertMenus(
  1014. HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
  1015. {
  1016. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  1017. ASSERT_VALID(pThis);
  1018. // get the associated COleClientItem object
  1019. COleClientItem* pItem = pThis->m_pActiveItem;
  1020. ASSERT_VALID(pItem);
  1021. SCODE sc = E_UNEXPECTED;
  1022. TRY
  1023. {
  1024. pItem->OnInsertMenus(CMenu::FromHandle(hmenuShared), lpMenuWidths);
  1025. sc = S_OK;
  1026. }
  1027. END_TRY
  1028. return sc;
  1029. }
  1030. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetMenu(
  1031. HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
  1032. {
  1033. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  1034. ASSERT_VALID(pThis);
  1035. // get the associated COleClientItem object
  1036. COleClientItem* pItem = pThis->m_pActiveItem;
  1037. ASSERT_VALID(pItem);
  1038. SCODE sc = E_UNEXPECTED;
  1039. TRY
  1040. {
  1041. pItem->OnSetMenu(CMenu::FromHandle(hmenuShared), holemenu,
  1042. hwndActiveObject);
  1043. sc = S_OK;
  1044. }
  1045. END_TRY
  1046. return sc;
  1047. }
  1048. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::RemoveMenus(
  1049. HMENU hmenuShared)
  1050. {
  1051. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  1052. ASSERT_VALID(pThis);
  1053. // get the associated COleClientItem object
  1054. COleClientItem* pItem = pThis->m_pActiveItem;
  1055. ASSERT_VALID(pItem);
  1056. SCODE sc = E_UNEXPECTED;
  1057. TRY
  1058. {
  1059. pItem->OnRemoveMenus(CMenu::FromHandle(hmenuShared));
  1060. sc = S_OK;
  1061. }
  1062. END_TRY
  1063. return sc;
  1064. }
  1065. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetStatusText(
  1066. LPCOLESTR lpszStatusText)
  1067. {
  1068. METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
  1069. USES_CONVERSION;
  1070. pThis->m_pFrameWnd->SendMessage(WM_SETMESSAGESTRING, 0,
  1071. (LPARAM)OLE2CT(lpszStatusText));
  1072. return S_OK;
  1073. }
  1074. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::EnableModeless(BOOL fEnable)
  1075. {
  1076. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  1077. ASSERT_VALID(pThis);
  1078. ASSERT_VALID(pThis->m_pFrameWnd);
  1079. SCODE sc = E_UNEXPECTED;
  1080. TRY
  1081. {
  1082. if (!fEnable)
  1083. pThis->m_pFrameWnd->BeginModalState();
  1084. else
  1085. pThis->m_pFrameWnd->EndModalState();
  1086. sc = S_OK;
  1087. }
  1088. END_TRY
  1089. return sc;
  1090. }
  1091. STDMETHODIMP COleFrameHook::XOleInPlaceFrame::TranslateAccelerator(
  1092. LPMSG lpmsg, WORD /*wID*/)
  1093. {
  1094. METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
  1095. ASSERT_VALID(pThis);
  1096. SCODE sc = E_UNEXPECTED;
  1097. TRY
  1098. {
  1099. // swap accel tables and call PreTranslateMessage
  1100. CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
  1101. HACCEL hAccelSave = pFrameWnd->m_hAccelTable;
  1102. pFrameWnd->m_hAccelTable = pThis->m_hAccelTable;
  1103. ASSERT(lpmsg != NULL);
  1104. MSG msg = *lpmsg;
  1105. sc = pFrameWnd->PreTranslateMessage(&msg) ? S_OK : S_FALSE;
  1106. *lpmsg = msg;
  1107. pFrameWnd->m_hAccelTable = hAccelSave;
  1108. }
  1109. END_TRY
  1110. return sc;
  1111. }
  1112. /////////////////////////////////////////////////////////////////////////////
  1113. // COleClientItem::XOleIPSite implementation
  1114. STDMETHODIMP_(ULONG) COleClientItem::XOleIPSite::AddRef()
  1115. {
  1116. METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
  1117. return pThis->ExternalAddRef();
  1118. }
  1119. STDMETHODIMP_(ULONG) COleClientItem::XOleIPSite::Release()
  1120. {
  1121. METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
  1122. return pThis->ExternalRelease();
  1123. }
  1124. STDMETHODIMP COleClientItem::XOleIPSite::QueryInterface(
  1125. REFIID iid, LPVOID* ppvObj)
  1126. {
  1127. METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
  1128. return pThis->ExternalQueryInterface(&iid, ppvObj);
  1129. }
  1130. STDMETHODIMP COleClientItem::XOleIPSite::GetWindow(HWND* lphwnd)
  1131. {
  1132. METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
  1133. *lphwnd = pThis->m_pView->GetSafeHwnd();
  1134. return *lphwnd != NULL ? S_OK : E_FAIL;
  1135. }
  1136. STDMETHODIMP COleClientItem::XOleIPSite::ContextSensitiveHelp(
  1137. BOOL fEnterMode)
  1138. {
  1139. METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
  1140. if (pThis->m_pInPlaceFrame == NULL)
  1141. return E_UNEXPECTED;
  1142. // simply delegate to frame window implementation
  1143. return pThis->m_pInPlaceFrame->
  1144. m_xOleInPlaceFrame.ContextSensitiveHelp(fEnterMode);
  1145. }
  1146. STDMETHODIMP COleClientItem::XOleIPSite::CanInPlaceActivate()
  1147. {
  1148. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1149. return pThis->CanActivate() ? S_OK : S_FALSE;
  1150. }
  1151. STDMETHODIMP COleClientItem::XOleIPSite::OnInPlaceActivate()
  1152. {
  1153. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1154. ASSERT_VALID(pThis);
  1155. SCODE sc = E_UNEXPECTED;
  1156. TRY
  1157. {
  1158. pThis->OnActivate();
  1159. sc = S_OK;
  1160. }
  1161. END_TRY
  1162. return sc;
  1163. }
  1164. STDMETHODIMP COleClientItem::XOleIPSite::OnUIActivate()
  1165. {
  1166. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1167. ASSERT_VALID(pThis);
  1168. SCODE sc = E_UNEXPECTED;
  1169. TRY
  1170. {
  1171. pThis->OnActivateUI();
  1172. sc = S_OK;
  1173. }
  1174. END_TRY
  1175. return sc;
  1176. }
  1177. STDMETHODIMP COleClientItem::XOleIPSite::GetWindowContext(
  1178. LPOLEINPLACEFRAME* lplpFrame,
  1179. LPOLEINPLACEUIWINDOW* lplpDoc,
  1180. LPRECT lpPosRect, LPRECT lpClipRect,
  1181. LPOLEINPLACEFRAMEINFO lpFrameInfo)
  1182. {
  1183. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1184. ASSERT_VALID(pThis);
  1185. *lplpFrame = NULL; // init these in-case of mem-alloc failure
  1186. *lplpDoc = NULL;
  1187. CFrameWnd* pMainFrame = NULL;
  1188. CFrameWnd* pDocFrame = NULL;
  1189. SCODE sc = E_UNEXPECTED;
  1190. TRY
  1191. {
  1192. // get position of the item relative to activation view
  1193. CRect rect;
  1194. pThis->OnGetItemPosition(rect);
  1195. ::CopyRect(lpPosRect, &rect);
  1196. pThis->OnGetClipRect(rect);
  1197. ::CopyRect(lpClipRect, &rect);
  1198. // get the window context information
  1199. if (pThis->OnGetWindowContext(&pMainFrame, &pDocFrame, lpFrameInfo))
  1200. {
  1201. // hook IOleInPlaceFrame interface to pMainFrame
  1202. if (pThis->m_pInPlaceFrame == NULL)
  1203. pThis->m_pInPlaceFrame = new COleFrameHook(pMainFrame, pThis);
  1204. pThis->m_pInPlaceFrame->InternalAddRef();
  1205. *lplpFrame = (LPOLEINPLACEFRAME)pThis->m_pInPlaceFrame->
  1206. GetInterface(&IID_IOleInPlaceFrame);
  1207. // save accel table for IOleInPlaceFrame::TranslateAccelerators
  1208. pThis->m_pInPlaceFrame->m_hAccelTable = lpFrameInfo->haccel;
  1209. // hook IOleInPlaceUIWindow to pDocFrame
  1210. if (pDocFrame != NULL)
  1211. {
  1212. if (pThis->m_pInPlaceDoc == NULL)
  1213. pThis->m_pInPlaceDoc = new COleFrameHook(pDocFrame, pThis);
  1214. pThis->m_pInPlaceDoc->InternalAddRef();
  1215. *lplpDoc = (LPOLEINPLACEUIWINDOW)pThis->m_pInPlaceDoc->
  1216. GetInterface(&IID_IOleInPlaceUIWindow);
  1217. }
  1218. sc = S_OK;
  1219. }
  1220. }
  1221. CATCH_ALL(e)
  1222. {
  1223. // cleanup memory that may be partially allocated
  1224. delete *lplpFrame;
  1225. ASSERT(*lplpDoc == NULL);
  1226. DELETE_EXCEPTION(e);
  1227. }
  1228. END_CATCH_ALL
  1229. return sc;
  1230. }
  1231. STDMETHODIMP COleClientItem::XOleIPSite::Scroll(SIZE scrollExtent)
  1232. {
  1233. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1234. ASSERT_VALID(pThis);
  1235. SCODE sc = E_UNEXPECTED;
  1236. TRY
  1237. {
  1238. if (!pThis->OnScrollBy(CSize(scrollExtent)))
  1239. sc = S_FALSE;
  1240. else
  1241. sc = S_OK;
  1242. }
  1243. END_TRY
  1244. return sc;
  1245. }
  1246. STDMETHODIMP COleClientItem::XOleIPSite::OnUIDeactivate(BOOL fUndoable)
  1247. {
  1248. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1249. ASSERT_VALID(pThis);
  1250. SCODE sc = E_UNEXPECTED;
  1251. TRY
  1252. {
  1253. pThis->OnDeactivateUI(fUndoable);
  1254. sc = S_OK;
  1255. }
  1256. END_TRY
  1257. return sc;
  1258. }
  1259. STDMETHODIMP COleClientItem::XOleIPSite::OnInPlaceDeactivate()
  1260. {
  1261. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1262. ASSERT_VALID(pThis);
  1263. SCODE sc = E_UNEXPECTED;
  1264. TRY
  1265. {
  1266. pThis->OnDeactivate();
  1267. sc = S_OK;
  1268. }
  1269. END_TRY
  1270. return sc;
  1271. }
  1272. STDMETHODIMP COleClientItem::XOleIPSite::DiscardUndoState()
  1273. {
  1274. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1275. ASSERT_VALID(pThis);
  1276. SCODE sc = E_UNEXPECTED;
  1277. TRY
  1278. {
  1279. pThis->OnDiscardUndoState();
  1280. sc = S_OK;
  1281. }
  1282. END_TRY
  1283. return sc;
  1284. }
  1285. STDMETHODIMP COleClientItem::XOleIPSite::DeactivateAndUndo()
  1286. {
  1287. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1288. ASSERT_VALID(pThis);
  1289. SCODE sc = E_UNEXPECTED;
  1290. TRY
  1291. {
  1292. pThis->OnDeactivateAndUndo();
  1293. sc = S_OK;
  1294. }
  1295. END_TRY
  1296. return sc;
  1297. }
  1298. STDMETHODIMP COleClientItem::XOleIPSite::OnPosRectChange(
  1299. LPCRECT lpPosRect)
  1300. {
  1301. METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
  1302. ASSERT_VALID(pThis);
  1303. SCODE sc = E_UNEXPECTED;
  1304. TRY
  1305. {
  1306. CRect rect;
  1307. rect.CopyRect(lpPosRect);
  1308. pThis->OnChangeItemPosition(rect);
  1309. sc = S_OK;
  1310. }
  1311. END_TRY
  1312. return sc;
  1313. }
  1314. /////////////////////////////////////////////////////////////////////////////