Key capture using global hotkey in C #

I have an application that runs in the background, since I can save my application in the system tray. If it stays on the system tray, my application will do the job. Whenever the user presses F10 or F9, some work will be performed. I tried this:

public partial class Form1 : Form { public int a = 1; [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc); [DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); [DllImport("User32.dll")] private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); [DllImport("User32.dll")] private static extern short GetAsyncKeyState(System.Int32 vKey); const int MYACTION_HOTKEY_ID = 1; public Form1() { InitializeComponent(); RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9); RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int)Keys.F10); this.ShowInTaskbar = false; } protected override void WndProc(ref Message m) { if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F9) == -32767)) { if ((a % 2) != 0) { a++; MessageBox.Show(a.ToString()+"not equal F9"); label1.Text = "not equal F9"; } if ((a % 2) == 0) { a++; MessageBox.Show(a.ToString()+"equal F9"); label1.Text = " equal F9"; } } else if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F10) == -32767)) { if ((a % 2) != 0) { a++; MessageBox.Show(a.ToString() + "not equal F10"); label1.Text = "not equal F10"; } if ((a % 2) == 0) { a++; MessageBox.Show(a.ToString() + "equal F10"); label1.Text = " equal F10"; } } base.WndProc(ref m); } } 

As I use set "this.ShowInTaskbar = false", this line does not work. But if I do not install this, it works fine. For my application, I have to use this line. How can I solve this ????

+4
source share
2 answers

You need to subscribe to certain messages that the operating system sends using the built-in function call of type RegisterHotKey() . When you call this function, you tell the operating system in which window to send messages, indicating Handle windows, this can be considered an address. When you set ShowInTaskbar = false , this handle changes, so the operating system will not know where to get you.

See first hand:

 RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9); 

To solve the problem, you can create a class derived from NativeWindow , which "Provides encapsulation of the lower level of the window descriptor and window procedure." and from within this class (or at least using this class descriptor depending on your implementation), register the keyboard shortcuts with a handle that will never change.

 public sealed class HotkeyManager : NativeWindow, IDisposable { public HotkeyManager() { CreateHandle(new CreateParams()); } protected override void WndProc(ref Message m) { if (m.Msg == Constants.WM_HOTKEY) { //handle hotkey message } base.WndProc(ref m); } public void Dispose() { DestroyHandle(); } } 
+7
source

As far as I know, you need to re-register the hotkey whenever you change the state of ShowInTaskbar.

Someone had a similar problem; see this thread .

+1
source

Source: https://habr.com/ru/post/1469527/


All Articles