How To Create lParam Of SendMessage WM_KEYDOWN
c#, interop, pinvoke
Solution
I realized that AutoIT has the functionality that I need, so have looked at the source file sendKeys.cpp and found the following C++ code snippet for this function, it will be easy enough to translate into 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
The scan code can be generated with MapVirtualKey
C# Translation:
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);
Problem
I'm trying to use SendMessage to send a keystroke, and don't really understand the lParam. I understand that the different bits represent each parameter and that they need to be arranged in order. I've read this question & this, so I know which order the bits need to be in, I just don't know how to do it... How would I create the following 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 ```