Windows窗口的创建过程#
WNDCLASS wc; //窗口类
wc.style = CS_HREDRAW | CS_VREDRAW; //CS_HREDRAW:当水平长度改变或移动窗口时,重画整个窗口
//CS_VREDRAW: 当垂直长度改变或移动窗口时,重画整个窗口
//其他选项查阅文档
wc.cbClsExtra = 0; //窗口类无扩展
wc.cbWndExtra = 0; //窗口实例无扩展
wc.lpszClassName = L"D3DAppWindow"; //窗口类名称为D3DAppWindow
wc.lpszMenuName = nullptr; //窗口菜单名称
wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(NULL_BRUSH)); //窗口背景色
wc.hCursor = LoadCursor(0, IDC_ARROW); //窗口鼠标为箭头光标
wc.hIcon = LoadIcon(0, IDI_APPLICATION); //窗口最小化图标为缺省图标
wc.hInstance = m_hAppInstance; //这个为应用程序的实例句柄
wc.lpfnWndProc = MainWndProc; //回调函数指针
if (FAILED(RegisterClass(&wc))) //将填充好的窗口类注册
{
MessageBox(nullptr, L"Failed Register Window!", 0, 0);
return FALSE;
}
HWND hWnd = CreateWindow(
L"D3DAppWindow", //之前注册的窗口类名称
L"D3DApp", //窗口标题名称,会显示在窗口左上角
WS_OVERLAPPEDWINDOW, //窗口的风格
CW_USEDEFAULT, CW_USEDEFAULT, //默认窗口左上角坐标
m_width, m_height, //窗口大小
nullptr, //窗口无父窗口
nullptr, //窗口无子菜单
m_hAppInstance, //应用程序的实例句柄
nullptr
);
ShowWindow(hWnd, SW_SHOW); //指定窗口的显示状态(最小化最大化等),SW_SHOW在原位置以原尺寸显示
UpdateWindow(hWnd); //UpdateWindow函数发送一个WM_PAINT消息来更新指定窗口的客户区
//函数绕过应用程序的消息队列,直接发送WM_PAINT消息给指定窗口的窗口过程
MSG msg; //消息对象
ZeroMemory(&msg, sizeof(MSG)); //零初始化消息对象
while (msg.message != WM_QUIT) //主循环,没有收到退出消息时循环执行
{
if (PeekMessage(&msg, m_hAppWnd, 0, 0, PM_REMOVE)) //以查看的方式从系统中获取消息,处理后,消息从队列里除掉
{
TranslateMessage(&msg); //该函数将虚拟键消息转换为字符消息,发送至消息队列
DispatchMessage(&msg); //该函数分发一个消息给窗口程序,消息被分发到回调函数
}
else
{
UpdateScene(0.1f); //没有消息时执行游戏场景逻辑
DrawScene(); //由D3D绘制场景
}
}
LRESULT WindowBase::MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
//收到窗口销毁消息时,发送退出信息
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam); //调用默认消息处理函数处理大多数消息
}
class WindowBase
{
public:
WindowBase(HINSTANCE hInstance):m_hAppInstance(hInstance) {}
~WindowBase() {}
//获取App的Instance句柄
HINSTANCE AppInst() const;
//获取窗口句柄
HWND AppWindow() const;
//设置窗口的大小,应在调用Init()初始化窗口之前设置
void SetHeightAndWidth(int width, int height);
//主循环
int Run();
//回掉函数
LRESULT MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
//初始化,在这里调用 InitGameWindow() 和 InitDirect3D()
virtual bool Init();
//游戏逻辑更新 必须重写
virtual void UpdateScene(float dt) = 0;
//游戏绘制 可以不重写 即不绘制任何东西 只处理游戏逻辑
virtual void DrawScene();
protected:
HRESULT InitGameWindow(); //所有注册、创建窗口实例的过程在这里写
HRESULT InitDirect3D(); //所有初始化Direct3D的过程在这里写
protected:
HINSTANCE m_hAppInstance = nullptr;
HWND m_hAppWnd = nullptr;
int m_height = 800;
int m_width = 600;
};