Медиа-ключи в WndProc не срабатывают

Я создаю медиаплеер в WinForms, С#. Я хочу ответить пользователю, нажимающему мультимедийные клавиши на клавиатуре, используя следующий код, который можно найти по всему Интернету:

public const int WM_APPCOMMAND = 0x0319;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_APPCOMMAND)
    {
        switch ((int)m.LParam)
        {
            case 14: // MediaPlayPause
                TogglePlayPause();
                break;
            default:
                break;
        }
    }
    base.WndProc(ref m);
}

Но это не сработает. Он просто никогда не получает ключевую команду. Медиа-ключи работают с любым другим приложением (и метод TogglePlayPause() тоже работает).


person Jonas Kohl    schedule 27.10.2018    source источник


Ответы (1)


Значение, сообщаемое LParam, является составным.

Как указано в Документах, относительно WM_APPCOMMAND, значение можно извлечь с помощью:

cmd  = GET_APPCOMMAND_LPARAM(lParam);
uDevice = GET_DEVICE_LPARAM(lParam);
dwKeys = GET_KEYSTATE_LPARAM(lParam);

Вам нужно значение cmd.

В C# это может быть закодировано как:

private const int WM_APPCOMMAND = 0x0319;
private const int APPCOMMAND_MEDIA_PLAY_PAUSE = 14;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg)
    {
        case WM_APPCOMMAND:
            int cmd = (int)m.LParam >> 16 & 0xFF;
            switch (cmd)
            {
                case APPCOMMAND_MEDIA_PLAY_PAUSE:
                    TogglePlayPause();
                    break;
                default:
                    break;
            }
            m.Result = (IntPtr)1;
            break;
        default:
            break;
    }
}

Правка:
Несколько полезных ссылок о KeyBoard Hooks и регистрации горячих клавиш.

На SetWindowHookEx:
SetWindowsHookEx WH_KEYBOARD_LL не получает события< br> Низкий уровень Перехват клавиатуры в C#

На RegisterHotKey:
Захват нажатия клавиши клавиатуры в фоновом режиме

person Jimi    schedule 27.10.2018
comment
Это работает безупречно, но только когда окно сфокусировано. Есть ли способ заставить это работать, даже когда приложение свернуто? - person Jonas Kohl; 28.10.2018
comment
@Jonas Kohl Вам нужен KeyBoard Hook или HotKeys, в зависимости от того, как работает ваше приложение (и насколько хорошо вы можете справляться с особенностями параллелизма). Ссылки на оба метода в файле Edit. Это, однако, другой вопрос и довольно широкий. Задайте еще один вопрос, если у вас возникнут проблемы с реализацией одного из методов (не используйте оба). - person Jimi; 28.10.2018