Archive for the ‘MFC’ Category

  1. Hello, DirectX(MFC) World!

    Posted on 7月 26th, 2012 by cx20

    Win32 DirectX(MFC)

    DirectX はマイクロソフトが Wnidows 用に開発したマルチメディア処理用 API である。
    以下は VC++(MFC) における DirectX アプリケーション の例となっている。

    ソースコード

    #include <afxwin.h>
    #include <tchar.h>
    #include <tchar.h>
    #include <d3d9.h>
    #include <d3dx9.h>
     
    class CMainFrame : public CFrameWnd
    {
    public:
        CMainFrame();
        ~CMainFrame();
        BOOL PreCreateWindow(CREATESTRUCT& cs);
     
        HRESULT InitD3D();
        HRESULT InitFont();
        VOID Cleanup();
        VOID Render();
    protected:
        afx_msg void OnPaint();
        DECLARE_MESSAGE_MAP()
     
    private:
        LPDIRECT3D9         m_pD3D;
        LPDIRECT3DDEVICE9   m_pd3dDevice;
        LPD3DXFONT          m_pd3dFont;
        RECT                m_rect;
    };
     
    class CHelloApp : public CWinApp
    {
    public:
        BOOL InitInstance();
    };
     
    BOOL CHelloApp::InitInstance()
    {
        m_pMainWnd = new CMainFrame;
     
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }
     
    CHelloApp App;
     
    BEGIN_MESSAGE_MAP( CMainFrame, CFrameWnd )
        ON_WM_PAINT()
    END_MESSAGE_MAP()
     
    CMainFrame::CMainFrame()
    {
        m_pD3D       = NULL;
        m_pd3dDevice = NULL;
        m_pd3dFont   = NULL;
     
        memset( &m_rect, 0, sizeof(m_rect) );
     
        Create( NULL, _T("Hello, World!") );
     
        InitD3D();
        InitFont();
    }
     
    CMainFrame::~CMainFrame()
    {
        Cleanup();
    }
     
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
        CFrameWnd::PreCreateWindow(cs);
        cs.cx = 640;
        cs.cy = 480;
     
        return TRUE;
    }
     
    void CMainFrame::OnPaint()
    {
        Render();
    }
     
    HRESULT CMainFrame::InitD3D()
    {
        HRESULT hr;
        m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
        if( m_pD3D == NULL )
        {
            return E_FAIL;
        }
     
        D3DPRESENT_PARAMETERS d3dpp;
        d3dpp.BackBufferWidth             = 0;
        d3dpp.BackBufferHeight            = 0;
        d3dpp.BackBufferFormat            = D3DFMT_UNKNOWN;
        d3dpp.BackBufferCount             = 0;
        d3dpp.MultiSampleType             = D3DMULTISAMPLE_NONE;
        d3dpp.MultiSampleQuality          = 0;
        d3dpp.SwapEffect                  = D3DSWAPEFFECT_DISCARD;
        d3dpp.hDeviceWindow               = NULL;
        d3dpp.Windowed                    = TRUE;
        d3dpp.EnableAutoDepthStencil      = 0;
        d3dpp.AutoDepthStencilFormat      = D3DFMT_UNKNOWN;
        d3dpp.Flags                       = 0;
        d3dpp.FullScreen_RefreshRateInHz  = 0;
        d3dpp.PresentationInterval        = 0;
     
        hr = m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
                                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                          &d3dpp, &m_pd3dDevice );
        if( FAILED( hr ) )
        {
            return E_FAIL;
        }
     
        return S_OK;
    }
     
    HRESULT CMainFrame::InitFont()
    {
        HRESULT hr;
        D3DXFONT_DESC lf;
        lf.Height          = 16;
        lf.Width           = 0;
        lf.Weight          = 0;
        lf.MipLevels       = 1;
        lf.Italic          = 0;
        lf.CharSet         = SHIFTJIS_CHARSET;
        lf.OutputPrecision = OUT_TT_ONLY_PRECIS;
        lf.Quality         = PROOF_QUALITY;
        lf.PitchAndFamily  = FIXED_PITCH | FF_MODERN;
        lstrcpy( lf.FaceName, _T("MS ゴシック") );
     
        hr = D3DXCreateFontIndirect(m_pd3dDevice, &lf, &m_pd3dFont );
        if ( FAILED( hr ) )
        {
            Cleanup();
            return hr;
        }
     
        hr = m_pd3dFont->DrawText(
            NULL, 
            _T("Hello, DirectX(MFC) World!"),
            -1,
            &m_rect,
            DT_CALCRECT | DT_LEFT | DT_SINGLELINE,
            0xffffffff
        );
     
        if ( FAILED( hr ) )
        {
            Cleanup();
            return hr;
        }
     
        return hr;
    }
     
    VOID CMainFrame::Cleanup()
    {
        if ( m_pd3dFont != NULL )
        {
            m_pd3dFont->Release();
        }
     
        if( m_pd3dDevice != NULL )
        {
            m_pd3dDevice->Release();
        }
     
        if( m_pD3D != NULL )
        {
            m_pD3D->Release();
        }
    }
     
    VOID CMainFrame::Render()
    {
        if( m_pd3dDevice == NULL )
        {
            return;
        }
     
        if ( m_pd3dFont == NULL )
        {
            return;
        }
     
        m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
     
        if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
        {
            m_pd3dFont->DrawText(
                NULL,
                _T("Hello, DirectX(MFC) World!"),
                -1,
                &m_rect,
                DT_LEFT | DT_SINGLELINE, 0xffffffff
            );
     
            m_pd3dDevice->EndScene();
        }
     
        m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
    }

    コンパイル方法

    C:¥> SET INCLUDE=%DXSDK_DIR%INCLUDE;%INCLUDE%
    C:¥> SET LIB=%DXSDK_DIR%Libx86;%LIB%
    C:¥> cl hello.cpp ^
             /link ^
             user32.lib ^
             dxguid.lib ^
             d3d9.lib ^
             d3dx9.lib ^
             /SUBSYSTEM:WINDOWS

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, DirectX(MFC) World!                |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  2. Hello, Win32 GUI(MFC) World!

    Posted on 7月 5th, 2012 by cx20

    Win32 GUI(MFC)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は VC++(MFC) における Win32 GUI アプリケーション の例となっている。

    ソースコード

    #include <afxwin.h>
    #include <tchar.h>
     
    class CMainFrame : public CFrameWnd
    {
    public:
        CMainFrame();
        BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
        afx_msg void OnPaint();
        DECLARE_MESSAGE_MAP()
    };
     
    class CHelloApp : public CWinApp
    {
    public:
        BOOL InitInstance();
    };
     
    BOOL CHelloApp::InitInstance()
    {
        m_pMainWnd = new CMainFrame;
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }
     
    CHelloApp App;
     
    BEGIN_MESSAGE_MAP( CMainFrame, CFrameWnd )
        ON_WM_PAINT()
    END_MESSAGE_MAP()
     
    CMainFrame::CMainFrame()
    {
        Create( NULL, _T("Hello, World!") );
    }
     
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
        CFrameWnd::PreCreateWindow(cs);
        cs.cx = 640;
        cs.cy = 480;
        return TRUE;
    }
     
    void CMainFrame::OnPaint()
    {
        CPaintDC dc(this);
        dc.TextOut( 0, 0, _T("Hello, Win32 GUI(MFC) World!") );
    }

    コンパイル方法

    C:¥> cl hello.cpp /link /SUBSYSTEM:WINDOWS

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(MFC) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  3. 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] |
    +----------------------------------------+
  4. Hello, DAO(MFC) World!

    Posted on 3月 26th, 2012 by cx20

    DAO(MFC)

    MFC(Microsoft Foundation Class)は、Visual C++ 用のクラスライブラリである。
    MFC DAO クラスは、DAO(Data Access Object)のラップクラスとして実装されている。
    現在、DAO クラスは既存のアプリケーションの保守の為だけに残されており、新しいプロジェクトでは ODBC クラスが推奨されている。
    なお、x64 プラットフォームでは DAO クラスはサポートされておらず、コンパイルエラーとなる。

    ソースコード(VC + MFC + DAO + Jet データベース)

    #include <afx.h>
    #include <afxdao.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDaoDatabase db;
        db.Open( _T("hello.mdb") );
     
        CDaoRecordset rs( &db );
        CString strSQL = _T("SELECT 'Hello, DAO(MFC) World!' AS Message");
        rs.Open(dbOpenDynaset, strSQL, dbReadOnly);
     
        while ( !rs.IsEOF() )
        {
            COleVariant varValue = rs.GetFieldValue( 0 );
            _tprintf( _T("%sn"), V_BSTRT( &varValue ) );
            rs.MoveNext();
        }
     
        rs.Close();
        db.Close();
     
        return 0;
    }

    ソースコード(VC + MFC + DAO + ODBC + SQL Server)

    #include <afx.h>
    #include <afxdao.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDaoDatabase db;
        db.Open( _T(""), FALSE, FALSE, 
            _T("Driver={SQL Server};SERVER=(local);DATABASE=master;UID=sa;PWD=P@ssW0rd") );
     
        CDaoRecordset rs( &db );
        CString strSQL = _T("SELECT 'Hello, DAO(MFC) World!' AS Message");
        rs.Open(dbOpenDynaset, strSQL, dbReadOnly);
     
        while ( !rs.IsEOF() )
        {
            COleVariant varValue = rs.GetFieldValue( 0 );
            _tprintf( _T("%sn"), V_BSTRT( &varValue ) );
            rs.MoveNext();
        }
     
        rs.Close();
        db.Close();
     
        return 0;
    }

    ソースコード(VC + MFC + DAO + ODBC + Oracle)

    #include <afx.h>
    #include <afxdao.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDaoDatabase db;
        db.Open( _T(""), FALSE, FALSE, 
            _T("ODBC;Driver={Oracle in OraDb11g_home1};DBQ=ORCL;UID=scott;PWD=tiger;") );
     
        CDaoRecordset rs( &db );
        CString strSQL = _T("SELECT 'Hello, DAO(MFC) World!' AS Message");
        rs.Open(dbOpenDynaset, strSQL, dbReadOnly);
     
        while ( !rs.IsEOF() )
        {
            COleVariant varValue = rs.GetFieldValue( 0 );
            _tprintf( _T("%sn"), V_BSTRT( &varValue ) );
            rs.MoveNext();
        }
     
        rs.Close();
        db.Close();
     
        return 0;
    }

    コンパイル&リンク方法(Visual C++)

    C:¥> cl hello.cpp

    実行結果

    Hello, DAO(MFC) World!
  5. Hello, ODBC(MFC) World!

    Posted on 3月 25th, 2012 by cx20

    ODBC(MFC)

    ODBC(Open Database Connectivity)は、マイクロソフト社が提唱した DBMS 接続用の API 仕様である。
    DBMS の差異は ODBC ドライバによって吸収される為、ODBC の手順にしたがってプログラムを作成すれば、基本的な差異を意識せず、プログラムすることができる。

    ODBCドライバ ファイル
    Microsoft Access Driver (*.mdb) ODBCJT32.DLL
    Microsoft Text Driver (*.txt; *.csv) ODBCJT32.DLL
    Microsoft Excel Driver (*.xls) ODBCJT32.DLL
    Microsoft dBase Driver (*.dbf) ODBCJT32.DLL
    Microsoft ODBC for Oracle MSORCL32.DLL
    Microsoft Paradox Driver (*.db ) ODBCJT32.DLL
    SQL Server SQLSRV32.DLL
    Microsoft Access Driver (*.mdb, *.accdb) ACEODBC.DLL
    SQL Server Native Client 10.0 SQLNCLI10.DLL

    MFC ODBC クラス は、Visual C++ の ODBC クラスライブラリである。

    ソースコード(VC + MFC + ODBC + Jet データベース)

    #include <afx.h>
    #include <afxdb.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDatabase db;
     
        CString strCon = _T("Driver={Microsoft Access Driver (*.mdb)};DBQ=hello.mdb");
        CString strSQL = _T("SELECT 'Hello, ODBC(MFC) World!' AS Message");
     
        db.OpenEx( strCon );
        CRecordset rs( &db );
        rs.Open( CRecordset::forwardOnly, strSQL );
     
        CString strMessage;
     
        while( !rs.IsEOF() )
        {
            rs.GetFieldValue( (short)0, strMessage );
            _tprintf( _T("%sn"), (LPCTSTR)strMessage );
            rs.MoveNext();
        }
        rs.Close();
        db.Close();
     
        return 0;
    }

    ソースコード(VC + MFC + ODBC + ACE データベース)

    #include <afx.h>
    #include <afxdb.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDatabase db;
     
        CString strCon = _T("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=.\hello.accdb");
        CString strSQL = _T("SELECT 'Hello, ODBC World!' AS Message");
     
        db.OpenEx( strCon );
        CRecordset rs( &db );
        rs.Open( CRecordset::forwardOnly, strSQL );
     
        CString strMessage;
     
        while( !rs.IsEOF() )
        {
            rs.GetFieldValue( (short)0, strMessage );
            _tprintf( _T("%sn"), (LPCTSTR)strMessage );
            rs.MoveNext();
        }
        rs.Close();
        db.Close();
     
        return 0;
    }

    ソースコード(VC + MFC + ODBC + SQL Server)

    #include <afx.h>
    #include <afxdb.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDatabase db;
     
        CString strCon = _T("Driver={SQL Server};SERVER=(local);DATABASE=master;UID=sa;PWD=P@ssW0rd");
        CString strSQL = _T("SELECT 'Hello, ODBC(MFC) World!' AS Message");
     
        db.OpenEx( strCon );
        CRecordset rs( &db );
        rs.Open( CRecordset::forwardOnly, strSQL );
     
        CString strMessage;
     
        while( !rs.IsEOF() )
        {
            rs.GetFieldValue( (short)0, strMessage );
            _tprintf( _T("%sn"), (LPCTSTR)strMessage );
            rs.MoveNext();
        }
        rs.Close();
        db.Close();
     
        return 0;
    }

    ソースコード(VC + MFC + ODBC + Oracle)

    #include <afx.h>
    #include <afxdb.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDatabase db;
     
        CString strCon = _T("Driver={Microsoft ODBC for Oracle};SERVER=ORCL;UID=scott;PWD=tiger");
        CString strSQL = _T("SELECT 'Hello, ODBC(MFC) World!' AS Message FROM DUAL");
     
        db.OpenEx( strCon );
        CRecordset rs( &db );
        rs.Open( CRecordset::forwardOnly, strSQL );
     
        CString strMessage;
     
        while( !rs.IsEOF() )
        {
            rs.GetFieldValue( (short)0, strMessage );
            _tprintf( _T("%sn"), (LPCTSTR)strMessage );
            rs.MoveNext();
        }
        rs.Close();
        db.Close();
     
        return 0;
    }

    ソースコード(VC + MFC + ODBC + MySQL)

    #include <afx.h>
    #include <afxdb.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        CDatabase db;
     
        CString strCon = _T("Driver={MySQL ODBC 5.1 Driver};Server=localhost;UID=root;PWD=P@ssW0rd");
        CString strSQL = _T("SELECT 'Hello, ODBC(MFC) World!' AS Message");
     
        db.OpenEx( strCon );
        CRecordset rs( &db );
        rs.Open( CRecordset::forwardOnly, strSQL );
     
        CString strMessage;
     
        while( !rs.IsEOF() )
        {
            rs.GetFieldValue( (short)0, strMessage );
            _tprintf( _T("%sn"), (LPCTSTR)strMessage );
            rs.MoveNext();
        }
        rs.Close();
        db.Close();
     
        return 0;
    }

    コンパイル&リンク方法(Visual C++)

    C:¥> cl hello.cpp

    実行結果

    Message
    Hello, ODBC(MFC) World!