Archive for the ‘C++’ 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, DirectX(WTL) World!

    Posted on 7月 25th, 2012 by cx20

    Win32 DirectX(WTL)

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

    ソースコード

    #include <atlbase.h>
    #include <atlapp.h>
    #include <atlcrack.h>
    #include <d3d9.h>
    #include <d3dx9.h>
     
    class CHelloWindow : public CWindowImpl<CHelloWindow>
    {
    public:
        CHelloWindow()
        {
            m_pD3D       = NULL;
            m_pd3dDevice = NULL;
            m_pd3dFont   = NULL;
     
            memset( &m_rect, 0, sizeof(m_rect) );
        }
     
        BEGIN_MSG_MAP( CHelloWindow )
            MSG_WM_PAINT   ( OnPaint   )
            MSG_WM_DESTROY ( OnDestroy )
        END_MSG_MAP()
     
        void OnPaint( HDC hDC )
        {
            Render();
        }
        void OnDestroy()
        {
            Cleanup();
            PostQuitMessage( 0 );
        }
     
        LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            Render();
            return 0;
        }
     
        LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
        }
     
        HRESULT 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 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(WTL) World!"),
                -1,
                &m_rect,
                DT_CALCRECT | DT_LEFT | DT_SINGLELINE,
                0xffffffff
            );
     
            if ( FAILED( hr ) )
            {
                Cleanup();
                return hr;
            }
     
            return hr;
        }
     
        VOID Cleanup()
        {
            if ( m_pd3dFont != NULL )
            {
                m_pd3dFont->Release();
            }
     
            if( m_pd3dDevice != NULL )
            {
                m_pd3dDevice->Release();
            }
     
            if( m_pD3D != NULL )
            {
                m_pD3D->Release();
            }
        }
     
        VOID 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(WTL) World!"),
                    -1,
                    &m_rect,
                    DT_LEFT | DT_SINGLELINE, 0xffffffff
                );
     
                m_pd3dDevice->EndScene();
            }
     
            m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
        }
    private:
        LPDIRECT3D9         m_pD3D;
        LPDIRECT3DDEVICE9   m_pd3dDevice;
        LPD3DXFONT          m_pd3dFont;
        RECT                m_rect;
    };
     
    CAppModule _Module;
     
    int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
    {
        _Module.Init(NULL, hInstance);
     
        CMessageLoop theLoop;
        _Module.AddMessageLoop(&theLoop);
     
        CHelloWindow wnd;
        wnd.Create( NULL, CWindow::rcDefault, _T("Hello, World!"), WS_OVERLAPPEDWINDOW | WS_VISIBLE );
        wnd.ResizeClient( 640, 480 );
        wnd.InitD3D();
        wnd.InitFont();
        int nRet = theLoop.Run();
     
        _Module.RemoveMessageLoop();
        _Module.Term();
     
        return nRet;
    }

    コンパイル方法

    C:¥> SET INCLUDE=<WTL>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(WTL) World!                |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  3. Hello, DirectX(ATL) World!

    Posted on 7月 24th, 2012 by cx20

    Win32 DirectX(ATL)

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

    ソースコード

    #include <atlbase.h>
    #include <atlwin.h> 
    #include <d3d9.h>
    #include <d3dx9.h>
     
    class CHelloWindow : public CWindowImpl<CHelloWindow>
    {
    public:
        CHelloWindow()
        {
            m_pD3D       = NULL;
            m_pd3dDevice = NULL;
            m_pd3dFont   = NULL;
     
            memset( &m_rect, 0, sizeof(m_rect) );
        }
     
        BEGIN_MSG_MAP( CHelloWindow )
            MESSAGE_HANDLER( WM_PAINT,   OnPaint   )
            MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
        END_MSG_MAP()
     
        LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            Render();
            return 0;
        }
     
        LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
        {
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
        }
     
        HRESULT 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 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(ATL) World!"),
                -1,
                &m_rect,
                DT_CALCRECT | DT_LEFT | DT_SINGLELINE,
                0xffffffff
            );
     
            if ( FAILED( hr ) )
            {
                Cleanup();
                return hr;
            }
     
            return hr;
        }
     
        VOID Cleanup()
        {
            if ( m_pd3dFont != NULL )
            {
                m_pd3dFont->Release();
            }
     
            if( m_pd3dDevice != NULL )
            {
                m_pd3dDevice->Release();
            }
     
            if( m_pD3D != NULL )
            {
                m_pD3D->Release();
            }
        }
     
        VOID 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(ATL) World!"),
                    -1,
                    &m_rect,
                    DT_LEFT | DT_SINGLELINE, 0xffffffff
                );
     
                m_pd3dDevice->EndScene();
            }
     
            m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
        }
     
    private:
        LPDIRECT3D9         m_pD3D;
        LPDIRECT3DDEVICE9   m_pd3dDevice;
        LPD3DXFONT          m_pd3dFont;
        RECT                m_rect;
    };
     
    CComModule _Module;
     
    int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
    {
        _Module.Init(NULL, hInstance);
     
        CHelloWindow wnd;
        wnd.Create( NULL, CWindow::rcDefault, _T("Hello, World!"), WS_OVERLAPPEDWINDOW | WS_VISIBLE );
        wnd.ResizeClient( 640, 480 );
        wnd.InitD3D();
        wnd.InitFont();
        MSG msg;
        while( GetMessage( &msg, NULL, 0, 0 ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
     
        _Module.Term();
     
        return (int)msg.wParam;
    }

    コンパイル方法

    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(ATL) World!                |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  4. Hello, DirectX(C++) World!

    Posted on 7月 23rd, 2012 by cx20

    Win32 DirectX(C++)

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

    ソースコード

    #include <windows.h>
    #include <tchar.h>
    #include <d3d9.h>
    #include <d3dx9.h>
     
    LPDIRECT3D9         g_pD3D       = NULL;
    LPDIRECT3DDEVICE9   g_pd3dDevice = NULL;
    LPD3DXFONT          g_pd3dFont   = NULL;
    RECT                g_rect       = { 0, 0, 0, 0 };
     
    HRESULT InitD3D( HWND hWnd );
    HRESULT InitFont();
    VOID Cleanup();
    VOID Render();
     
    HRESULT InitD3D( HWND hWnd )
    {
        HRESULT hr;
        g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
        if( g_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 = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                          &d3dpp, &g_pd3dDevice );
        if( FAILED( hr ) )
        {
            return E_FAIL;
        }
     
        return S_OK;
    }
     
    HRESULT 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(g_pd3dDevice, &lf, &g_pd3dFont );
        if ( FAILED( hr ) )
        {
            Cleanup();
            return hr;
        }
     
        hr = g_pd3dFont->DrawText(
            NULL, 
            _T("Hello, DirectX(C++) World!"),
            -1,
            &g_rect,
            DT_CALCRECT | DT_LEFT | DT_SINGLELINE,
            0xffffffff
        );
     
        if ( FAILED( hr ) )
        {
            Cleanup();
            return hr;
        }
     
        return hr;
    }
     
    VOID Cleanup()
    {
        if ( g_pd3dFont != NULL )
        {
            g_pd3dFont->Release();
        }
     
        if( g_pd3dDevice != NULL )
        {
            g_pd3dDevice->Release();
        }
     
        if( g_pD3D != NULL )
        {
            g_pD3D->Release();
        }
    }
     
    VOID Render()
    {
        if( g_pd3dDevice == NULL )
        {
            return;
        }
     
        if ( g_pd3dFont == NULL )
        {
            return;
        }
     
        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
     
        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
        {
            g_pd3dFont->DrawText(
                NULL,
                _T("Hello, DirectX(C++) World!"),
                -1,
                &g_rect,
                DT_LEFT | DT_SINGLELINE, 0xffffffff
            );
     
            g_pd3dDevice->EndScene();
        }
     
        g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
    }
     
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch( message )
        {
            case WM_DESTROY:
                Cleanup();
                PostQuitMessage( 0 );
                return 0;
     
            case WM_PAINT:
                Render();
                ValidateRect( hWnd, NULL );
                return 0;
        }
     
        return DefWindowProc( hWnd, message, wParam, lParam );
    }
     
     
    int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
        LPCTSTR lpszClassName = _T("helloWindow");
        LPCTSTR lpszWindowName = _T("Hello, World!");
     
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = lpszClassName;
        wcex.hIconSm        = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
     
        RegisterClassEx(&wcex);
        HWND hWnd = CreateWindow(
            lpszClassName,
            lpszWindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            NULL, NULL, hInstance, NULL
            );
     
        InitD3D( hWnd );
        InitFont();
     
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );
     
        MSG msg;
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
     
        return 0;
    }

    コンパイル方法

    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(C++) World!                |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  5. Hello, Win32 GUI(C++) World!

    Posted on 7月 2nd, 2012 by cx20

    Win32 GUI(C++)

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

    ソースコード

    #include <windows.h>
    #include <tchar.h>
     
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
        LPCTSTR lpszMessage = _T("Hello, Win32 GUI(C++) World!");
     
        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            TextOut( hdc, 0, 0, lpszMessage, lstrlen(lpszMessage) );
            EndPaint( hWnd, &ps );
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
            break;
        }
     
        return 0;
    }
     
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        LPCTSTR lpszClassName = _T("helloWindow");
        LPCTSTR lpszWindowName = _T("Hello, World!");
     
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = lpszClassName;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
     
        RegisterClassEx(&wcex);
        HWND hWnd = CreateWindow(
            lpszClassName,
            lpszWindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            NULL, NULL, hInstance, NULL
        );
     
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);
     
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
     
        return (int)msg.wParam;
    }

    コンパイル方法

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

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(C++) World!              |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  6. 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] |
    +----------------------------------------+
  7. 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] |
    +----------------------------------------+
  8. Hello, Win32 API(C++) World!

    Posted on 4月 14th, 2012 by cx20

    Win32 API(C++)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は C++ からの呼出し例である。

    ソースコード

    #include <windows.h>
    #include <tchar.h>
     
    int _tmain( int argc, TCHAR* argv[] )
    {
        MessageBox( NULL, _T("Hello, Win32 API(C++) World!"), _T("Hello, World!"), MB_OK );
        return 0;
    }

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

    C:¥> cl hello.cpp /link user32.lib

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(C++) World!
    ---------------------------
    OK   
    ---------------------------
  9. Hello, JNI World!

    Posted on 4月 10th, 2012 by cx20

    JNI

    JNA(Java Native Interface)は、Java と他の言語のインターフェイス仕様である。
    Java から C言語のライブラリの呼び出し、また、C言語から Java のライブラリの呼び出し等が可能である。
    ここでは、C言語から Java のライブラリの呼び出しのサンプルを記載する。

    ソースコード(呼び出す側(C++))

    #include <jni.h>
     
    int main( int argc, char* argv[] )
    {
        JNIEnv* env;
        JavaVM* jvm;
     
        // Java VM オプション設定
        JavaVMOption options[1];
        options[0].optionString = "-Xmx128m";
     
        JavaVMInitArgs vm_args;
        vm_args.version = JNI_VERSION_1_6;
        vm_args.options = options;
        vm_args.nOptions = 1;
     
        // Java VM 作成
        JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
        // Class 検索
        jclass clazz = env->FindClass("Hello");
        // Method ID 取得
        jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
        // Class メソッド呼び出し
        env->CallStaticVoidMethod(clazz, mid, NULL);
        // Java VM 破棄
        jvm->DestroyJavaVM();
     
        return 0;
    }

    ソースコード(呼び出される側(Java))

    public class Hello {
        public static void main( String[] args ) {
            System.out.println( "Hello, JNI World!" );
        }
    }

    コンパイル&実行方法

    $ javac Hello.java
    $ c++ -o jnihello jnihello.cpp ¥
    -I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/ ¥
    -framework JavaVM ¥
    -m64
    $ ./jnihello

    実行結果

    Hello, JNI World!
  10. Hello, OCCI World!

    Posted on 3月 31st, 2012 by cx20

    OCCI

    OCCI(Oracle C++ Call Interface)は Oracle Database 用の C++ API である。

    ソースコード

    #include <iostream>
    #include <occi.h>
     
    using namespace std;
    using namespace oracle::occi;
     
    int main( int argc, char* argv[] )
    {
        Environment* env = Environment::createEnvironment();
        Connection* con = env->createConnection("scott", "tiger", "orcl");
     
        Statement* stmt = con->createStatement("SELECT 'Hello, OCCI World!' AS Message FROM DUAL");
        ResultSet* rs = stmt->executeQuery();
        while( rs->next() )
        {
            cout << rs->getString(1) << endl;
        }
        stmt->closeResultSet(rs);
        con->terminateStatement(stmt);
        env->terminateConnection(con);
        Environment::terminateEnvironment(env);
     
        return 0;
    }

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

    C:¥> SET INCLUDE=ORACLE_BASEORACLE_HOMEociinclude;%INCLUDE%
    C:¥> SET LIB=ORACLE_BASEORACLE_HOMEocilibmsvc;%LIB%
    C:¥> cl hello.cpp /link oraocci11.lib

    実行結果

    Hello, OCCI World!