Archive for 5月 11th, 2012

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