home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / OCCCONT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-19  |  17.8 KB  |  757 lines

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