⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 occsite.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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"
#include "msdadc.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

#define S_QUICKACTIVATED S_FALSE

#include "initguid.h"
#define DBINITCONSTANTS
#define INITGUID

DEFINE_GUID(IID_IDataSourceListener,0x7C0FFAB2L,0xCD84,0x11D0,0x94,0x9A,0x00,0xA0,0xC9,0x11,0x10,0xED);
DEFINE_GUID(IID_IDataSource,0x7c0ffab3L, 0xcd84, 0x11d0, 0x94, 0x9a, 0x00, 0xa0, 0xc9, 0x11, 0x10, 0xed);

/////////////////////////////////////////////////////////////////////////////
// COleControlSite

BEGIN_INTERFACE_MAP(COleControlSite, CCmdTarget)
	INTERFACE_PART(COleControlSite, IID_IOleClientSite, OleClientSite)
	INTERFACE_PART(COleControlSite, IID_IOleInPlaceSite, OleIPSite)
	INTERFACE_PART(COleControlSite, IID_IOleControlSite, OleControlSite)
	INTERFACE_PART(COleControlSite, IID_IDispatch, AmbientProps)
	INTERFACE_PART(COleControlSite, IID_IBoundObjectSite, BoundObjectSite)
	INTERFACE_PART(COleControlSite, IID_INotifyDBEvents, NotifyDBEvents)
	INTERFACE_PART(COleControlSite, IID_IRowsetNotify, RowsetNotify)
END_INTERFACE_MAP()

COleControlSite::COleControlSite(COleControlContainer* pCtrlCont) :
	m_pCtrlCont(pCtrlCont),
	m_pWndCtrl(NULL),
	m_nID((UINT)-1),
	m_pObject(NULL),
	m_pInPlaceObject(NULL),
	m_pActiveObject(NULL),
	m_dwEventSink(0),
	m_dwPropNotifySink(0),
	m_dwMiscStatus(0),
	m_dwNotifyDBEvents(0),
	m_pDataSourceControl(NULL),
	m_pDSCSite(NULL),
	m_defdispid(0),
	m_dwType(0),
	m_pBindings(NULL),
	m_bIgnoreNotify(FALSE),
	m_bIsDirty(FALSE)
{
	memset(&m_varResult, 0, sizeof(VARIANT));
	m_varResult.vt = VT_EMPTY;
}

COleControlSite::~COleControlSite()
{
	delete m_pDataSourceControl;

	DetachWindow();

	DisconnectSink(m_iidEvents, m_dwEventSink);
	DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
	DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);

	if (m_pInPlaceObject != NULL)
	{
		m_pInPlaceObject->InPlaceDeactivate();
		m_pInPlaceObject->Release();
		m_pInPlaceObject = NULL;
	}

	if (m_pActiveObject != NULL)
	{
		m_pActiveObject->Release();
		m_pActiveObject = NULL;
	}

	if (m_pObject != NULL)
	{
		m_pObject->SetClientSite(NULL);
		m_pObject->Close(OLECLOSE_NOSAVE);
		m_pObject->Release();
		m_pObject = NULL;
	}

	::VariantClear(&m_varResult);

	BindProperty(DISPID_UNKNOWN, NULL);  // gets rid of complex bindings

	if (m_defdispid != 0 && m_pDSCSite != NULL &&
		m_pDSCSite->m_pDataSourceControl != NULL)
	{
		// get rid of simple bindings
		m_pDSCSite->m_pDataSourceControl->BindProp(this, FALSE);
	}
}

BOOL COleControlSite::SetExtent()
{
	CSize size(m_rect.Size());
	CClientDC dc(NULL);
	dc.DPtoHIMETRIC(&size);

	HRESULT hr;

	if (SUCCEEDED(hr = m_pObject->SetExtent(DVASPECT_CONTENT, (SIZEL*)&size)))
	{
		if (SUCCEEDED(m_pObject->GetExtent(DVASPECT_CONTENT, (SIZEL*)&size)))
		{
			dc.HIMETRICtoDP(&size);
			m_rect.right = m_rect.left + size.cx;
			m_rect.bottom = m_rect.top + size.cy;
		}
	}

	return SUCCEEDED(hr);
}

HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
	LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, UINT nID,
	CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
{
   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 ) );
}

HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
	LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
   UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
{
	HRESULT hr = E_FAIL;
	m_hWnd = NULL;
   CSize size;

	// Connect the OLE Control with its proxy CWnd object
	if (pWndCtrl != NULL)
	{
		ASSERT(pWndCtrl->m_pCtrlSite == NULL);
		m_pWndCtrl = pWndCtrl;
		pWndCtrl->m_pCtrlSite = this;
	}

	// Initialize OLE, if necessary
	_AFX_THREAD_STATE* pState = AfxGetThreadState();
	if (!pState->m_bNeedTerm && !AfxOleInit())
		return hr;

	if (SUCCEEDED(hr = CreateOrLoad(clsid, pPersist, bStorage, bstrLicKey)))
	{
		ASSERT(m_pObject != NULL);
		m_nID = nID;

		if (psize == NULL)
		{
			// If psize is NULL, ask the object how big it wants to be.
			CClientDC dc(NULL);

			m_pObject->GetExtent(DVASPECT_CONTENT, &size);
			dc.HIMETRICtoDP(&size);
			m_rect = CRect(*ppt, size);
		}
		else
		{
			m_rect = CRect(*ppt, *psize);
		}

		m_dwStyleMask = WS_GROUP | WS_TABSTOP;

		if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
			m_dwStyleMask |= BS_DEFPUSHBUTTON;

		if (m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)
			dwStyle &= ~WS_VISIBLE;

		m_dwStyle = dwStyle & m_dwStyleMask;

		// If control wasn't quick-activated, then connect sinks now.
		if (hr != S_QUICKACTIVATED)
		{
			m_dwEventSink = ConnectSink(m_iidEvents, &m_xEventSink);
			m_dwPropNotifySink = ConnectSink(IID_IPropertyNotifySink,
				&m_xPropertyNotifySink);
		}
		m_dwNotifyDBEvents = ConnectSink(IID_INotifyDBEvents, &m_xNotifyDBEvents);

		// Now that the object has been created, attempt to
		// in-place activate it.

		SetExtent();

		if (SUCCEEDED(hr = m_pObject->QueryInterface(IID_IOleInPlaceObject,
				(LPVOID*)&m_pInPlaceObject)))
		{
			if (dwStyle & WS_VISIBLE)
			{
				// control is visible: just activate it
				hr = DoVerb(OLEIVERB_INPLACEACTIVATE);
			}
			else
			{
				// control is not visible: activate off-screen, hide, then move
				m_rect.OffsetRect(-32000, -32000);
				if (SUCCEEDED(hr = DoVerb(OLEIVERB_INPLACEACTIVATE)) &&
					SUCCEEDED(hr = DoVerb(OLEIVERB_HIDE)))
				{
					m_rect.OffsetRect(32000, 32000);
					hr = m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
				}
			}
		}
		else
		{
			TRACE1("IOleInPlaceObject not supported on OLE control (dialog ID %d).\n", nID);
			TRACE1(">>> Result code: 0x%08lx\n", hr);
		}

		if (SUCCEEDED(hr))
			GetControlInfo();

		// if QueryInterface or activation failed, cleanup everything
		if (FAILED(hr))
		{
			if (m_pInPlaceObject != NULL)
			{
				m_pInPlaceObject->Release();
				m_pInPlaceObject = NULL;
			}
			DisconnectSink(m_iidEvents, m_dwEventSink);
			DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
			DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
			m_dwEventSink = 0;
			m_dwPropNotifySink = 0;
			m_dwNotifyDBEvents = 0;
			m_pObject->Release();
			m_pObject = NULL;
		}
	}

	if (SUCCEEDED(hr))
	{
		AttachWindow();

		ASSERT(m_hWnd != NULL);

		// Initialize the control's Caption or Text property, if any
		if (lpszWindowName != NULL)
			SetWindowText(lpszWindowName);

		// Initialize styles
		ModifyStyle(0, m_dwStyle | (dwStyle & (WS_DISABLED|WS_BORDER)), 0);
	}

	return hr;
}

BOOL COleControlSite::DestroyControl()
{
	ASSERT(m_hWnd != NULL);     // was control ever successfully created?
	m_pCtrlCont->m_siteMap.RemoveKey(m_hWnd);

	//VBBUG: VB controls will crash if IOleObject::Close is called on them
	//  when they have focus (and unfortunately, deactivating them does not
	//  always move the focus).  To work around this problem, we always hide
	//  the control before closing it.
	ShowWindow(SW_HIDE);

	// Now it is safe to close the control.
	delete this;

	return TRUE;
}

AFX_STATIC HRESULT AFXAPI _AfxCoCreateInstanceLic(REFCLSID clsid, LPUNKNOWN pUnkOuter,
	DWORD dwClsCtx, REFIID iid, LPVOID* ppv, BSTR bstrLicKey)
{
	HRESULT hr;

	if (bstrLicKey == NULL)
	{
		LPCLASSFACTORY pClassFactory = NULL;

		if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL,
			IID_IClassFactory, (void**)&pClassFactory)))
		{
			ASSERT(pClassFactory != NULL);
			hr = pClassFactory->CreateInstance(pUnkOuter, iid, ppv);
			pClassFactory->Release();
		}
	}
	else
	{
		LPCLASSFACTORY2 pClassFactory = NULL;

		if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL,
			IID_IClassFactory2, (void**)&pClassFactory)))
		{
			ASSERT(pClassFactory != NULL);
			hr = pClassFactory->CreateInstanceLic(pUnkOuter, NULL, iid,
				bstrLicKey, ppv);
			pClassFactory->Release();
		}
	}

	return hr;
}

AFX_STATIC_DATA const struct { DISPID dwDispID; DWORD dwFlag; } _afxAmbients[] =
{
	{ DISPID_AMBIENT_USERMODE,          QACONTAINER_USERMODE },
	{ DISPID_AMBIENT_UIDEAD,            QACONTAINER_UIDEAD },
	{ DISPID_AMBIENT_SHOWGRABHANDLES,   QACONTAINER_SHOWGRABHANDLES },
	{ DISPID_AMBIENT_SHOWHATCHING,      QACONTAINER_SHOWHATCHING },
	{ DISPID_AMBIENT_DISPLAYASDEFAULT,  QACONTAINER_DISPLAYASDEFAULT },
	{ DISPID_AMBIENT_AUTOCLIP,          QACONTAINER_AUTOCLIP },
	{ DISPID_AMBIENT_MESSAGEREFLECT,    QACONTAINER_MESSAGEREFLECT },
	{ DISPID_AMBIENT_SUPPORTSMNEMONICS, QACONTAINER_SUPPORTSMNEMONICS },
};

BOOL COleControlSite::QuickActivate()
{
	BOOL bQuickActivated = FALSE;
	IQuickActivate* pQuick = NULL;
	if (SUCCEEDED(m_pObject->QueryInterface(IID_IQuickActivate,
		reinterpret_cast<void**>(&pQuick))))
	{
		ASSERT(pQuick != NULL);

		// Initialize QACONTAINER structure.
		QACONTAINER qaContainer;
		qaContainer.cbSize = sizeof(QACONTAINER);
		qaContainer.pClientSite = &m_xOleClientSite;
		qaContainer.pAdviseSink = NULL;
		qaContainer.pPropertyNotifySink = &m_xPropertyNotifySink;
		qaContainer.pUnkEventSink = &m_xEventSink;
		qaContainer.pUndoMgr = NULL;
		qaContainer.hpal = NULL;
		qaContainer.pBindHost = NULL;

		// Fill ambient property values in QACONTAINER.
		COleVariant var;
		CWnd* pWndContain = m_pCtrlCont->m_pWnd;

		qaContainer.dwAmbientFlags = 0;
		for (int i = 0; i < _countof(_afxAmbients); i++)
		{
			pWndContain->OnAmbientProperty(this, _afxAmbients[i].dwDispID, &var);
			if (V_BOOL(&var))
				qaContainer.dwAmbientFlags |= _afxAmbients[i].dwFlag;
		}

		pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_FORECOLOR, &var);
		qaContainer.colorFore = V_I4(&var);
		pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_BACKCOLOR, &var);
		qaContainer.colorBack = V_I4(&var);
		pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_APPEARANCE, &var);
		qaContainer.dwAppearance = V_I2(&var);
		pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_LOCALEID, &var);
		qaContainer.lcid = V_I4(&var);
		pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_FONT, &var);
		if (FAILED(V_DISPATCH(&var)->QueryInterface(IID_IFont,
			reinterpret_cast<void**>(&qaContainer.pFont))))
		{
			qaContainer.pFont = NULL;
		}

		// Initialize QACONTROL structure.
		QACONTROL qaControl;
		qaControl.cbSize = sizeof(QACONTROL);

		// Do the quick activation.
		if (SUCCEEDED(pQuick->QuickActivate(&qaContainer, &qaControl)))
		{
			// Extract return values from QACONTROL structure.
			m_dwMiscStatus = qaControl.dwMiscStatus;
			m_dwEventSink = qaControl.dwEventCookie;
			m_dwPropNotifySink = qaControl.dwPropNotifyCookie;
			bQuickActivated = TRUE;
		}
		pQuick->Release();

		if (qaContainer.pFont != NULL)
			qaContainer.pFont->Release();
	}

	return bQuickActivated;
}

HRESULT COleControlSite::CreateOrLoad(REFCLSID clsid, CFile* pFile,
	BOOL bStorage, BSTR bstrLicKey)
{
	ASSERT(m_pObject == NULL);

#ifdef _DEBUG
	OLECHAR wszClsid[40];
	StringFromGUID2(clsid, wszClsid, 40);
#endif //_DEBUG

	HRESULT hr;
	if (FAILED(hr = _AfxCoCreateInstanceLic(clsid, NULL,
		CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IOleObject,
		(void**)&m_pObject, bstrLicKey)))
	{
		TRACE1("CoCreateInstance of OLE control %ls failed.\n", wszClsid);
		TRACE1(">>> Result code: 0x%08lx\n", hr);
		TRACE0(">>> Is the control is properly registered?\n");
		return hr;
	}

	LPPERSISTSTREAMINIT pPersStm = NULL;
	LPPERSISTSTORAGE pPersStg = NULL;
	LPPERSISTMEMORY pPersMem = NULL;

	GetEventIID(&m_iidEvents);
	// Try to quick-activate first
	BOOL bQuickActivated = QuickActivate();

	if (!bQuickActivated)
	{
		m_pObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);

		// set client site first, if appropriate
		if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
		{
			if (FAILED(hr = m_pObject->SetClientSite(&m_xOleClientSite)))
			{
				TRACE1("SetClientSite on OLE control %ls failed.\n", wszClsid);
				TRACE1(">>> Result code: 0x%08lx\n", hr);
				goto CreateOrLoadFailed;
			}
		}
	}

	ASSERT(!bStorage || pFile != NULL);

	// initialize via IPersistMemory (direct buffering)
	if (pFile != NULL && !bStorage &&
		SUCCEEDED(m_pObject->QueryInterface(IID_IPersistMemory, (void**)&pPersMem)) &&
		pFile->GetBufferPtr(CFile::bufferCheck) != 0)
	{
		ASSERT(pPersMem != NULL);

		// file supports direct buffering, get its buffer pointer and size
		LPVOID pvBuffer = NULL;
		LPVOID pvEnd;
		ULONG cbBuffer = pFile->GetBufferPtr(
			CFile::bufferRead, (UINT)-1, &pvBuffer, &pvEnd);
		ASSERT(((LPBYTE)pvEnd - (LPBYTE)pvBuffer) == (int)cbBuffer);

		// and then load it directly
		hr = pPersMem->Load(pvBuffer, cbBuffer);
		pPersMem->Release();
		pPersMem = NULL;
		if (FAILED(hr))
			goto CreateOrLoadFailed;
	}
	// initialize via IPersistStreamInit
	else if (!bStorage && SUCCEEDED(m_pObject->QueryInterface(
		IID_IPersistStreamInit, (void**)&pPersStm)))
	{
		ASSERT(pPersStm != NULL);

		if (pFile == NULL)
		{
			// just call InitNew
			hr = pPersStm->InitNew();
		}
		else
		{
			// open an IStream on the data and pass it to Load
			CArchive ar(pFile, CArchive::load);
			CArchiveStream stm(&ar);
			hr = pPersStm->Load(&stm);
		}
		pPersStm->Release();

		if (FAILED(hr))
		{
			TRACE1("InitNew or Load on OLE control %ls failed.\n", wszClsid);
			TRACE1(">>> Result code: 0x%08lx\n", hr);
			goto CreateOrLoadFailed;
		}
	}
	// initialize via IPersistStorage
	else if (SUCCEEDED(m_pObject->QueryInterface(
		IID_IPersistStorage, (void**)&pPersStg)))
	{
		ASSERT(pPersStg != NULL);

		if (pFile == NULL)
		{
			// create a scratch IStorage and pass it to InitNew
			LPLOCKBYTES pLockBytes = NULL;
			if (SUCCEEDED(hr = CreateILockBytesOnHGlobal(NULL, TRUE,
				&pLockBytes)))
			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -