Tuesday, May 29, 2012

Bring Application to the Front

In this post I want to show, how to bring an application to the front using C#. The presented method should work, no matter if the program currently has the focus or is minimized, granting the application the input focus and set it as the top most window on the screen.
By default in C# forms have the property TopMost and the function BringToFront(), but these just move the form forward in relation to other forms of the application. Therefore, we have to dig a bit deeper and to use the Win32 API.

For above needs we need the function SetForegroundWindow(), which expects the handle of the target window. It grants the application the input focus, if the application is minimized though, it is now shown. The reason is, that minimized applications do not have a window which could be shown.

To create this window we use the function ShowWindowAsync(). It expects 2 arguments, the first one is again the window handle, the second one an integer value determining how the window is shown. For an overview over all possibilities I want to refer to the MSDN, I only use SW_RESTORE, which shows the window in its original size.

We now simply add a request asking whether the window is minimized, which is possible via the function IsIconic().

The following program uses the previously described functions to bring the program after elapse of the timer event to the front:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        private static extern
            bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern
            bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        private static extern
            bool IsIconic(IntPtr hWnd);

        private const int SW_RESTORE = 9;

        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (IsIconic(this.Handle))
                ShowWindowAsync(this.Handle, SW_RESTORE);

            SetForegroundWindow(this.Handle);
        }
    }
}

Monday, May 28, 2012

Create Global Hotkeys

This topic is about creating global hotkeys for a C# application. Once registered, the hotkeys are active system wide - meaining: Also when another program is active at the moment, the pressing of the hotkey is still made known to our application. This way, for example a running inactive application can be called to the front.
We define a hotkey with the API function RegisterHotKey(). This expects 4 parameters:

  • The handle of the window, which is supposed to get the message.
  • The ID of the hotkey, important when multiple hotkeys are registered per application. If NULL is handed over, the hotkey is just registered as the only hotkey for the application.
  • The control keys, which have to be pressed for activating the hotkey (e.g. Alt, Ctrl ...).
  • The key, which has to be pressed for activating the hotkey (e.g. "X").
Analogously to that there exists the function UnregisterHotKey(), which expects the window handle and ID of the hotkey, with which the function can be deleted (for example at the termination of the program).
When the hotkey is pressed, the application gets the message WM_HOTKEY. To receive this, the function WndProc() has to be overridden.
The following sample code creates 2 hotkeys (Shift + Ctrl + X and Shift + Ctrl + Y), I think the method should become clear this way:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        const int MOD_CONTROL = 0x0002;
        const int MOD_SHIFT = 0x0004;
        const int WM_HOTKEY = 0x0312;

        private void Form1_Load(object sender, EventArgs e)
        {
            RegisterHotKey(this.Handle, 1, MOD_CONTROL + MOD_SHIFT, (int)Keys.X);
            RegisterHotKey(this.Handle, 2, MOD_CONTROL + MOD_SHIFT, (int)Keys.Y);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnregisterHotKey(this.Handle, 1);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_HOTKEY && (int)m.WParam == 1)
                MessageBox.Show("Hotkey X pressed.");
            if (m.Msg == WM_HOTKEY && (int)m.WParam == 2)
                MessageBox.Show("Hotkey Y pressed.");
            base.WndProc(ref m);
        }

    }
}


Further information can be found in the MSDN.