Archive for the ‘COM’ Category
-
Hello, COM(VB6) World!
Posted on 5月 13th, 2012 by cx20
COM(VB6)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は VB6 による COM クライアント(事前バインディングならびに実行時バインディング)の例となっている。ソースコード(事前バインディング)
Sub Main() Dim shell As New Shell32.shell Dim vRootFolder vRootFolder = Shell32.ShellSpecialFolderConstants.ssfWINDOWS Dim folder As Shell32.folder Set folder = shell.BrowseForFolder(0, "Hello, COM(VB6) World!", 0, vRootFolder) If Not folder Is Nothing Then Set folder = Nothing End If Set shell = Nothing End Sub
以下、プロジェクトファイルより一部抜粋。
プロジェクトファイル(事前バインディング)
Type=Exe Reference=*G{00020430-0000-0000-C000-000000000046}#2.0#0#WINDOWSsystem32STDOLE2.TLB#OLE Automation Reference=*G{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}#1.0#0#WINDOWSsystem32SHELL32.dll#Microsoft Shell Controls And Automation Module=Hello; Hello.bas Startup="Sub Main" ExeName32="hello.exe" Name="HelloProject"
ソースコード(実行時バインディング)
Sub Main() Dim shell Set shell = CreateObject("Shell.Application") Dim vRootFolder vRootFolder = 36 ' ssfWINDOWS Dim folder Set folder = shell.BrowseForFolder(0, "Hello, COM(VB6) World!", 0, vRootFolder) If Not folder Is Nothing Then Set folder = Nothing End If Set shell = Nothing End Sub
コンパイル方法
C:¥> vb6 /make Hello.vbp
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM(VB6) Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(MASM) World!
Posted on 5月 12th, 2012 by cx20
COM(MASM)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は MASM による COM クライアントの例となっている。ソースコード
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01 TITLE hello.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG113507 DB 'H', 00H, 'e', 00H, 'l', 00H, 'l', 00H, 'o', 00H, ',', 00H DB ' ', 00H, 'C', 00H, 'O', 00H, 'M', 00H, '(', 00H, 'M', 00H, 'A' DB 00H, 'S', 00H, 'M', 00H, ')', 00H, ' ', 00H, 'W', 00H, 'o', 00H DB 'r', 00H, 'l', 00H, 'd', 00H, '!', 00H, 00H, 00H _DATA ENDS PUBLIC _main EXTRN __imp__CoUninitialize@0:PROC EXTRN __imp__CoCreateInstance@20:PROC EXTRN _CLSID_Shell:BYTE EXTRN _IID_IShellDispatch:BYTE EXTRN __imp__CoInitialize@4:PROC ; Function compile flags: /Odtp _TEXT SEGMENT _pFolder$ = -36 ; size = 4 _vRootFolder$ = -32 ; size = 16 _folder$ = -12 ; size = 4 _pShell$ = -4 ; size = 4 _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; File hello.c ; Line 4 push ebp mov ebp, esp sub esp, 36 ; 00000024H ; Line 11 push 0 call DWORD PTR __imp__CoInitialize@4 ; Line 13 lea eax, DWORD PTR _pShell$[ebp] push eax push OFFSET _IID_IShellDispatch push 1 push 0 push OFFSET _CLSID_Shell call DWORD PTR __imp__CoCreateInstance@20 ; Line 15 mov ecx, 3 mov WORD PTR _vRootFolder$[ebp], cx ; Line 16 mov DWORD PTR _vRootFolder$[ebp+8], 36 ; 00000024H ; Line 17 lea edx, DWORD PTR _folder$[ebp] mov DWORD PTR _pFolder$[ebp], edx ; Line 19 lea eax, DWORD PTR _pFolder$[ebp] push eax sub esp, 16 ; 00000010H mov ecx, esp mov edx, DWORD PTR _vRootFolder$[ebp] mov DWORD PTR [ecx], edx mov eax, DWORD PTR _vRootFolder$[ebp+4] mov DWORD PTR [ecx+4], eax mov edx, DWORD PTR _vRootFolder$[ebp+8] mov DWORD PTR [ecx+8], edx mov eax, DWORD PTR _vRootFolder$[ebp+12] mov DWORD PTR [ecx+12], eax push 0 push OFFSET $SG113507 push 0 mov ecx, DWORD PTR _pShell$[ebp] push ecx mov edx, DWORD PTR _pShell$[ebp] mov eax, DWORD PTR [edx] mov ecx, DWORD PTR [eax+40] call ecx ; Line 20 cmp DWORD PTR _pFolder$[ebp], 0 je SHORT $LN1@main ; Line 22 mov edx, DWORD PTR _pFolder$[ebp] push edx mov eax, DWORD PTR _pFolder$[ebp] mov ecx, DWORD PTR [eax] mov edx, DWORD PTR [ecx+8] call edx $LN1@main: ; Line 24 mov eax, DWORD PTR _pShell$[ebp] push eax mov ecx, DWORD PTR _pShell$[ebp] mov edx, DWORD PTR [ecx] mov eax, DWORD PTR [edx+8] call eax ; Line 26 call DWORD PTR __imp__CoUninitialize@0 ; Line 28 xor eax, eax ; Line 29 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
上記コードは以下のC言語のソースを VC++ でアセンブリコード出力(cl /FA hello.c)したものに相当する。
#include <shlobj.h> int main( int argc, char* argv[] ) { HRESULT hResult; IShellDispatch* pShell; VARIANT vRootFolder; Folder* pFolder; CoInitialize( NULL ); CoCreateInstance( &CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&pShell ); VariantInit( &vRootFolder ); vRootFolder.vt = VT_I4; vRootFolder.lVal = ssfWINDOWS; pShell->lpVtbl->BrowseForFolder( (void*)pShell, 0, L"Hello, COM(MASM) World!", 0, vRootFolder, &pFolder ); VariantClear( &vRootFolder ); if ( pFolder != NULL ) { pFolder->lpVtbl->Release( (void*)pFolder ); } pShell->lpVtbl->Release( (void*)pShell ); CoUninitialize(); return 0; }
コンパイル&リンク方法
C:¥> ml -c hello.asm C:¥> midl shldisp.idl C:¥> cl shldisp_i.c C:¥> link hello.obj shldisp_i.obj ole32.lib oleaut32.lib
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM(MASM) Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(MFC) World!
Posted on 5月 11th, 2012 by cx20
COM(MFC)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は Visual C++ / MFC による COM クライアント(事前バインディングならびに実行時バインディング)の例となっている。ソースコード(事前バインディング)
#include <afxdisp.h> // [Typelib クラス追加ウィザード] で作成された IDispatch ラッパー クラスより一部抜粋 class CFolder : public COleDispatchDriver { public: CFolder(){} CFolder(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {} CFolder(const CFolder& dispatchSrc) : COleDispatchDriver(dispatchSrc) {} public: CString get_Title() { CString result; InvokeHelper(0x0, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); return result; } }; // [Typelib クラス追加ウィザード] で作成された IDispatch ラッパー クラスより一部抜粋 class CShellDispatch : public COleDispatchDriver { public: CShellDispatch(){} CShellDispatch(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {} CShellDispatch(const CShellDispatch& dispatchSrc) : COleDispatchDriver(dispatchSrc) {} public: LPDISPATCH BrowseForFolder(long Hwnd, LPCTSTR Title, long Options, VARIANT& RootFolder) { LPDISPATCH result; static BYTE parms[] = VTS_I4 VTS_BSTR VTS_I4 VTS_VARIANT ; InvokeHelper(0x60020003, DISPATCH_METHOD, VT_DISPATCH, (void*)&result, parms, Hwnd, Title, Options, &RootFolder); return result; } }; int _tmain(int argc, TCHAR* argv[] ) { CoInitialize( NULL ); CFolder folder; CShellDispatch shell; shell.CreateDispatch( _T("Shell.Application") ); COleVariant vRootFolder( (long)ssfWINDOWS ); folder = shell.BrowseForFolder( 0, _T("Hello, COM(MFC) World!"), 0, vRootFolder ); if ( folder != NULL ) { folder.DetachDispatch(); folder.ReleaseDispatch(); } shell.DetachDispatch(); shell.ReleaseDispatch(); CoUninitialize(); return 0; }
ソースコード(実行時バインディング)
#include <afxdisp.h> int _tmain(int argc, TCHAR* argv[] ) { CoInitialize( NULL ); COleDispatchDriver shell; shell.CreateDispatch( _T("Shell.Application") ); DISPID dispid; OLECHAR* ptName = L"BrowseForFolder"; ((LPDISPATCH)shell)->GetIDsOfNames( IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid ); LPDISPATCH pResult; COleVariant vRootFolder( 36L ); // ssfWINDOWS BYTE parms[] = VTS_I4 VTS_BSTR VTS_I4 VTS_VARIANT; shell.InvokeHelper( dispid, DISPATCH_METHOD, VT_DISPATCH, &pResult, parms, 0, _T("Hello, COM(MFC) World!"), 0, &vRootFolder); COleDispatchDriver folder = pResult; if ( folder != NULL ) { folder.DetachDispatch(); folder.ReleaseDispatch(); } shell.DetachDispatch(); shell.ReleaseDispatch(); CoUninitialize(); return 0; }
コンパイル方法(Visual C++)
C:¥> cl hello.cpp
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM(MFC) Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(ATL) World!
Posted on 5月 10th, 2012 by cx20
COM(ATL)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は Visual C++ / ATL による COM クライアント(事前バインディングならびに実行時バインディング)の例となっている。ソースコード(事前バインディング)
#include <atlbase.h> #include <shlobj.h> int _tmain(int argc, TCHAR* argv[] ) { CoInitialize( NULL ); CComPtr<Folder> pFolder; CComPtr<IShellDispatch> pShell; pShell.CoCreateInstance( CLSID_Shell ); CComVariant vRootFolder( ssfWINDOWS ); pShell->BrowseForFolder( 0, L"Hello, COM(ATL) World!", 0, vRootFolder, &pFolder ); if ( pFolder != NULL ) { pFolder = NULL; } pShell = NULL; CoUninitialize(); return 0; }
ソースコード(実行時バインディング)
#include <atlbase.h> int _tmain(int argc, TCHAR* argv[] ) { CoInitialize( NULL ); CComPtr<IDispatch> pShell; pShell.CoCreateInstance( L"Shell.Application" ); DISPPARAMS param = { NULL, NULL, 0, 0 }; CComVariant varg[4]; varg[0] = 36L; // VT_I4 ssfWINDOWS varg[1] = 0L; // VT_I4 varg[2] = L"Hello, COM(ATL) World!"; // VT_BSTR varg[3] = 0L; // VT_I4 CComVariant vResult; pShell.InvokeN(L"BrowseForFolder", varg, 4, &vResult ); CComPtr<IDispatch> pFolder = vResult.pdispVal; if ( pFolder != NULL ) { pFolder = NULL; } pShell = NULL; CoUninitialize(); return 0; }
コンパイル方法(Visual C++)
C:¥> cl hello.cpp
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM(ATL) Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(#import) World!
Posted on 5月 9th, 2012 by cx20
COM(#import)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は Visual C++ のコンパイラ機能である #import ディレクティブを使用した COM クライアントの例となっている。ソースコード(事前バインディング)
#import "shell32.dll" using namespace Shell32; int main( int argc, char* argv[] ) { CoInitialize( NULL ); IShellDispatchPtr pShell("Shell.Application"); FolderPtr pFolder = NULL; _variant_t vRootFolder( ssfWINDOWS ); pFolder = pShell->BrowseForFolder( 0, L"Hello, COM(#import) World!", 0, vRootFolder ); if ( pFolder != NULL ) { pFolder = NULL; } pShell = NULL; CoUninitialize(); return 0; }
#import ディレクティブにより、以下の2ファイル(「*.tlh(タイプライブラリヘッダ)」「*.tli(タイプライブラリ実装ファイル)」)が自動生成されタイプライブラリの情報が C++ ヘッダとして取り込まれる。
ソースコード(タイプライブラリヘッダ)
// #import "shell32.dll" にて自動生成された shell32.tlh より一部抜粋 #include <comdef.h> namespace Shell32 { enum ShellSpecialFolderConstants; struct __declspec(uuid("bbcbde60-c3ff-11ce-8350-444553540000")) /* dual interface */ Folder; struct __declspec(uuid("d8f015c0-c278-11ce-a49e-444553540000")) /* dual interface */ IShellDispatch; _COM_SMARTPTR_TYPEDEF(Folder, __uuidof(Folder)); _COM_SMARTPTR_TYPEDEF(IShellDispatch, __uuidof(IShellDispatch)); enum __declspec(uuid("ca31ea20-48d0-11cf-8350-444553540000")) ShellSpecialFolderConstants { ssfWINDOWS = 36, }; struct __declspec(uuid("d8f015c0-c278-11ce-a49e-444553540000")) IShellDispatch : IDispatch { // Wrapper methods for error-handling FolderPtr BrowseForFolder ( long Hwnd, _bstr_t Title, long Options, const _variant_t & RootFolder = vtMissing ); // Raw methods provided by interface virtual HRESULT __stdcall get_Application ( /*[out,retval]*/ IDispatch * * ppid ) = 0; virtual HRESULT __stdcall get_Parent ( /*[out,retval]*/ IDispatch * * ppid ) = 0; virtual HRESULT __stdcall raw_NameSpace ( /*[in]*/ VARIANT vDir, /*[out,retval]*/ struct Folder * * ppsdf ) = 0; virtual HRESULT __stdcall raw_BrowseForFolder ( /*[in]*/ long Hwnd, /*[in]*/ BSTR Title, /*[in]*/ long Options, /*[in]*/ VARIANT RootFolder, /*[out,retval]*/ struct Folder * * ppsdf ) = 0; virtual HRESULT __stdcall raw_Windows ( /*[out,retval]*/ IDispatch * * ppid ) = 0; virtual HRESULT __stdcall raw_Open ( /*[in]*/ VARIANT vDir ) = 0; virtual HRESULT __stdcall raw_Explore ( /*[in]*/ VARIANT vDir ) = 0; virtual HRESULT __stdcall raw_MinimizeAll ( ) = 0; virtual HRESULT __stdcall raw_UndoMinimizeALL ( ) = 0; virtual HRESULT __stdcall raw_FileRun ( ) = 0; virtual HRESULT __stdcall raw_CascadeWindows ( ) = 0; virtual HRESULT __stdcall raw_TileVertically ( ) = 0; virtual HRESULT __stdcall raw_TileHorizontally ( ) = 0; virtual HRESULT __stdcall raw_ShutdownWindows ( ) = 0; virtual HRESULT __stdcall raw_Suspend ( ) = 0; virtual HRESULT __stdcall raw_EjectPC ( ) = 0; virtual HRESULT __stdcall raw_SetTime ( ) = 0; virtual HRESULT __stdcall raw_TrayProperties ( ) = 0; virtual HRESULT __stdcall raw_Help ( ) = 0; virtual HRESULT __stdcall raw_FindFiles ( ) = 0; virtual HRESULT __stdcall raw_FindComputer ( ) = 0; virtual HRESULT __stdcall raw_RefreshMenu ( ) = 0; virtual HRESULT __stdcall raw_ControlPanelItem ( /*[in]*/ BSTR bstrDir ) = 0; }; struct __declspec(uuid("bbcbde60-c3ff-11ce-8350-444553540000")) Folder : IDispatch { // Property data __declspec(property(get=GetTitle)) _bstr_t Title; // Wrapper methods for error-handling _bstr_t GetTitle ( ); // Raw methods provided by interface virtual HRESULT __stdcall get_Title ( /*[out,retval]*/ BSTR * pbs ) = 0; virtual HRESULT __stdcall get_Application ( /*[out,retval]*/ IDispatch * * ppid ) = 0; virtual HRESULT __stdcall get_Parent ( /*[out,retval]*/ IDispatch * * ppid ) = 0; virtual HRESULT __stdcall get_ParentFolder ( /*[out,retval]*/ struct Folder * * ppsf ) = 0; virtual HRESULT __stdcall raw_Items ( /*[out,retval]*/ struct FolderItems * * ppid ) = 0; virtual HRESULT __stdcall raw_ParseName ( /*[in]*/ BSTR bName, /*[out,retval]*/ struct FolderItem * * ppid ) = 0; virtual HRESULT __stdcall raw_NewFolder ( /*[in]*/ BSTR bName, /*[in]*/ VARIANT vOptions = vtMissing ) = 0; virtual HRESULT __stdcall raw_MoveHere ( /*[in]*/ VARIANT vItem, /*[in]*/ VARIANT vOptions = vtMissing ) = 0; virtual HRESULT __stdcall raw_CopyHere ( /*[in]*/ VARIANT vItem, /*[in]*/ VARIANT vOptions = vtMissing ) = 0; virtual HRESULT __stdcall raw_GetDetailsOf ( /*[in]*/ VARIANT vItem, /*[in]*/ int iColumn, /*[out,retval]*/ BSTR * pbs ) = 0; }; // Wrapper method implementations #include "shell32.tli" } // namespace Shell32
ソースコード(タイプライブラリ実装ファイル)
// #import "shell32.dll" にて自動生成された shell32.tli より一部抜粋 // interface IShellDispatch wrapper method implementations inline FolderPtr IShellDispatch::BrowseForFolder ( long Hwnd, _bstr_t Title, long Options, const _variant_t & RootFolder ) { struct Folder * _result = 0; HRESULT _hr = raw_BrowseForFolder(Hwnd, Title, Options, RootFolder, &_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return FolderPtr(_result, false); } // interface Folder wrapper method implementations inline _bstr_t Folder::GetTitle ( ) { BSTR _result = 0; HRESULT _hr = get_Title(&_result); if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this)); return _bstr_t(_result, false); }
コンパイル方法(Visual C++)
C:¥> cl hello.cpp
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM(#import) Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(C++) World!
Posted on 5月 8th, 2012 by cx20
COM(C++)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は C++ による COM クライアント(事前バインディングならびに実行時バインディング)の例となっている。ソースコード(事前バインディング)
#include <shlobj.h> int main( int argc, char* argv[] ) { CoInitialize( NULL ); IShellDispatch* pShell; CoCreateInstance( CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShell) ); VARIANT vRootFolder; VariantInit( &vRootFolder ); vRootFolder.vt = VT_I4; vRootFolder.lVal = ssfWINDOWS; Folder* pFolder; pShell->BrowseForFolder( 0, L"Hello, COM(C++) World!", 0, vRootFolder, &pFolder ); VariantClear( &vRootFolder ); if ( pFolder != NULL ) { pFolder->Release(); } pShell->Release(); CoUninitialize(); return 0; }
コンパイル方法(Visual C++)
C:¥> cl hello.cpp /link ole32.lib
ソースコード(実行時バインディング)
#include <ole2.h> int main( int argc, char* argv[] ) { CoInitialize( NULL ); CLSID clsid; CLSIDFromProgID( L"Shell.Application", &clsid ); IDispatch* pShell; CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShell) ); DISPID dispid; OLECHAR* ptName = L"BrowseForFolder"; pShell->GetIDsOfNames( IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid ); DISPPARAMS param = { NULL, NULL, 0, 0 }; VARIANT varg[4]; VariantInit( &varg[0] ); varg[0].vt = VT_I4; varg[0].lVal = 36L; // ssfWINDOWS VariantInit( &varg[1] ); varg[1].vt = VT_I4; varg[1].lVal = 0L; VariantInit( &varg[2] ); varg[2].vt = VT_BSTR; varg[2].bstrVal = SysAllocString(L"Hello, COM(C++) World!"); VariantInit( &varg[3] ); varg[3].vt = VT_I4; varg[3].lVal = 0L; param.cArgs = 4; param.rgvarg = varg; VARIANT vResult; pShell->Invoke( dispid, IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, &vResult, NULL, NULL ); VariantClear( &varg[0] ); VariantClear( &varg[1] ); VariantClear( &varg[2] ); VariantClear( &varg[3] ); IDispatch* pFolder = V_DISPATCH( &vResult ); if ( pFolder != NULL ) { pFolder->Release(); } pShell->Release(); CoUninitialize(); }
コンパイル方法(Visual C++)
C:¥> cl hello.cpp /link ole32.lib oleaut32.lib
以下は、コンパイラ COM サポートクラス(comdef.h で定義されている)を使用した例となっている。
ソースコード(実行時バインディング)
#include <comdef.h> int main( int argc, char* argv[] ) { CoInitialize( NULL ); IDispatchPtr pShell( L"Shell.Application" ); DISPID dispid; OLECHAR* ptName = L"BrowseForFolder"; pShell->GetIDsOfNames( IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid ); DISPPARAMS param = { NULL, NULL, 0, 0 }; _variant_t varg[4]; varg[0] = 36L; // ssfWINDOWS varg[1] = 0L; varg[2] = L"Hello, COM(C++) World!"; varg[3] = 0L; param.cArgs = 4; param.rgvarg = varg; _variant_t vResult; pShell->Invoke( dispid, IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, &vResult, NULL, NULL ); IDispatchPtr pFolder = V_DISPATCH(&vResult); if ( pFolder != NULL ) { pFolder = NULL; } pShell = NULL; CoUninitialize(); }
コンパイル方法(Visual C++)
C:¥> cl hello.cpp
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM(C++) Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(C言語) World!
Posted on 5月 7th, 2012 by cx20
COM(C言語)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は C言語による COM クライアント(事前バインディングならびに実行時バインディング)の例となっている。
ここでは Windows 標準のプログラム部品である Shell.Application(Shell オブジェクト)の呼出しを例としてる。ソースコード(事前バインディング)
#include <shlobj.h> int main( int argc, char* argv[] ) { HRESULT hResult; IShellDispatch* pShell; VARIANT vRootFolder; Folder* pFolder; CoInitialize( NULL ); CoCreateInstance( &CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&pShell ); VariantInit( &vRootFolder ); vRootFolder.vt = VT_I4; vRootFolder.lVal = ssfWINDOWS; pShell->lpVtbl->BrowseForFolder( (void*)pShell, 0, L"Hello, COM World!", 0, vRootFolder, &pFolder ); VariantClear( &vRootFolder ); if ( pFolder != NULL ) { pFolder->lpVtbl->Release( (void*)pFolder ); } pShell->lpVtbl->Release( (void*)pShell ); CoUninitialize(); return 0; }
コンパイル方法(Visual C++)
C:¥> cl hello.c /link ole32.lib
ソースコード(実行時バインディング)
#include <ole2.h> int main( int argc, char* argv[] ) { CLSID clsid; IDispatch* pShell; IDispatch* pFolder; DISPID dispid; OLECHAR* ptName = L"BrowseForFolder"; DISPPARAMS param = { NULL, NULL, 0, 0 }; VARIANT varg[4]; VARIANT vResult; CoInitialize( NULL ); CLSIDFromProgID(L"Shell.Application", &clsid ); CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell); pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid ); VariantInit( &varg[0] ); varg[0].vt = VT_I4; varg[0].lVal = 36L; /* ssfWINDOWS */ VariantInit( &varg[1] ); varg[1].vt = VT_I4; varg[1].lVal = 0L; VariantInit( &varg[2] ); varg[2].vt = VT_BSTR; varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); VariantInit( &varg[3] ); varg[3].vt = VT_I4; varg[3].lVal = 0L; param.cArgs = 4; param.rgvarg = varg; pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, &vResult, NULL, NULL ); VariantInit( &varg[0] ); VariantInit( &varg[1] ); VariantInit( &varg[2] ); VariantInit( &varg[3] ); pFolder = V_DISPATCH( &vResult ); if ( pFolder != NULL ) { pFolder->lpVtbl->Release( (void*)pFolder ); } pShell->lpVtbl->Release( (void*)pShell ); CoUninitialize(); return 0; }
コンパイル方法(Visual C++)
C:¥> cl hello.c /link ole32.lib oleaut32.lib
コンパイル方法(MinGW 版 gcc)
C:¥> gcc -o hello hello.c -l ole32 -l oleaut32 -l uuid
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+