1
0

occcont.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  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. #include "occimpl.h"
  12. #ifdef AFX_OCC_SEG
  13. #pragma code_seg(AFX_OCC_SEG)
  14. #endif
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. #define new DEBUG_NEW
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CWnd support for OLE Control containment
  22. BOOL CWnd::CreateControl(LPCTSTR lpszClass, LPCTSTR lpszWindowName,
  23. DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
  24. CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
  25. {
  26. ASSERT(lpszClass != NULL);
  27. CLSID clsid;
  28. HRESULT hr = AfxGetClassIDFromString(lpszClass, &clsid);
  29. if (FAILED(hr))
  30. return FALSE;
  31. return CreateControl(clsid, lpszWindowName, dwStyle, rect, pParentWnd, nID,
  32. pPersist, bStorage, bstrLicKey);
  33. }
  34. BOOL CWnd::CreateControl( REFCLSID clsid, LPCTSTR lpszWindowName,
  35. DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
  36. CFile* pPersist, BOOL bStorage, BSTR bstrLicKey )
  37. {
  38. CRect rect2( rect );
  39. CPoint pt;
  40. CSize size;
  41. pt = rect2.TopLeft();
  42. size = rect2.Size();
  43. return( CreateControl( clsid, lpszWindowName, dwStyle, &pt, &size,
  44. pParentWnd, nID, pPersist, bStorage, bstrLicKey ) );
  45. }
  46. BOOL CWnd::CreateControl(REFCLSID clsid, LPCTSTR lpszWindowName, DWORD dwStyle,
  47. const POINT* ppt, const SIZE* psize, CWnd* pParentWnd, UINT nID,
  48. CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
  49. {
  50. ASSERT(pParentWnd != NULL);
  51. #ifdef _DEBUG
  52. if (afxOccManager == NULL)
  53. {
  54. TRACE0("Warning: AfxEnableControlContainer has not been called yet.\n");
  55. TRACE0(">>> You should call it in your app's InitInstance function.\n");
  56. }
  57. #endif
  58. if ((pParentWnd == NULL) || !pParentWnd->InitControlContainer())
  59. return FALSE;
  60. return pParentWnd->m_pCtrlCont->CreateControl(this, clsid, lpszWindowName,
  61. dwStyle, ppt, psize, nID, pPersist, bStorage, bstrLicKey);
  62. }
  63. BOOL CWnd::InitControlContainer()
  64. {
  65. TRY
  66. {
  67. if (m_pCtrlCont == NULL)
  68. m_pCtrlCont = afxOccManager->CreateContainer(this);
  69. }
  70. END_TRY
  71. // Mark all ancestor windows as containing OLE controls.
  72. if (m_pCtrlCont != NULL)
  73. {
  74. CWnd* pWnd = this;
  75. while ((pWnd != NULL) && !(pWnd->m_nFlags & WF_OLECTLCONTAINER))
  76. {
  77. pWnd->m_nFlags |= WF_OLECTLCONTAINER;
  78. pWnd = pWnd->GetParent();
  79. if (! (GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE) & WS_CHILD))
  80. break;
  81. }
  82. }
  83. return (m_pCtrlCont != NULL);
  84. }
  85. /////////////////////////////////////////////////////////////////////////////
  86. // COleControlContainer
  87. BEGIN_INTERFACE_MAP(COleControlContainer, CCmdTarget)
  88. INTERFACE_PART(COleControlContainer, IID_IOleInPlaceFrame, OleIPFrame)
  89. INTERFACE_PART(COleControlContainer, IID_IOleContainer, OleContainer)
  90. END_INTERFACE_MAP()
  91. BEGIN_DISPATCH_MAP(COleControlContainer, CCmdTarget)
  92. END_DISPATCH_MAP()
  93. COleControlContainer::COleControlContainer(CWnd* pWnd) :
  94. m_pWnd(pWnd),
  95. m_crBack((COLORREF)-1),
  96. m_crFore((COLORREF)-1),
  97. m_pOleFont(NULL),
  98. m_pSiteUIActive(NULL)
  99. {
  100. }
  101. COleControlContainer::~COleControlContainer()
  102. {
  103. HWND hWnd;
  104. COleControlSite* pSite;
  105. POSITION pos = m_siteMap.GetStartPosition();
  106. while (pos != NULL)
  107. {
  108. m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  109. if (!(pSite->m_pDataSourceControl))
  110. {
  111. m_siteMap.RemoveKey((void*&)hWnd);
  112. delete pSite;
  113. }
  114. }
  115. pos = m_siteMap.GetStartPosition();
  116. while (pos != NULL)
  117. {
  118. m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  119. delete pSite;
  120. }
  121. m_siteMap.RemoveAll();
  122. RELEASE(m_pOleFont);
  123. }
  124. BOOL COleControlContainer::CreateControl( CWnd* pWndCtrl, REFCLSID clsid,
  125. LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, UINT nID,
  126. CFile* pPersist, BOOL bStorage, BSTR bstrLicKey,
  127. COleControlSite** ppNewSite )
  128. {
  129. CRect rect2( rect );
  130. CPoint pt;
  131. CSize size;
  132. pt = rect2.TopLeft();
  133. size = rect2.Size();
  134. return( CreateControl( pWndCtrl, clsid, lpszWindowName, dwStyle, &pt, &size,
  135. nID, pPersist, bStorage, bstrLicKey, ppNewSite ) );
  136. }
  137. BOOL COleControlContainer::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
  138. LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
  139. UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey,
  140. COleControlSite** ppNewSite)
  141. {
  142. COleControlSite* pSite = NULL;
  143. TRY
  144. {
  145. pSite = afxOccManager->CreateSite(this);
  146. }
  147. END_TRY
  148. if (pSite == NULL)
  149. return FALSE;
  150. BOOL bCreated = SUCCEEDED( pSite->CreateControl(pWndCtrl, clsid,
  151. lpszWindowName, dwStyle, ppt, psize, nID, pPersist, bStorage,
  152. bstrLicKey ) );
  153. if (bCreated)
  154. {
  155. ASSERT(pSite->m_hWnd != NULL);
  156. m_siteMap.SetAt(pSite->m_hWnd, pSite);
  157. if (ppNewSite != NULL)
  158. *ppNewSite = pSite;
  159. }
  160. else
  161. {
  162. delete pSite;
  163. }
  164. return bCreated;
  165. }
  166. COleControlSite* COleControlContainer::FindItem(UINT nID) const
  167. {
  168. POSITION pos = m_siteMap.GetStartPosition();
  169. while (pos != NULL)
  170. {
  171. HWND hWnd;
  172. COleControlSite* pSite;
  173. m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  174. if (pSite->GetID() == nID)
  175. return pSite;
  176. }
  177. return NULL;
  178. }
  179. BOOL COleControlContainer::GetAmbientProp(COleControlSite* pSite, DISPID dispid,
  180. VARIANT* pvarResult)
  181. {
  182. switch (dispid)
  183. {
  184. case DISPID_AMBIENT_AUTOCLIP:
  185. case DISPID_AMBIENT_MESSAGEREFLECT:
  186. case DISPID_AMBIENT_SUPPORTSMNEMONICS:
  187. case DISPID_AMBIENT_USERMODE:
  188. V_VT(pvarResult) = VT_BOOL;
  189. V_BOOL(pvarResult) = (VARIANT_BOOL)-1;
  190. return TRUE;
  191. case DISPID_AMBIENT_SHOWGRABHANDLES:
  192. case DISPID_AMBIENT_SHOWHATCHING:
  193. case DISPID_AMBIENT_UIDEAD:
  194. V_VT(pvarResult) = VT_BOOL;
  195. V_BOOL(pvarResult) = 0;
  196. return TRUE;
  197. case DISPID_AMBIENT_APPEARANCE: // ambient appearance is 3D
  198. V_VT(pvarResult) = VT_I2;
  199. #ifndef _AFX_NO_CTL3D_SUPPORT
  200. if (afxData.bWin4 || AfxGetCtl3dState()->m_pfnSubclassDlgEx != NULL)
  201. #else
  202. if (afxData.bWin4)
  203. #endif
  204. V_I2(pvarResult) = 1;
  205. else
  206. V_I2(pvarResult) = 0;
  207. return TRUE;
  208. case DISPID_AMBIENT_BACKCOLOR:
  209. case DISPID_AMBIENT_FORECOLOR:
  210. if (m_crBack == (COLORREF)-1) // ambient colors not initialized
  211. {
  212. CWindowDC dc(m_pWnd);
  213. m_pWnd->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC,
  214. (LPARAM)m_pWnd->m_hWnd);
  215. m_crBack = dc.GetBkColor();
  216. m_crFore = dc.GetTextColor();
  217. }
  218. V_VT(pvarResult) = VT_COLOR;
  219. V_I4(pvarResult) = (dispid == DISPID_AMBIENT_BACKCOLOR) ?
  220. m_crBack : m_crFore;
  221. return TRUE;
  222. case DISPID_AMBIENT_FONT:
  223. if (m_pOleFont == NULL) // ambient font not initialized
  224. CreateOleFont(m_pWnd->GetFont());
  225. ASSERT(m_pOleFont != NULL);
  226. if (m_pOleFont == NULL) // failed to create font
  227. return FALSE;
  228. V_VT(pvarResult) = VT_FONT;
  229. m_pOleFont->AddRef();
  230. V_DISPATCH(pvarResult) = m_pOleFont;
  231. return TRUE;
  232. case DISPID_AMBIENT_DISPLAYASDEFAULT:
  233. V_VT(pvarResult) = VT_BOOL;
  234. V_BOOL(pvarResult) = (VARIANT_BOOL)(pSite->IsDefaultButton() ? -1 : 0);
  235. return TRUE;
  236. case DISPID_AMBIENT_LOCALEID:
  237. V_VT(pvarResult) = VT_I4;
  238. V_I4(pvarResult) = GetThreadLocale();
  239. return TRUE;
  240. case DISPID_AMBIENT_DISPLAYNAME:
  241. {
  242. CString str; // return blank string
  243. V_VT(pvarResult) = VT_BSTR;
  244. V_BSTR(pvarResult) = str.AllocSysString();
  245. }
  246. return TRUE;
  247. case DISPID_AMBIENT_SCALEUNITS:
  248. {
  249. CString str;
  250. str.LoadString(AFX_IDS_OCC_SCALEUNITS_PIXELS);
  251. V_VT(pvarResult) = VT_BSTR;
  252. V_BSTR(pvarResult) = str.AllocSysString();
  253. }
  254. return TRUE;
  255. }
  256. return FALSE;
  257. }
  258. void COleControlContainer::CreateOleFont(CFont* pFont)
  259. {
  260. USES_CONVERSION;
  261. CFont fontSys;
  262. if ((pFont == NULL) || (pFont->m_hObject == NULL))
  263. {
  264. // no font was provided, so use the system font
  265. if (fontSys.CreateStockObject(DEFAULT_GUI_FONT) ||
  266. fontSys.CreateStockObject(SYSTEM_FONT))
  267. {
  268. pFont = &fontSys;
  269. }
  270. else
  271. {
  272. m_pOleFont = NULL;
  273. return;
  274. }
  275. }
  276. LOGFONT logfont;
  277. pFont->GetLogFont(&logfont);
  278. FONTDESC fd;
  279. fd.cbSizeofstruct = sizeof(FONTDESC);
  280. fd.lpstrName = T2OLE(logfont.lfFaceName);
  281. fd.sWeight = (short)logfont.lfWeight;
  282. fd.sCharset = logfont.lfCharSet;
  283. fd.fItalic = logfont.lfItalic;
  284. fd.fUnderline = logfont.lfUnderline;
  285. fd.fStrikethrough = logfont.lfStrikeOut;
  286. long lfHeight = logfont.lfHeight;
  287. if (lfHeight < 0)
  288. lfHeight = -lfHeight;
  289. CWindowDC dc(m_pWnd);
  290. int ppi = dc.GetDeviceCaps(LOGPIXELSY);
  291. fd.cySize.Lo = lfHeight * 720000 / ppi;
  292. fd.cySize.Hi = 0;
  293. RELEASE(m_pOleFont);
  294. if (FAILED(::OleCreateFontIndirect(&fd, IID_IFontDisp, (void**)&m_pOleFont)))
  295. m_pOleFont = NULL;
  296. }
  297. void COleControlContainer::FreezeAllEvents(BOOL bFreeze)
  298. {
  299. HWND hWnd;
  300. COleControlSite* pSite;
  301. POSITION pos = m_siteMap.GetStartPosition();
  302. while (pos != NULL)
  303. {
  304. m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  305. pSite->FreezeEvents(bFreeze);
  306. }
  307. }
  308. void COleControlContainer::ScrollChildren(int dx, int dy)
  309. {
  310. HWND hWnd;
  311. COleControlSite* pSite;
  312. POSITION pos = m_siteMap.GetStartPosition();
  313. while (pos != NULL)
  314. {
  315. m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  316. ASSERT(pSite->m_pInPlaceObject != NULL);
  317. ASSERT(pSite->m_pObject != NULL);
  318. pSite->m_rect.OffsetRect(dx, dy);
  319. pSite->m_pInPlaceObject->SetObjectRects(pSite->m_rect, pSite->m_rect);
  320. }
  321. }
  322. void COleControlContainer::OnUIActivate(COleControlSite* pSite)
  323. {
  324. if (m_pSiteUIActive != NULL)
  325. m_pSiteUIActive->m_pInPlaceObject->UIDeactivate();
  326. ASSERT(m_pSiteUIActive == NULL); // did control call OnUIDeactivate?
  327. m_pSiteUIActive = pSite;
  328. }
  329. void COleControlContainer::OnUIDeactivate(COleControlSite* pSite)
  330. {
  331. UNUSED(pSite);
  332. if (m_pSiteUIActive == pSite)
  333. m_pSiteUIActive = NULL;
  334. }
  335. /////////////////////////////////////////////////////////////////////////////
  336. // special cases for CWnd functions
  337. void COleControlContainer::CheckDlgButton(int nIDButton, UINT nCheck)
  338. {
  339. CWnd* pWnd = GetDlgItem(nIDButton);
  340. if (pWnd == NULL)
  341. return;
  342. if (pWnd->m_pCtrlSite == NULL)
  343. {
  344. pWnd->SendMessage(BM_SETCHECK, nCheck, 0);
  345. return;
  346. }
  347. pWnd->m_pCtrlSite->SafeSetProperty(DISPID_VALUE, VT_I4, (DWORD)nCheck);
  348. }
  349. void COleControlContainer::CheckRadioButton(int nIDFirstButton, int nIDLastButton,
  350. int nIDCheckButton)
  351. {
  352. ASSERT(nIDFirstButton <= nIDCheckButton);
  353. ASSERT(nIDCheckButton <= nIDLastButton);
  354. // the following code is for OLE control containers only
  355. for (int nID = nIDFirstButton; nID <= nIDLastButton; nID++)
  356. CheckDlgButton(nID, (nID == nIDCheckButton));
  357. }
  358. CWnd* COleControlContainer::GetDlgItem(int nID) const
  359. {
  360. HWND hWnd;
  361. GetDlgItem(nID, &hWnd);
  362. return CWnd::FromHandle(hWnd);
  363. }
  364. void COleControlContainer::GetDlgItem(int nID, HWND* phWnd) const
  365. {
  366. // first, look for a non-OLE control
  367. HWND hWnd = ::GetDlgItem(m_pWnd->GetSafeHwnd(), nID);
  368. if (hWnd == NULL)
  369. {
  370. // now, look for an OLE control
  371. COleControlSite* pSite = FindItem(nID);
  372. if (pSite != NULL)
  373. hWnd = pSite->m_hWnd;
  374. }
  375. *phWnd = hWnd;
  376. }
  377. UINT COleControlContainer::GetDlgItemInt(int nID, BOOL* lpTrans, BOOL bSigned) const
  378. {
  379. TCHAR szText[256];
  380. if (GetDlgItemText(nID, szText, 256) == 0)
  381. {
  382. if (lpTrans != NULL)
  383. *lpTrans = FALSE;
  384. return 0;
  385. }
  386. // Quick check for valid number
  387. LPTSTR pch = szText;
  388. while (_istspace(*pch))
  389. pch = CharNext(pch); // skip whitespace
  390. if ((*pch) == '+' || (*pch) == '-')
  391. pch = CharNext(pch); // skip sign
  392. BOOL bTrans = _istdigit(*pch); // did we find a digit?
  393. if (lpTrans != NULL)
  394. *lpTrans = bTrans;
  395. if (!bTrans)
  396. return 0;
  397. if (bSigned)
  398. return _tcstol(szText, NULL, 10);
  399. else
  400. return _tcstoul(szText, NULL, 10);
  401. }
  402. int COleControlContainer::GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
  403. {
  404. CWnd* pWnd = GetDlgItem(nID);
  405. if (pWnd == NULL)
  406. return 0;
  407. return pWnd->GetWindowText(lpStr, nMaxCount);
  408. }
  409. LRESULT COleControlContainer::SendDlgItemMessage(int nID, UINT message, WPARAM wParam,
  410. LPARAM lParam)
  411. {
  412. CWnd* pWnd = GetDlgItem(nID);
  413. if (pWnd == NULL)
  414. return 0;
  415. return pWnd->SendMessage(message, wParam, lParam);
  416. }
  417. void COleControlContainer::SetDlgItemInt(int nID, UINT nValue, BOOL bSigned)
  418. {
  419. TCHAR szText[34];
  420. if (bSigned)
  421. _ltot((long)nValue, szText, 10);
  422. else
  423. _ultot((unsigned long)nValue, szText, 10);
  424. SetDlgItemText(nID, szText);
  425. }
  426. void COleControlContainer::SetDlgItemText(int nID, LPCTSTR lpszString)
  427. {
  428. CWnd* pWnd = GetDlgItem(nID);
  429. if (pWnd == NULL)
  430. return;
  431. pWnd->SetWindowText(lpszString);
  432. }
  433. UINT COleControlContainer::IsDlgButtonChecked(int nIDButton) const
  434. {
  435. CWnd* pWnd = GetDlgItem(nIDButton);
  436. if (pWnd == NULL)
  437. return 0;
  438. if (pWnd->m_pCtrlSite == NULL)
  439. return pWnd->SendMessage(BM_GETCHECK, 0, 0);
  440. DWORD dwValue;
  441. TRY
  442. {
  443. pWnd->GetProperty(DISPID_VALUE, VT_I4, &dwValue);
  444. }
  445. CATCH_ALL(e)
  446. {
  447. DELETE_EXCEPTION(e);
  448. dwValue = 0;
  449. }
  450. END_CATCH_ALL
  451. if (dwValue == 0x0000ffff) // VARIANT_BOOL TRUE
  452. dwValue = 1;
  453. return dwValue;
  454. }
  455. /////////////////////////////////////////////////////////////////////////////
  456. // COleControlContainer::XOleIPFrame
  457. STDMETHODIMP COleControlContainer::XOleIPFrame::QueryInterface(
  458. REFIID iid, LPVOID* ppvObj)
  459. {
  460. METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  461. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  462. }
  463. STDMETHODIMP_(ULONG) COleControlContainer::XOleIPFrame::AddRef()
  464. {
  465. METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  466. return (ULONG)pThis->InternalAddRef();
  467. }
  468. STDMETHODIMP_(ULONG) COleControlContainer::XOleIPFrame::Release()
  469. {
  470. METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  471. return (ULONG)pThis->InternalRelease();
  472. }
  473. STDMETHODIMP COleControlContainer::XOleIPFrame::GetWindow(HWND* phWnd)
  474. {
  475. METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  476. *phWnd = pThis->m_pWnd->m_hWnd;
  477. return S_OK;
  478. }
  479. STDMETHODIMP COleControlContainer::XOleIPFrame::ContextSensitiveHelp(BOOL)
  480. {
  481. return E_NOTIMPL;
  482. }
  483. STDMETHODIMP COleControlContainer::XOleIPFrame::GetBorder(LPRECT)
  484. {
  485. return E_NOTIMPL;
  486. }
  487. STDMETHODIMP COleControlContainer::XOleIPFrame::RequestBorderSpace(
  488. LPCBORDERWIDTHS)
  489. {
  490. return E_NOTIMPL;
  491. }
  492. STDMETHODIMP COleControlContainer::XOleIPFrame::SetBorderSpace(
  493. LPCBORDERWIDTHS)
  494. {
  495. return E_NOTIMPL;
  496. }
  497. STDMETHODIMP COleControlContainer::XOleIPFrame::SetActiveObject(
  498. LPOLEINPLACEACTIVEOBJECT pActiveObject, LPCOLESTR)
  499. {
  500. METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  501. if (pThis->m_pSiteUIActive != NULL)
  502. {
  503. LPOLEINPLACEACTIVEOBJECT pOldActiveObject = pThis->m_pSiteUIActive->m_pActiveObject;
  504. if (pActiveObject != NULL)
  505. pActiveObject->AddRef();
  506. pThis->m_pSiteUIActive->m_pActiveObject = pActiveObject;
  507. if (pOldActiveObject != NULL)
  508. pOldActiveObject->Release();
  509. }
  510. return S_OK;
  511. }
  512. STDMETHODIMP COleControlContainer::XOleIPFrame::InsertMenus(HMENU,
  513. LPOLEMENUGROUPWIDTHS)
  514. {
  515. return E_NOTIMPL;
  516. }
  517. STDMETHODIMP COleControlContainer::XOleIPFrame::SetMenu(HMENU, HOLEMENU, HWND)
  518. {
  519. return E_NOTIMPL;
  520. }
  521. STDMETHODIMP COleControlContainer::XOleIPFrame::RemoveMenus(HMENU)
  522. {
  523. return E_NOTIMPL;
  524. }
  525. STDMETHODIMP COleControlContainer::XOleIPFrame::SetStatusText(LPCOLESTR)
  526. {
  527. return E_NOTIMPL;
  528. }
  529. STDMETHODIMP COleControlContainer::XOleIPFrame::EnableModeless(BOOL)
  530. {
  531. // As long as we don't create any modeless dialogs, we can just return S_OK.
  532. return S_OK;
  533. }
  534. STDMETHODIMP COleControlContainer::XOleIPFrame::TranslateAccelerator(LPMSG,
  535. WORD)
  536. {
  537. return E_NOTIMPL;
  538. }
  539. /////////////////////////////////////////////////////////////////////////////
  540. // CEnumUnknown - enumerator for IUnknown pointers
  541. class CEnumUnknown : public CEnumArray
  542. {
  543. public:
  544. CEnumUnknown(const void* pvEnum, UINT nSize) :
  545. CEnumArray(sizeof(LPUNKNOWN), pvEnum, nSize, TRUE) {}
  546. ~CEnumUnknown();
  547. protected:
  548. virtual BOOL OnNext(void* pv);
  549. DECLARE_INTERFACE_MAP()
  550. };
  551. BEGIN_INTERFACE_MAP(CEnumUnknown, CEnumArray)
  552. INTERFACE_PART(CEnumUnknown, IID_IEnumUnknown, EnumVOID)
  553. END_INTERFACE_MAP()
  554. CEnumUnknown::~CEnumUnknown()
  555. {
  556. if (m_pClonedFrom == NULL)
  557. {
  558. LPUNKNOWN* ppUnk = (LPUNKNOWN*)(void*)m_pvEnum;
  559. for (UINT i = 0; i < m_nSize; i++)
  560. {
  561. ASSERT(ppUnk[i] != NULL);
  562. ppUnk[i]->Release();
  563. }
  564. }
  565. // destructor will free the actual array (if it was not a clone)
  566. }
  567. BOOL CEnumUnknown::OnNext(void* pv)
  568. {
  569. if (!CEnumArray::OnNext(pv))
  570. return FALSE;
  571. // AddRef the pointer (the caller has responsibility to Release it)
  572. ASSERT(*(LPUNKNOWN*)pv != NULL);
  573. (*(LPUNKNOWN*)pv)->AddRef();
  574. return TRUE;
  575. }
  576. /////////////////////////////////////////////////////////////////////////////
  577. // COleControlContainer::XOleContainer
  578. STDMETHODIMP COleControlContainer::XOleContainer::QueryInterface(
  579. REFIID iid, LPVOID* ppvObj)
  580. {
  581. METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  582. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  583. }
  584. STDMETHODIMP_(ULONG) COleControlContainer::XOleContainer::Release()
  585. {
  586. METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  587. return (ULONG)pThis->InternalRelease();
  588. }
  589. STDMETHODIMP_(ULONG) COleControlContainer::XOleContainer::AddRef()
  590. {
  591. METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  592. return (ULONG)pThis->InternalAddRef();
  593. }
  594. STDMETHODIMP COleControlContainer::XOleContainer::ParseDisplayName(LPBINDCTX,
  595. LPOLESTR, ULONG*, LPMONIKER*)
  596. {
  597. return E_NOTIMPL;
  598. }
  599. STDMETHODIMP COleControlContainer::XOleContainer::EnumObjects(DWORD dwFlags,
  600. LPENUMUNKNOWN* ppEnumUnknown)
  601. {
  602. METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  603. *ppEnumUnknown = NULL;
  604. HRESULT hr = S_OK;
  605. CEnumUnknown* pEnum = NULL;
  606. UINT cObjects = 0;
  607. LPUNKNOWN* ppUnk = NULL;
  608. TRY
  609. {
  610. if (dwFlags & OLECONTF_EMBEDDINGS)
  611. {
  612. cObjects = pThis->m_siteMap.GetCount();
  613. ppUnk = new LPUNKNOWN[cObjects];
  614. UINT i = 0;
  615. POSITION pos = pThis->m_siteMap.GetStartPosition();
  616. HWND hWnd;
  617. COleControlSite* pSite;
  618. while (pos != NULL)
  619. {
  620. pThis->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  621. ASSERT(pSite->m_pObject != NULL);
  622. pSite->m_pObject->AddRef();
  623. ppUnk[i++] = pSite->m_pObject;
  624. }
  625. ASSERT(cObjects == i);
  626. }
  627. pEnum = new CEnumUnknown(ppUnk, cObjects);
  628. }
  629. CATCH_ALL(e)
  630. {
  631. // Note: DELETE_EXCEPTION(e) not necessary
  632. hr = E_OUTOFMEMORY;
  633. }
  634. END_CATCH_ALL
  635. // clean up in case of failure
  636. if (SUCCEEDED(hr))
  637. {
  638. ASSERT(pEnum != NULL);
  639. *ppEnumUnknown = (IEnumUnknown*)&pEnum->m_xEnumVOID;
  640. }
  641. else
  642. {
  643. ASSERT(pEnum == NULL);
  644. ASSERT(*ppEnumUnknown == NULL);
  645. if (ppUnk != NULL)
  646. {
  647. for (UINT i = 0; i < cObjects; i++)
  648. {
  649. ASSERT(ppUnk[i] != NULL);
  650. ppUnk[i]->Release();
  651. }
  652. }
  653. }
  654. return hr;
  655. }
  656. STDMETHODIMP COleControlContainer::XOleContainer::LockContainer(BOOL)
  657. {
  658. return E_NOTIMPL;
  659. }