Windows窗口消息实例详解

yizhihongxing

Windows窗口消息实例详解

简介

在 Windows 操作系统中,窗口消息是非常重要的概念。这些消息包括用户输入、系统通知以及应用程序间的通信等信息。理解窗口消息的处理方式对于开发 Windows 应用程序非常重要。

本篇文章将详细探讨 Windows 窗口消息的处理,并提供两个实例来帮助理解。

窗口消息的处理方式

消息循环

窗口消息是通过消息循环机制进行处理的。在消息循环中,程序会不断地从消息队列中取出消息,并把它们分发给相应的窗口进行处理。

Windows 应用程序中的主消息循环可以简单地描述为以下的代码:

MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

该代码段中,GetMessage 函数从消息队列中获取一个消息,并将其存储在 msg 变量中。然后,TranslateMessage 函数用于将一些特定的键盘消息(如 WM_KEYDOWN、WM_KEYUP 等)翻译成对应的字符消息,最后 DispatchMessage 函数将该消息发送给目标窗口的窗口回调函数(即 WndProc)进行处理。

窗口回调函数

每个窗口都有一个窗口过程函数(即窗口回调函数),该函数用于处理窗口收到的消息。在窗口创建时,可以为窗口指定一个回调函数。

回调函数的模板如下所示:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        // 处理各种消息
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

其中,hWnd 参数代表目标窗口的句柄,message 参数代表窗口收到的消息类型,wParam 和 lParam 参数则是消息的参数。

在窗口过程函数中,常常使用 switch 语句来处理各种类型的消息,如 WM_PAINT、WM_SIZE、WM_CLOSE 等。

处理用户输入

窗口消息中的一种很重要的消息类型是用户输入,如鼠标、键盘等。使用窗口回调函数可以方便地处理这些消息。

以下是一个处理鼠标输入消息的示例(仅提供代码片段):

switch (message)
{
    case WM_LBUTTONDOWN:
        //鼠标左键按下的处理代码
        break;
    case WM_LBUTTONUP:
        //鼠标左键释放的处理代码
        break;
    case WM_MOUSEMOVE:
        //鼠标移动的处理代码
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
}

在该示例中,当收到 WM_LBUTTONDOWN 消息时,会执行鼠标左键按下的处理代码。其他类型的鼠标消息也可以在 switch 语句中进行处理。

示例一:创建一个窗口

以下是一个创建一个简单窗口的示例代码:

#include <Windows.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    // 注册窗口类
    WNDCLASS wc = { 0 };
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = L"WindowClass";
    RegisterClass(&wc);

    // 创建窗口
    HWND hWnd = CreateWindow(
        L"WindowClass",
        L"Hello, Windows!",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 300,
        NULL, NULL,
        hInstance, NULL
    );

    // 显示窗口
    ShowWindow(hWnd, nShowCmd);
    UpdateWindow(hWnd);

    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        TextOut(hdc, 5, 5, L"Hello, Windows!", 16);
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_CLOSE:
        DestroyWindow(hWnd);
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
    break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

在该示例中,我们首先注册了一个名为 "WindowClass" 的窗口类,然后创建了一个名为 "Hello, Windows!" 的窗口。在消息循环中,我们将窗口消息发送到 WndProc 函数进行处理。

在 WndProc 函数中,我们使用了 switch 语句来处理收到的不同类型消息。其中,在 WM_PAINT 消息种我们使用 TextOut 函数向窗口绘制了一些文本,在 WM_CLOSE 和 WM_DESTROY 消息中则分别销毁了窗口和退出程序。

示例二:向窗口发送自定义消息

以下是一个向窗口发送自定义消息的示例:

#include <Windows.h>

#define WM_MY_MESSAGE (WM_USER + 1)

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    // 注册窗口类
    WNDCLASS wc = { 0 };
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = L"WindowClass";
    RegisterClass(&wc);

    // 创建窗口
    HWND hWnd = CreateWindow(
        L"WindowClass",
        L"Hello, Windows!",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 300,
        NULL, NULL,
        hInstance, NULL
    );

    // 显示窗口
    ShowWindow(hWnd, nShowCmd);
    UpdateWindow(hWnd);

    // 发送自定义消息
    SendMessage(hWnd, WM_MY_MESSAGE, 0, 0);

    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_MY_MESSAGE:
        MessageBox(hWnd, L"This is my message!", L"Message", MB_OK);
        break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        TextOut(hdc, 5, 5, L"Hello, Windows!", 16);
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

在该示例中,我们向窗口发送一个自定义的消息 WM_MY_MESSAGE,并在 WndProc 函数中将该消息与一个 MessageBox 进行关联。当收到该消息时,程序将会弹出一个包含字符串 "This is my message!" 的对话框。

结论

对于 Windows 应用程序开发,理解窗口消息的处理方式是非常必要的。本文探讨了消息循环、窗口回调函数以及事实中的两个示例,并希望这可以提高读者对 Windows 窗口消息的理解能力。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Windows窗口消息实例详解 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python Flask 搭建微信小程序后台详解

    我来详细讲解一下“Python Flask 搭建微信小程序后台详解”的完整攻略。 1. 什么是Python Flask Python Flask是一个轻量级的 Web 框架,它基于 Python 语言开发,被广泛应用于 Web 应用开发。 2. 搭建Python Flask项目 (1)安装Python环境由于Python Flask是基于Python语言开发…

    python 2023年5月23日
    00
  • Python CSV 文件解析和生成方法示例

    以下是关于 Python CSV 文件解析和生成的完整攻略,其中包含了两条示例说明。 CSV 文件简介 CSV(Comma Separated Values)文件是一种通用的数据交换格式,数据以逗号作为分隔符进行存储,每行记录代表一条数据,可以用任何文本编辑器打开并查看。CSV 文件常用于数据导入和导出,并且易于处理。在 Python 中,我们可以使用标准库…

    python 2023年6月3日
    00
  • python遍历字符串中每一个字符的4种方式

    当我们需要操作字符串的时候,遍历每一个字符是最基本的操作之一。Python语言提供了多种方式来遍历字符串中的每一个字符,下面将详细讲解这4种方式: 1. 使用下标遍历字符串 使用下标遍历字符串,可以通过字符串的长度和下标的范围来获取每个字符。下面是一个简单的示例: s = "abcdefg" length = len(s) for i i…

    python 2023年6月5日
    00
  • python pandas中索引函数loc和iloc的区别分析

    Pandas索引函数 loc iloc 基于标签的索引 √ 基于位置的索引 √ Pandas提供了两种不同类型的索引函数:基于标签的索引函数loc和基于位置的索引函数iloc。二者的主要区别在于索引的方式不同,因此在选择数据的过程中需要根据具体情况选择使用哪种类型的索引函数。 loc(基于标签的索引) loc函数通过标签(列名、行名)提取数据,可以用来选择某…

    python 2023年6月7日
    00
  • 如何使用 python-google-api 下载文件

    【问题标题】:How to download a file with python-google-api如何使用 python-google-api 下载文件 【发布时间】:2023-04-06 04:26:01 【问题描述】: 如何使用 GoogleAPI 下载文件?这是我目前所拥有的: CLIENT_ID = ‘255556’ CLIENT_SECRET…

    Python开发 2023年4月7日
    00
  • Python环境配置实现pip加速过程解析

    下面是Python环境配置实现pip加速过程解析的完整攻略。 环境配置 安装Python 首先,需要在官网 https://www.python.org/downloads/ 下载 Python 版本的安装文件。 下载完成后,双击安装包运行,一路点击下一步进行安装。安装完成后,打开命令提示符或者终端,输入以下命令检查 Python 是否安装成功: pytho…

    python 2023年5月14日
    00
  • python实现Excel文件转换为TXT文件

    下面是详细的“python实现Excel文件转换为TXT文件”的完整实例教程。 1. 准备工作 在开始转换前,需要准备以下需要的库和工具: Python环境:本教程使用的是Python 3.x版本 openpyxl库:Python中用于读写Excel文件的库 安装openpyxl库可通过运行以下命令完成: python -m pip install open…

    python 2023年5月13日
    00
  • Python编写单元测试代码实例

    当我们编写Python代码时,测试是至关重要的,因为它可以确保代码的正确性,并且能够避免代码的错误蔓延。单元测试是一种测试代码的方法,我们可以在Python中使用unittest库来编写单元测试代码。 以下是编写Python单元测试代码的完整攻略: 1. 安装unittest库 在Python中,unittest是一个内置库,因此无需安装。 2. 编写测试用…

    python 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部