захват ключа с использованием глобальной горячей клавиши в С#

У меня есть приложение, которое работает в фоновом режиме, как будто я могу держать свое приложение на панели задач. Если оно останется на панели задач, мое приложение выполнит свою работу. Всякий раз, когда пользователь нажимает F10 или F9, выполняются некоторые действия. я пробовал это:

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);
    }

}

Поскольку я использую set "this.ShowInTaskbar = false" в этой строке, она не работает. Но если я не устанавливаю это, она работает нормально. Для моего приложения я должен использовать эту строку. Как я могу решить эту проблему????


person ImonBayazid    schedule 15.03.2013    source источник


Ответы (2)


Вам необходимо подписаться на определенные сообщения, которые операционная система отправляет с помощью собственного вызова функции, например RegisterHotKey(). Когда вы вызываете эту функцию, вы сообщаете операционной системе, в какое окно отправлять сообщения, указывая Handle окна, это можно считать адресом. Когда вы устанавливаете ShowInTaskbar = false, дескриптор изменяется, поэтому операционная система не будет знать, где вас найти.

См. первый аргумент:

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

Чтобы решить вашу проблему, вы можете создать класс, производный от NativeWindow , который "обеспечивает низкоуровневую инкапсуляцию дескриптора окна и оконной процедуры." и изнутри этого класса (или, по крайней мере, используя дескриптор этого класса, в зависимости от вашей реализации), зарегистрируйте горячие клавиши, используя дескриптор, который никогда не изменится.

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();
    }
}
person User 12345678    schedule 15.03.2013

Насколько я знаю, вам нужно перерегистрировать горячую клавишу всякий раз, когда вы меняете состояние «ShowInTaskbar».

У кого-то была похожая проблема; см. эту тему.

person Matthew Watson    schedule 15.03.2013