PostMessage() VK_SHIFT

05/16/2014 21:26 pushbyte#1
I am trying to send the SHIFT key to another application, and then PostMessage() my characters so they show up in their shift key states.

The target process must run in the background, so setting the focus to it is not possible. Meaning SetForegroundWindow(), GetForegroundWindow(), SentInput(), keybd_event(), SendKeys() will not work.

I have seen some examples of SetKeyboardState() and I have used AttachThreadInput() to attach my thread to the thread of the target process, then SetKeyboardState() to press the SHIFT key, then detach my thread.

The target process still does not recognise my the SHIFT key being pressed.

Code:
// Send keystrokes to provided window handle using PostMessage API
DWORD SendKeys(HWND hWnd, char ch, DWORD pause)
{
	short vkChar;
	short vkState;
	DWORD dwDuration = 0;
	BYTE kbState[256];
	DWORD dwTargetId = 0;
	DWORD dwThisId = 0;

	vkChar = LOBYTE(VkKeyScan(ch)); // Scan code for selected key
	vkState = HIBYTE(VkKeyScan(ch));

	if ( vkState |= VKSC_SHIFT )
	{
		BYTE kbState[256];
		DWORD dwTargetId, dwThisId;

		memset(kbState, 0, sizeof(kbState));
		GetKeyboardState(kbState);
		kbState[VK_SHIFT] |= 0x80;

		dwTargetId = GetWindowThreadProcessId(hWnd, NULL);
		dwThisId = GetCurrentProcessId();

		if ( dwTargetId != dwThisId )
			AttachThreadInput(dwTargetId, dwThisId, TRUE);

		SetKeyboardState(kbState);
	}

	PostMessage(hWnd, WM_KEYDOWN, (WPARAM)vkChar,
		(LPARAM)CreateLParam(0, MapVirtualKey(vkChar, MAPVK_VK_TO_VSC), FALSE, FALSE));
	Sleep(pause);
	PostMessage(hWnd, WM_KEYUP, (WPARAM)vkChar,
		(LPARAM)CreateLParam(1, MapVirtualKey(vkChar, MAPVK_VK_TO_VSC), TRUE, TRUE));

	if ( vkState |= VKSC_SHIFT )
	{
		kbState[VK_SHIFT] &= 0x00;

		SetKeyboardState(kbState);

		if ( dwTargetId != dwThisId )
			AttachThreadInput(dwTargetId, dwThisId, FALSE);
	}

	return pause;
}