如何创建发送消息WM_KEYDOWN的参数

本文关键字:WM 消息 KEYDOWN 参数 何创建 创建 | 更新日期: 2023-09-27 18:31:56

我正在尝试使用SendMessage发送击键,但并不真正理解lParam。我知道不同的位代表每个参数,它们需要按顺序排列。

我已经读过这个问题和这个,所以我知道位需要按哪个顺序排列,我只是不知道该怎么做......

我将如何创建以下 lParam?

repeat cound = 0,
scan code = {Don't know what this is?},
extended key = 1,
reserved = 0,
context code = 0,
previous key state = 1,
transition state = 0

如何创建发送消息WM_KEYDOWN的参数

我意识到AutoIT具有我需要的功能,因此查看了源文件sendKeys.cpp并找到了此函数的以下C++代码片段,将其转换为C#将很容易:

scan = MapVirtualKey(vk, 0);
// Build the generic lparam to be used for WM_KEYDOWN/WM_KEYUP/WM_CHAR
lparam = 0x00000001 | (LPARAM)(scan << 16);         // Scan code, repeat=1
if (bForceExtended == true || IsVKExtended(vk) == true)
    lparam = lparam | 0x01000000;       // Extended code if required
if ( (m_nKeyMod & ALTMOD) && !(m_nKeyMod & CTRLMOD) )   // Alt without Ctrl
    PostMessage(m_hWnd, WM_SYSKEYDOWN, vk, lparam | 0x20000000);    // Key down, AltDown=1
else
    PostMessage(m_hWnd, WM_KEYDOWN, vk, lparam);    // Key down

扫描码可以用地图虚拟钥匙生成

C# 翻译:

public static void sendKey(IntPtr hwnd, VKeys keyCode, bool extended)
{
    uint scanCode = MapVirtualKey((uint)keyCode, 0);
    uint lParam;
    //KEY DOWN
    lParam = (0x00000001 | (scanCode << 16));
    if (extended)
    {
        lParam |= 0x01000000;
    }
    PostMessage(hwnd, (UInt32)WMessages.WM_KEYDOWN, (IntPtr)keyCode, (IntPtr)lParam);
    //KEY UP
    lParam |= 0xC0000000;  // set previous key and transition states (bits 30 and 31)
    PostMessage(hwnd, WMessages.WM_KEYUP, (uint)keyCode, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern uint MapVirtualKey(uint uCode, uint uMapType);

如果您绝对必须使用 SendMessage,那么您需要将 int 的位切换到正确的位置。

此站点记录了如何在 C# 中执行此操作:

http://codeidol.com/csharp/csharpckbk2/Classes-and-Structures/Turning-Bits-On-or-Off/

参考您的问题,ScanCode 是您尝试发送的密钥的值,也代表某些状态。例如,按 A 的扫描代码与释放 A 的代码不同。

维基百科有一篇关于它们的文章:

http://en.wikipedia.org/wiki/Scancode