Directx11 教程(2) 基本的windows應用程式架構(2)

來源:互聯網
上載者:User

     在本教程中,我們把前面一個教程的代碼,進行封裝。把初始化函數,Run函數,視窗回呼函數,ShutdownWindows函數等封裝到一個System class中。

    首先我們要在前面建立的solution,myTutorialD3D11中,滑鼠右鍵點擊,選擇New Project,

 

建立一個名為myTutorialD3D11_1的空工程,在工程中增加main.cpp檔案。

main.cpp的代碼如下:

#include "SystemClass.h"

//應用程式入口main函數
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
    {
    SystemClass* System;
    bool result;

    // 建立一個system對象.
    System = new SystemClass;
    if(!System)
        {
        return 0;
        }

    // 初始化system對象.
    result = System->Initialize();
    if(result)
        {
        System->Run();
        }

    // 關閉以及釋放system對象.
    System->Shutdown();
    delete System;
    System = 0;
    return 0;
    }

 

在工程myTutorialD3D11_1上滑鼠右鍵點擊,選擇Add->Class,建立一個名為SystemClass的類。

 

SystemClass.h的代碼如下:

#pragma once
//定義該宏能夠減少windows標頭檔的大小,使編譯器不編譯一些不必要的檔案,加快編譯時間
#define WIN32_LEAN_AND_MEAN

#include <windows.h>

const bool FULL_SCREEN = false;
static bool bexit = false;

class SystemClass
    {
    public:
        SystemClass(void);
        SystemClass(const SystemClass &);
        ~SystemClass(void);

        bool Initialize();
        void Shutdown();
        void Run();

        LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
    private:
        bool Frame();
        void InitializeWindows(int&, int&);
        void ShutdownWindows();

        LPCWSTR m_applicationName;
        HINSTANCE m_hinstance;
        HWND m_hwnd;
    };

//定義靜態回呼函數以及應用程式控制代碼
//因為定義視窗類別的時候,必須指定視窗回呼函數,所以我們用靜態回呼函數WndProc
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

static SystemClass* ApplicationHandle = 0;

SystemClass.cpp代碼如下:

#include "SystemClass.h"

SystemClass::SystemClass(void)
    {
    bexit = false;
    }

SystemClass::SystemClass(const SystemClass &)
    {

    }

SystemClass::~SystemClass(void)
    {
    }

//調用視窗初始化函數和其它一些類的初始化函數
//本例子中,只調用初始化視窗函數
bool SystemClass::Initialize()
    {
    int screenWidth = 0, screenHeight = 0;

    // 初始化視窗
    InitializeWindows(screenWidth, screenHeight);

    return true;
    }

void SystemClass::Shutdown()
    {
    //其它類的一些銷毀工作
    //...

    // 執行視窗一些銷毀工作.
    ShutdownWindows();

    }

//處理訊息
void  SystemClass::Run()
    {
    MSG msg;
    bool done, result = 1;

    // 初始化訊息結構.
    ZeroMemory(&msg, sizeof(MSG));

   // 迴圈進行訊息處理,如果接收到WM_QUIT.
    done = false;
    while(!done)
        {
        // 處理windows訊息.
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            }

        // 接收到WM_QUIT訊息,退出程式.
        if(msg.message == WM_QUIT)
            {
            done = true;
            }
        else
            {
            result = bexit; //如果按了ESC,也退出程式

            //我們的渲染或者其它處理,可以放在這兒
            //....
            //.....
            Frame();
            if(result)
                {
                done = true;
                }
            }

        }

    return;
    }

bool SystemClass::Frame()
    {
    return true;
    }

//初始化視窗類別,建立應用程式視窗
void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight)
    {
    WNDCLASSEX wc;
    DEVMODE dmScreenSettings;
    int posX, posY;

    //得到System class對象(應用程式控制代碼)
    ApplicationHandle = this;

    // 得到應用程式執行個體控制代碼
    m_hinstance = GetModuleHandle(NULL);

    // 應用程式名稱字
    m_applicationName = L"Engine";

   // 設定視窗類別參數.
    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc   = WndProc; //指定回呼函數
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = m_hinstance;
    wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
    wc.hIconSm       = wc.hIcon;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //預設黑色視窗黑色背景
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = m_applicationName;
    wc.cbSize        = sizeof(WNDCLASSEX);

   // 註冊視窗類別
    RegisterClassEx(&wc);

    // 得到windows案頭解析度
    screenWidth  = GetSystemMetrics(SM_CXSCREEN);
    screenHeight = GetSystemMetrics(SM_CYSCREEN);

    // 根據是否全屏設定不同的解析度.
    if(FULL_SCREEN)
        {
       //全螢幕模式下,設定視窗大小為windows案頭解析度.
        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize       = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth  = (unsigned long)screenWidth;
        dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
        dmScreenSettings.dmBitsPerPel = 32;           
        dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        // 臨時設定顯示裝置為全螢幕模式,注意:應用程式退出時候,將恢複系統預設設定。
        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);

        // 設定視窗的預設位置為(0,0).
        posX = posY = 0;
        }
    else
        {
        // 視窗模式:800*600.
        screenWidth  = 800;
        screenHeight = 600;

        // 視窗位置,posX, posY視窗左上方座標
        posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth)  / 2;
        posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
        }

    // 全屏和視窗使用不同的參數.
    if( FULL_SCREEN)
        {
        m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName,
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
            posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
        }
    else
        {
        m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName,
            WS_OVERLAPPEDWINDOW,
            posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
        }

    // 顯示視窗並設定其為焦點.
    ShowWindow(m_hwnd, SW_SHOW);
    SetForegroundWindow(m_hwnd);
    SetFocus(m_hwnd);

    // 隱藏滑鼠.
    //ShowCursor(false);

    }

void SystemClass::ShutdownWindows()
    {
    //顯示光線標.
    //ShowCursor(true);

    // 恢複預設顯示設定.
    if(FULL_SCREEN)
        {
        ChangeDisplaySettings(NULL, 0);
        }

    // 銷毀視窗
    DestroyWindow(m_hwnd);
    m_hwnd = NULL;

    // 銷毀應用程式執行個體.
    UnregisterClass(m_applicationName, m_hinstance);
    m_hinstance = NULL;
    ApplicationHandle = NULL;

    return;

    }

LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
    {

    switch(umsg)
        {
        // 檢測按鍵訊息.
    case WM_KEYDOWN:
        if(wparam==VK_ESCAPE)
            bexit = true;
        return 0;
       //任何其它訊息發送到windows預設處理.
    default:
        {
        return DefWindowProc(hwnd, umsg, wparam, lparam);
        }
        }
    }

LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
    {
    switch(umessage)
        {

        // 視窗銷毀訊息.
    case WM_DESTROY:
        {
        PostQuitMessage(0);
        return 0;
        }

        // 視窗關閉訊息.
    case WM_CLOSE:
        {
        PostQuitMessage(0);       
        return 0;
        }

        //MessageHandle過程處理其它所有訊息.
    default:
        {
        return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam);
        }
        }
    }

程式執行後的介面和上次是一樣的。

完整的代碼請參考:

工程檔案myTutorialD3D11_1

代碼下載:

http://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.