1. 程式人生 > >Direct2D教程(外篇)環境配置

Direct2D教程(外篇)環境配置

2014年世界盃首場淘汰賽馬上開始了,閒著沒事,整理以前的部落格草稿打發時間,意外的發現這篇文章,本來是打算加入到Direct2D那個系列的,不知道為什麼把它給遺漏了。環境配置,對於熟手來說,不是什麼重要的東西,但是對於新手卻很重要,尤其是沒有接觸過Direct2D的朋友們,整理一下發了出來,沒有放部落格園首頁。喜歡的來頂頂。

引子

上一篇鼓吹了一些關於D2D的東西,從這一篇開始說說如何使用D2D來程式設計,由於我自己也是從頭開始摸索,所以就寫得詳細點,把如何建立工程的部分也寫一下,這就是這篇的由來。本篇的主要內容包括,如何配置D2D開發環境,如何建立工程,新增必要的檔案,編譯工程等等。

開發環境

系統:Windows 7

IDE:Visual Studio 2008或更高版本,在Windows上,VS是開發DX程式的不二之選。

程式碼外掛:Visual AssistX,這個東西必不可少,沒有它,寫C/C++程式碼很痛苦,現在我已經離不開它了。

語言:C/C++混合。

上面這些都可以在網上下載到,對於大多數開發者來說,我想Windows 7和VS應該已經具備了,只需要安裝一下DX 11的SDK或者Windows SDK v7.1即可。對於仍然在使用XP系統的使用者,非常抱歉,您只能觀望了,因為Direct2D系統最低需求是Vista SP2。關於如何安裝SDK,這裡我就省略了。下面開始詳細的步驟。

建立工程

開啟Visual Studio,選擇File-New-Project,彈出如下對話方塊

在對話方塊的左側,Project typeset中選擇Visual C++,在對話方塊的右邊,Templates中選擇Win32 Project,在Name欄填上工程的名字D2DApp,Location欄填上工程所在的路徑,最後在Solution Name中填上整個解決方案的名字D2DSolution,因為任何一個工程都隸屬於一個解決方案(Solution)。單擊OK按鈕,彈出如下對話方塊。

這個對話方塊中沒有任何設定,直接單擊Next按鈕,來到如下對話方塊。

在Application type中選擇Windows application(其實預設已經選好),在Additional option中選擇Empty project。單擊Finish按鈕,好了,工程建立完畢,但只不過是空的而已,還需新增一些東西。回到Visual Studio主介面,單擊選單欄上的View,選擇Solution explorer,在其中可以看到我們剛剛建立的工程。

在Solution Explorer中,右鍵單擊工程D2DApp,選擇Add-New Item,在Categories中選擇Visual C++,在Templates中選擇C++ File(.cpp),在Name欄中給檔案取個名字,比如Main。然後單擊Add按鈕。這樣檔案就新增到工程中了,只不過是個空檔案,待我們配置好標頭檔案和lib檔案後,再往這個檔案裡面加東西。

配置標頭檔案和庫檔案路徑

基於單個工程的設定

在工程上單擊右鍵,選擇Properties,在彈出的對話方塊中依次選擇Configuration Properties-C/C++-General,在右側視窗中第一行Additional Include Directories右邊有一個帶省略號的小按鈕,單擊該按鈕添,在彈出的對話方塊上點選新建資料夾的按鈕,然後點選下拉框右側的按鈕來新增標頭檔案路徑,如下圖

如法炮製,配置.lib檔案,不贅述,直接上圖

基於所有工程的配置

上面的方法只是針對單個工程,也就是說,每建立一個Direct2D程式時,都要按照上面的步驟做一次,如果想避免這個麻煩,那麼可以針對所有工程進行設定,這樣以後建立的工程都應用這個配置。豈不哉?

在VS選單欄上選擇Tools-Options,在彈出的對話方塊中選擇Projects and Solutions-VC++ Directories,在右側的Show Directories for下拉框中選擇Include Files,單擊下面的New Line按鈕,新增標頭檔案路徑,在下拉框中選擇Libraries files新增庫檔案路徑。最後單擊OK即可。

新增標頭檔案和庫檔案

D2D程式最常用的庫檔案就是D2D1.lib,通過下圖所示方法將其加入到工程之中,最常用的標頭檔案是D2D1.h,直接寫到程式程式碼中即可。

編譯工程

雙擊工程中的Main.cpp檔案,在檔案中新增如下程式碼。

#include <windows.h>
#include <D2D1.h>// header for Direct2D

#define SAFE_RELEASE(P) if(P){P->Release() ; P = NULL ;}

ID2D1Factory* pD2DFactory = NULL ; // Direct2D factory
ID2D1HwndRenderTarget* pRenderTarget = NULL; // Render target
ID2D1SolidColorBrush* pBlackBrush = NULL ; // A black brush, reflect the line color

RECT rc ; // Render area
HWND g_Hwnd ; // Window handle

VOID CreateD2DResource(HWND hWnd)
{
    if (!pRenderTarget)
    {
        HRESULT hr ;

        hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory) ;
        if (FAILED(hr))
        {
            MessageBox(hWnd, "Create D2D factory failed!", "Error", 0) ;
            return ;
        }

        // Obtain the size of the drawing area
        GetClientRect(hWnd, &rc) ;

        // Create a Direct2D render target
        hr = pD2DFactory->CreateHwndRenderTarget(
            D2D1::RenderTargetProperties(),
            D2D1::HwndRenderTargetProperties(
            hWnd, 
            D2D1::SizeU(rc.right - rc.left,rc.bottom - rc.top)
            ), 
            &pRenderTarget
            ) ;
        if (FAILED(hr))
        {
            MessageBox(hWnd, "Create render target failed!", "Error", 0) ;
            return ;
        }

        // Create a brush
        hr = pRenderTarget->CreateSolidColorBrush(
            D2D1::ColorF(D2D1::ColorF::Black),
            &pBlackBrush
            ) ;
        if (FAILED(hr))
        {
            MessageBox(hWnd, "Create brush failed!", "Error", 0) ;
            return ;
        }
    }
}

VOID DrawRectangle()
{
    CreateD2DResource(g_Hwnd) ;

    pRenderTarget->BeginDraw() ;

    // Clear background color white
    pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

    // Draw Rectangle
    pRenderTarget->DrawRectangle(
        D2D1::RectF(100.f, 100.f, 500.f, 500.f),
        pBlackBrush
        );

    HRESULT hr = pRenderTarget->EndDraw() ;

    if (FAILED(hr))
    {
        MessageBox(NULL, "Draw failed!", "Error", 0) ;
        return ;
    }
}

VOID Cleanup()
{
    SAFE_RELEASE(pRenderTarget) ;
    SAFE_RELEASE(pBlackBrush) ;
    SAFE_RELEASE(pD2DFactory) ;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    switch (message) 
    {
    case WM_PAINT:
        DrawRectangle() ;
        ValidateRect(g_Hwnd, NULL) ;
        return0 ;

    case WM_KEYDOWN: 
        { 
            switch( wParam ) 
            { 
            case VK_ESCAPE: 
                SendMessage( hwnd, WM_CLOSE, 0, 0 ); 
                break ; 
            default: 
                break ; 
            } 
        } 
        break ; 

    case WM_DESTROY: 
        Cleanup(); 
        PostQuitMessage( 0 ); 
        return0; 
    }

    return DefWindowProc (hwnd, message, wParam, lParam) ;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
{

    WNDCLASSEX winClass ;

    winClass.lpszClassName ="Direct2D";
    winClass.cbSize =sizeof(WNDCLASSEX);
    winClass.style = CS_HREDRAW | CS_VREDRAW;
    winClass.lpfnWndProc = WndProc;
    winClass.hInstance = hInstance;
    winClass.hIcon = NULL ;
    winClass.hIconSm = NULL ;
    winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winClass.hbrBackground = NULL ;
    winClass.lpszMenuName = NULL;
    winClass.cbClsExtra =0;
    winClass.cbWndExtra =0;

    if (!RegisterClassEx (&winClass)) 
    {
        MessageBox ( NULL, TEXT( "This program requires Windows NT!" ), "error", MB_ICONERROR) ;
        return 0 ; 
    } 

    g_Hwnd = CreateWindowEx(NULL, 
        "Direct2D", // window class name
        "Draw Rectangle", // window caption
        WS_OVERLAPPEDWINDOW, // window style
        CW_USEDEFAULT, // initial x position
        CW_USEDEFAULT, // initial y position
        600, // initial x size
        600, // initial y size
        NULL, // parent window handle
        NULL, // window menu handle
        hInstance, // program instance handle
        NULL) ; // creation parameters

    ShowWindow (g_Hwnd, iCmdShow) ;
    UpdateWindow (g_Hwnd) ;

    MSG msg ; 
    ZeroMemory(&msg, sizeof(msg)) ;

    while (GetMessage (&msg, NULL, 0, 0)) 
    {
        TranslateMessage (&msg) ;
        DispatchMessage (&msg) ;
    }

    return msg.wParam ;
}

編譯工程,可以在工程上單擊右鍵,選擇Build。執行程式,如果沒有錯誤,你將會看到一個簡單的矩形,至於詳細原理,請看下一篇,Direct2D教程(三)來看Direct2D中的Hello World!

Hayyp Coding

== THE END ==