I am trying to inject keys into a program. I have managed to inject the keys but I cannot find the Virtual Key Code for the @ sign. I have found this site that was very useful but still can't find it. Keys.Send(); is not an option as I do not want the window selected, I want to be able to do it all in the background.
This i开发者_开发知识库s my code so far:
const UInt32 WM_KEYDOWN = 0x0100;
int VK_A = 0x41;
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcessesByName("Notepad");
foreach (Process proc in processes)
{
PostMessage(proc.MainWindowHandle, WM_KEYDOWN, VK_A, 0);
}
}
This would send the A key to notepad.
Any help would be appreciated.
Windows defines special constants for each key the user can press, called virtual key codes. You don't have a @ key on your keyboard, instead you use Shift+2 (at least on my keyboard) to do it.
I think though you can't simulate Shift+2 using PostMessage.
See http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx.
@
has no corresponding key by itself. You can send the key(s)+modifier key state corresponding to it, which is Shift+2 on American keyboards.
But on other keyboard layouts the keys are different. For example on the German layout it's AltGr+Q.
Or you can send WM_CHAR directly. That will work with most applications, some(typically games) won't accept it though.
I'd try WM_CHAR
first, and only if that doesn't work switch to WM_KEYDOWN.
@
isn't a key in an of itself and is an 'alternate' character, meaning it can only be applied when a modifier key is pressed (shift); so, you might need to combine two values:
const int VK_OEM7 = 0xDE; // (" ') - this can be 'any' key, apparently
const int VK_SHIFT = 0xA0; // (left shift)
var keycode = VK_OEM7 | VK_SHIFT;
Another possibility is that you might need to push each key in a sequence of calls.
Either way, you need more than a single key code.
Though I'm sure you'll have to take the second approach I mentioned above (combining the values isn't likely to work), I've become a little concerned as to how you've actually managed to post characters to notepad
in the first place, seeing as you're using the MainWindowHandle
as opposed to the editor handle - just in case you run into any troubles not yet noticed, the following code grabs the notepad text area and does allow you to 'post' to it:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
var editorHandle = FindWindowEx(proc.MainWindowHandle, new IntPtr(0), "Edit", null);
Here is an alternate solution - find what keyboard is in use in the foreign app and map the character to an appropriate key if available.
C/C++ I don't have a handy C# definitions
HWND handle; // the handle of the window you wish to type to
DWORD idThread = GetWindowThreadProcessId(handle, NULL);
// may also want to work in the same input queue - allows forground and focus to work
// AttachThreadInput(GetCurrentThreadId(), idThread,TRUE);
HKL hklRemote = GetKeyboardLayout(idThread);
SHORT VkCode = VkKeyScanEx(key, hklRemote );
Also, if you want to send several keys (or mouse clicks) without interruption by the user then SendInput might be a better option.
精彩评论