Windows窗口消息实例详解

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日

相关文章

  • Python3逻辑运算符与成员运算符

    请看下文对”Python3逻辑运算符与成员运算符”的详细讲解。 Python3逻辑运算符 Python中常用的逻辑运算符包括三个符号:and,or,not。其中,and代表逻辑与,or代表逻辑或,not代表逻辑非,它们的真值表如下: 逻辑运算符 说明 示例 and 与,要求表达式的两边的值同时满足条件,才返回True True and False返回Fals…

    python 2023年5月14日
    00
  • Python中assert函数的使用(含源代码)

    Python中assert函数的使用 在Python中,assert函数是一种常用的调试工具。它用于检查一个条件是否为真,如果条件为假,则会抛出AssertionError异常。本文将为您详细讲解Python中assert函数的使用,包括语法、参数、示例等。 assert函数语法 assert函数的语法如下: assert expression [, arg…

    python 2023年5月14日
    00
  • 如何使用Python在MySQL中使用表级锁?

    在MySQL中,表级锁是一种用于控制并发访问的机制,它可以确保多个用户同时访问同一表时不会发生冲突。在Python中,可以使用MySQL连接来执行表级锁查询以下是Python使用表级的完整攻略,包括表级锁的基本语法、使用表级锁的例以及如何在Python中使用表级锁。 表锁的基本语法 在MySQL中,可以使用LOCK TABLES语句来获取表级锁。以下是表级锁…

    python 2023年5月12日
    00
  • Python初学者需要注意的事项小结(python2与python3)

    Python初学者需要注意的事项小结(python2与python3) Python是一门非常适合初学者学习的编程语言,在学习的过程中,初学者需要注意一些事项,尤其对于Python2与Python3版本的区别需要特别注意。在这里,我们来总结一下初学者需要注意的事项。 注意Python版本 Python2和Python3有一些不同之处,其中最主要的不同就在于P…

    python 2023年5月14日
    00
  • python 3.7.0 下pillow安装方法

    下面是Python 3.7.0下安装Pillow的完整攻略: 安装前准备 在开始安装过程前,需要先确认一下以下几点: 电脑中已经安装好了Python 3.7.0版本,可以通过命令行输入python –version或python3 –version来确认版本号。 已经安装pip,可以通过输入pip –version来检测pip是否已经正确安装。 确认了…

    python 2023年5月14日
    00
  • PYTHON正则表达式 re模块使用说明

    PYTHON正则表达式re模块使用说明 在Python中,我们可以使用re模块进行正则表达式的匹配和替换。re模块提供了一系列函数,可以用处理字符串。本攻略将细讲解re模的使用方法,包括如何使用re.match()、re.search()函数、re.findall()函数、re()函数等。 re.match()函数 re()函数用于从字符串的起始位置匹配一个…

    python 2023年5月14日
    00
  • 如何在Python中连接MySQL数据库?

    以下是如何在Python中连接MySQL数据库的完整使用攻略,包括导入模块、连接数据库、执行查询操作等步骤。提供了两个示例以便更好地理解如何连接MySQL。 步骤1:导入模块 在Python中,我们需要导入相应的模块连接数据库。以下是导入mysql-connector-python模块的基本语法: import mysql.connector 步骤2:连接数…

    python 2023年5月12日
    00
  • python初学者,用python实现基本的学生管理系统(python3)代码实例

    以下是“python初学者,用python实现基本的学生管理系统(python3)代码实例”的完整攻略: 1. 前置知识 在学习和实现这个学生管理系统之前,我们需要掌握一些Python的基础知识,例如: 数据类型与变量 条件语句与循环语句 函数 文件操作 如果你不熟悉以上知识点,可以先通过阅读Python的入门教程进行学习和练习。 2. 学生管理系统功能需求…

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