05/28/2020
Window编程入门
前言
学习Direct 3D之前,一定先要创建一个窗口,并在窗口中渲染3D场景。使用DirectX 11,绕不开的话题就是用Win 32 API来编写windows应用程序。
窗口程序
windows应用程序由许多组件构成
- 主窗口
- 菜单
- 工具栏
- 滚动条
- 按钮
- 其他的对话框控件
资源
资源:CPU,内存或者显示器这些硬件资源,都在多应用程序的共享范围之列。Windows应用程序并不能直接访问硬件,Windows系统的主要任务之一管理当前正在运行的实例化程序并为它们合理分配资源
事件、消息队列、消息以及消息循环
事件驱动编程模型
- 坐等某事的发生,即事件的发生。比如按键盘、点击鼠标,窗口的放大放小等
- 当事件发生时,Windows会向发生事件的应用程序发送相应的消息,随后该消息会被添加至此应用程序的消息队列
- 应用程序会在消息循环中不断地检测队列中的消息,在接受到消息之后,它会将此消息分派到相应窗口过程的函数
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
//....
例子说明,当按键按下去,事件发生,发送消息给应用程序,应用程序接受到这个消息并把这个消息发送给相应的主窗口,主窗口接受到消息,并处理消息,按下去的键是不是ESC键
winMain函数与窗口消息回调
- 类似于大多数的main函数
- 封装了许多数据类型
/*
Main 函数
*/
int WINAPI WinMin(HINSTANCE hInstance, //application instance
HINSTANCE hPrevInstance,
PWSTR nCmdShow,
int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc; //跟踪回调函数,在描述WNDCLASS时,必须有一个回调函数
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc); //register the window class
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop. 不停的响应操作系统或者用户传来的消息
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); //针对键盘输入,键盘值转换成字符
DispatchMessage(&msg); //调用回调函数WinProc
}
return 0;
}
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd, //a handle to the window
_In_ UINT uMsg, //system-provided messages 获得操作系统提供的消息,比如键盘鼠标的输入
_In_ WPARAM wParam, //额外提供message信息,值依赖于uMsg
_In_ LPARAM lPram //额外桶的message,值依赖于uMsg
)
{
switch(uMsg)
{
case WM_DESTORY: //关闭应用程序
PostQuitMessage(0);
return 0;
case WM_SIZE: //处理窗口大小变化
//获得改变后窗口大小
int width = LOWORD(lParam); // Macro to get the low-order word.
int height = HIWORD(lParam); // Macro to get the high-order word.
// Respond to the message: wParam表示是否最小化或者最大化
OnSize(hwnd, (UINT)wParam, width, height);
return 0;
}
return DefWindoProc(hwnd,uMsg,wParam,lParam); //如果未处理的消息,返回给系统默认处理
}
总结
- 系统创建进程,分配资源,给定一个hInstance应用程序
- 窗口类设置一个应用程序
- 窗口类设置一个回调函数
- 在描述WNDCLASS时,必须有一个回调函数,因为在CreateWindow时候需要使用回调函数,不然无法创建窗口
微软文档关于WinMain函数
微软文档关于WindowProc函数