locked
Get back to my program with keyboard

    Question

  • Hi,

    My program will be hidden and at times I want to come back to it with a keyboard combination, such as alt-u.

    Can anyone tell me how to do that?

    Thanks in advance,

    Wayne

    Saturday, July 22, 2006 11:58 AM

Answers

  • You'd need to register a hotkey with Windows and have your form respond to it.  .NET doesn't let you do it but you can use the necessary P/Invoke voodoo like this:

    Imports System.Runtime.InteropServices

    Public Class Form1
      '--- Windows API declarations
      Private Const WM_HOTKEY As Integer = &H312
      Private Const MOD_ALT As Integer = &H1
      Private Const MOD_CONTROL As Integer = &H2
      Private Const MOD_SHIFT As Integer = &H4
      Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer
      Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Boolean
      Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean

      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        RegisterHotKey(Me.Handle, 0, MOD_CONTROL + MOD_SHIFT, Keys.U)
      End Sub
      Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        UnregisterHotKey(Me.Handle, 0)
      End Sub
      Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If (m.Msg = WM_HOTKEY AndAlso m.WParam = CType(0, IntPtr)) Then
          Me.Visible = True
          If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal
          SetForegroundWindow(Me.Handle)
        End If
        MyBase.WndProc(m)
      End Sub
    End Class

    Note that I've made the hotkey Control + Shift + U, Alt + U would trigger too often.
    Saturday, July 22, 2006 3:39 PM

All replies

  • interesting. I'm unsure actually.

    your best bet is to store the application in the systray instead (right handside in the taskbar where all the icons are) and access it from that, as if the form was hidden, then you would not know how to access it, since it'll lose its focus.

    I guess the user could also access it by pressing the ALT+Tab keys to swtich to a different program, which yours will be in there since its in a process and actively running

    Saturday, July 22, 2006 2:51 PM
  • You'd need to register a hotkey with Windows and have your form respond to it.  .NET doesn't let you do it but you can use the necessary P/Invoke voodoo like this:

    Imports System.Runtime.InteropServices

    Public Class Form1
      '--- Windows API declarations
      Private Const WM_HOTKEY As Integer = &H312
      Private Const MOD_ALT As Integer = &H1
      Private Const MOD_CONTROL As Integer = &H2
      Private Const MOD_SHIFT As Integer = &H4
      Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer
      Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Boolean
      Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean

      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        RegisterHotKey(Me.Handle, 0, MOD_CONTROL + MOD_SHIFT, Keys.U)
      End Sub
      Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        UnregisterHotKey(Me.Handle, 0)
      End Sub
      Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If (m.Msg = WM_HOTKEY AndAlso m.WParam = CType(0, IntPtr)) Then
          Me.Visible = True
          If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal
          SetForegroundWindow(Me.Handle)
        End If
        MyBase.WndProc(m)
      End Sub
    End Class

    Note that I've made the hotkey Control + Shift + U, Alt + U would trigger too often.
    Saturday, July 22, 2006 3:39 PM
  • Good pickup NoBugz

    I personally wouldnt register hotkeys with Windows for a number of reasons.

     

    1) the hotkey you assigned could change within say future version of Windows (unlikely)

    2) the hotkey maybe registered with perhaps another applications

     

    It is good that you unregister the hotkey just before you exit, good practice. But that was just my own personal opinion :-)

    Saturday, July 22, 2006 4:00 PM
  • Thanks guys,

    I have a friend that pointed me to this site which is what I need. I works like the old TSR programs, get the key - if it is what you need then process - forward the key back to windows.

    If anyone is interested the link is: http://www.developer.com/net/net/article.php/2193301

    Thanks again,

    Wayne

    Sunday, July 23, 2006 1:52 PM
  • nobugz,

    The one I tried to use didn't work out. Yours did just what I wanted to do. Thanks.

     

    Wednesday, July 26, 2006 4:07 PM
  • nobugz,

    do you know by any chance how can I write the line that has the "user32.dll" reference in C#?

    Friday, January 12, 2007 9:50 PM
  • There's more than one.  I just wrote the full C# version, it is popular code:

    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    namespace WindowsApplication1 {
      public partial class Form1 : Form {
        private const int MYKEYID = 0;    // In case you want to register more than one...
        public Form1() {
          InitializeComponent();
          RegisterHotKey(this.Handle, MYKEYID, MOD_CONTROL + MOD_SHIFT, Keys.U);
          this.FormClosing += Form1_FormClosing;
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
          UnregisterHotKey(this.Handle, MYKEYID);
        }
        protected override void WndProc(ref Message m) {
          if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == MYKEYID) {
            this.Visible = true;
            if (this.WindowState == FormWindowState.Minimized)
              this.WindowState = FormWindowState.Normal;
            SetForegroundWindow(this.Handle);
          }
          base.WndProc(ref m);
        }
        // P/Invoke declarations
        private const int WM_HOTKEY = 0x312;
        private const int MOD_ALT = 1;
        private const int MOD_CONTROL = 2;
        private const int MOD_SHIFT = 4;
        [DllImport("user32.dll")]
        private static extern int RegisterHotKey(IntPtr hWnd, int id, int modifier, Keys vk);
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
      }
    }
    Friday, January 12, 2007 10:17 PM
  • nobugz,
    thank you so much, I was about to post my translation (I managed to translate your VB code to C#). But man, you're fast :)

    I had a problem though, whenever I call SetForgroundWindow I get an exception : Unable to find an entry point named 'SetForgroundWindow' in DLL 'user32.dll'. (Same exception for UnregisterHotkey).

    Anyway, I guess the problem somewhere in my translation, I'll copy and paste your C# code and try again.

    Many thanks again & kind regards

    Saturday, January 13, 2007 12:30 AM
  • The C# example was just what i need, but one more thing...

    I'm building a macro program in C#, so i also need to know how long the button is being pressed..  any ideas on that?
    Thursday, August 28, 2008 7:37 AM
  • Ok this all works great until the program is minimized to the taskbar the hot keys are no longer getting hit.

    this.Hide();
    ShowInTaskbar = false;

    Is what i call when minimizing the application so that it will show in system tray.

    After doing that the hot keys no longer work.

    On a side note when double clicking on the notifyicon

    I do the following

                this.Show();
                this.WindowState = FormWindowState.Normal;
                ShowInTaskbar = true;

    I have to reregister the keys again for them to work.
    Tuesday, March 17, 2009 11:11 PM
  • You got an answer in this thread.
    Hans Passant.
    Tuesday, March 17, 2009 11:29 PM