Windows原生窗口创建全流程(代码+说明)
#include <Windows.h>
// 窗口过程函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Win32Window");
// 1. 窗口类注册
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szAppName;
wcex.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
if (!RegisterClassEx(&wcex)) {
MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// 2. 创建窗口
HWND hWnd = CreateWindowEx(
0, // 扩展样式
szAppName, // 窗口类名
TEXT("Windows原生窗口示例"), // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, CW_USEDEFAULT, // 初始位置
800, // 宽度
600, // 高度
NULL, // 父窗口
NULL, // 菜单
hInstance, // 实例句柄
NULL // 创建参数
);
if (!hWnd) {
MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// 3. 显示窗口
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
// 4. 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
// 5. 窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// 绘制文本
RECT rect;
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("Hello Windows!"), 14, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Windows原生窗口创建关键系统函数详解
1. 窗口类注册
| 函数/结构体 | 作用 | 关键参数说明 |
|---|---|---|
| WNDCLASSEX | 定义窗口类属性 | - cbSize: 结构体大小- style: 窗口样式(CS_HREDRAW|CS_VREDRAW)- lpfnWndProc: 窗口过程函数指针- hInstance: 应用程序实例句柄- hbrBackground: 背景画刷(COLOR_WINDOW+1)- lpszClassName: 注册类名 |
| RegisterClassEx | 注册窗口类到系统 | 接收WNDCLASSEX*指针,成功返回TRUE,失败返回FALSE |
| LoadIcon | 加载图标资源 | 第一个参数为NULL时使用系统默认图标(如IDI_APPLICATION) |
| LoadCursor | 加载光标资源 | 使用系统默认箭头光标(IDC_ARROW) |
2. 窗口创建与显示
| 函数 | 作用 | 关键参数说明 |
|---|---|---|
| CreateWindowEx | 创建窗口实例 | - 扩展样式(0为默认) - 窗口类名(必须已注册) - 窗口标题 - 窗口样式(WS_OVERLAPPEDWINDOW) - 初始位置/尺寸(CW_USEDEFAULT表示默认) - 父窗口句柄(NULL表示无父窗口) - 菜单句柄(NULL表示无菜单) |
| ShowWindow | 控制窗口显示状态 | iCmdShow参数决定显示方式(SW_SHOW默认显示) |
| UpdateWindow | 强制重绘窗口 | 发送WM_PAINT消息到消息队列,触发首次绘制 |
3. 消息循环系统
| 函数 | 作用 | 关键参数说明 |
|---|---|---|
| GetMessage | 从消息队列获取消息 | 参数:MSG结构体指针,窗口句柄(NULL接收所有窗口消息),消息范围(0,0表示所有消息) |
| TranslateMessage | 转换键盘消息 | 将虚拟键消息转换为字符消息(如WM_KEYDOWN→WM_CHAR) |
| DispatchMessage | 分发消息到窗口过程 | 将消息发送给目标窗口的WndProc函数处理 |
4. 窗口过程函数
| 函数 | 作用 | 关键参数说明 |
|---|---|---|
| WndProc | 处理窗口消息 | - message: 消息类型(如WM_PAINT/WM_DESTROY)- wParam/lParam: 消息附加参数 |
| DefWindowProc | 默认消息处理 | 未处理的消息由系统进行默认处理 |
| PostQuitMessage | 发送退出消息 | 退出消息循环时调用,设置MSG的wParam为退出码 |
Windows共享内存操作全指南(代码+说明)
核心函数与参数说明
| 函数名 | 作用 | 关键参数说明 | 所属头文件 |
|---|---|---|---|
| CreateFileMapping | 创建内存映射对象 | hFile:文件句柄(INVALID_HANDLE_VALUE表示使用页文件)flProtect:内存保护属性(如PAGE_READWRITE)lpName:共享内存名称(跨进程标识) | <windows.h> |
| OpenFileMapping | 打开已存在的内存映射对象 | dwDesiredAccess:访问模式(FILE_MAP_READ/WRITE)lpName:共享内存名称 | <windows.h> |
| MapViewOfFile | 映射内存到进程地址空间 | hFileMappingObject:映射对象句柄dwDesiredAccess:访问模式dwNumberOfBytesToMap:映射字节数 | <windows.h> |
| UnmapViewOfFile | 解除内存映射 | lpBaseAddress:映射视图地址 | <windows.h> |
| CloseHandle | 关闭对象句柄 | hObject:要关闭的句柄 | <windows.h> |
完整代码示例
#include <windows.h>
#include <iostream>
#include <cassert>
int main() {
const char* sharedMemName = "Global\\MySharedMemory";
const SIZE_T sharedMemSize = 1024; // 1KB
// 创建共享内存
HANDLE hMapping = CreateFileMapping(
INVALID_HANDLE_VALUE, // 使用系统页文件
NULL, // 默认安全属性
PAGE_READWRITE, // 可读写
0, // 高位文件大小
sharedMemSize, // 低位文件大小
sharedMemName // 共享内存名称
);
if (!hMapping) {
std::cerr << "创建共享内存失败!错误代码:" << GetLastError() << std::endl;
return 1;
}
// 映射到进程地址空间
LPVOID pSharedMem = MapViewOfFile(
hMapping, // 映射对象句柄
FILE_MAP_ALL_ACCESS, // 完全访问权限
0, // 偏移高位
0, // 偏移低位
0 // 映射整个区域
);
if (!pSharedMem) {
std::cerr << "映射共享内存失败!错误代码:" << GetLastError() << std::endl;
CloseHandle(hMapping);
return 1;
}
// 写入数据到共享内存
int* pData = static_cast<int*>(pSharedMem);
pData[0] = 42; // 写入示例数据
std::cout << "写入共享内存的值:" << pData[0] << std::endl;
// 解除映射
if (!UnmapViewOfFile(pSharedMem)) {
std::cerr << "解除映射失败!错误代码:" << GetLastError() << std::endl;
}
// 关闭句柄
CloseHandle(hMapping);
// 示例:另一个进程打开已存在的共享内存
HANDLE hExistingMapping = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // 完全访问权限
FALSE, // 不可继承
sharedMemName // 共享内存名称
);
if (hExistingMapping) {
LPVOID pExistingMem = MapViewOfFile(
hExistingMapping,
FILE_MAP_ALL_ACCESS,
0,
0,
0
);
if (pExistingMem) {
int* pExistingData = static_cast<int*>(pExistingMem);
std::cout << "从共享内存读取的值:" << pExistingData[0] << std::endl;
assert(pExistingData[0] == 42); // 验证数据一致性
UnmapViewOfFile(pExistingMem);
}
CloseHandle(hExistingMapping);
} else {
std::cerr << "打开共享内存失败!错误代码:" << GetLastError() << std::endl;
}
return 0;
}