当前位置: 首页 > news >正文

强制输出wParam 和 lParam,会是什么内容?

当你“强制输出” wParamlParam 时,通常是指在调试或日志记录中直接查看这些参数的原始数值。这些值的内容会根据消息类型的不同而有所变化,因为 wParamlParam 的意义和使用取决于它们所在的消息上下文。

下面我将详细讨论在不同消息情况下,wParamlParam 可能包含的内容,以及如何强制输出它们。

强制输出 wParamlParam

在 C/C++ 中,"强制输出"通常是指使用打印函数(如 printfOutputDebugString)直接打印 wParamlParam 的值。这可以帮助你在调试过程中查看这些参数的原始数据。

如何输出 wParamlParam

你可以使用以下代码片段来输出 wParamlParam 的值:

printf("wParam: %ld, lParam: %ld\n", (long)wParam, (long)lParam);

或者在 Windows 环境下使用 OutputDebugString 将调试信息输出到调试器窗口:

char buffer[100];
snprintf(buffer, sizeof(buffer), "wParam: %ld, lParam: %ld\n", (long)wParam, (long)lParam);
OutputDebugString(buffer);

不同消息情况下 wParamlParam 的内容

不同消息类型的 wParamlParam 含义不同。以下是一些常见的消息及其参数含义和输出内容示例:

1. 键盘消息(WM_KEYDOWNWM_KEYUPWM_CHAR
  • wParam:通常是虚拟键码(如 VK_RETURN 表示 Enter 键)。
  • lParam:包含有关按键的附加信息,如按键重复次数、扫描码、扩展键标志等。

强制输出示例:

case WM_KEYDOWN: {printf("WM_KEYDOWN: wParam (Virtual Key Code): %ld, lParam: %ld\n", (long)wParam, (long)lParam);break;
}

示例输出

WM_KEYDOWN: wParam (Virtual Key Code): 13, lParam: 536870913

解释:wParam 是虚拟键码 13VK_RETURN),lParam 的值 536870913 结合了按键重复次数、扫描码和扩展键标志。

2. 鼠标消息(WM_MOUSEMOVEWM_LBUTTONDOWNWM_RBUTTONUP
  • wParam:鼠标按键状态(如 MK_LBUTTON 表示鼠标左键被按下)。
  • lParam:鼠标指针的 x 和 y 坐标,使用低 16 位和高 16 位表示。

强制输出示例:

case WM_MOUSEMOVE: {printf("WM_MOUSEMOVE: wParam (Mouse Key State): %ld, lParam (Position): %ld\n", (long)wParam, (long)lParam);break;
}

示例输出

WM_MOUSEMOVE: wParam (Mouse Key State): 1, lParam (Position): 655370

解释:wParam1(通常表示 MK_LBUTTON),lParam655370。用 LOWORD(lParam)HIWORD(lParam) 分别提取鼠标的 x 和 y 坐标。

3. 窗口调整大小消息(WM_SIZE
  • wParam:表示调整大小的类型(如 SIZE_MINIMIZEDSIZE_MAXIMIZED)。
  • lParam:窗口的新宽度(低 16 位)和高度(高 16 位)。

强制输出示例:

case WM_SIZE: {printf("WM_SIZE: wParam (Resize Type): %ld, lParam (New Size): %ld\n", (long)wParam, (long)lParam);break;
}

示例输出

WM_SIZE: wParam (Resize Type): 2, lParam (New Size): 3276800

解释:wParam2SIZE_MAXIMIZED),lParam3276800,表示新的窗口宽度和高度。

4. 命令消息(WM_COMMAND
  • wParam:低位字是控件的 ID 或命令标识符,高位字是通知代码。
  • lParam:是控件的句柄(HWND)。

强制输出示例:

case WM_COMMAND: {printf("WM_COMMAND: wParam (ID and Code): %ld, lParam (Control Handle): %ld\n", (long)wParam, (long)lParam);break;
}

示例输出

WM_COMMAND: wParam (ID and Code): 65537, lParam (Control Handle): 123456

解释:wParam 的低 16 位 1 是控件 ID,高 16 位 1 是通知代码(例如按钮点击)。lParam 为控件的句柄。

5. 自定义消息(如 WM_USER 及以上)

自定义消息的 wParamlParam 完全由程序员定义。

  • wParam:可以是任何需要传递的整数值、标志等。
  • lParam:可以是指针、句柄、结构体、整数值等。

强制输出示例:

case WM_USER_MY_MESSAGE: {printf("WM_USER_MY_MESSAGE: wParam: %ld, lParam: %ld\n", (long)wParam, (long)lParam);break;
}

示例输出

WM_USER_MY_MESSAGE: wParam: 100, lParam: 200

解释:wParamlParam 是根据自定义需求传递的值,具体意义需要参考自定义消息的处理逻辑。

如何理解强制输出的内容

输出的 wParamlParam 的数值本身通常是一些整数表示的位模式。通过这些值,你可以获取消息携带的具体信息。使用正确的宏(如 LOWORDHIWORDGET_WHEEL_DELTA_WPARAM 等)可以分解这些位模式,并提取出有意义的数据。例如,LOWORD(lParam)HIWORD(lParam) 经常用于分解 32 位的 lParam 中的两个 16 位值,分别代表鼠标坐标、窗口尺寸等。

总结

通过强制输出 wParamlParam 的值,你可以在调试时查看这些参数的原始数值,这有助于理解不同消息的内部结构和数据传递方式。不同的消息类型会将不同的信息编码到这两个参数中,因此,了解如何正确解析这些参数对于有效地处理消息至关重要。

 

#include <windows.h>
#include <stdio.h>LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {switch (msg) {case WM_KEYDOWN: {// 获取虚拟键码int virtualKeyCode = (int)wParam;// 获取按键重复计数int repeatCount = LOWORD(lParam);// 提取扫描码(高字节的低 8 位)int scanCode = (HIWORD(lParam) & 0xFF);// 扩展键标志int isExtendedKey = (HIWORD(lParam) & KF_EXTENDED) ? 1 : 0;// 格式化信息并更新窗口标题栏char buf[256];snprintf(buf, sizeof(buf), "VK Code: %d, Repeat Count: %d, Scan Code: %d, Extended Key: %d",virtualKeyCode, repeatCount, scanCode, isExtendedKey);SetWindowText(hwnd, buf);// 输出到调试控制台printf("VK Code: %d, Repeat Count: %d, Scan Code: %d, Extended Key: %d\n",virtualKeyCode, repeatCount, scanCode, isExtendedKey);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,"Key Info 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;
}
// 解释:
// WM_KEYDOWN 消息处理:// 虚拟键码 (virtualKeyCode) 从 wParam 中获取。
// 按键重复计数 (repeatCount) 从 lParam 的低字节中获取。
// 扫描码 (scanCode) 从 lParam 的高字节中提取(通过 HIWORD(lParam) & 0xFF)。
// 扩展键标志 (isExtendedKey) 从 lParam 的高字节中提取(通过 HIWORD(lParam) & KF_EXTENDED)。
// 使用 snprintf 格式化信息并更新窗口标题栏,以显示按键的详细信息。
// 输出到调试控制台:// 使用 printf 将按键信息输出到调试控制台,便于调试和验证信息的正确性。
// 窗口创建和消息循环:// 程序创建一个窗口并进入消息循环,以处理窗口消息,包括按键消息。
// 这个示例演示了如何处理 WM_KEYDOWN 消息并获取相关的按键信息,以及如何将这些信息显示在窗口标题栏上。你可以运行这个程序并按下不同的键,以查看窗口标题栏中显示的按键信息。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 数据仓库系列 3:数据仓库的主要组成部分有哪些?
  • jmeter中CSV 数据文件设置用例
  • DescuentosController : ControllerBase
  • MySQL 系统学习系列 - SQL 语句 DML 语句的使用《MySQL系列篇-02》
  • 数学建模学习(125):使用Python实现Borda计数法进行多标准决策分析
  • 【嵌入式开发之网络编程】TCP端口和UDP端口
  • 《计算机网络-期末模拟卷》
  • Android如何高效的加载大型位图
  • ELK基础搭建
  • 22.计算球体积
  • 二叉树的介绍
  • 2024.8.26
  • 景联文科技:专业人像采集服务,助力人像采集在多领域应用
  • npm阿里云制品仓库
  • C++竞赛初阶L1-14-第六单元-数组(31~33课)542: T456472 数组逆序重存放
  • Elasticsearch 参考指南(升级前重新索引)
  • Hexo+码云+git快速搭建免费的静态Blog
  • Java基本数据类型之Number
  • js作用域和this的理解
  • Redash本地开发环境搭建
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 机器学习中为什么要做归一化normalization
  • 力扣(LeetCode)21
  • 入门到放弃node系列之Hello Word篇
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 学习使用ExpressJS 4.0中的新Router
  • 在Unity中实现一个简单的消息管理器
  • 栈实现走出迷宫(C++)
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • RDS-Mysql 物理备份恢复到本地数据库上
  • #ifdef 的技巧用法
  • #Linux(Source Insight安装及工程建立)
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (7)svelte 教程: Props(属性)
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (差分)胡桃爱原石
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (六)DockerCompose安装与配置
  • (十一)图像的罗伯特梯度锐化
  • (太强大了) - Linux 性能监控、测试、优化工具
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET 使用 XPath 来读写 XML 文件
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @AliasFor 使用
  • @Bean注解详解
  • @ComponentScan比较
  • @ConditionalOnProperty注解使用说明
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝