📄 occcont.cpp
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 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 )
{
CRect rect2( rect );
CPoint pt;
CSize size;
pt = rect2.TopLeft();
size = rect2.Size();
return( CreateControl( clsid, lpszWindowName, dwStyle, &pt, &size,
pParentWnd, nID, pPersist, bStorage, bstrLicKey ) );
}
BOOL CWnd::CreateControl(REFCLSID clsid, LPCTSTR lpszWindowName, DWORD dwStyle,
const POINT* ppt, const SIZE* psize, 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, ppt, psize, nID, pPersist, bStorage, bstrLicKey);
}
BOOL CWnd::InitControlContainer()
{
TRY
{
if (m_pCtrlCont == NULL)
m_pCtrlCont = afxOccManager->CreateContainer(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);
if (!(pSite->m_pDataSourceControl))
{
m_siteMap.RemoveKey((void*&)hWnd);
delete pSite;
}
}
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 )
{
CRect rect2( rect );
CPoint pt;
CSize size;
pt = rect2.TopLeft();
size = rect2.Size();
return( CreateControl( pWndCtrl, clsid, lpszWindowName, dwStyle, &pt, &size,
nID, pPersist, bStorage, bstrLicKey, ppNewSite ) );
}
BOOL COleControlContainer::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey,
COleControlSite** ppNewSite)
{
COleControlSite* pSite = NULL;
TRY
{
pSite = afxOccManager->CreateSite(this);
}
END_TRY
if (pSite == NULL)
return FALSE;
BOOL bCreated = SUCCEEDED( pSite->CreateControl(pWndCtrl, clsid,
lpszWindowName, dwStyle, ppt, psize, 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;
#ifndef _AFX_NO_CTL3D_SUPPORT
if (afxData.bWin4 || AfxGetCtl3dState()->m_pfnSubclassDlgEx != NULL)
#else
if (afxData.bWin4)
#endif
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_DISPLAYNAME:
{
CString str; // return blank string
V_VT(pvarResult) = VT_BSTR;
V_BSTR(pvarResult) = str.AllocSysString();
}
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::FreezeAllEvents(BOOL bFreeze)
{
HWND hWnd;
COleControlSite* pSite;
POSITION pos = m_siteMap.GetStartPosition();
while (pos != NULL)
{
m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
pSite->FreezeEvents(bFreeze);
}
}
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);
if (m_pSiteUIActive == pSite)
m_pSiteUIActive = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -