mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
16 KiB
729 lines
16 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
#include "occimpl.h"
|
|
|
|
#ifdef AFX_OCC_SEG
|
|
#pragma code_seg(AFX_OCC_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWnd support for OLE Control containment
|
|
|
|
BOOL CWnd::CreateControl(LPCTSTR lpszClass, LPCTSTR lpszWindowName,
|
|
DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
|
|
CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
|
|
{
|
|
ASSERT(lpszClass != NULL);
|
|
|
|
CLSID clsid;
|
|
HRESULT hr = AfxGetClassIDFromString(lpszClass, &clsid);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
|
|
return CreateControl(clsid, lpszWindowName, dwStyle, rect, pParentWnd, nID,
|
|
pPersist, bStorage, bstrLicKey);
|
|
}
|
|
|
|
BOOL CWnd::CreateControl(REFCLSID clsid, LPCTSTR lpszWindowName, DWORD dwStyle,
|
|
const RECT& rect, CWnd* pParentWnd, UINT nID, CFile* pPersist,
|
|
BOOL bStorage, BSTR bstrLicKey)
|
|
{
|
|
ASSERT(pParentWnd != NULL);
|
|
|
|
#ifdef _DEBUG
|
|
if (afxOccManager == NULL)
|
|
{
|
|
TRACE0("Warning: AfxEnableControlContainer has not been called yet.\n");
|
|
TRACE0(">>> You should call it in your app's InitInstance function.\n");
|
|
}
|
|
#endif
|
|
|
|
if ((pParentWnd == NULL) || !pParentWnd->InitControlContainer())
|
|
return FALSE;
|
|
|
|
return pParentWnd->m_pCtrlCont->CreateControl(this, clsid, lpszWindowName,
|
|
dwStyle, rect, nID, pPersist, bStorage, bstrLicKey);
|
|
}
|
|
|
|
BOOL CWnd::InitControlContainer()
|
|
{
|
|
TRY
|
|
{
|
|
if (m_pCtrlCont == NULL)
|
|
m_pCtrlCont = new COleControlContainer(this);
|
|
}
|
|
END_TRY
|
|
|
|
// Mark all ancestor windows as containing OLE controls.
|
|
if (m_pCtrlCont != NULL)
|
|
{
|
|
CWnd* pWnd = this;
|
|
while ((pWnd != NULL) && !(pWnd->m_nFlags & WF_OLECTLCONTAINER))
|
|
{
|
|
pWnd->m_nFlags |= WF_OLECTLCONTAINER;
|
|
pWnd = pWnd->GetParent();
|
|
if (!GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE) & WS_CHILD)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (m_pCtrlCont != NULL);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleControlContainer
|
|
|
|
BEGIN_INTERFACE_MAP(COleControlContainer, CCmdTarget)
|
|
INTERFACE_PART(COleControlContainer, IID_IOleInPlaceFrame, OleIPFrame)
|
|
INTERFACE_PART(COleControlContainer, IID_IOleContainer, OleContainer)
|
|
END_INTERFACE_MAP()
|
|
|
|
BEGIN_DISPATCH_MAP(COleControlContainer, CCmdTarget)
|
|
END_DISPATCH_MAP()
|
|
|
|
COleControlContainer::COleControlContainer(CWnd* pWnd) :
|
|
m_pWnd(pWnd),
|
|
m_crBack((COLORREF)-1),
|
|
m_crFore((COLORREF)-1),
|
|
m_pOleFont(NULL),
|
|
m_pSiteUIActive(NULL)
|
|
{
|
|
}
|
|
|
|
COleControlContainer::~COleControlContainer()
|
|
{
|
|
HWND hWnd;
|
|
COleControlSite* pSite;
|
|
POSITION pos = m_siteMap.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
|
|
delete pSite;
|
|
}
|
|
m_siteMap.RemoveAll();
|
|
|
|
RELEASE(m_pOleFont);
|
|
}
|
|
|
|
BOOL COleControlContainer::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
|
|
LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, UINT nID,
|
|
CFile* pPersist, BOOL bStorage, BSTR bstrLicKey,
|
|
COleControlSite** ppNewSite)
|
|
{
|
|
COleControlSite* pSite = NULL;
|
|
|
|
TRY
|
|
{
|
|
pSite = new COleControlSite(this);
|
|
}
|
|
END_TRY
|
|
|
|
if (pSite == NULL)
|
|
return FALSE;
|
|
|
|
BOOL bCreated = SUCCEEDED(pSite->CreateControl(pWndCtrl, clsid,
|
|
lpszWindowName, dwStyle, rect, nID, pPersist, bStorage, bstrLicKey));
|
|
|
|
if (bCreated)
|
|
{
|
|
ASSERT(pSite->m_hWnd != NULL);
|
|
m_siteMap.SetAt(pSite->m_hWnd, pSite);
|
|
if (ppNewSite != NULL)
|
|
*ppNewSite = pSite;
|
|
}
|
|
else
|
|
{
|
|
delete pSite;
|
|
}
|
|
|
|
return bCreated;
|
|
}
|
|
|
|
COleControlSite* COleControlContainer::FindItem(UINT nID) const
|
|
{
|
|
POSITION pos = m_siteMap.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
HWND hWnd;
|
|
COleControlSite* pSite;
|
|
m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
|
|
if (pSite->GetID() == nID)
|
|
return pSite;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL COleControlContainer::GetAmbientProp(COleControlSite* pSite, DISPID dispid,
|
|
VARIANT* pvarResult)
|
|
{
|
|
switch (dispid)
|
|
{
|
|
case DISPID_AMBIENT_AUTOCLIP:
|
|
case DISPID_AMBIENT_MESSAGEREFLECT:
|
|
case DISPID_AMBIENT_SUPPORTSMNEMONICS:
|
|
case DISPID_AMBIENT_USERMODE:
|
|
V_VT(pvarResult) = VT_BOOL;
|
|
V_BOOL(pvarResult) = (VARIANT_BOOL)-1;
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_SHOWGRABHANDLES:
|
|
case DISPID_AMBIENT_SHOWHATCHING:
|
|
case DISPID_AMBIENT_UIDEAD:
|
|
V_VT(pvarResult) = VT_BOOL;
|
|
V_BOOL(pvarResult) = 0;
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_APPEARANCE: // ambient appearance is 3D
|
|
V_VT(pvarResult) = VT_I2;
|
|
if (afxData.bWin4 || AfxGetCtl3dState()->m_pfnSubclassDlgEx != NULL)
|
|
V_I2(pvarResult) = 1;
|
|
else
|
|
V_I2(pvarResult) = 0;
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_BACKCOLOR:
|
|
case DISPID_AMBIENT_FORECOLOR:
|
|
if (m_crBack == (COLORREF)-1) // ambient colors not initialized
|
|
{
|
|
CWindowDC dc(m_pWnd);
|
|
m_pWnd->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC,
|
|
(LPARAM)m_pWnd->m_hWnd);
|
|
m_crBack = dc.GetBkColor();
|
|
m_crFore = dc.GetTextColor();
|
|
}
|
|
|
|
V_VT(pvarResult) = VT_COLOR;
|
|
V_I4(pvarResult) = (dispid == DISPID_AMBIENT_BACKCOLOR) ?
|
|
m_crBack : m_crFore;
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_FONT:
|
|
if (m_pOleFont == NULL) // ambient font not initialized
|
|
CreateOleFont(m_pWnd->GetFont());
|
|
|
|
ASSERT(m_pOleFont != NULL);
|
|
if (m_pOleFont == NULL) // failed to create font
|
|
return FALSE;
|
|
|
|
V_VT(pvarResult) = VT_FONT;
|
|
m_pOleFont->AddRef();
|
|
V_DISPATCH(pvarResult) = m_pOleFont;
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_DISPLAYASDEFAULT:
|
|
V_VT(pvarResult) = VT_BOOL;
|
|
V_BOOL(pvarResult) = (VARIANT_BOOL)(pSite->IsDefaultButton() ? -1 : 0);
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_LOCALEID:
|
|
V_VT(pvarResult) = VT_I4;
|
|
V_I4(pvarResult) = GetThreadLocale();
|
|
return TRUE;
|
|
|
|
case DISPID_AMBIENT_SCALEUNITS:
|
|
{
|
|
CString str;
|
|
str.LoadString(AFX_IDS_OCC_SCALEUNITS_PIXELS);
|
|
V_VT(pvarResult) = VT_BSTR;
|
|
V_BSTR(pvarResult) = str.AllocSysString();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void COleControlContainer::CreateOleFont(CFont* pFont)
|
|
{
|
|
USES_CONVERSION;
|
|
|
|
CFont fontSys;
|
|
if ((pFont == NULL) || (pFont->m_hObject == NULL))
|
|
{
|
|
// no font was provided, so use the system font
|
|
if (fontSys.CreateStockObject(DEFAULT_GUI_FONT) ||
|
|
fontSys.CreateStockObject(SYSTEM_FONT))
|
|
{
|
|
pFont = &fontSys;
|
|
}
|
|
else
|
|
{
|
|
m_pOleFont = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
LOGFONT logfont;
|
|
pFont->GetLogFont(&logfont);
|
|
|
|
FONTDESC fd;
|
|
fd.cbSizeofstruct = sizeof(FONTDESC);
|
|
fd.lpstrName = T2OLE(logfont.lfFaceName);
|
|
fd.sWeight = (short)logfont.lfWeight;
|
|
fd.sCharset = logfont.lfCharSet;
|
|
fd.fItalic = logfont.lfItalic;
|
|
fd.fUnderline = logfont.lfUnderline;
|
|
fd.fStrikethrough = logfont.lfStrikeOut;
|
|
|
|
long lfHeight = logfont.lfHeight;
|
|
if (lfHeight < 0)
|
|
lfHeight = -lfHeight;
|
|
|
|
CWindowDC dc(m_pWnd);
|
|
int ppi = dc.GetDeviceCaps(LOGPIXELSY);
|
|
fd.cySize.Lo = lfHeight * 720000 / ppi;
|
|
fd.cySize.Hi = 0;
|
|
|
|
RELEASE(m_pOleFont);
|
|
if (FAILED(OleCreateFontIndirect(&fd, IID_IFontDisp, (void**)&m_pOleFont)))
|
|
m_pOleFont = NULL;
|
|
}
|
|
|
|
void COleControlContainer::ScrollChildren(int dx, int dy)
|
|
{
|
|
HWND hWnd;
|
|
COleControlSite* pSite;
|
|
POSITION pos = m_siteMap.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
|
|
ASSERT(pSite->m_pInPlaceObject != NULL);
|
|
ASSERT(pSite->m_pObject != NULL);
|
|
pSite->m_rect.OffsetRect(dx, dy);
|
|
pSite->m_pInPlaceObject->SetObjectRects(pSite->m_rect, pSite->m_rect);
|
|
}
|
|
}
|
|
|
|
void COleControlContainer::OnUIActivate(COleControlSite* pSite)
|
|
{
|
|
if (m_pSiteUIActive != NULL)
|
|
m_pSiteUIActive->m_pInPlaceObject->UIDeactivate();
|
|
|
|
ASSERT(m_pSiteUIActive == NULL); // did control call OnUIDeactivate?
|
|
m_pSiteUIActive = pSite;
|
|
}
|
|
|
|
void COleControlContainer::OnUIDeactivate(COleControlSite* pSite)
|
|
{
|
|
UNUSED(pSite);
|
|
|
|
ASSERT(m_pSiteUIActive == pSite);
|
|
m_pSiteUIActive = NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// special cases for CWnd functions
|
|
|
|
void COleControlContainer::CheckDlgButton(int nIDButton, UINT nCheck)
|
|
{
|
|
CWnd* pWnd = GetDlgItem(nIDButton);
|
|
if (pWnd == NULL)
|
|
return;
|
|
|
|
if (pWnd->m_pCtrlSite == NULL)
|
|
{
|
|
pWnd->SendMessage(BM_SETCHECK, nCheck, 0);
|
|
return;
|
|
}
|
|
|
|
pWnd->m_pCtrlSite->SafeSetProperty(DISPID_VALUE, VT_I4, (DWORD)nCheck);
|
|
}
|
|
|
|
void COleControlContainer::CheckRadioButton(int nIDFirstButton, int nIDLastButton,
|
|
int nIDCheckButton)
|
|
{
|
|
ASSERT(nIDFirstButton <= nIDCheckButton);
|
|
ASSERT(nIDCheckButton <= nIDLastButton);
|
|
|
|
// the following code is for OLE control containers only
|
|
for (int nID = nIDFirstButton; nID <= nIDLastButton; nID++)
|
|
CheckDlgButton(nID, (nID == nIDCheckButton));
|
|
}
|
|
|
|
CWnd* COleControlContainer::GetDlgItem(int nID) const
|
|
{
|
|
HWND hWnd;
|
|
GetDlgItem(nID, &hWnd);
|
|
return CWnd::FromHandle(hWnd);
|
|
}
|
|
|
|
void COleControlContainer::GetDlgItem(int nID, HWND* phWnd) const
|
|
{
|
|
// first, look for a non-OLE control
|
|
HWND hWnd = ::GetDlgItem(m_pWnd->GetSafeHwnd(), nID);
|
|
if (hWnd == NULL)
|
|
{
|
|
// now, look for an OLE control
|
|
COleControlSite* pSite = FindItem(nID);
|
|
if (pSite != NULL)
|
|
hWnd = pSite->m_hWnd;
|
|
}
|
|
|
|
*phWnd = hWnd;
|
|
}
|
|
|
|
UINT COleControlContainer::GetDlgItemInt(int nID, BOOL* lpTrans, BOOL bSigned) const
|
|
{
|
|
TCHAR szText[256];
|
|
if (GetDlgItemText(nID, szText, 256) == 0)
|
|
{
|
|
if (lpTrans != NULL)
|
|
*lpTrans = FALSE;
|
|
return 0;
|
|
}
|
|
|
|
// Quick check for valid number
|
|
LPTSTR pch = szText;
|
|
|
|
while (isspace((int)(unsigned char)*pch))
|
|
pch = CharNext(pch); // skip whitespace
|
|
|
|
if ((*pch) == '+' || (*pch) == '-')
|
|
pch = CharNext(pch); // skip sign
|
|
|
|
BOOL bTrans = isdigit((int)(unsigned char)*pch); // did we find a digit?
|
|
|
|
if (lpTrans != NULL)
|
|
*lpTrans = bTrans;
|
|
|
|
if (!bTrans)
|
|
return 0;
|
|
|
|
if (bSigned)
|
|
return _tcstol(szText, NULL, 10);
|
|
else
|
|
return _tcstoul(szText, NULL, 10);
|
|
}
|
|
|
|
int COleControlContainer::GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
|
|
{
|
|
CWnd* pWnd = GetDlgItem(nID);
|
|
if (pWnd == NULL)
|
|
return 0;
|
|
|
|
return pWnd->GetWindowText(lpStr, nMaxCount);
|
|
}
|
|
|
|
LRESULT COleControlContainer::SendDlgItemMessage(int nID, UINT message, WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
CWnd* pWnd = GetDlgItem(nID);
|
|
if (pWnd == NULL)
|
|
return 0;
|
|
|
|
return pWnd->SendMessage(message, wParam, lParam);
|
|
}
|
|
|
|
void COleControlContainer::SetDlgItemInt(int nID, UINT nValue, BOOL bSigned)
|
|
{
|
|
TCHAR szText[34];
|
|
if (bSigned)
|
|
_ltot((long)nValue, szText, 10);
|
|
else
|
|
_ultot((unsigned long)nValue, szText, 10);
|
|
|
|
SetDlgItemText(nID, szText);
|
|
}
|
|
|
|
void COleControlContainer::SetDlgItemText(int nID, LPCTSTR lpszString)
|
|
{
|
|
CWnd* pWnd = GetDlgItem(nID);
|
|
if (pWnd == NULL)
|
|
return;
|
|
|
|
pWnd->SetWindowText(lpszString);
|
|
}
|
|
|
|
UINT COleControlContainer::IsDlgButtonChecked(int nIDButton) const
|
|
{
|
|
CWnd* pWnd = GetDlgItem(nIDButton);
|
|
if (pWnd == NULL)
|
|
return 0;
|
|
|
|
if (pWnd->m_pCtrlSite == NULL)
|
|
return pWnd->SendMessage(BM_GETCHECK, 0, 0);
|
|
|
|
DWORD dwValue;
|
|
|
|
TRY
|
|
{
|
|
pWnd->GetProperty(DISPID_VALUE, VT_I4, &dwValue);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
DELETE_EXCEPTION(e);
|
|
dwValue = 0;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
if (dwValue == 0x0000ffff) // VARIANT_BOOL TRUE
|
|
dwValue = 1;
|
|
|
|
return dwValue;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleControlContainer::XOleIPFrame
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::QueryInterface(
|
|
REFIID iid, LPVOID* ppvObj)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
|
|
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COleControlContainer::XOleIPFrame::AddRef()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
|
|
return (ULONG)pThis->ExternalAddRef();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COleControlContainer::XOleIPFrame::Release()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
|
|
return (ULONG)pThis->ExternalRelease();
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::GetWindow(HWND* phWnd)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
|
|
|
|
*phWnd = pThis->m_pWnd->m_hWnd;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::ContextSensitiveHelp(BOOL)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::GetBorder(LPRECT)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::RequestBorderSpace(
|
|
LPCBORDERWIDTHS)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::SetBorderSpace(
|
|
LPCBORDERWIDTHS)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::SetActiveObject(
|
|
LPOLEINPLACEACTIVEOBJECT pActiveObject, LPCOLESTR)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
|
|
|
|
ASSERT(pThis->m_pSiteUIActive != NULL);
|
|
|
|
if (pActiveObject != NULL)
|
|
{
|
|
ASSERT(pThis->m_pSiteUIActive->m_pActiveObject == NULL);
|
|
pActiveObject->AddRef();
|
|
pThis->m_pSiteUIActive->m_pActiveObject = pActiveObject;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pThis->m_pSiteUIActive->m_pActiveObject != NULL);
|
|
pThis->m_pSiteUIActive->m_pActiveObject->Release();
|
|
pThis->m_pSiteUIActive->m_pActiveObject = NULL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::InsertMenus(HMENU,
|
|
LPOLEMENUGROUPWIDTHS)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::SetMenu(HMENU, HOLEMENU, HWND)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::RemoveMenus(HMENU)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::SetStatusText(LPCOLESTR)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::EnableModeless(BOOL)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleIPFrame::TranslateAccelerator(LPMSG,
|
|
WORD)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumUnknown - enumerator for IUnknown pointers
|
|
|
|
class CEnumUnknown : public CEnumArray
|
|
{
|
|
public:
|
|
CEnumUnknown(const void* pvEnum, UINT nSize) :
|
|
CEnumArray(sizeof(LPUNKNOWN), pvEnum, nSize, TRUE) {}
|
|
~CEnumUnknown();
|
|
|
|
protected:
|
|
virtual BOOL OnNext(void* pv);
|
|
|
|
DECLARE_INTERFACE_MAP()
|
|
};
|
|
|
|
BEGIN_INTERFACE_MAP(CEnumUnknown, CEnumArray)
|
|
INTERFACE_PART(CEnumUnknown, IID_IEnumUnknown, EnumVOID)
|
|
END_INTERFACE_MAP()
|
|
|
|
CEnumUnknown::~CEnumUnknown()
|
|
{
|
|
if (m_pClonedFrom == NULL)
|
|
{
|
|
LPUNKNOWN* ppUnk = (LPUNKNOWN*)(void*)m_pvEnum;
|
|
for (UINT i = 0; i < m_nSize; i++)
|
|
{
|
|
ASSERT(ppUnk[i] != NULL);
|
|
ppUnk[i]->Release();
|
|
}
|
|
}
|
|
// destructor will free the actual array (if it was not a clone)
|
|
}
|
|
|
|
BOOL CEnumUnknown::OnNext(void* pv)
|
|
{
|
|
if (!CEnumArray::OnNext(pv))
|
|
return FALSE;
|
|
|
|
// AddRef the pointer (the caller has responsibility to Release it)
|
|
ASSERT(*(LPUNKNOWN*)pv != NULL);
|
|
(*(LPUNKNOWN*)pv)->AddRef();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleControlContainer::XOleContainer
|
|
|
|
STDMETHODIMP COleControlContainer::XOleContainer::QueryInterface(
|
|
REFIID iid, LPVOID* ppvObj)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
|
|
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COleControlContainer::XOleContainer::Release()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
|
|
return (ULONG)pThis->ExternalRelease();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COleControlContainer::XOleContainer::AddRef()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
|
|
return (ULONG)pThis->ExternalAddRef();
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleContainer::ParseDisplayName(LPBINDCTX,
|
|
LPOLESTR, ULONG*, LPMONIKER*)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleContainer::EnumObjects(DWORD dwFlags,
|
|
LPENUMUNKNOWN* ppEnumUnknown)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
|
|
|
|
*ppEnumUnknown = NULL;
|
|
HRESULT hr = S_OK;
|
|
CEnumUnknown* pEnum = NULL;
|
|
UINT cObjects = 0;
|
|
LPUNKNOWN* ppUnk = NULL;
|
|
|
|
TRY
|
|
{
|
|
if (dwFlags & OLECONTF_EMBEDDINGS)
|
|
{
|
|
cObjects = pThis->m_siteMap.GetCount();
|
|
ppUnk = new LPUNKNOWN[cObjects];
|
|
UINT i = 0;
|
|
POSITION pos = pThis->m_siteMap.GetStartPosition();
|
|
HWND hWnd;
|
|
COleControlSite* pSite;
|
|
while (pos != NULL)
|
|
{
|
|
pThis->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
|
|
ASSERT(pSite->m_pObject != NULL);
|
|
pSite->m_pObject->AddRef();
|
|
ppUnk[i++] = pSite->m_pObject;
|
|
}
|
|
|
|
ASSERT(cObjects == i);
|
|
}
|
|
pEnum = new CEnumUnknown(ppUnk, cObjects);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Note: DELETE_EXCEPTION(e) not necessary
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
// clean up in case of failure
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ASSERT(pEnum != NULL);
|
|
*ppEnumUnknown = (IEnumUnknown*)&pEnum->m_xEnumVOID;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pEnum = NULL);
|
|
ASSERT(*ppEnumUnknown == NULL);
|
|
|
|
if (ppUnk != NULL)
|
|
{
|
|
for (UINT i = 0; i < cObjects; i++)
|
|
{
|
|
ASSERT(ppUnk[i] != NULL);
|
|
ppUnk[i]->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP COleControlContainer::XOleContainer::LockContainer(BOOL)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|