views:

402

answers:

4

Hi, I need to interact with an external application running, and send specific keypresses & releases. I've tried to use the SendKeys class, but it does only half of the job, as the keypress is being sent with an immediate keyrelease to the external applications.

I need to be able to simulate a "key hold down" for the external app. I'm now trying to use the SendMessage thing, but for now it won't work at all :( and I don't even get errors.

+1  A: 

have you tried using PostMessage to send WM_KEYDOWN and WM_KEYUP ?

Edit

You would use it this way (I am writing in C++, but you can easily use PInvoke and ..NET)

HWND hwnd = FindWindow(NULL,_T("Mywindow"));
PostMessage(hwnd,WM_KEYDOWN,VK_A,0);
Andrew Keith
Can you please show me a working piece of code? I'm struggling to find an answer for like 3 days now and nothing worked even remotely except for the SendKeys
MeLight
I added a link to pinvoke.net where you can find the PInvoke headers for the given functions
Martinho Fernandes
Ok, I've tried to tweak your solution and to get it to work in C#, I've also got the headers from Pinvoke (I think!). It's still not working and I feel like I'm getting in to a recursion of things I don't get... Any chance of someone explaining why the SendMessage won't work, or a C# example of PostMessage?
MeLight
Could you post the sample code that you have and a better description of what you see happen (or not) versus what you expect to happen?
Jason D
+1  A: 

The official API is SendInput.

MSN
I'm struggling to find a working C# example for more than 3 days now... I would really appreciate one of those.
MeLight
Googling C# "SendInput" got me this: http://blogs.msdn.com/robgruen/archive/2004/05/10/129221.aspx
MSN
+1  A: 

Ok, case solved. I actually installed VC++ to try the core keybd_event() function, and after it worked I was able to use it wisely in C#.

Here's the code, and surprisingly it's very simple. You'll need to add this using to your code to be able to import dll's: using System.Runtime.InteropServices;

This code will press and hold the '1' button for 3 secs, and then will release for 1 second and repeat the process.

(the code highlight got messed up :/, copy from 'namespace ...' to the last bracket '}')

namespace ConsoleApplication1 
{
class Program 
{ 
 [DllImport("user32.dll")] 
 static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,UIntPtr dwExtraInfo);

 static void Main(string[] args)
 {            
  while (true)
  {
   keybd_event((byte)0x31, (byte)0x02, 0, UIntPtr.Zero);
   Thread.Sleep(3000);

   keybd_event((byte)0x31, (byte)0x82, (uint)0x2, UIntPtr.Zero);
   Thread.Sleep(1000);
  }
 }
}

}
MeLight
Blindy, thanks for the edit :D
MeLight
+1  A: 

You can use the WSH Scripting Shell to do this:

        WshShell shell = new WshShellClass();
        object missing=System.Reflection.Missing.Value;

        shell.SendKeys("MOO!!!", ref missing);

All you need to do is add a COM reference to "Windows Scripting Host Object", version 1.0. Everything is in the namespace IWshRuntimeLibrary.

Blindy