0
votes

I have an application (that always runs in minimized mode) that constantly listens to keys typed on the keyboard. When certain key is pressed, I want the C# application to post a command on the message queue of the active window to minimize, close, maximize, etc. I know it is possible to get the handle to the active window, but, how can I post a message on its message queue (as we can do in win32). Thanks.

1
Post the message using PostMessageDavid Heffernan
You should take a look at PInvoke, which gives you the ability to call win32 procedures. msdn and PInvokeJeroen van Langen
Thanks David and Jeroen.Vijay Rajanna

1 Answers

1
votes

You can use interop to call the native WINAPI functions. Using the p/invoke website I have created the following solution:

var proc = Process.GetProcesses().First(p => p.ProcessName.Contains("firefox"));

PostMessageSafe(
    new HandleRef(proc, proc.MainWindowHandle), 
     (uint) WM.WM_SYSCOMMAND, 
    new IntPtr((int) SysCommands.SC_MAXIMIZE), 
    IntPtr.Zero);

What I basically do here is find a WindowHandle I'm interested in and then invoke PostMessage with the WM_SYSCOMMAND in Msg and the appropriate syscommand in the wParam, in this case Maximize, with the value 0xF030. The lParam is set to 0.

Please be aware that if your only goal is to change the window state you better use the specialized API endpoint for that, it's called ShowWindow

Its signature looks like this:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);

and it is invoked like this:

ShowWindow(proc.MainWindowHandle, ShowWindowCommands.Maximize);

When either of these methods are called, a window from a process named firefox will be maximized.

Here are the helper methods and enums you need as a wrapper around PostMessage

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

// http://www.pinvoke.net/default.aspx/Enums/WindowsMessages.html
public enum WM : uint
{
    WM_SYSCOMMAND = 0x0112
}

// http://www.pinvoke.net/default.aspx/Enums/SysCommands.html
enum SysCommands : int
{
    SC_SIZE = 0xF000,
    SC_MOVE = 0xF010,
    SC_MINIMIZE = 0xF020,
    SC_MAXIMIZE = 0xF030,
    SC_NEXTWINDOW = 0xF040,
    SC_PREVWINDOW = 0xF050,
    SC_CLOSE = 0xF060,
    SC_VSCROLL = 0xF070,
    SC_HSCROLL = 0xF080,
    SC_MOUSEMENU = 0xF090,
    SC_KEYMENU = 0xF100,
    SC_ARRANGE = 0xF110,
    SC_RESTORE = 0xF120,
    SC_TASKLIST = 0xF130,
    SC_SCREENSAVE = 0xF140,
    SC_HOTKEY = 0xF150,
    //#if(WINVER >= 0x0400) //Win95
    SC_DEFAULT = 0xF160,
    SC_MONITORPOWER = 0xF170,
    SC_CONTEXTHELP = 0xF180,
    SC_SEPARATOR = 0xF00F,
    //#endif /* WINVER >= 0x0400 */

    //#if(WINVER >= 0x0600) //Vista
    SCF_ISSECURE = 0x00000001,
    //#endif /* WINVER >= 0x0600 */

    /*
        * Obsolete names
        */
    SC_ICON = SC_MINIMIZE,
    SC_ZOOM = SC_MAXIMIZE,
}


// http://www.pinvoke.net/default.aspx/Enums/ShowWindowCommand.html
enum ShowWindowCommands
{
    /// <summary>
    /// Hides the window and activates another window.
    /// </summary>
    Hide = 0,
    /// <summary>
    /// Activates and displays a window. If the window is minimized or 
    /// maximized, the system restores it to its original size and position.
    /// An application should specify this flag when displaying the window 
    /// for the first time.
    /// </summary>
    Normal = 1,
    /// <summary>
    /// Activates the window and displays it as a minimized window.
    /// </summary>
    ShowMinimized = 2,
    /// <summary>
    /// Maximizes the specified window.
    /// </summary>
    Maximize = 3, // is this the right value?
                  /// <summary>
                  /// Activates the window and displays it as a maximized window.
                  /// </summary>       
    ShowMaximized = 3,
    /// <summary>
    /// Displays a window in its most recent size and position. This value 
    /// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except 
    /// the window is not activated.
    /// </summary>
    ShowNoActivate = 4,
    /// <summary>
    /// Activates the window and displays it in its current size and position. 
    /// </summary>
    Show = 5,
    /// <summary>
    /// Minimizes the specified window and activates the next top-level 
    /// window in the Z order.
    /// </summary>
    Minimize = 6,
    /// <summary>
    /// Displays the window as a minimized window. This value is similar to
    /// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the 
    /// window is not activated.
    /// </summary>
    ShowMinNoActive = 7,
    /// <summary>
    /// Displays the window in its current size and position. This value is 
    /// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the 
    /// window is not activated.
    /// </summary>
    ShowNA = 8,
    /// <summary>
    /// Activates and displays the window. If the window is minimized or 
    /// maximized, the system restores it to its original size and position. 
    /// An application should specify this flag when restoring a minimized window.
    /// </summary>
    Restore = 9,
    /// <summary>
    /// Sets the show state based on the SW_* value specified in the 
    /// STARTUPINFO structure passed to the CreateProcess function by the 
    /// program that started the application.
    /// </summary>
    ShowDefault = 10,
    /// <summary>
    ///  <b>Windows 2000/XP:</b> Minimizes a window, even if the thread 
    /// that owns the window is not responding. This flag should only be 
    /// used when minimizing windows from a different thread.
    /// </summary>
    ForceMinimize = 11
}