Using the PostMessage Method turned out to be easier than I thought it
was going to be. Heres my code if anyone ever runs into a simular
problem and wants to send a key
------------------------------------------------------------------------------------------
[Flags]
public enum mySendKeyFlags : byte {
None = 0x00,
SimReal = 0x01,
SendExtendedKey = 0x02
}
public void SendKey(int key, int[] Modifier, IntPtr
ForGroundWindow, mySendKeyFlags Flags) {
if(Flags & mySendKeyFlags.SimReal !=0) {
byte[] kbState = new byte[255];
AttachThreadInput((uint)AppDomain.GetCurrentThreadId(), (uint)*GET
PROCESS ID OF CURRENT APP*, true);
GetKeyboardState(kbState);
byte[] kbStateMOD = kbState;
for(byte i = 0; i < Modifier.Length; i++)
kbStateMOD[Modifier
] = 0x80;
SetKeyboardState(kbStateMOD);
SendKeyHelp(ref key, ref Modifier, ref
ForGroundWindow, ref Flags);
SetKeyboardState(kbState);
AttachThreadInput((uint)AppDomain.GetCurrentThreadId(), (uint)*GET
PROCESS ID OF CURRENT APP*, false);
} else SendDAKeyHelp(ref key, ref Modifier, ref
ForGroundWindow, ref Flags);
}
private void SendKeyHelp(ref int key, ref int[] Modifier, ref
IntPtr ForGroundWindow, ref mySendKeyFlags Flags) {
if(Modifier != null) {
for(byte i = 0; i < Modifier.Length; i++) {
if(Modifier == (int)Keys.Alt)
PostMessage(Params.hWnd, WM_SYSKEYDOWN, Modifier,
(int)MAKELONG(0x1, (ushort)MapVirtualKey((uint)Modifier, 0)));
else PostMessage(Params.hWnd, WM_KEYDOWN,
Modifier, (int)MAKELONG(0x1,
(ushort)MapVirtualKey((uint)Modifier, 0)));
}
}
if(Flags & mySendKeyFlags.SendExtendedKey != 0)
PostMessage(Params.hWnd, WM_KEYDOWN, key, (int)MAKELONG(0x1, (ushort)
(MapVirtualKey((uint)key, 0) | 0x0100)));
else PostMessage(Params.hWnd, WM_KEYDOWN, key,
(int)MAKELONG(0x1, (ushort)MapVirtualKey((uint)key, 0)));
if(Flags & mySendKeyFlags.SimReal != 0) Thread.Sleep(10);
if(Flags & mySendKeyFlags.SendExtendedKey != 0)
PostMessage(Params.hWnd, WM_KEYUP, key, (int)MAKELONG(0x1, (ushort)
(MapVirtualKey((uint)key, 0) | 0xC100)));
else PostMessage(Params.hWnd, WM_KEYUP, key,
(int)MAKELONG(0x1, (ushort)(MapVirtualKey((uint)key, 0) | 0xC000)));
if(Modifier != null) {
for(byte i = 0; i < Modifier.Length; i++) {
if(Modifier == (int)Keys.Alt)
PostMessage(Params.hWnd, WM_SYSKEYUP, Modifier, (int)MAKELONG(0x1,
(ushort)(MapVirtualKey((uint)key, 0) | 0xC000)));
else PostMessage(Params.hWnd, WM_KEYUP,
Modifier, (int)MAKELONG(0x1, (ushort)
(MapVirtualKey((uint)Modifier, 0) | 0xC000)));
}
}
}
------------------------------------------------------------------------------------------
Basically the Key is the Virtual Key code (given in the WM_HOTKEY
message alonge with the Modifiers used). You have to convert the
modifers to an int[] of VKcodes. Have to manual give the extended key
flag if the hotkey is an extended one. Use SimReal if you have
modifiers (ctrl/alt/shift/etc) but you have to get the process id of
the current app (Most my hotkeys don't have modifiers which is why I
have a flag I set only when I have to use it). If anyone knows an
easy way to get the active windows process id (maybe a winapi?) it
would be nice (mine just goes though all processes and checks their
MainWindowHandle against the GetForgroundWindow() that I have).
I was forced to add a 10ms delay in the middle for the SimReal case
(for the application to produce its WM_CHAR message after the
WM_KEYDOWN message is sent... I don't know how to know when the
external message loop produced it.
I'm still in the process of tested/making it the way I want it. If
anyone knows a quick solutions to the processID / WM_CHAR message
problems it would be a help.