I'm having trouble with the parameter LPARAM of PostMessage().
This is a widely available example of the letter z being typed with PostMessage():
PostMessage(handle, WM_KEYDOWN, 0x5A, 0x002C0001) // key down for z
PostMessage(handle, WM_KEYUP, 0x5A, 0xC02C0001) // key up for z
What is the formula for arriving at LPARAM "0x002C0001" for key down and "0xC02C0001" for key up? I want to replicate it for all keys. Is it possible to create two functions, say, CreateLPARAM_KeyDown() and CreateLPARAM_KeyUp() where you just pass the scan code — or better yet, the device-independent virtual key code — and they return the LPARAM?
With keybd_event() it's much easier, you just leave the dwFlags parameter 0 for key down, and use KEYEVENTF_KEYUP for key up, but the window must have focus and the window I'm sending to is in the background, so keybd_event() and SendInput() are of no use in my case.
Is it possible to create two functions, say, CreateLPARAM_KeyDown() and CreateLPARAM_KeyUp() where you just pass the scan code — or better yet, the device-independent virtual key code — and they return the LPARAM?
Try something like this:
std::pair<USHORT, bool> VirtualKeyToScanCode(UINT VirtualKey)
{
USHORT ScanCode = (USHORT) MapVirtualKey(VirtualKey, MAPVK_VK_TO_VSC);
bool IsExtended = false;
// because MapVirtualKey strips the extended bit for some keys
switch (VirtualKey)
{
case VK_RMENU: case VK_RCONTROL:
case VK_LEFT: case VK_UP: case VK_RIGHT: case VK_DOWN: // arrow keys
case VK_PRIOR: case VK_NEXT: // page up and page down
case VK_END: case VK_HOME:
case VK_INSERT: case VK_DELETE:
case VK_DIVIDE: // numpad slash
case VK_NUMLOCK:
{
IsExtended = true;
break;
}
}
return std::make_pair(ScanCode, IsExtended);
}
LPARAM CreateLPARAM_KeyUpDown(UINT VirtualKey, USHORT RepeatCount, bool TransitionState, bool PreviousKeyState, bool ContextCode)
{
std::pair<USHORT, bool> ScanCode = VirtualKeyToScanCode(VirtualKey);
return (
(LPARAM(TransitionState) << 31) |
(LPARAM(PreviousKeyState) << 30) |
(LPARAM(ContextCode) << 29) |
(LPARAM(ScanCode.second) << 24) |
(LPARAM(ScanCode.first) << 16) |
LPARAM(RepeatCount)
);
}
LPARAM CreateLPARAM_KeyDown(UINT VirtualKey, USHORT RepeatCount = 1)
{
return CreateLPARAM_KeyUpDown(VirtualKey, RepeatCount, false, RepeatCount > 1, false);
}
LPARAM CreateLPARAM_KeyUp(UINT VirtualKey)
{
return CreateLPARAM_KeyUpDown(VirtualKey, 1, true, true, false);
}