:: MVP ::
|
|
:: RSS ::
|
|
|
Использование горячих клавиш в приложении – тема, которая всегда будет актуальной.
И чем “крупнее” ваше приложение, тем нагруженнее меню и тем чаще пользователь будет желать пользоваться
горячими клавишами. Добавить горячие клавиши в приложение можно различными способами. Так, к примеру,
если горячие клавиши дублируют действие какого либо пункта главного меню, то и прописать их логичнее в
свойстве ShortCut этого пункта меню. Но в это свойство можно записать лишь одну комбинацию, а как быть
в случае, если за выполнение одного действия должны отвечать два (или более) сочетания горячих клавиш
(например, за действие “обновить” могут отвечать клавиши F5 и Ctrl + R,
как это реализовано в различных Web браузерах). Или другой случай – сочетание горячих клавиш должно запускать
функционал, доступа к которому нет из главного меню? И тут у нас есть выбор, можно зарегистрировать горячие
клавиши с помощью функции RegisterHotKey и потом обрабатывать сообщение WM_HOTKEY, а можно воспользоваться
компонентом ActionList. Лично мне второй вариант нравится больше, и именно о нем пойдет дальше речь.
Казалось бы, заезженная тема, все и так понятно – бросили компонент, создали Action, в свойстве ShortCut
выбрали из списка комбинацию, которая нас устраивает и все готово, можно пользоваться. И все вроде бы хорошо,
кроме того, что этот список достаточно скуден. Что же нам делать, если в нем не оказалось нужной нам комбинации?
Сейчас разберемся, а в качестве демонстрации создадим обработчик для пункта меню на основе экшена. Бросим на
форму ActionList, создадим Action, напишем его обработчик, определим свойства ShortCut и Caption, и пропишем
его в свойстве Action у пункта меню. Сразу бросается в глаза то, что значения свойств Caption и ShortCut у
пункта меню изменились, и стали такими же, как у экшена, а сама комбинация горячих клавиш отображается в пункте
главного меню, справа от заголовка. Теперь разберемся с назначением нескольких сочетаний горячих клавиш на одно
действие. И для этого вовсе не обязательно создавать несколько Action’ов, достаточно обратить внимание на свойство
SecondaryShortcuts, являющееся объектом класса TShortCutList (TStringList). В его свойстве Items хранятся названия
горячих клавиш: те, которые вводятся в Object Inspector. А в свойстве Objects список «закодированных» в тип
TShortCut горячих клавиш, соответствующих тем, что находятся в свойстве Items.
А вот это уже интересно! Список горячих клавиш представляет собой список строк, а кодирование в тип TShortCut
очевидно происходит во время компиляции программы. Свойство ShortCut так же имеет тип TShortCut, а, следовательно,
все сказанное выше относится и к нему. Покопавшись в модуле Menus можно найти функции TextToShortCut и
ShortCutToText, отвечающие за это преобразование. Посмотрев реализацию функции TextToShortCut, замечаем, что она
обращается к массиву MenuKeyCaps:
type
TMenuKeyCap = (mkcBkSp, mkcTab, mkcEsc, mkcEnter, mkcSpace, mkcPgUp,
mkcPgDn, mkcEnd, mkcHome, mkcLeft, mkcUp, mkcRight, mkcDown, mkcIns,
mkcDel, mkcShift, mkcCtrl, mkcAlt);
var
MenuKeyCaps: array[TMenuKeyCap] of string = (
SmkcBkSp, SmkcTab, SmkcEsc, SmkcEnter, SmkcSpace, SmkcPgUp,
SmkcPgDn, SmkcEnd, SmkcHome, SmkcLeft, SmkcUp, SmkcRight,
SmkcDown, SmkcIns, SmkcDel, SmkcShift, SmkcCtrl, SmkcAlt);
|
Элементы массива – обычные строковые константы, объявленные в модуле Consts:
SmkcBkSp = 'BkSp';
SmkcTab = 'Tab';
SmkcEsc = 'Esc';
SmkcEnter = 'Enter';
SmkcSpace = 'Space';
SmkcPgUp = 'PgUp';
SmkcPgDn = 'PgDn';
SmkcEnd = 'End';
SmkcHome = 'Home';
SmkcLeft = 'Left';
SmkcUp = 'Up';
SmkcRight = 'Right';
SmkcDown = 'Down';
SmkcIns = 'Ins';
SmkcDel = 'Del';
SmkcShift = 'Shift+';
SmkcCtrl = 'Ctrl+';
SmkcAlt = 'Alt+';
|
Значит, из этих строк мы можем собирать свои комбинации горячих клавиш, в том числе и такие, которые отсутствуют в
выпадающем списке свойства ShortCut. Вот несколько примеров – 'Ctrl+Up', 'Ctrl+Alt+Down', 'Shift+Tab', 'Alt+BkSp',
'Ctrl+Alt+Enter'. Разумеется, сочетания клавиш, занятые системой (например, 'Ctrl+Shift+Esc'), в приложении работать
не будут.
Движемся дальше. Допустим, нам нужно задействовать в своем приложении цифровую клавиатуру, мы хотим при нажатии
комбинации клавиш 'Ctrl +' и 'Ctrl –' осуществлять масштабирование чего либо. Но как это записать в свойство ShortCut
в виде строки? За строчку 'Ctrl++' Delphi ругнется на нас чем-то вроде 'Invalid property value', а строка 'Ctrl+-'
хоть и запишется, но работать не будет. Как же быть? Оказывается, для такого случая можно использовать слово 'Num',
хотя найти в Delphi константу с таким значением мне не удалось (может быть плохо искал). И так, нужные нам строки
будут выглядеть следующим образом 'Ctrl+Num +' и 'Ctrl+Num -' (пробел после Num является обязательным).
Вполне может возникнуть ситуация, когда вы захотели использовать одну из дополнительных функциональных клавиш, для
которых нет строкового эквивалента. К примеру, вы запустили в отдельном потоке длительную операцию, и готовы
предоставить пользователю возможность приостановить/возобновить поток нажатием на кнопку Pause. Как быть? Выход
есть, установим это свойство программно:
uses
Menus;
procedure TForm1.FormCreate(Sender: TObject);
begin
Action1.ShortCut := ShortCut( VK_PAUSE, [] );
end;
|
Аналогично следует поступать в случае, когда нам хочется задействовать в своем приложении мультимедийные клавиши,
такие например, как Home, Back, Forward, Refresh, Stop и т.д.
Загвоздка с ними такая же – для них нет специального строкового эквивалента, кроме того они не эмулируют нажатие той или
иной комбинации, а имеют собственные коды:
Название |
Код |
Константа |
Вызываемое приложение (по умолчанию) |
Группа - Internet |
Back |
166 |
VK_BROWSER_BACK |
|
Forward |
167 |
VK_BROWSER_FORWARD |
|
Stop |
169 |
VK_BROWSER_STOP |
|
Favorites |
171 |
VK_BROWSER_FAVORITES |
|
Search |
170 |
VK_BROWSER_SEARCH |
Windows Search |
Refresh |
168 |
VK_BROWSER_REFRESH |
|
Home |
172 |
VK_BROWSER_HOME |
Браузер по умолчанию |
Mail |
180 |
VK_LAUNCH_MAIL |
Почтовый клиент по умолчанию |
Группа - Audio |
Mute |
173 |
VK_VOLUME_MUTE |
Включает/выключает звук в системе |
-Vol |
174 |
VK_VOLUME_DOWN |
Уменьшает уровень звука в системе |
+Vol |
175 |
VK_VOLUME_UP |
Увеличивает уровень звука в системе |
Media |
181 |
VK_LAUNCH_MEDIA_SELECT |
Windows Media Player |
Stop |
178 |
VK_MEDIA_STOP |
|
Play/Pause |
179 |
VK_MEDIA_PLAY_PAUSE |
|
Next |
176 |
VK_MEDIA_NEXT_TRACK |
|
Prev |
177 |
VK_MEDIA_PREV_TRACK |
|
Другие |
Calculator |
183 |
VK_LAUNCH_APP2 |
Калькулятор |
My Computer |
182 |
VK_LAUNCH_APP1 |
Мой компьютер |
За подробностями и кодами других клавиш обращайтесь к модулю Windows.pas.
Мы можем поступить как в случае с клавишей Pause, а можем вспомнить про свойство Objects, которое хранит «закодированные»
в тип TShortCut горячие клавиши. В дизайнере с ним сделать ничего не получится, зато в RunTime нет никаких проблем:
procedure TForm1.FormCreate(Sender: TObject);
begin
Action1.SecondaryShortCuts.AddObject( '', TObject( ShortCut( VK_PAUSE, [] ) ) );
end;
|
Вот мы и добились того, чего хотели – получили контроль над клавиатурой. На последок хотелось бы сказать несколько слов о
функциях TextToShortCut и ShortCutToText. Они прекрасно подойдут в случае, если вы хотите предоставить пользователю
возможность самостоятельной настройки горячих клавиш в приложении. В таком случае эти функции можно использовать для
сохранения пользовательских горячих клавиш в конфигурационном файле и считывании их оттуда. Но следует помнить – не все
горячие клавиши можно преобразовать в строку (внимательно смотрим на массив MenuKeyCaps и константы, являющиеся значениями
этого массива). Убедиться в этом нам поможет следующий код:
Action1.ShortCut := TextToShortCut( ShortCutToText( ShortCut( VK_F1, [] ) ) ); // Будет работать
Action1.ShortCut := TextToShortCut( ShortCutToText( ShortCut( VK_PAUSE, [] ) ) ); // Не будет работать
|
Удачного программирования!
.: Пример к данной статье :.
|
При использовании материала - ссылка на сайт обязательна
|
|