我們把上一個教程的代碼封裝到一個類中來方便以后的使用。
首先新建一個空工程叫做MyHelloWin,添加一個main.cpp文件,然后新建一個類叫做MyWindow,將於窗體有關的操作封裝到里面
MyWindow.h文件
1 /************************************************************************ 2 Directx11學習筆記【2】 將HelloWin封裝成類 3 2016.01 by zhangbaochong 4 /************************************************************************/ 5 #pragma once 6 #include <windows.h> 7 8 static bool isPushEsc = false;//是否按下Esc鍵 9 10 class MyWindow 11 { 12 public: 13 MyWindow(); 14 ~MyWindow(); 15 public: 16 HWND GetHandle();//返回窗口句柄 17 bool Create(int &width, int &height);//創建窗口 18 void Run();//處理消息循環 19 LRESULT CALLBACK MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);//消息處理 20 private: 21 HWND m_hwnd; 22 HINSTANCE m_hinstance; 23 LPCWSTR m_name; 24 };
MyWindow.cpp
因為定義窗口的時候必須指定一個回調函數,所以我們定義一個靜態的WndProc,因為在WndProc中需要調用其他消息的處理函數MessageHandler,所以我們又定義一個類的實例句柄applicationHandle。
1 /************************************************************************ 2 Directx11學習筆記【2】 將HelloWin封裝成類 3 2016.01 by zhangbaochong 4 /************************************************************************/ 5 6 #include "MyWindow.h" 7 8 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);//靜態回調函數 9 static MyWindow *applicationHandle;//類的一個靜態實例 10 11 MyWindow::MyWindow() 12 { 13 isPushEsc = false; 14 m_hwnd = NULL; 15 m_name = L"HelloWin"; 16 } 17 18 19 MyWindow::~MyWindow() 20 { 21 } 22 23 24 HWND MyWindow::GetHandle() 25 { 26 return m_hwnd; 27 } 28 29 bool MyWindow::Create(int &width, int &height) 30 { 31 WNDCLASSEX wnd; 32 applicationHandle = this; 33 m_hinstance = GetModuleHandle(NULL); 34 wnd.cbClsExtra = 0; 35 wnd.cbSize = sizeof(WNDCLASSEX); 36 wnd.cbWndExtra = 0; 37 wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 38 wnd.hCursor = LoadCursor(NULL, IDC_ARROW); 39 wnd.hIcon = LoadIcon(NULL, IDI_WINLOGO); 40 wnd.hIconSm = wnd.hIcon; 41 wnd.hInstance = m_hinstance; 42 wnd.lpfnWndProc = WndProc; 43 wnd.lpszClassName = m_name; 44 wnd.lpszMenuName = m_name; 45 wnd.style = CS_VREDRAW | CS_HREDRAW; 46 47 //注冊窗口 48 if ( !RegisterClassEx(&wnd) ) 49 { 50 MessageBox(NULL, L"注冊窗口失敗", L"error", 0); 51 return false; 52 } 53 m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_name, m_name, WS_OVERLAPPEDWINDOW, 0, 0, width, height, 54 NULL, NULL, m_hinstance, NULL); 55 //顯示窗口設置其為焦點 56 ShowWindow(m_hwnd, SW_SHOW); 57 UpdateWindow(m_hwnd); 58 return true; 59 } 60 61 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) 62 { 63 switch (message) 64 { 65 case WM_DESTROY: 66 PostQuitMessage(0); 67 return 0; 68 //其他消息發送MessageHandler處理 69 default: 70 return applicationHandle->MessageHandler(hwnd, message, wparam, lparam); 71 } 72 } 73 74 LRESULT CALLBACK MyWindow::MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) 75 { 76 switch (message) 77 { 78 //檢測按鍵消息 79 case WM_KEYDOWN: 80 if (wparam == VK_ESCAPE)//用戶按下退出鍵 81 isPushEsc = true; 82 return 0; 83 84 //其他消息發送windows缺省處理 85 default: 86 return DefWindowProc(hwnd, message, wparam, lparam); 87 } 88 } 89 90 void MyWindow::Run() 91 { 92 MSG msg; 93 ZeroMemory(&msg, sizeof(MSG)); 94 bool isRuning = true;//控制是否退出消息循環 95 while (isRuning) 96 { 97 //處理windows消息 98 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 99 { 100 TranslateMessage(&msg); 101 DispatchMessage(&msg); 102 } 103 if (msg.message == WM_QUIT) 104 { 105 isRuning = false; 106 } 107 else//按下esc鍵也退出 108 { 109 isRuning = !isPushEsc; 110 111 //渲染等處理可以放在這兒 112 } 113 114 } 115 }
main.cpp
1 /************************************************************************ 2 Directx11學習筆記【2】 將HelloWin封裝成類 3 2016.01 by zhangbaochong 4 /************************************************************************/ 5 #include "MyWindow.h" 6 7 int WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) 8 { 9 int width = 800, height = 600; 10 MyWindow *window = new MyWindow; 11 if (window->Create(width, height)) 12 { 13 window->Run(); 14 } 15 return 0; 16 }
運行結果和上次一樣: