-1

I'm writing C# desktop application, which would allow me to mute my mic on hotkey, when I'm playing smtng with discord/skype/teamspeak etc. So, I need my app to accept my hotkey (ex: ctrl + B) without me alt+tabbing from my game.

public partial class Form1 : Form
    {
        private const int APPCOMMAND_MICROPHONE_VOLUME_MUTE = 0x180000;
        
        private const int APPCOMMAND_VOLUME_MUTE = 0x80000;

        private const int WM_APPCOMMAND = 0x319;

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg,
            IntPtr wParam, IntPtr lParam);
        public Form1()
        {
            InitializeComponent();
        }
        
        private void Form1_Load(object sender, EventArgs e)
        {
            return;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
                (IntPtr)APPCOMMAND_VOLUME_MUTE);
        }
        
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
            if (keyData == (Keys.Control | Keys.B)) {
                SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
                    (IntPtr)APPCOMMAND_VOLUME_MUTE);
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void Form1_Resize_1(object sender, EventArgs e)
        {
            if (FormWindowState.Minimized == this.WindowState)
            {
                notifyIcon1.Visible = true;
                notifyIcon1.ShowBalloonTip(500);
                this.Hide();    
            }
            else if (FormWindowState.Normal == this.WindowState)
            {
                notifyIcon1.Visible = false;
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }
    }

My form is just a test environment, it has 1 button for turn on/off mic, it reads Ctrl+B hotkey to turn on/off mic, and it goes to tray, when minimized.

So, the main point is: I need it to accept Ctrl+B combinaton when my app is minimized and my app mustn't steal focus from program(game), that i'm using in the moment.

AndyPearce
  • 41
  • 1
  • 4
  • You need a global hotkey if you want to intercept keystrokes when your app is not active and focused. This is probably a duplicate of this one https://stackoverflow.com/questions/2450373/set-global-hotkeys-using-c-sharp – Steve Aug 15 '20 at 19:59
  • I am using a `Hook` to catch such events as discussed in this [related post](https://stackoverflow.com/questions/8765906/global-hooks-non-active-program). – Axel Kemper Aug 15 '20 at 20:21
  • Your only other options are to register your hotkey combo with RegisterHotKey(), or poll the keyboard with GetAsyncKeyState(). – Idle_Mind Aug 16 '20 at 01:15
  • https://stackoverflow.com/questions/2450373/set-global-hotkeys-using-c-sharp thanks, Steve, it helped me – AndyPearce Aug 16 '20 at 20:09

1 Answers1

0

Thanks to Steve for the answer Set global hotkeys using C#

More information: https://ourcodeworld.com/articles/read/573/how-to-register-a-single-or-multiple-global-hotkeys-for-a-single-key-in-winforms

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;

// 1. Import the InteropServices type
using System.Runtime.InteropServices;

namespace Sandbox
{
    public partial class Form1 : Form
    {
        // 2. Import the RegisterHotKey Method
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        public Form1()
        {
            InitializeComponent();

            // 3. Register HotKey

            // Set an unique id to your Hotkey, it will be used to
            // identify which hotkey was pressed in your code to execute something
            int UniqueHotkeyId = 1;
            // Set the Hotkey triggerer the F9 key 
            // Expected an integer value for F9: 0x78, but you can convert the Keys.KEY to its int value
            // See: https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
            int HotKeyCode = (int)Keys.F9;
            // Register the "F9" hotkey
            Boolean F9Registered = RegisterHotKey(
                this.Handle, UniqueHotkeyId, 0x0000, HotKeyCode
            );

            // 4. Verify if the hotkey was succesfully registered, if not, show message in the console
            if (F9Registered)
            {
                Console.WriteLine("Global Hotkey F9 was succesfully registered");
            }
            else
            {
                Console.WriteLine("Global Hotkey F9 couldn't be registered !");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        protected override void WndProc(ref Message m)
        {
            // 5. Catch when a HotKey is pressed !
            if (m.Msg == 0x0312)
            {
                int id = m.WParam.ToInt32();
                // MessageBox.Show(string.Format("Hotkey #{0} pressed", id));

                if (id == 1)
                {
                    MessageBox.Show("F9 Was pressed !");
                }
            }

            base.WndProc(ref m);
        }
    }
}
AndyPearce
  • 41
  • 1
  • 4
  • That is pretty fundamentally wrong. Odds that it tends to work are well above zero, but programmers easily lose a week of their life when they trust "it worked for me" too much. Make SO better by not promoting bad solutions, deleting this Q+A is best. – Hans Passant Aug 18 '20 at 21:54