强制输出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 消息并获取相关的按键信息,以及如何将这些信息显示在窗口标题栏上。你可以运行这个程序并按下不同的键,以查看窗口标题栏中显示的按键信息。

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值