MFCを使ってActiveXコントロールを作成する

【目標】

【必要な環境】

 

【始めに】

(できる限り)インターフェイスを決めておく
後で足しても反映されないことがある

ここでは仮に以下のような外部インタフェースを用意しておく。

【メソッド・・・コントロールを実装した実装側から呼び出す】

メソッド説明
BSTR DoCommand(BSTR param)後で困ったときに機能を追加するために文字列をやりとりするメソッド
void SetParam(INT what, INT value);パラメータをセットするメソッド
INT GetParam(INT what);パラメータを取得するメソッド


【イベント・・・ActiveX 側から実装側を呼び出す】

メソッド説明
ClickIn(x,y)クリックされたコントロール内の座標を返す


【プロジェクトを作成】

新しいプロジェクトを作成
VisualC++ -> MFC -> MFCActiveX コントロール
ここでは「MFCActiveXControlSample」という名前でコントロールを作ることにする。


設定画面、特に変更なし


ベースにするコントロールとか・・・とくに設定しない(役に立ちそうにない)

 

 

【ビルドする前に・・・プロジェクト設定】

UAC回避

プロジェクトー>プロパティー>リンカーー>全般
出力の登録をいいえに設定



以上、Release x64 / Release Win32 / Debug x64 / Debug Win32
全てに設定

ここでいったんビルド
エラーなくビルドができる事を確認

 

【イベントハンドラの追加】

クラスビューから、MFCActiveXControlSampleCtrlを右クリックして、
プロパティを選ぶ

ここではマウスの左ボタンに反応するように、LButtonDown イベントを実装する.

 

すると、以下のようなプログラムができあがる。
後で使うので今はこのまま.

 

【DISPATCH / EVENT ID追加】

ファイルIDs.h を追加する

/******************************************
 *@file IDs.h
 * ディスパッチIDおよびイベントIDの定義
 ******************************************/
#pragma once

#define DISPID_DoCommand	1
#define DISPID_SetParam		2
#define DISPID_GetParam		3

#define EVENTID_ClickIn 1

 

 

新しい項目、CatHelp.h / CatHelp.cpp を追加

【CatHelp.h(Microsoft社提供ファイル)】

#pragma once
#include "comcat.h"

// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);

// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

 

 

【CatHelp.cpp(Microsoft社提供ファイル)】

#include "stdafx.h"
#include "comcat.h"

// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{
    ICatRegister* pcr = NULL;
    HRESULT hr = S_OK;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_ICatRegister,
        (void**)&pcr);
    if (FAILED(hr))
        return hr;

    // Make sure the HKCR\Component Categories\{..catid...}
    // key is registered
    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409; // english

    // Make sure the provided description is not too long.
    // Only copy the first 127 characters if it is
    int len = wcslen(catDescription);
    if (len>127)
        len = 127;
    wcsncpy_s(catinfo.szDescription, catDescription, len);
    // Make sure the description is null terminated
    catinfo.szDescription[len] = '\0';

    hr = pcr->RegisterCategories(1, &catinfo);
    pcr->Release();

    return hr;
}

// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
    // Register your component categories information.
    ICatRegister* pcr = NULL;
    HRESULT hr = S_OK;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_ICatRegister,
        (void**)&pcr);
    if (SUCCEEDED(hr))
    {
        // Register this category as being "implemented" by
        // the class.
        CATID rgcatid[1];
        rgcatid[0] = catid;
        hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }

    if (pcr != NULL)
        pcr->Release();

    return hr;
}


【dllエントリ及びセルフレジストリモジュール(MFCActiveXControlSample.cpp)変更】

// MFCActiveXControlSample.cpp : CMFCActiveXControlSampleApp および DLL 登録の実装。

#include "stdafx.h"
#include "CatHelp.h"    //!< 追加
#include "MFCActiveXControlSample.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CMFCActiveXControlSampleApp theApp;

const GUID CDECL _tlid = {0x0a4f0747,0xde05,0x414c,{0xa3,0x7f,0x1a,0xb3,0x87,0xcd,0xb3,0x11}};
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;



// CMFCActiveXControlSampleApp::InitInstance - DLL 初期化

BOOL CMFCActiveXControlSampleApp::InitInstance()
{
    BOOL bInit = COleControlModule::InitInstance();

    if (bInit)
    {
        // TODO: この位置にモジュールの初期化処理コードを追加してください。
    }

    return bInit;
}



// CMFCActiveXControlSampleApp::ExitInstance - DLL 終了

int CMFCActiveXControlSampleApp::ExitInstance()
{
    // TODO: この位置にモジュールの終了処理を追加してください。

    return COleControlModule::ExitInstance();
}



// DllRegisterServer - エントリをシステム レジストリに追加します。

STDAPI DllRegisterServer(void)
{
    AFX_MANAGE_STATE(_afxModuleAddrThis);

    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
        return ResultFromScode(SELFREG_E_TYPELIB);

    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
        return ResultFromScode(SELFREG_E_CLASS);
#ifdef OBJECTSAFETY if (FAILED(CreateComponentCategory( CATID_SafeForInitializing, L"Controls safely initializable from persistent data"))) return ResultFromScode(SELFREG_E_CLASS); if (FAILED(RegisterCLSIDInCategory( _tlid, CATID_SafeForScripting))) return ResultFromScode(SELFREG_E_CLASS); if (FAILED(RegisterCLSIDInCategory( _tlid, CATID_SafeForInitializing))) return ResultFromScode(SELFREG_E_CLASS); #endif  
return NOERROR; } // DllUnregisterServer - エントリをレジストリから削除します。 // STDAPI DllUnregisterServer(void) { AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) return ResultFromScode(SELFREG_E_CLASS); return NOERROR; }


【基本ヘッダファイル(MFCActiveXControlSample.h)編集】

#pragma once

#include <atlctl.h>      //!< 追加
#define OBJECTSAFETY     //!< 追加

// MFCActiveXControlSample.h : MFCActiveXControlSample.DLL のメイン ヘッダー ファイル

#if !defined( __AFXCTL_H__ )
#error "このファイルをインクルードする前に 'afxctl.h' をインクルードしてください。"
#endif

#include "resource.h"       // メイン シンボル


// CMFCActiveXControlSampleApp : 実装については MFCActiveXControlSample.cpp を参照してください。

class CMFCActiveXControlSampleApp : public COleControlModule
{
public:
    BOOL InitInstance();
    int ExitInstance();
};

extern const GUID CDECL _tlid;
extern const WORD _wVerMajor;
extern const WORD _wVerMinor;

 

 

【インタフェース記述ファイル(MFCActiveXControlSample.idl)編集】

// MFCActiveXControlSample.idl : ActiveX コントロール プロジェクトのタイプ ライブラリ ソースです。

// このファイルは、[!output PROJECT_NAME].ocx のリソース
// になるタイプ ライブラリ (MFCActiveXControlSample.tlb) を生成するために MIDL コンパイラ ツールによって処理されます。これは次のリソースになります:
// MFCActiveXControlSample.ocx。

#include <olectl.h>
#include <idispids.h>
#include "IDs.h"  //!< 追加
[ uuid(0a4f0747-de05-414c-a37f-1ab387cdb311), version(1.0),
  control ]
library MFCActiveXControlSampleLib
{
    importlib(STDOLE_TLB);

    //  CMFCActiveXControlSampleCtrl のプライマリ ディスパッチ インターフェイス
    [ 
        uuid(b560ce81-958e-4cb9-b74f-3e5518c3c140)
    ]
    dispinterface _DMFCActiveXControlSample
    {
        properties:
        methods:
            [id(DISPID_ABOUTBOX)] void AboutBox();
            [id(DISPID_DoCommand)] BSTR DoCommand(BSTR param);
            [id(DISPID_SetParam)] void SetParam(INT what, INT param);
            [id(DISPID_GetParam)] INT GetParam(INT what);
    };

    //  CMFCActiveXControlSampleCtrl のイベント ディスパッチ インターフェイス

    [ 
        uuid(8e5b29ae-9ba3-4451-95da-7d1add44a834)
    ]
    dispinterface _DMFCActiveXControlSampleEvents
    {
        properties:
            //  イベント インターフェイスにプロパティがありません。

        methods:
            [id(EVENTID_ClickIn)] void ClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);
    };

    //  CMFCActiveXControlSampleCtrl のクラス情報
    [
        uuid(cc5b7637-b6a2-4c37-ba8f-67eac6efcafb)
    ]
    coclass MFCActiveXControlSample
    {
        [default] dispinterface _DMFCActiveXControlSample;
        [default, source] dispinterface _DMFCActiveXControlSampleEvents;
    };

};

 

 

【ActiveXコントロールクラスの宣言(MFCActiveXControlSampleCtrl.h)を編集】

#pragma once

// MFCActiveXControlSampleCtrl.h : CMFCActiveXControlSampleCtrl ActiveX コントロール クラスの宣言。


// CMFCActiveXControlSampleCtrl : 実装については MFCActiveXControlSampleCtrl.cpp を参照してください。

class CMFCActiveXControlSampleCtrl : public COleControl
{
    DECLARE_DYNCREATE(CMFCActiveXControlSampleCtrl)

#ifdef OBJECTSAFETY
    //  IObjectSafety の実装
protected:
    DECLARE_INTERFACE_MAP()
    BEGIN_INTERFACE_PART(ObjectSafety, IObjectSafety)
        STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions);
        STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions);
    END_INTERFACE_PART(ObjectSafety)
#endif
    // コンストラクター
public:
    CMFCActiveXControlSampleCtrl();

// オーバーライド
public:
    virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
    virtual void DoPropExchange(CPropExchange* pPX);
    virtual void OnResetState();

    void FireClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);

// 実装
protected:
    ~CMFCActiveXControlSampleCtrl();

    DECLARE_OLECREATE_EX(CMFCActiveXControlSampleCtrl)    // クラス ファクトリ と guid
    DECLARE_OLETYPELIB(CMFCActiveXControlSampleCtrl)      // GetTypeInfo
    DECLARE_PROPPAGEIDS(CMFCActiveXControlSampleCtrl)     // プロパティ ページ ID
    DECLARE_OLECTLTYPE(CMFCActiveXControlSampleCtrl)        // タイプ名とその他のステータス

// メッセージ マップ
    DECLARE_MESSAGE_MAP()



// ディスパッチ マップ
    DECLARE_DISPATCH_MAP()

    afx_msg void AboutBox();
    afx_msg BSTR DoCommand(BSTR param);
    afx_msg void SetParam(INT what, INT value);
    afx_msg INT  GetParam(INT what);

// イベント マップ
    DECLARE_EVENT_MAP()

// ディスパッチ と イベント ID
public:
    enum {
    };
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};

 

 

【ActiveXコントロールクラスの実装(MFCActiveXControlSampleCtrl.cpp)を編集】

// MFCActiveXControlSampleCtrl.cpp : CMFCActiveXControlSampleCtrl ActiveX コントロール クラスの実装。

#include "stdafx.h"
#include "MFCActiveXControlSample.h"
#include "MFCActiveXControlSampleCtrl.h"
#include "MFCActiveXControlSamplePropPage.h"
#include "afxdialogex.h"
#include "IDs.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNCREATE(CMFCActiveXControlSampleCtrl, COleControl)

// メッセージ マップ

BEGIN_MESSAGE_MAP(CMFCActiveXControlSampleCtrl, COleControl)
    ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// ディスパッチ マップ
BEGIN_DISPATCH_MAP(CMFCActiveXControlSampleCtrl, COleControl)
    DISP_FUNCTION_ID(CMFCActiveXControlSampleCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CMFCActiveXControlSampleCtrl, "DoCommand",DISPID_DoCommand,DoCommand,VT_BSTR,VTS_BSTR) DISP_FUNCTION_ID(CMFCActiveXControlSampleCtrl, "SetParam", DISPID_SetParam, SetParam, VT_EMPTY, VTS_I4 VTS_I4) DISP_FUNCTION_ID(CMFCActiveXControlSampleCtrl, "GetParam", DISPID_GetParam, GetParam, VT_I4, VTS_I4)  
END_DISPATCH_MAP() // イベント マップ BEGIN_EVENT_MAP(CMFCActiveXControlSampleCtrl, COleControl) EVENT_CUSTOM_ID("ClickIn", EVENTID_ClickIn, FireClickIn, VTS_XPOS_PIXELS VTS_YPOS_PIXELS) END_EVENT_MAP() // プロパティ ページ // TODO: プロパティ ページを追加して、BEGIN 行の最後にあるカウントを増やしてください。 BEGIN_PROPPAGEIDS(CMFCActiveXControlSampleCtrl, 1) PROPPAGEID(CMFCActiveXControlSamplePropPage::guid) END_PROPPAGEIDS(CMFCActiveXControlSampleCtrl)
#ifdef OBJECTSAFETY BEGIN_INTERFACE_MAP(CMFCActiveXControlSampleCtrl, COleControl) INTERFACE_PART(CMFCActiveXControlSampleCtrl, IID_IObjectSafety, ObjectSafety) END_INTERFACE_MAP() #endif  
// クラス ファクトリおよび GUID を初期化します。 IMPLEMENT_OLECREATE_EX(CMFCActiveXControlSampleCtrl, "MFCACTIVEXCONTRO.MFCActiveXControlSampleCtrl.1", 0xcc5b7637,0xb6a2,0x4c37,0xba,0x8f,0x67,0xea,0xc6,0xef,0xca,0xfb) // タイプ ライブラリ ID およびバージョン IMPLEMENT_OLETYPELIB(CMFCActiveXControlSampleCtrl, _tlid, _wVerMajor, _wVerMinor) // インターフェイス ID const IID IID_DMFCActiveXControlSample = {0xb560ce81,0x958e,0x4cb9,{0xb7,0x4f,0x3e,0x55,0x18,0xc3,0xc1,0x40}}; const IID IID_DMFCActiveXControlSampleEvents = {0x8e5b29ae,0x9ba3,0x4451,{0x95,0xda,0x7d,0x1a,0xdd,0x44,0xa8,0x34}}; // コントロールの種類の情報 static const DWORD _dwMFCActiveXControlSampleOleMisc = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CMFCActiveXControlSampleCtrl, IDS_MFCACTIVEXCONTROLSAMPLE, _dwMFCActiveXControlSampleOleMisc) // CMFCActiveXControlSampleCtrl::CMFCActiveXControlSampleCtrlFactory::UpdateRegistry - // CMFCActiveXControlSampleCtrl のシステム レジストリ エントリを追加または削除します BOOL CMFCActiveXControlSampleCtrl::CMFCActiveXControlSampleCtrlFactory::UpdateRegistry(BOOL bRegister) { // TODO: コントロールが apartment モデルのスレッド処理の規則に従っていることを // 確認してください。詳細については MFC のテクニカル ノート 64 を参照してください。 // アパートメント モデルのスレッド処理の規則に従わないコントロールの場合は、6 番目 // のパラメーターを以下のように変更してください。 // afxRegApartmentThreading を 0 に設定します。 if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_MFCACTIVEXCONTROLSAMPLE, IDB_MFCACTIVEXCONTROLSAMPLE, afxRegApartmentThreading, _dwMFCActiveXControlSampleOleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } // CMFCActiveXControlSampleCtrl::CMFCActiveXControlSampleCtrl - コンストラクター CMFCActiveXControlSampleCtrl::CMFCActiveXControlSampleCtrl() { InitializeIIDs(&IID_DMFCActiveXControlSample, &IID_DMFCActiveXControlSampleEvents); // TODO: この位置にコントロールのインスタンス データの初期化処理を追加してください } // CMFCActiveXControlSampleCtrl::~CMFCActiveXControlSampleCtrl - デストラクタ― CMFCActiveXControlSampleCtrl::~CMFCActiveXControlSampleCtrl() { // TODO: この位置にコントロールのインスタンス データの後処理用のコードを追加してください } // CMFCActiveXControlSampleCtrl::OnDraw - 描画関数 void CMFCActiveXControlSampleCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& /* rcInvalid */) { if (!pdc) return; // TODO: 以下のコードを描画用のコードに置き換えてください pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds); } // CMFCActiveXControlSampleCtrl::DoPropExchange - 永続性のサポート void CMFCActiveXControlSampleCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: 永続属性を持つ各カスタム プロパティ用の PX_ 関数を呼び出します。 } // CMFCActiveXControlSampleCtrl::OnResetState - コントロールを既定の状態にリセットします void CMFCActiveXControlSampleCtrl::OnResetState() { COleControl::OnResetState(); // DoPropExchange を呼び出して既定値にリセット // TODO: この位置にコントロールの状態をリセットする処理を追加してください } // CMFCActiveXControlSampleCtrl::AboutBox - "バージョン情報" ボックスをユーザーに表示します void CMFCActiveXControlSampleCtrl::AboutBox() { CDialogEx dlgAbout(IDD_ABOUTBOX_MFCACTIVEXCONTROLSAMPLE); dlgAbout.DoModal(); } // CMFCActiveXControlSampleCtrl メッセージ ハンドラー
BSTR CMFCActiveXControlSampleCtrl::DoCommand(BSTR param) { return SysAllocString(L"DoCommand done!"); } void CMFCActiveXControlSampleCtrl::SetParam(INT what, INT value) { } INT CMFCActiveXControlSampleCtrl::GetParam(INT what) { return 0; } void CMFCActiveXControlSampleCtrl::FireClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord) { FireEvent(EVENTID_ClickIn, EVENT_PARAM(VTS_XPOS_PIXELS VTS_YPOS_PIXELS), xCoord, yCoord); }  
#ifdef OBJECTSAFETY /** * IObjectSafety をMFC 向けにインプリメントする * クラス名に注意! */ /** *@fn * SafetyOption を取得する *@param in riid 実装されている(と思われている)インタフェースを示すGUID *@param out pdwSupportedOptions サポートされているオプション *@param out pdwEnabledOptions 有効化されているオプション *@return 成功すれば S_OK */ STDMETHODIMP CMFCActiveXControlSampleCtrl::XObjectSafety::GetInterfaceSafetyOptions( REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE_EX(CMFCActiveXControlSampleCtrl, ObjectSafety) if (!pdwSupportedOptions || !pdwEnabledOptions) { return E_POINTER; } *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; *pdwEnabledOptions = 0; if (NULL == pThis->GetInterface(&riid)) { _RPT0(_CRT_WARN, "Requested interface is not supported./n"); return E_NOINTERFACE; } // エラーメッセージの為に // 指定されたレジストリが何か確認しておく( HKEY_CLASSES_ROOT/Interface ) USES_CONVERSION; char *szGUID; OLECHAR _szGUID[39]; int i = StringFromGUID2(riid, _szGUID, 39); #ifdef _UNICODE szGUID = W2A(_szGUID); #else szGUID = _szGUID; #endif if (riid == IID_IDispatch) { // Client wants to know if object is safe for scripting *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; return S_OK; } else if (riid == IID_IPersistPropertyBag || riid == IID_IPersistStreamInit || riid == IID_IPersistStorage || riid == IID_IPersistMemory) { // Those are the persistence interfaces COleControl derived controls support // as indicated in AFXCTL.H // Client wants to know if object is safe for initializing from persistent data *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; return S_OK; } else { // 判断不能なとき(IDispatch / IPersist 以外) _RPT0(_CRT_WARN, "We didn't account for the safety of this interface, and it's one we support.../n"); return E_NOINTERFACE; } } /** *@fn * SafetyOption を設定する *@param in riid 実装されている(と思われている)インタフェースを示すGUID *@param in dwOptionSetMask 設定するオプションの指定 *@param in dwEnabledOptions それぞれのオプションに対して設定する値 *@return 成功すれば S_OK */ STDMETHODIMP CMFCActiveXControlSampleCtrl::XObjectSafety::SetInterfaceSafetyOptions( REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) { METHOD_PROLOGUE_EX(CMFCActiveXControlSampleCtrl, ObjectSafety) // エラーメッセージの為に // 指定されたレジストリが何か確認しておく( HKEY_CLASSES_ROOT/Interface ) USES_CONVERSION; char *szGUID; OLECHAR _szGUID[39]; int i = StringFromGUID2(riid, _szGUID, 39); #ifdef _UNICODE szGUID = W2A(_szGUID); #else szGUID = _szGUID; #endif if (0 == dwOptionSetMask && 0 == dwEnabledOptions) { // the control certainly supports NO requests through the specified interface // so it's safe to return S_OK even if the interface isn't supported. return S_OK; } // Do we support the specified interface? if (NULL == pThis->GetInterface(&riid)) { _RPT1(_CRT_WARN, "%s is not support./n", szGUID); return E_FAIL; } if (riid == IID_IDispatch) { _RPT0(_CRT_WARN, "IDispatch 経由での呼び出し設定./n"); if (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions) { return S_OK; } else { return E_FAIL; } } else if (riid == IID_IPersistPropertyBag || riid == IID_IPersistStreamInit || riid == IID_IPersistStorage || riid == IID_IPersistMemory) { _RPT0(_CRT_WARN, "IPersist 経由での呼び出し設定./n"); if (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions) { return NOERROR; } else { return E_FAIL; } } else { // 判断不能なとき(IDispatch / IPersist 以外) _RPT1(_CRT_WARN, "We didn't account for the safety of %s, and it's one we support.../n", szGUID); return E_FAIL; } } STDMETHODIMP_(ULONG) CMFCActiveXControlSampleCtrl::XObjectSafety::AddRef() { METHOD_PROLOGUE_EX_(CMFCActiveXControlSampleCtrl, ObjectSafety) return (ULONG)pThis->ExternalAddRef(); } STDMETHODIMP_(ULONG) CMFCActiveXControlSampleCtrl::XObjectSafety::Release() { METHOD_PROLOGUE_EX_(CMFCActiveXControlSampleCtrl, ObjectSafety) return (ULONG)pThis->ExternalRelease(); } STDMETHODIMP CMFCActiveXControlSampleCtrl::XObjectSafety::QueryInterface( REFIID iid, LPVOID* ppvObj) { METHOD_PROLOGUE_EX_(CMFCActiveXControlSampleCtrl, ObjectSafety) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } #endif  
void CMFCActiveXControlSampleCtrl::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: ここにメッセージ ハンドラー コードを追加するか、既定の処理を呼び出します。 this->FireClickIn(point.x, point.y); COleControl::OnLButtonDown(nFlags, point); }

 

 

ActiveX コントロールのインストールには、コマンドプロンプトを、管理者権限で起動して、
(Windows+R でファイル名を指定して実行ウィンドウを表示させ、cmdと入力して、Ctrl+Shift+Alt で Enter)
regsvr32 を使用して以下のようにする
regsvr32 MFCActiveXControlSample.ocx


こうなれば成功

 

 

インストーラプロジェクトでは、インストール時の登録モードを、 vsdrSelfReg にすればOK

 

 

【Excel に配置する例】

VBAエディタにてツール -> 参照設定

 

ツールボックスに登録

 

ユーザフォームに配置

 

試してみる・・・イベント・プロシージャが使えることを確認。

 

 

以上、警告なしで動作できるようになりました。
戻る