本文是学习以下视频课程的记录
02_底层窗口实现(一)_WinMain入口函数_哔哩哔哩_bilibili
03_底层窗口实现(二)_创建窗口的前五步_哔哩哔哩_bilibili
04_底层窗口现实(三)_窗口过程处理_哔哩哔哩_bilibili
基本流程
- 设计窗口
- 注册窗口
- 创建窗口
- 显示和更新窗口
- 通过循环取消息
- 处理消息(窗口过程)
代码实现
首先在visual studio中创建windows桌面向导项目:
然后创建头文件win32.h(名称自定义):
#pragma once
#include <Windows.h>
//设计、注册窗口
BOOL InitApplication(HINSTANCE);
//创建、显示、更新窗口
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam);
创建源文件为win32.c:
#include "win32.h"
//程序入口函数
//WINAPI 代表 __stdcall 参数传递顺序:从右往左依次入栈,函数返回前清栈
int WINAPI WinMain(
HINSTANCE hInstance,//应用程序实例句柄
HINSTANCE hPrevInstance,//上一个应用程序句柄
PWSTR pCmdLine,//char *argv[]命令行参数
int nCmdShow)//显示命令 最大化、最小化、正常
{
MSG msg;
if (!hPrevInstance) {
if (!InitApplication(hInstance)) {
return FALSE;
}
}
if (!InitInstance(hInstance, nCmdShow)) {
return FALSE;
}
//通过循环取消息
while (GetMessage(
&msg,//消息
NULL,//捕获窗口,填NULL代表捕获所有的窗口
0, //最大最小的过滤的消息,一般填0
0)) {//填0代表捕获所有的消息
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
BOOL InitApplication(HINSTANCE hInstance)
{
//设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0;//类的额外内存
wc.cbClsExtra = 0;//窗口的额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置背景
wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标,第一个参数为NULL,代表使用系统提供的光标
wc.hIcon = LoadIcon(NULL, IDI_INFORMATION);//图标,第一个参数为NULL,代表使用系统提供的图标
wc.hInstance = hInstance;//应用程序实例句柄
wc.lpszClassName = TEXT("WIN");//窗口类名称
wc.lpszMenuName = NULL;//菜单名称
wc.style = 0;//显示风格,0代表默认风格
wc.lpfnWndProc = WindowProc;//回调函数
//注册窗口类
return (RegisterClass(&wc));
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//创建窗口
HWND _hwind = CreateWindow(TEXT("WIN"), TEXT("Win32Test"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
//显示和更新
ShowWindow(_hwind, nCmdShow);
UpdateWindow(_hwind);
return TRUE;
}
LRESULT CALLBACK WindowProc(
HWND hwnd, //消息所属的窗口句柄
UINT uMsg, //具体消息名称 WM_XXXX 消息名
WPARAM wparam, //键盘附加消息
LPARAM lparam) //鼠标附加消息
{
switch (uMsg)
{
case WM_CLOSE:
//所有xxxWindows为结尾的方法,都不会进入消息队列,而是直接执行
DestroyWindow(hwnd); //发送另一个消息 WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);//这时,GetMessage返回FALSE,程序退出
break;
case WM_LBUTTONDOWN:
{//C语言,在switch-case结构中声明局部变量要在case下加一个大括号
int xPos = LOWORD(lparam);
int yPos = HIWORD(lparam);
char buf[1024];
wsprintf(buf, TEXT("x = %d, y = %d"), xPos, yPos);
MessageBox(hwnd, buf, TEXT("WM_LBUTTONDOWN"), MB_OK);
break;
}
case WM_KEYDOWN:
MessageBox(hwnd, TEXT("WM_KEYDOWN"), TEXT("WM_KEYDOWN"), MB_OK);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("HELLO"), strlen("HELLO"));
EndPaint(hwnd, &ps);
break;
}
}
return DefWindowProc(hwnd, uMsg, wparam, lparam);
}