Windows原生开发

Windows原生窗口创建全流程(代码+说明)

cpp 复制代码
#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>

完整代码示例

cpp 复制代码
#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;
}
相关推荐
Lazy_zheng2 小时前
Map / Set / WeakMap / WeakSet,一次给你讲透
前端·javascript·面试
uzong2 小时前
ClaudeCode 入门详细教程,手把手带你Vibe Coding
前端·人工智能
英俊潇洒美少年2 小时前
前端安全 完整精讲
前端·安全
aircrushin2 小时前
2026我最推荐的前端设计skills
前端
problc2 小时前
Pretext —— 无 DOM 文本测量与布局引擎
前端·ai
阿kun要赚马内2 小时前
Python面向对象:@property装饰器
开发语言·前端·python
徒 花2 小时前
web前端技术知识复习
前端·html·web
意法半导体STM322 小时前
【官方原创】STM32H7双核芯片通过 STlink连接失败问题分析 LAT1654
开发语言·前端·javascript·stm32·单片机·嵌入式硬件
小王C语言2 小时前
【基础IO】————简单设计一下libc库
前端·数据结构·算法