Windows 操作系统定义了大量的消息类型

2024-08-25 06:04

本文主要是介绍Windows 操作系统定义了大量的消息类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Windows 操作系统定义了大量的消息类型,每种消息类型都有其特定的含义和用途。Windows 消息是操作系统与应用程序之间进行通信的主要机制,它们用于通知应用程序各种事件的发生,例如用户输入(键盘、鼠标)、窗口状态变化、系统事件等。

常见的 Windows 消息类型

下面列出了几种常见的 Windows 消息类型及其用途:

1. 窗口管理消息

这些消息用于管理窗口的生命周期、大小、位置和状态等。

  • WM_CREATE:窗口正在被创建时发送,通常用于进行初始化。
  • WM_DESTROY:窗口即将被销毁时发送,通常用于清理资源。
  • WM_CLOSE:请求关闭窗口时发送,例如用户点击窗口的关闭按钮。
  • WM_QUIT:指示应用程序应终止。通常由 PostQuitMessage 发送。
  • WM_SIZE:窗口大小改变时发送,应用程序可以在此消息中调整窗口的布局。
  • WM_MOVE:窗口被移动时发送。
2. 鼠标输入消息

这些消息用于处理鼠标事件,例如移动、点击、滚动等。

  • WM_MOUSEMOVE:鼠标移动时发送。
  • WM_LBUTTONDOWN:鼠标左键按下时发送。
  • WM_LBUTTONUP:鼠标左键释放时发送。
  • WM_RBUTTONDOWN:鼠标右键按下时发送。
  • WM_RBUTTONUP:鼠标右键释放时发送。
  • WM_MOUSEWHEEL:鼠标滚轮滚动时发送。
3. 键盘输入消息

这些消息用于处理键盘事件,例如按键按下和释放。

  • WM_KEYDOWN:按下一个键时发送。
  • WM_KEYUP:释放一个键时发送。
  • WM_CHAR:按键被按下并转换为字符时发送。
4. 绘制和重绘消息

这些消息用于处理窗口的绘制和重绘操作。

  • WM_PAINT:需要重绘窗口时发送,例如窗口首次显示时或被覆盖的窗口区域重新出现时。
  • WM_ERASEBKGND:窗口背景需要被擦除时发送,通常在处理 WM_PAINT 消息前发送。
5. 定时器消息

这些消息用于处理定时事件。

  • WM_TIMER:定时器触发时发送,应用程序可以使用 SetTimer 设置定时器并响应此消息。
6. 剪贴板消息

这些消息用于处理剪贴板操作。

  • WM_CUT:执行剪切操作时发送。
  • WM_COPY:执行复制操作时发送。
  • WM_PASTE:执行粘贴操作时发送。
7. 系统命令消息

这些消息用于处理系统菜单命令和其他系统相关操作。

  • WM_SYSCOMMAND:用户选择窗口的系统菜单命令(例如,最小化、最大化、关闭)时发送。
8. 控制和对话框消息

这些消息用于处理控件(如按钮、编辑框等)和对话框的交互。

  • WM_COMMAND:用于通知控件事件(如按钮点击),常用于菜单命令和控件事件。
  • WM_NOTIFY:用于处理控件的通知消息,例如列表视图的状态变化。
  • WM_HSCROLLWM_VSCROLL:处理水平和垂直滚动条的消息。
9. 系统级消息

这些消息通常涉及整个系统或非特定窗口的事件。

  • WM_POWERBROADCAST:系统电源状态改变时发送,例如系统进入睡眠模式。
  • WM_DEVICECHANGE:系统中设备状态改变时发送,例如插入或移除 USB 设备。

消息处理的机制

Windows 应用程序通过一个称为“窗口过程函数”的函数来处理这些消息。窗口过程函数通常是一个 switch 语句,根据接收到的消息类型进行相应的处理。例如:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_CREATE:// 初始化代码break;case WM_PAINT:// 绘制代码break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;
}

在此函数中,msg 参数表示消息类型。应用程序根据消息类型调用适当的处理代码。如果消息类型不在 switch 语句中处理,通常会调用 DefWindowProc 函数进行默认处理。

总结

Windows 消息类型众多,每种消息类型都对应特定的事件或行为。理解和处理这些消息是开发 Windows 桌面应用程序的基础。程序通过消息循环不断获取和分派消息,并在窗口过程函数中根据消息类型执行相应的操作。

----------

深入了解 Windows 消息机制和具体消息类型的作用有助于开发更加高效和响应式的 Windows 应用程序。以下将进一步探讨 Windows 消息机制的核心概念和几种常用消息的详细解释。

Windows 消息机制的核心概念

Windows 消息机制是操作系统和应用程序之间沟通的桥梁。通过这种机制,Windows 能够通知应用程序关于用户输入、系统事件以及窗口状态变化等各种事件。

消息的生命周期
  1. 消息的生成

    • 用户输入:如键盘输入、鼠标点击、鼠标移动等。
    • 系统事件:如窗口重绘请求、系统命令、设备变化、电源状态变化等。
    • 应用程序事件:如定时器到期、自定义消息等。
  2. 消息的排队

    • Windows 将生成的消息放入相应线程的消息队列中。每个 GUI 线程都有一个自己的消息队列,用于存放与该线程相关的消息。
  3. 消息的获取和分派

    • 应用程序通过消息循环(GetMessageTranslateMessageDispatchMessage)获取消息,并将其发送到合适的窗口过程函数进行处理。
  4. 消息的处理

    • 在窗口过程函数中,应用程序根据消息类型决定如何处理消息,执行相应的代码逻辑。
  5. 消息的结束

    • 部分消息处理后不会再进行额外操作,例如绘制窗口、处理用户输入等;而其他消息可能会被传递给默认窗口过程函数 DefWindowProc 进行默认处理。

深入探讨常见消息类型

1. 窗口管理消息

这些消息主要用于管理窗口的生命周期和状态。

  • WM_CREATE:

    • 含义:在窗口被创建时发送。此消息在 CreateWindowCreateWindowEx 函数返回之前发送,表示窗口的初始化开始。
    • 用途:常用于初始化窗口控件、分配资源等。例如,创建一个子窗口或控件。
    • 处理方式:在窗口过程函数中,可以使用 lParam 参数指向的 CREATESTRUCT 结构体获取创建窗口时传递的附加数据。
  • WM_DESTROY:

    • 含义:窗口即将被销毁时发送。此消息通常在用户关闭窗口或者调用 DestroyWindow 函数时触发。
    • 用途:用于释放在 WM_CREATE 或其他地方分配的资源,例如销毁控件、关闭文件、释放内存等。
    • 处理方式:调用 PostQuitMessage(0) 函数来退出消息循环,关闭应用程序。
  • WM_CLOSE:

    • 含义:请求关闭窗口时发送。例如,用户点击窗口的关闭按钮或按下 Alt+F4
    • 用途:用于执行关闭前的清理操作,如提示用户保存数据或确认退出。
    • 处理方式:可以调用 DestroyWindow(hwnd) 来销毁窗口,也可以拦截消息以取消关闭操作。
2. 鼠标输入消息

这些消息用于处理鼠标事件,帮助应用程序响应用户的鼠标操作。

  • WM_MOUSEMOVE:

    • 含义:当鼠标移动到窗口的客户区内时发送。
    • 用途:用于更新鼠标坐标、显示提示信息、改变鼠标光标外观等。
    • 处理方式lParam 包含鼠标的 x 和 y 坐标,可以通过 LOWORD(lParam)HIWORD(lParam) 获取。
  • WM_LBUTTONDOWNWM_LBUTTONUP:

    • 含义:分别表示鼠标左键按下和释放事件。
    • 用途:用于检测鼠标点击事件,执行相应的操作,如选择、拖放、按钮点击等。
    • 处理方式wParam 包含键盘状态(如 MK_CONTROLMK_SHIFT),lParam 包含鼠标坐标。
  • WM_RBUTTONDOWNWM_RBUTTONUP:

    • 含义:分别表示鼠标右键按下和释放事件。
    • 用途:通常用于显示上下文菜单或执行其他右键操作。
    • 处理方式:类似于 WM_LBUTTONDOWNWM_LBUTTONUP,处理鼠标右键事件。
  • WM_MOUSEWHEEL:

    • 含义:鼠标滚轮滚动时发送。
    • 用途:用于滚动视图、缩放内容等。
    • 处理方式wParam 高位字包含滚轮增量(每个滚动单位 120),低位字表示键盘状态;lParam 包含鼠标光标的 x 和 y 坐标。
3. 键盘输入消息

这些消息用于处理键盘事件,让应用程序能够响应用户的键盘操作。

  • WM_KEYDOWNWM_KEYUP:

    • 含义:分别表示按键按下和释放事件。
    • 用途:用于处理键盘输入,例如快捷键、游戏控制、文本输入等。
    • 处理方式wParam 包含虚拟键码,lParam 包含按键状态信息(如重复计数、扩展键标志)。
  • WM_CHAR:

    • 含义:键盘输入被转换为字符时发送。它与 WM_KEYDOWN 的区别在于 WM_CHAR 代表字符,而 WM_KEYDOWN 代表虚拟键。
    • 用途:用于文本输入,处理字符信息而不是物理按键。例如,在一个文本编辑器中处理字符输入。
    • 处理方式wParam 包含字符代码(如 Unicode 字符),lParam 包含键盘状态信息。
4. 绘制和重绘消息

这些消息用于管理窗口的绘制和重绘过程。

  • WM_PAINT:

    • 含义:窗口客户区需要重绘时发送,如窗口首次显示、被覆盖部分重新出现、窗口大小改变等。
    • 用途:用于重绘窗口内容,确保显示正确的界面。
    • 处理方式:通常调用 BeginPaint 函数开始绘制,使用 GDI 函数绘制内容后,调用 EndPaint 函数结束绘制。
  • WM_ERASEBKGND:

    • 含义:在 WM_PAINT 消息处理之前发送,用于擦除窗口背景。
    • 用途:用于清除旧的绘制内容,避免图像残留。
    • 处理方式:应用程序可以选择处理此消息,返回一个非零值表示背景已被擦除,或者调用 DefWindowProc 使用默认背景擦除。
5. 系统命令消息

这些消息用于响应系统相关的操作,如系统菜单命令、窗口最小化和最大化等。

  • WM_SYSCOMMAND:
    • 含义:当用户选择系统菜单中的命令或使用快捷键(如 Alt + 空格)时发送。
    • 用途:处理系统级命令,如最小化、最大化、关闭窗口等。
    • 处理方式wParam 的低位字包含系统命令标识符(如 SC_CLOSESC_MINIMIZESC_MAXIMIZE),lParam 通常未使用。

消息的处理顺序

Windows 应用程序通常会在一个窗口过程中处理多种类型的消息。典型的消息处理顺序如下:

  1. WM_CREATE:初始化窗口或控件。
  2. WM_PAINT:绘制或重绘窗口内容。
  3. WM_KEYDOWN / WM_CHAR / WM_KEYUP:处理键盘输入。
  4. WM_MOUSEMOVE / WM_LBUTTONDOWN / WM_LBUTTONUP:处理鼠标输入。
  5. WM_CLOSE:处理窗口关闭请求。
  6. WM_DESTROY:执行清理工作,准备退出程序。

深入理解窗口过程函数

窗口过程函数(WndProc)是处理所有消息的核心。每一个与窗口关联的消息都会通过 WndProc 函数进行处理。它是一个回调函数,具有以下典型的定义:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_CREATE:// 初始化窗口资源break;case WM_PAINT:// 绘制窗口break;case WM_COMMAND:// 处理菜单或控件命令break;case WM_DESTROY:PostQuitMessage(0); // 发送退出消息break;

 

#include <windows.h>
#include <stdio.h>// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_LBUTTONDOWN: { // 处理左键点击int xPos = LOWORD(lParam);  // 获取鼠标x坐标int yPos = HIWORD(lParam);  // 获取鼠标y坐标char buf[100];snprintf(buf, sizeof(buf), "Left button clicked at (%d, %d)", xPos, yPos);SetWindowText(hwnd, buf);  // 更新窗口标题栏为点击位置break;}case WM_RBUTTONDOWN: { // 处理右键点击int xPos = LOWORD(lParam);  // 获取鼠标x坐标int yPos = HIWORD(lParam);  // 获取鼠标y坐标char buf[100];snprintf(buf, sizeof(buf), "Right button clicked at (%d, %d)", xPos, yPos);SetWindowText(hwnd, buf);  // 更新窗口标题栏为点击位置break;}case WM_MOUSEMOVE: { // 处理鼠标移动int xPos = LOWORD(lParam);  // 获取鼠标x坐标int yPos = HIWORD(lParam);  // 获取鼠标y坐标char buf[100];snprintf(buf, sizeof(buf), "Mouse moved to (%d, %d)", xPos, yPos);SetWindowText(hwnd, buf);  // 更新窗口标题栏为鼠标移动位置break;}case WM_DESTROY:PostQuitMessage(0); // 退出消息循环break;default:return DefWindowProc(hwnd, msg, wParam, lParam); // 默认窗口过程}return 0;
}// 程序入口
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {const char CLASS_NAME[] = "Sample Window Class";// 定义窗口类WNDCLASS wc = {};wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.lpszClassName = CLASS_NAME;wc.hCursor = LoadCursor(NULL, IDC_ARROW);  // 设置光标// 注册窗口类if (!RegisterClass(&wc)) {MessageBox(NULL, "Window Class Registration Failed!", "Error", MB_OK | MB_ICONERROR);return 0;}// 创建窗口HWND hwnd = CreateWindowEx(0,                              // 可选窗口样式CLASS_NAME,                     // 窗口类名"Sample Window",                // 窗口标题WS_OVERLAPPEDWINDOW,            // 窗口样式CW_USEDEFAULT, CW_USEDEFAULT,   // 初始位置CW_USEDEFAULT, CW_USEDEFAULT,   // 初始尺寸NULL,                           // 父窗口NULL,                           // 菜单hInstance,                      // 实例句柄NULL                            // 附加应用程序数据);if (hwnd == NULL) {MessageBox(NULL, "Window Creation Failed!", "Error", MB_OK | MB_ICONERROR);return 0;}// 显示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循环MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0;
}

这篇关于Windows 操作系统定义了大量的消息类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104743

相关文章

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

Linux操作系统 初识

在认识操作系统之前,我们首先来了解一下计算机的发展: 计算机的发展 世界上第一台计算机名叫埃尼阿克,诞生在1945年2月14日,用于军事用途。 后来因为计算机的优势和潜力巨大,计算机开始飞速发展,并产生了一个当时一直有效的定律:摩尔定律--当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 那么相应的,计算机就会变得越来越快,越来越小型化。

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

Mysql BLOB类型介绍

BLOB类型的字段用于存储二进制数据 在MySQL中,BLOB类型,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是在存储的大小不同。 TinyBlob 最大 255 Blob 最大 65K MediumBlob 最大 16M LongBlob 最大 4G

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起

Windows如何添加右键新建菜单

Windows如何添加右键新建菜单 文章目录 Windows如何添加右键新建菜单实验环境缘起以新建`.md`文件为例第一步第二步第三步 总结 实验环境 Windows7 缘起 因为我习惯用 Markdown 格式写文本,每次新建一个.txt后都要手动修改为.md,真的麻烦。如何在右键新建菜单中添加.md选项呢? 网上有很多方法,这些方法我都尝试了,要么太麻烦,要么不凑效