ブラウザでダウンロード COM は、ビルドするとその PC に登録されてしまいます。 リリースしたものは、他の PC で regsvr32.exe で登録します。 以下、Microsoft の regsvr32 的なドキュメント 1) ダウンロード センターから入手可能な Regsvr32.exe 2) Regsvr32.exe の登録し、COM DLL の登録を解除するソースコード ● ATL プロジェクトを作成する● クラスを追加する● メソッドを追加● ビルド環境設定● 簡単なメソッドの実装tool.h に lightbox.h の参照を追加して、#pragma の記述を行います #pragma once #include "resource.h" #include "night.h" #include "lightbox\lightbox.h" #pragma comment( lib, "lightbox\\lightbox.lib" ) #pragma comment( lib, "shlwapi.lib" ) #pragma comment( lib, "wininet.lib" ) // ********************************************************* // MsgBox // ********************************************************* STDMETHODIMP Ctool::MsgBox(BSTR str) { _bstr_t bstr = str; ::MessageBox( NULL, (LPTSTR)bstr, "", MB_OK ); return S_OK; } テスト用スクリプト
Set obj = CreateObject("night.tool") obj.MsgBox("OK") ● 戻り値を返すメソッドの実装何故か、ウィザードでは指定できないようなので、手作業で追加します 場所は 3 箇所あるので注意して下さい。 night.idl
// night.idl : night の IDL ソース // // このファイルは、タイプ ライブラリ (night.tlb) およびマーシャリング コードを // 作成するために MIDL ツールによって処理されます。 import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(56CFD513-9FFE-49F7-BE4F-CCFFD77A260D), dual, nonextensible, helpstring("Itool インターフェイス"), pointer_default(unique) ] interface Itool : IDispatch{ [id(1), helpstring("メソッド MsgBox")] HRESULT MsgBox([in] BSTR str); [id(2), helpstring("メソッド GetClipboard")] HRESULT GetClipboard([out,retval] BSTR *pVal); }; [ uuid(246E5E95-954B-4461-A7A8-1677C3412E20), version(1.0), helpstring("night 1.0 タイプ ライブラリ") ] library nightLib { importlib("stdole2.tlb"); [ uuid(543A98AE-FEFC-4D34-99ED-D8D7FE94823C), helpstring("tool Class") ] coclass tool { [default] interface Itool; }; }; id(2) の行が追加されています 戻り値は、[out,retval] BSTR *pVal で表現されます tool.h
// Ctool class ATL_NO_VTABLE Ctool : public CComObjectRootEx<CComMultiThreadModel>, public CComCoClass<Ctool, &CLSID_tool>, public IDispatchImpl<Itool, &IID_Itool, &LIBID_nightLib, /*wMajor =*/ 1, /*wMinor =*/ 0> { public: Ctool() { } DECLARE_REGISTRY_RESOURCEID(IDR_TOOL) BEGIN_COM_MAP(Ctool) COM_INTERFACE_ENTRY(Itool) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } public: STDMETHOD(MsgBox)(BSTR str); STDMETHOD(GetClipboard)(BSTR *pVal); }; OBJECT_ENTRY_AUTO(__uuidof(tool), Ctool) Ctool クラスとしてのメソッド宣言の追加です 仮引数の記述のみを行います tool.cpp
STDMETHODIMP Ctool::GetClipboard(BSTR *pVal) { _bstr_t bstrValue; LboxString LString; LboxTool Tool; Tool.GetClipboardText( LString ); bstrValue.operator = (LString.szLboxString); *pVal = bstrValue.copy(); return S_OK; } 処理本体です。 戻り値のメモリ管理は、受け渡したアプリケーションで行われるので、 copy メソッドにより作成された新しいメモリを渡します。 テスト用スクリプト
Set obj = CreateObject("night.tool") obj.MsgBox( obj.GetClipboard() ) ● 引数を省略可能にするには以下は、別の COM のサンプルです interface IMyAPI : IDispatch { [id(1), helpstring("メソッド MsgBox")] HRESULT MsgBox( [in] BSTR Message, [in,optional] VARIANT Title ); }; public: STDMETHOD(MsgBox)( BSTR Message, VARIANT Title ); STDMETHODIMP CMyAPI::MsgBox( BSTR Message, VARIANT Title ) { // 引数省略チェック用 _variant_t vtWork(Title); _bstr_t bstr(Message); _bstr_t bstr2; // タイトル引数チェック if ( vtWork.vt != VT_ERROR ) { bstr2.operator = (Title); } else { bstr2.operator = ("デフォルト文字列"); } MessageBox( NULL, (LPTSTR)bstr, (LPTSTR)bstr2, MB_OK ); return S_OK; } ● BOOLを返すには通常の C++ における 真偽値の扱いと違うので( 正確に定義されている ) LboxBool 関数によって変換します。 [id(3), helpstring("メソッド MsgOkCancel")] HRESULT MsgOkCancel( [in] BSTR Value, [out,retval] BOOL *pVal ); STDMETHOD(MsgOkCancel)( BSTR Value, BOOL *pVal ); STDMETHODIMP CMyAPI::MsgOkCancel( BSTR Value, BOOL *pVal ) { _bstr_t bstrValue; LboxWintool Wintool; bstrValue.operator = (Value); *pVal = LboxBool( Wintool.MsgOkCancel((LPTSTR)bstrValue) ); return S_OK; } LboxBool
BOOL LboxBool( BOOL bFlg ) { BOOL bRet; if ( bFlg ) { bRet = 0xffffffff; } else { bRet = 0; } return bRet; } |