赞
踩
使用VS创建一个空项目。我这里使用的是Visual Studio 2022。具体方法不再描述。
右键属性,将C++语言标准升到C++20.
添加头文件:
#include <windows.h>
#include <iostream>
声明WindowProc
函数:
LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
该函数是一个应用程序定义的函数。它处理发送给窗口的消息。
编写main函数:
int wmain(int argc, wchar_t* argv[])
{
wmain()是unicode版本的的main() 。
设置控制台的显示中文,否则无法使用宽字符来输出中文:
setlocale(LC_ALL, "chs");
定义窗口类属性:
int width = 1024;
int height = 720;
HINSTANCE hInstance;
hInstance = GetModuleHandle(NULL);
WNDCLASS wndClass{};
// 设置应用图标
wndClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClass.lpfnWndProc = WindowProc;
// 设置类名字
wndClass.lpszClassName = L"SGE";
wndClass.hInstance = hInstance;
// 指定唯一一个style
wndClass.style = CS_OWNDC;
注册窗口类:
RegisterClass(&wndClass);
根据之前的窗口类,创建一个Windows窗口:
HWND hwnd = CreateWindow(
L"SGE", // 类名
L"The Seed Game Engine", // 窗口名
WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE,
38,
20,
width,
height,
NULL,
NULL,
hInstance,
NULL);
其中第三个参数为窗口样式:WS_OVERLAPPED
表示该窗口拥有标题栏和窗口边框;WS_SYSMENU
表示该窗口拥有窗口系统控制按钮;WS_MINIMIZEBOX
表示窗口拥有最小化按钮;WS_VISIBLE
表示窗口初始可视。
判断窗体时候创建成功:
if (FAILED(hwnd))
{
std::wcout << L"创建窗口出错!" << std::endl;
throw;
return 0;
}
由于窗口存在标题栏和边框,需要修改窗口大小,保证绘图区域为固定的分辨率:
RECT rc;
GetClientRect(hwnd, &rc);
MoveWindow(hwnd, 0, 0, width + width - rc.right, height + height - rc.bottom, true);
创建消息循环:
MSG msg;
while (true)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return 0;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(300);
}
消息循环是很重要的一部分。主逻辑每隔一段时间就清空所有的Windows消息队列中的消息,对其中的消息进行转发和处理,然后休眠一段时间,继续循环。
最后,就剩下补充WindowProc
函数实现:
LRESULT CALLBACK WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
#include <windows.h> #include <iostream> LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); int wmain(int argc, wchar_t* argv[]) { // 设置控制台的中文显示 setlocale(LC_ALL, "chs"); int width = 1024; int height = 720; HINSTANCE hInstance; hInstance = GetModuleHandle(NULL); WNDCLASS wndClass{}; // 设置应用图标 wndClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION); wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW; wndClass.lpfnWndProc = WindowProc; // 设置类名字 wndClass.lpszClassName = L"SGE"; wndClass.hInstance = hInstance; // 指定唯一一个style wndClass.style = CS_OWNDC; // 注册 RegisterClass(&wndClass); HWND hwnd = CreateWindow( L"SGE", // 类名 L"The Seed Game Engine", // 窗口名 WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, 38, 20, width, height, NULL, NULL, hInstance, NULL); if (FAILED(hwnd)) { std::wcout << L"创建窗口出错!" << std::endl; throw; return 0; } RECT rc; GetClientRect(hwnd, &rc); MoveWindow(hwnd, 0, 0, width + width - rc.right, height + height - rc.bottom, true); MSG msg; while (true) { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return 0; TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(300); } return 0; } LRESULT CALLBACK WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
本节项目链接地址:https://github.com/nayaku/SGE/tree/dev_1
这一章节,我们实现了一个简单的Window窗口的创建。然而,窗体内容还是空的。下一章节,将会开始搭建引擎的框架来一步步实现一个完整的游戏引擎。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。