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, &param, &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, &param, &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] |
+----------------------------------------+

Tags:

Categories: C++, COM, library

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

WP-SpamFree by Pole Position Marketing