Archive for 5月 8th, 2012

  1. 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] |
    +----------------------------------------+