EternalWindows
ActiveX コントロール / コントロールサンプル

ActiveXコントロールのサンプルコードです。 defファイル、ヘッダーファイル、ソースファイル(DLL関連)、ソースファイル(CActiveXControl)の順に示します。

LIBRARY	"sample"

EXPORTS
	DllCanUnloadNow PRIVATE
	DllGetClassObject PRIVATE
	DllRegisterServer PRIVATE
	DllUnregisterServer PRIVATE
class CActiveXControl : public IOleObject, public IOleInPlaceObject, public IOleControl, public IDispatch, public IQuickActivate, public IPersistStreamInit, public IPersistPropertyBag, public IObjectSafety
{
public:
	STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
	STDMETHODIMP_(ULONG) AddRef();
	STDMETHODIMP_(ULONG) Release();
	
	STDMETHODIMP SetClientSite(IOleClientSite *pClientSite);
	STDMETHODIMP GetClientSite(IOleClientSite **ppClientSite);
	STDMETHODIMP SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj);
	STDMETHODIMP Close(DWORD dwSaveOption);
	STDMETHODIMP SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk);
	STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
	STDMETHODIMP InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved);
	STDMETHODIMP GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject);
	STDMETHODIMP DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect);
	STDMETHODIMP EnumVerbs(IEnumOLEVERB **ppEnumOleVerb);
	STDMETHODIMP Update();
	STDMETHODIMP IsUpToDate();
	STDMETHODIMP GetUserClassID(CLSID *pClsid);
	STDMETHODIMP GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType);
	STDMETHODIMP SetExtent(DWORD dwDrawAspect, SIZEL *psizel);
	STDMETHODIMP GetExtent(DWORD dwDrawAspect, SIZEL *psizel);
	STDMETHODIMP Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection);
	STDMETHODIMP Unadvise(DWORD dwConnection);
	STDMETHODIMP EnumAdvise(IEnumSTATDATA **ppenumAdvise);
	STDMETHODIMP GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus);
	STDMETHODIMP SetColorScheme(LOGPALETTE *pLogpal);
	
	STDMETHODIMP GetWindow(HWND *phwnd);
	STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
	STDMETHODIMP InPlaceDeactivate();
	STDMETHODIMP ReactivateAndUndo();
	STDMETHODIMP SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
	STDMETHODIMP UIDeactivate();
	
	STDMETHODIMP GetControlInfo(CONTROLINFO *pCI);
	STDMETHODIMP OnMnemonic(MSG *pMsg);
	STDMETHODIMP OnAmbientPropertyChange(DISPID dispID);
	STDMETHODIMP FreezeEvents(BOOL bFreeze);

	STDMETHODIMP GetTypeInfoCount(UINT *pctinfo);
	STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
	STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
	STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);

	STDMETHODIMP QuickActivate(QACONTAINER *pQaContainer, QACONTROL *pQaControl);
	STDMETHODIMP SetContentExtent(LPSIZEL pSizel);
	STDMETHODIMP GetContentExtent(LPSIZEL pSizel);

	STDMETHODIMP GetClassID(CLSID *pClassID);
	STDMETHODIMP IsDirty();
	STDMETHODIMP Load(LPSTREAM pStm);
	STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty);
	STDMETHODIMP GetSizeMax(ULARGE_INTEGER *pCbSize);
	STDMETHODIMP InitNew();

	STDMETHODIMP Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog);
	STDMETHODIMP Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);
	
	STDMETHODIMP GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions);
	STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions);

	CActiveXControl();
	~CActiveXControl();
	LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	BOOL InPlaceActivate(HWND hwndParent, LPRECT lprc);
	void DPtoHIMETRIC(LPSIZEL lpSizel);
	void HIMETRICtoDP(LPSIZEL lpSizel);

private:
	LONG            m_cRef;
	HWND            m_hwnd;
	COLORREF        m_crEllipse;
	int             m_nState;
	SIZEL           m_sizeInit;
	IOleClientSite  *m_pClientSite;
	IOleInPlaceSite *m_pInPlaceSite;
};

class CClassFactory : public IClassFactory
{
public:
	STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
	STDMETHODIMP_(ULONG) AddRef();
	STDMETHODIMP_(ULONG) Release();
	
	STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
	STDMETHODIMP LockServer(BOOL fLock);
};

const CLSID CLSID_ActiveXControlSample = {0xe4a5c7bc, 0xbde7, 0x43e8, {0x96, 0xdc, 0x98, 0xfe, 0xa0, 0x2f, 0x1a, 0x18}};
const TCHAR g_szClsid[] = TEXT("{E4A5C7BC-BDE7-43e8-96DC-98FEA02F1A18}");
const TCHAR g_szClassName[] = TEXT("ActiveXWindow");

extern HINSTANCE g_hinstDll;
#include <windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <objsafe.h>
#include "sample.h"

#pragma comment (lib, "shlwapi.lib")

LONG      g_lLocks = 0;
HINSTANCE g_hinstDll = NULL;

void LockModule(BOOL bLock);
BOOL CreateRegistryKey(HKEY hKeyRoot, LPTSTR lpszKey, LPTSTR lpszValue, LPTSTR lpszData);
BOOL RegisterWindowClass(BOOL bRegister, HINSTANCE hinst);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);


// CClassFactory


STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObject)
{
	*ppvObject = NULL;

	if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
		*ppvObject = static_cast<IClassFactory *>(this);
	else
		return E_NOINTERFACE;

	AddRef();
	
	return S_OK;
}

STDMETHODIMP_(ULONG) CClassFactory::AddRef()
{
	LockModule(TRUE);

	return 2;
}

STDMETHODIMP_(ULONG) CClassFactory::Release()
{
	LockModule(FALSE);

	return 1;
}

STDMETHODIMP CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
{
	CActiveXControl *p;
	HRESULT         hr;
	
	*ppvObject = NULL;

	if (pUnkOuter != NULL)
		return CLASS_E_NOAGGREGATION;

	p = new CActiveXControl();
	if (p == NULL)
		return E_OUTOFMEMORY;

	hr = p->QueryInterface(riid, ppvObject);
	p->Release();

	return hr;
}

STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
{
	LockModule(fLock);

	return S_OK;
}


// DLL Export


STDAPI DllCanUnloadNow(void)
{
	return g_lLocks == 0 ? S_OK : S_FALSE;
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
	static CClassFactory serverFactory;
	HRESULT hr;
	
	*ppv = NULL;

	if (IsEqualCLSID(rclsid, CLSID_ActiveXControlSample))
		hr = serverFactory.QueryInterface(riid, ppv);
	else
		hr = CLASS_E_CLASSNOTAVAILABLE;

	return hr;
}

STDAPI DllRegisterServer(void)
{
	TCHAR szModulePath[256];
	TCHAR szKey[256];

	wsprintf(szKey, TEXT("CLSID\\%s"), g_szClsid);
	if (!CreateRegistryKey(HKEY_CLASSES_ROOT, szKey, NULL, TEXT("My ActiveX")))
		return E_FAIL;

	GetModuleFileName(g_hinstDll, szModulePath, sizeof(szModulePath) / sizeof(TCHAR));
	wsprintf(szKey, TEXT("CLSID\\%s\\InprocServer32"), g_szClsid);
	if (!CreateRegistryKey(HKEY_CLASSES_ROOT, szKey, NULL, szModulePath))
		return E_FAIL;
	
	wsprintf(szKey, TEXT("CLSID\\%s\\InprocServer32"), g_szClsid);
	if (!CreateRegistryKey(HKEY_CLASSES_ROOT, szKey, TEXT("ThreadingModel"), TEXT("Apartment")))
		return E_FAIL;
	
	return S_OK;
}

STDAPI DllUnregisterServer(void)
{
	TCHAR szKey[256];

	wsprintf(szKey, TEXT("CLSID\\%s"), g_szClsid);
	SHDeleteKey(HKEY_CLASSES_ROOT, szKey);

	return S_OK;
}

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved)
{
	switch (dwReason) {

	case DLL_PROCESS_ATTACH:
		g_hinstDll = hinstDll;
		DisableThreadLibraryCalls(hinstDll);
		RegisterWindowClass(TRUE, hinstDll);
		return TRUE;
	
	case DLL_PROCESS_DETACH:
		RegisterWindowClass(FALSE, hinstDll);
		return TRUE;

	}

	return TRUE;
}


// Function


void LockModule(BOOL bLock)
{
	if (bLock)
		InterlockedIncrement(&g_lLocks);
	else
		InterlockedDecrement(&g_lLocks);
}

BOOL CreateRegistryKey(HKEY hKeyRoot, LPTSTR lpszKey, LPTSTR lpszValue, LPTSTR lpszData)
{
	HKEY  hKey;
	LONG  lResult;
	DWORD dwSize;

	lResult = RegCreateKeyEx(hKeyRoot, lpszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
	if (lResult != ERROR_SUCCESS)
		return FALSE;

	if (lpszData != NULL)
		dwSize = (lstrlen(lpszData) + 1) * sizeof(TCHAR);
	else
		dwSize = 0;

	RegSetValueEx(hKey, lpszValue, 0, REG_SZ, (LPBYTE)lpszData, dwSize);
	RegCloseKey(hKey);
	
	return TRUE;
}

BOOL RegisterWindowClass(BOOL bRegister, HINSTANCE hinst)
{
	BOOL bResult;

	if (bRegister) {
		WNDCLASSEX wc;
		
		wc.cbSize        = sizeof(WNDCLASSEX);
		wc.style         = CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc   = ::WindowProc;
		wc.cbClsExtra    = 0;
		wc.cbWndExtra    = 0;
		wc.hInstance     = hinst;
		wc.hIcon         = NULL;
		wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
		wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
		wc.lpszMenuName  = NULL;
		wc.lpszClassName = g_szClassName;
		wc.hIconSm       = NULL;
		
		bResult = (BOOL)RegisterClassEx(&wc);

		g_hinstDll = hinst;
	}
	else
		bResult = UnregisterClass(g_szClassName, hinst);

	return bResult;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	CActiveXControl *p = (CActiveXControl *)GetWindowLongPtr(hwnd, GWLP_USERDATA);

	if (p != NULL)
		return p->WindowProc(hwnd, uMsg, wParam, lParam);
	else
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
#include <windows.h>
#include <olectl.h>
#include <objsafe.h>
#include "sample.h"

#define ID_WINDOW 100

CActiveXControl::CActiveXControl()
{
	m_cRef = 1;
	m_hwnd = NULL;
	m_crEllipse = RGB(255, 255, 255);
	m_nState = READYSTATE_UNINITIALIZED;
	m_sizeInit.cx = 100;
	m_sizeInit.cy = 100;
	m_pClientSite = NULL;
	m_pInPlaceSite = NULL;
}

CActiveXControl::~CActiveXControl()
{
}

STDMETHODIMP CActiveXControl::QueryInterface(REFIID riid, void **ppvObject)
{
	*ppvObject = NULL;	

	if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IOleObject))
		*ppvObject = static_cast<IOleObject *>(this);
	else if (IsEqualIID(riid, IID_IOleWindow) || IsEqualIID(riid, IID_IOleInPlaceObject))
		*ppvObject = static_cast<IOleInPlaceObject *>(this);
	else if (IsEqualIID(riid, IID_IOleControl))
		*ppvObject = static_cast<IOleControl *>(this);
	else if (IsEqualIID(riid, IID_IDispatch))
		*ppvObject = static_cast<IDispatch *>(this);
	else if (IsEqualIID(riid, IID_IQuickActivate))
		*ppvObject = static_cast<IQuickActivate *>(this);
	else if (IsEqualIID(riid, IID_IPersist) || IsEqualIID(riid, IID_IPersistStreamInit))
		*ppvObject = static_cast<IPersistStreamInit *>(this);
	else if (IsEqualIID(riid, IID_IPersistPropertyBag))
		*ppvObject = static_cast<IPersistPropertyBag *>(this);
	else if (IsEqualIID(riid, IID_IObjectSafety))
		*ppvObject = static_cast<IObjectSafety *>(this);
	else
		return E_NOINTERFACE;

	AddRef();
	
	return S_OK;
}

STDMETHODIMP_(ULONG) CActiveXControl::AddRef()
{
	return InterlockedIncrement(&m_cRef);
}

STDMETHODIMP_(ULONG) CActiveXControl::Release()
{
	if (InterlockedDecrement(&m_cRef) == 0) {
		delete this;
		return 0;
	}

	return m_cRef;
}


// IOleObject


STDMETHODIMP CActiveXControl::SetClientSite(IOleClientSite *pClientSite)
{
	if (m_pClientSite != NULL)
		m_pClientSite->Release();

	m_pClientSite = pClientSite;

	if (m_pClientSite != NULL)
		m_pClientSite->AddRef();

	return S_OK;
}

STDMETHODIMP CActiveXControl::GetClientSite(IOleClientSite **ppClientSite)
{
	*ppClientSite = m_pClientSite;
	m_pClientSite->AddRef();

	return S_OK;
}

STDMETHODIMP CActiveXControl::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
	return S_OK;
}

STDMETHODIMP CActiveXControl::Close(DWORD dwSaveOption)
{
	DestroyWindow(m_hwnd);
	m_hwnd = NULL;

	return S_OK;
}

STDMETHODIMP CActiveXControl::SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
	if (iVerb == OLEIVERB_INPLACEACTIVATE){
		if (!InPlaceActivate(hwndParent, (LPRECT)lprcPosRect))
			return E_FAIL;
	}
	else if (iVerb == OLEIVERB_HIDE)
		InPlaceDeactivate();
	else
		;

	return S_OK;
}

STDMETHODIMP CActiveXControl::EnumVerbs(IEnumOLEVERB **ppEnumOleVerb)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::Update()
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::IsUpToDate()
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::GetUserClassID(CLSID *pClsid)
{
	*pClsid = CLSID_ActiveXControlSample;

	return S_OK;
}

STDMETHODIMP CActiveXControl::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
{
	SIZEL sizel = *psizel;
	RECT  rc;

	HIMETRICtoDP(&sizel);

	if (m_hwnd != NULL) {
		GetClientRect(m_hwnd, &rc);
		SetRect(&rc, rc.left, rc.top, rc.left + sizel.cx, rc.top + sizel.cy);
		MoveWindow(m_hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
	}
	else
		m_sizeInit = sizel;

	return S_OK;
}

STDMETHODIMP CActiveXControl::GetExtent(DWORD dwDrawAspect, SIZEL *psizel)
{
	RECT rc;
	
	if (m_hwnd != NULL) {
		GetClientRect(m_hwnd, &rc);
		psizel->cx = rc.right - rc.left;
		psizel->cy = rc.bottom - rc.top;
	}
	else
		*psizel = m_sizeInit;

	DPtoHIMETRIC(psizel);

	return S_OK;
}

STDMETHODIMP CActiveXControl::Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::Unadvise(DWORD dwConnection)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::EnumAdvise(IEnumSTATDATA **ppenumAdvise)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
{
	*pdwStatus = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_INSIDEOUT;

	return S_OK;
}

STDMETHODIMP CActiveXControl::SetColorScheme(LOGPALETTE *pLogpal)
{
	return E_NOTIMPL;
}


// IOleInPlaceObject


STDMETHODIMP CActiveXControl::GetWindow(HWND *phwnd)
{
	*phwnd = m_hwnd;

	return S_OK;
}

STDMETHODIMP CActiveXControl::ContextSensitiveHelp(BOOL fEnterMode)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::InPlaceDeactivate()
{
	if (m_pInPlaceSite != NULL) {
		m_pInPlaceSite->OnInPlaceDeactivate();
		m_pInPlaceSite->Release();
		m_pInPlaceSite = NULL;
	}

	ShowWindow(m_hwnd, SW_HIDE);
	m_pClientSite->OnShowWindow(FALSE);

	return S_OK;
}

STDMETHODIMP CActiveXControl::ReactivateAndUndo()
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
	MoveWindow(m_hwnd, lprcPosRect->left, lprcPosRect->top, lprcPosRect->right - lprcPosRect->left, lprcPosRect->bottom - lprcPosRect->top, TRUE);

	return S_OK;
}

STDMETHODIMP CActiveXControl::UIDeactivate()
{
	return S_OK;
}


// IOleControl


STDMETHODIMP CActiveXControl::GetControlInfo(CONTROLINFO *pCI)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::OnMnemonic(MSG *pMsg)
{
	return S_OK;
}

STDMETHODIMP CActiveXControl::OnAmbientPropertyChange(DISPID dispID)
{
	return S_OK;
}

STDMETHODIMP CActiveXControl::FreezeEvents(BOOL bFreeze)
{
	return E_NOTIMPL;
}


// IDispatch


STDMETHODIMP CActiveXControl::GetTypeInfoCount(UINT *pctinfo)
{
	*pctinfo = 0;
	
	return S_OK;
}

STDMETHODIMP CActiveXControl::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
	if (wFlags == DISPATCH_PROPERTYGET) {
		if (dispIdMember == DISPID_ENABLED) {
			pVarResult->vt = VT_BOOL;
			pVarResult->boolVal = VARIANT_TRUE;
		}
		else if (dispIdMember == DISPID_READYSTATE) {
			pVarResult->vt = VT_I4;
			pVarResult->lVal = m_nState;
		}
		else if (dispIdMember == DISPID_FORECOLOR) {
			pVarResult->vt = VT_I4;
			pVarResult->lVal = m_crEllipse;
		}
		else
			;
	}

	return S_OK;
}


// IQuickActivate


HRESULT CActiveXControl::QuickActivate(QACONTAINER *pQaContainer, QACONTROL *pQaControl)
{
	GetMiscStatus(DVASPECT_CONTENT, &pQaControl->dwMiscStatus);
	SetClientSite(pQaContainer->pClientSite);
	pQaControl->dwViewStatus = 0;
	pQaControl->dwEventCookie = 0;
	pQaControl->dwPropNotifyCookie = 0;
	pQaControl->dwPointerActivationPolicy = 0;

	return S_OK;
}

HRESULT CActiveXControl::SetContentExtent(LPSIZEL pSizel)
{
	return SetExtent(DVASPECT_CONTENT, pSizel);
}

HRESULT CActiveXControl::GetContentExtent(LPSIZEL pSizel)
{
	return GetExtent(DVASPECT_CONTENT, pSizel);
}


STDMETHODIMP CActiveXControl::GetClassID(CLSID *pClassID)
{
	*pClassID = CLSID_ActiveXControlSample;

	return S_OK;
}


// IPersistStreamInit


STDMETHODIMP CActiveXControl::IsDirty()
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::Load(LPSTREAM pStm)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::Save(LPSTREAM pStm, BOOL fClearDirty)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::GetSizeMax(ULARGE_INTEGER *pCbSize)
{
	return E_NOTIMPL;
}

STDMETHODIMP CActiveXControl::InitNew(VOID)
{
	m_crEllipse = RGB(255, 255, 255);
	m_nState = READYSTATE_COMPLETE;

	return S_OK;
}


// IPersistPropertyBag


STDMETHODIMP CActiveXControl::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
{
	VARIANT var;

	var.vt = VT_BSTR;
	pPropBag->Read(L"color", &var, NULL);

	if (lstrcmpW(var.bstrVal, L"red") == 0)
		m_crEllipse = RGB(255, 0, 0);
	else if (lstrcmpW(var.bstrVal, L"green") == 0)
		m_crEllipse = RGB(0, 255, 0);
	else if (lstrcmpW(var.bstrVal, L"blue") == 0)
		m_crEllipse = RGB(0, 0, 255);
	else
		m_crEllipse = RGB(255, 255, 255);
	
	m_nState = READYSTATE_COMPLETE;

	return S_OK;
}

STDMETHODIMP CActiveXControl::Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
{
	return E_NOTIMPL;
}


// IObjectSafety


STDMETHODIMP CActiveXControl::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{
	*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACESAFE_FOR_UNTRUSTED_CALLER;
	
	if (IsEqualIID(riid, IID_IPersistPropertyBag))
		*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
	else if (IsEqualIID(riid, IID_IDispatch))
		*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
	else
		*pdwEnabledOptions = 0;

	return S_OK;
}

STDMETHODIMP CActiveXControl::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
	if (dwOptionSetMask == 0 && dwEnabledOptions == 0)
		return S_OK;
	
	if (IsEqualIID(riid, IID_IPersistPropertyBag)) {
		if (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions)
			return S_OK;
	}
	else if (IsEqualIID(riid, IID_IDispatch)) {
		if (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions)
			return S_OK;
	}
	else
		;

	return E_FAIL;
}


// original


LRESULT CActiveXControl::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {

	case WM_PAINT: {
		HDC         hdc;
		RECT        rc;
		HBRUSH      hbr, hbrPrev;
		PAINTSTRUCT ps;

		hdc = BeginPaint(hwnd, &ps);

		GetClientRect(hwnd, &rc);
		
		hbr = CreateSolidBrush(m_crEllipse);
		hbrPrev = (HBRUSH)SelectObject(hdc, hbr);
		Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom);
		SelectObject(hdc, hbrPrev);
		DeleteObject(hbr);

		EndPaint(hwnd, &ps);

		return 0;
	}

	default:
		break;

	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

BOOL CActiveXControl::InPlaceActivate(HWND hwndParent, LPRECT lprc)
{
	HRESULT hr;

	hr = m_pClientSite->QueryInterface(IID_PPV_ARGS(&m_pInPlaceSite));
	if (FAILED(hr))
		return FALSE;
	
	hr = m_pInPlaceSite->CanInPlaceActivate();
	if (FAILED(hr)) {
		m_pInPlaceSite->Release();
		m_pInPlaceSite = NULL;
		return FALSE;
	}

	m_pInPlaceSite->OnInPlaceActivate();

	m_hwnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, g_szClassName, TEXT(""), WS_CHILD | WS_CLIPSIBLINGS, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top, hwndParent, (HMENU)ID_WINDOW, g_hinstDll, NULL);
	SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this);

	m_pClientSite->ShowObject();
	ShowWindow(m_hwnd, SW_SHOW);
	m_pClientSite->OnShowWindow(TRUE);

	return TRUE;
}

void CActiveXControl::DPtoHIMETRIC(LPSIZEL lpSizel)
{
	HDC hdc;
	const int HIMETRIC_INCH = 2540;

	hdc = GetDC(NULL);
	lpSizel->cx = lpSizel->cx * HIMETRIC_INCH / GetDeviceCaps(hdc, LOGPIXELSX);
	lpSizel->cy = lpSizel->cy * HIMETRIC_INCH / GetDeviceCaps(hdc, LOGPIXELSY);
	ReleaseDC(NULL, hdc);
}

void CActiveXControl::HIMETRICtoDP(LPSIZEL lpSizel)
{
	HDC hdc;
	const int HIMETRIC_INCH = 2540;

	hdc = GetDC(NULL);
	lpSizel->cx = lpSizel->cx * GetDeviceCaps(hdc, LOGPIXELSX) / HIMETRIC_INCH;
	lpSizel->cy = lpSizel->cy * GetDeviceCaps(hdc, LOGPIXELSY) / HIMETRIC_INCH;
	ReleaseDC(NULL, hdc);
}

戻る