Sending Commands/Events to Another Application

In order to send a keystroke to another application, you can just utilize Win32’s PostMessage.

Windows is very event-driven.  Anytime anything changes within a window, an event is fired.  If you click your mouse button, an event is fired.  If you resize the window, an event is fired.  If you press a key, an event is fired.

Quiz time.  What happens when you move your mouse within a window?
If you guessed “The pointer moves”, you are technically correct but not getting what I’m trying to say.
If you guessed “A bobcat will charge out of my monitor and eat my childhood friend”, you’re way off.
If you guessed “An event is fired”, you’ve somehow retained the knowledge I bestowed upon you 1.2 seconds ago!

All pretty easy – but how is your window notified of these events?  Windows sends messages to the window with codes regarding the type of command that has occurred, along with any information related to that command.

PostMessage() essentially does the same thing.  Alternatively, you can use SendMessage (to post the message, then wait until the message is received), SendMessageTimeout (to do the same but timeout after a given time).  Here’s PostMessage’s syntax:

BOOL PostMessage(
    HWND hWnd,        // the handle of the window the message is to be posted to
    UINT Msg,            // the message code
    WPARAM wParam,  // message-specific information
    LPARAM lParam      // message-specific information
);

The window handle is how Windows references application windows.  If you’re using .NET, you can use the System.Diagnostics.Process.MainWindowHandle property with the application’s process.

The message code is of course specific to the type of message that you want.  For example:

  • If you want to close a window, use WM_COMMAND (0x0112), with wParam = WM_CLOSE (0xF060).
  • If you want to send keystrokes to a window, use a call to PostMessage with WM_KEYDOWN (0x100) and WM_KEYUP (0x101) as message codes with the VK key code as the WPARAM (for a list of VK key codes, check this page out).

For more Windows Messages, check out this random list of Windows Messages.

So, say we want to close Notepad if it is open.  Using C#, here’s a complete example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
 
namespace TestCmd
{
    class Program
    {
        // Import the library containing PostMessage
        [DllImport ("user32.dll")]
        public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
 
        public const int WM_COMMAND = 0x0112;	   // Code for Windows command
		public const int WM_CLOSE = 0xF060;		 // Command code for close window
 
        static void Main(string[] args)
        {
            try
            {
                IntPtr hWndNotepad = Process.GetProcessesByName("notepad")[0].MainWindowHandle;
                Console.WriteLine("Ready to tell Notepad to close.  Press enter to send the command.");
                Console.ReadLine();
                if (hWndNotepad != null)
                {
                    // Close Window
                    PostMessage(hWndNotepad, WM_COMMAND, WM_CLOSE, 0);
                }
                Console.WriteLine("Command sent.  Press enter to close.");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine ("Notepad not running.  Press enter to close.");
                Console.Read();
            }
        }
    }
}

Take that, Notepad! Now to make a tray application to close iTunes everytime it starts.

Wait…

No.  Please, code responsibly.

–Andrew

One thought on “Sending Commands/Events to Another Application

  1. Pingback: Attaching to WndProc in WPF | Andrew Eichacker

Comments are closed.