Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_4427.html
 

Global HotKeys

Опубликовано 22.06.2010 г. 19:26

В очередной раз наткнувшись в документации на функцию с интуитивно понятным называнием RegisterHotKey решил посмотреть как ее применять. Как же использовать глобальные сочетания клавиш, например, для сворачивания и разворачивания программы?

Всем думаю ясно, чем отличаются глобальные и локальные сочетания клавиш. Локальные применяются, например, для активации пунктов меню вашего приложения, в то время как глобальные регистрируются в системе, и после нажатия искомой комбинации отправляется сообщение WM_HOTKEY. Глобальные сочетания при этом имеют более высокий приоритет, нежели локальные. Допустим мы хотим зарегистрировать для нашего приложения две комбинации клавиш:
  1. Свернуть окно Ctrl + Shift + H (hide)
  2. Показать окно Ctrl + Shift + S (show)
Второй пункт как раз таки иллюстрирует "приоритеты" сочетаний, поскольку данная комбинация клавиш применяться для вызова пункта меню Save As, поэтому нажатие данной комбинации до и после регистрации, будет давать разный результат. Итак, что нам потребуется чтобы зарегистрировать сочетание клавиш? Очевидно, что это будут виртуальный код клавиши, и состояния системных кнопок alt/ctrl/shift/win. Но нам также понадобится уникальный идентификатор для нашего сочетания, с помощью которого будет отслеживаться, использует ли его кто либо в системе. Итого, получение уникального ID с помощью GlobalAddAtom и регистрация глобальной комбинации клавиш будет выглядеть следующим образом:
  var idShow, idHide : integer;
procedure TMainForm.FormCreate(Sender: TObject);
begin
    idShow := GlobalAddAtom('ApplicatoinHotKeyTest_Show'#0);
    registerHotKey(handle, idShow, MOD_SHIFT or MOD_CONTROL, ord('S'));

    idHide := GlobalAddAtom('ApplicatoinHotKeyTest_Hide'#0);
    registerHotKey(handle, idHide, MOD_SHIFT or MOD_CONTROL, ord('H'));
end;

по завершении работы программы необходимо провести обратные процедуры:

procedure TMainForm.FormDestroy(Sender: TObject);
begin
    UnregisterHotKey(handle,idShow);
    UnregisterHotKey(handle,idHide);

    GlobalDeleteAtom(idShow);
    GlobalDeleteAtom(idHide);
end;

Вспомним, что теперь при нажатии данной комбинации клавиш, мы будем получать сообщение WM_HOTKEY, поэтому расширим описание нашей формы следующим образом:

    procedure wmHotKey(var msg: TMessage);message WM_HOTKEY;

Теперь, чтобы описать процедуру реакции на соответствующие нажатия клавиш, нам потребуется реализовать и сам метод. Согласно документации WM_HOTKEY младшее слово параметра LParam будет определять нажатия кнопок alt/ctrl/shift/win, а старшее определять нажатую клавишу. Что мы в этой же последовательности и должны проверить:

procedure TMainForm.wmHotKey(var msg: TMessage);
begin
    inherited;
    if msg.LParamLo = (MOD_CONTROL or MOD_SHIFT) then begin
        case msg.LParamHi of
            ord('S') : begin
                          Self.WindowState := wsNormal;
                          Application.BringToFront();
                       end;
            ord('H') : Application.Minimize();
        end;
    end;
end;

Смысла реализовывать функцию простого сворачивания программы с помощью глобальных сочетаний нет, но вот сворачивание программы в трей, и разворачивание ее обратно вполне можно сделать.

Метки:  hotkeys 

Комментарии

underchronos
30.12.2010 в 21:57
У меня почему-то не отлавливаются никакие мессаги с WM_HotKey. Может я что-то не догоняю?
underchronos
30.12.2010 в 22:21
Прошу прощения, забылся - виртуальный код клавиши равен лишь орду капсной буквы.
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно