1. 程式人生 > >基於 DirectX11 的 MMDViewer 02-創建一個窗口

基於 DirectX11 的 MMDViewer 02-創建一個窗口

ret window 固定 over 渲染 font 代碼 draw image

  項目的創建和配置:

  1、新建一個 Win32 空項目

技術分享圖片

技術分享圖片

  2、創建源碼文件夾、庫文件夾和資源文件夾

技術分享圖片

  3、在 VS2013(我使用的 IDE 是 vs2013)配置這些文件夾

技術分享圖片

  這裏使用了 $(SolutionDir) 宏來指定上面創建的文件夾,因為使用的不是絕對路徑,所以將項目拷貝到其他文件夾或電腦也可以正確讀取。通過上面的設置,告訴程序去哪找到源碼文件和庫文件。

  創建窗口:

  創建窗口有幾個固定的步驟,只要按照這些步驟來就好了,下面是創建的代碼

HWND Create()
{
    /* 設計窗口類 */
    WNDCLASS wndclass;
    memset(
&wndclass, 0, sizeof(WNDCLASSA)); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndclass.lpfnWndProc = ( WNDPROC ) WindowProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = ( HINSTANCE ) GetModuleHandle(0); wndclass.hIcon = 0; wndclass.hCursor
= 0; wndclass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255)); wndclass.lpszMenuName = 0; wndclass.lpszClassName = L"MMDViewer"; /* 註冊窗口類 */ RegisterClass(&wndclass); /* 不能改變窗口大小 */ int style = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX; /* 根據客戶區大小計算窗口大小
*/ RECT rect = { 0, 0, 800, 600 }; AdjustWindowRect(&rect, style, 0); /* 居中顯示計算窗口位置和大小 */ int w = rect.right - rect.left; int h = rect.bottom - rect.top; int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; /* 創建窗口 */ HWND hwnd = CreateWindow(L"MMDViewer", L"MMDViewer", style, x, y, w, h, NULL, 0, ( HINSTANCE ) GetModuleHandle(0), 0); /* 顯示窗口 */ ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); return hwnd; }

  該函數返回新建的窗口句柄,需要註意的是,這裏重新計算了窗口的大小。如果按 800x600 創建窗口,則窗口客戶區的大小就會小於 800x600,因為客戶區才是真正渲染的區域,所以希望客戶區的大小就是 800x600,而窗口的大小需要重新計算。使用的函數是 AdjustWindowRect(),它能過返回窗口的需要大小。

  還有就是窗口事件處理函數,這裏添加了可以使窗口關閉的代碼:

LRESULT CALLBACK WindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch ( msg )
    {
    case WM_CLOSE:
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_PAINT:
        RECT rect;
        if ( GetUpdateRect(wnd, &rect, FALSE) )
        {
            ValidateRect(wnd, &rect);
        }
        break;
    }
    return DefWindowProc(wnd, msg, wParam, lParam);
}

  最後就是事件循環,它在主函數中:

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    HWND hwnd = Create();

    /* 主事件循環 */
    MSG msg = { 0 };
    while ( WM_QUIT != msg.message )
    {
        if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return ( int ) msg.wParam;
}

  編譯程序,成功運行後就會彈出一個窗口:

技術分享圖片

  源碼下載:MMDViewer 02.zip

基於 DirectX11 的 MMDViewer 02-創建一個窗口