Archive for the ‘library’ Category
-
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] | +----------------------------------------+
-
Hello, Win32 API(Go) World!
Posted on 5月 6th, 2012 by cx20
Win32 API(Go)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は Go言語 にて syscall.Syscall 関数を用いた呼出し例である。ソースコード
package main import ( "syscall" "unsafe" ) var ( user32, _ = syscall.LoadLibrary("user32.dll") procMessageBoxW, _ = syscall.GetProcAddress(user32, "MessageBoxW") ) func MessageBox(hwnd uintptr, text string, caption string, style uintptr) (int32) { ret, _, _ := syscall.Syscall6( uintptr(procMessageBoxW), 4, hwnd, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))), style, 0, 0 ) return int32(ret) } func main() { defer syscall.FreeLibrary(user32) MessageBox( 0, "Hello, Win32 API(Go) World!", "Hello, World!", 0 ) }
Win32 データ型と Go言語 データ型の対応は主に以下のようになっている。
Win32 データ型 C/C++ データ型 Go データ型 HANDLE void * uintptr BYTE unsigned char uint8, byte SHORT short int16 WORD unsigned short uint16 INT int int32, int UINT unsigned int uint32 LONG long int32 BOOL int int DWORD unsigned long uint32 ULONG unsigned long uint32 CHAR char byte WCHAR wchar_t uint16 LPSTR char * *byte LPCSTR const char * *byte, syscall.StringByPtr() LPWSTR wchar_t * *uint16 LPCWSTR const wchar_t * *uint16, syscall.StringToUTF16Ptr() FLOAT float float32 DOUBLE double float64 LONGLONG __int64 int64 DWORD64 unsigned __int64 uint64 コンパイル方法
C:¥> SET GOROOT=C:go C:¥> go build -ldflags -Hwindowsgui hello.go
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(Go) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(Delphi) World!
Posted on 5月 5th, 2012 by cx20
Win32 API(Delphi)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は Delphi からの呼出し例である。
Win32 API の参照方法としては、external 宣言を用いる方法の他、Winapi.Windows ライブラリを用いる方法などがある。ソースコード(external 宣言)
program hello; function MessageBox(hWnd: THandle; lpText: PAnsiChar; lpCaption: PAnsiChar; uType: Cardinal): Integer; stdcall; external 'user32.dll' name 'MessageBoxA'; begin MessageBox( 0, 'Hello, Win32 API(Delphi) World!', 'Hello, World!', 0 ); end.
ソースコード(Winapi.Windows ライブラリ)
program hello; uses Windows; begin MessageBox( 0, 'Hello, Win32 API(Delphi) World!', 'Hello, World!', MB_OK ); end.
Win32 データ型と Delphi データ型の対応は主に以下のようになっている。
Win32 データ型 C/C++ データ型 Delphi データ型 HANDLE void * THandle BYTE unsigned char Byte SHORT short Smallint WORD unsigned short Word INT int Integer UINT unsigned int Cardinal LONG long Integer BOOL int LongBool DWORD unsigned long LongWord ULONG unsigned long LongWord CHAR char AnsiChar WCHAR wchar_t WideChar, Char LPSTR char * PAnsiChar LPCSTR const char * PAnsiChar LPWSTR wchar_t * PWideChar, PChar LPCWSTR const wchar_t * PWideChar, PChar FLOAT float Single DOUBLE double Double LONGLONG __int64 Int64 DWORD64 unsigned __int64 UInt64 コンパイル方法(Delphi XE2)
C:¥> dcc32 hello.pas
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(Delphi) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(D言語) World!
Posted on 5月 4th, 2012 by cx20
Win32 API(D言語)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は D言語 からの呼出し例である。
D言語では、Platform SDK のヘッダファイル相当のものがプロトタイプ宣言されている為、基本的な Win32 API であれば、C/C++ の場合と同様に、呼び出すことが可能となっている。ソースコード
import std.c.windows.windows; int main( char[][] args ) { MessageBoxA( null, "Hello, Win32 API(D) World!", "Hello, World!", MB_OK ); return 0; }
Win32 API のプロトタイプ宣言(参考)
extern (Windows) { : int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); int MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); : }
また、Win32 データ型に関しても、同じ名前の型が、D言語用に定義されている為、特段、言語の差異を意識することなく使うことが可能となっている。
Win32 データ型 C/C++ データ型 D言語データ型 HANDLE void * void * BYTE unsigned char ubyte SHORT short short WORD unsigned short ushort INT int int UINT unsigned int uint LONG long int BOOL int int DWORD unsigned long uint ULONG unsigned long uint CHAR char char WCHAR wchar_t wchar LPSTR char * char * LPCSTR const char * const(char) * LPWSTR wchar_t * wchar * LPCWSTR const wchar_t * const(wchar) * FLOAT float float DOUBLE double double LONGLONG __int64 long DWORD64 unsigned __int64 ulong コンパイル方法(Digital Mars D コンパイラ)
C:¥> dmd hello.d
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(D) World! --------------------------- OK ---------------------------
-
Hello, Win32 API(JNI) World!
Posted on 5月 3rd, 2012 by cx20
Win32 API(JNI)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は JNI(Java Native Interface)による呼出し例である。
Java からは 直接、Win32 API を呼び出すことは出来ないが、JNI 用の DLL を作成することで呼び出すことが可能となっている。ソースコード(Java)
import java.io.*; public class Hello { static { System.loadLibrary("Hello"); } public native int MessageBox( int hwnd, String text, String title, int type ); public static void main(String args[]) { Hello hello = new Hello(); hello.MessageBox( 0, "Hello, Win32 API(JNI) World!", "Hello, World!", 0 ); } }
C ヘッダファイル作成
C:¥> javah -jni Hello
ソースコード(C ヘッダファイル)
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Hello */ #ifndef _Included_Hello #define _Included_Hello #ifdef __cplusplus extern "C" { #endif /* * Class: Hello * Method: MessageBox * Signature: (ILjava/lang/String;Ljava/lang/String;I)I */ JNIEXPORT jint JNICALL Java_Hello_MessageBox (JNIEnv *, jobject, jint, jstring, jstring, jint); #ifdef __cplusplus } #endif #endif
ソースコード(C 実装ファイル)
#include "Hello.h" #include <windows.h> /* * Class: Hello * Method: MessageBox * Signature: (ILjava/lang/String;Ljava/lang/String;I)I */ JNIEXPORT jint JNICALL Java_Hello_MessageBox (JNIEnv* env, jobject me, jint hwnd, jstring text, jstring caption, jint type) { #ifdef UNICODE const jchar* _text = env->GetStringChars(text, 0); const jchar* _caption = env->GetStringChars(caption, 0); const int result = MessageBoxW(NULL, (LPCWSTR)_text, (LPCWSTR)_caption, type); env->ReleaseStringChars(text, _text); env->ReleaseStringChars(caption, _caption); #else /* このコードはマルチバイト文字(MBCS)を考慮していない為、全角文字列を渡した場合に文字化けする。正しくは SJIS に変換する処理が必要。*/ const char* _text = env->GetStringUTFChars(text, 0); const char* _caption = env->GetStringUTFChars(caption, 0); const int result = MessageBoxA(NULL, (LPCSTR)_text, (LPCSTR)_caption, type); env->ReleaseStringUTFChars(text, _text); env->ReleaseStringUTFChars(caption, _caption); #endif return result; }
Win32 データ型と JNI データ型の対応は主に以下のようになっている。
Win32 データ型 C/C++ データ型 JNI データ型 Java データ型 BOOL int jboolean boolean BYTE char jbyte byte WCHAR wchar_t jchar char SHORT short jshort short INT int jint int LONGLONG __int64 jlong long FLOAT float jfloat float DOUBLE double jdouble double VOID void void void LPCSTR const char * jstring string LPCWSTR const wchar_t * jstring string なお、jstring については、使用時に、正しい C/C++ データ型(ANSI, MBCS / UNICODE)に適宜、変換する必要がある。
DLL作成(Visual C++)
C:¥> SET INCLUDE=%JAVA_HOME%include;%JAVA_HOME%includewin32;%INCLUDE% C:¥> cl Hello.cpp /LD /link user32.lib
コンパイル&実行方法
C:¥> javac Hello.java C:¥> java Hello
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API(JNI) World! --------------------------- OK ---------------------------