Чего только не придумывают производители для привлечения внимания покупателей, особенно в сегменте игр и развлечений. Клавиатуры и мыши из устройства ввода информации превратились в произведение искусства или выставочный образец высоких технологий, поражая своим внешним видом или техническими возможностями. Но речь пойдет о приёме программирования, который позволит значительно улучить удобство работы с любой программой.
Горячие клавиши (от англ. hot key ) — это комбинация нажатий клавиш на клавиатуре, которые выполняют то или иное действие.
Большинство пользователей так полюбили мышку, что даже не догадываются о том, что все операции, которые они проделывают этим удобным манипулятором, возможно выполнить с помощью клавиатуры. А если речь идет о вводе текстовой информации, то мышку лучше отложить в сторону.
В My Visual Database ключевые операции по работе с таблицами (добавление, редактирование и удаление записей) обычно реализуются через программирование кнопок, по которым пользователю приходится кликать мышкой. Cтандартный вариант с клавиатурой ещё хуже – нужно несколько раз нажать клавишу Tab, чтобы переместить фокус на кнопку, а затем нажать клавишу Enter. Поэтому для повышения скорости ввода данных необходимо добавить в программу механизм горячих клавиш.
Теория
В операционной системе Windows взаимодействия пользователя и программы идет через события: каждое нажатие клавиши, перемещение мышки или вращение нажатие на ней кнопок вызывает отправку сообщения о произведенном пользователем действии.
По сути передача сообщений реализована как вызов метода обработки сообщений: сообщение сначала передаётся форме, но обрабатывается оно согласно иерархии расположения компонентов. Первым оно поступает к тем элементам, у которых находится фокус ввода (для сообщений от клавиатуры) или которые расположены поверх остальных элементов (для сообщений от мыши). Если компонент принимает сообщение, то обычно оно уничтожается и уже не попадает к другим компонентам, стоящим в очереди обработки сообщений.
Кроме заранее запрограммированной реакции на сообщение, компонент может сам создавать события, для обработки которых программист пишет специальную процедуру – обработчик события. По сути, вся программа – это набор обработчиков таких событий. Даже код, который находится в основном блоке begin end можно рассматривать как обработчик события, которое возникает при запуске программы.
Механизм действия горячих клавиш основан на возможности изменять последовательность обработки очереди сообщений от клавиатуры: при установке свойства формы KeyPreview = True такие сообщения в первую очередь начинают поступать к форме, вне зависимости от того, где сейчас находится фокус ввода. Таким образом, написав обработчик нажатия клавиш для формы и включив механизм KeyPreview, можно создать систему горячих клавиш в пределах одной формы. В случае с ClassExplorer нужно добавить такой обработчик на форму frmMain и обрабатывать нажатия клавиш клавиатуры: нажимать кнопки в интерфейсе или вызывать пункты главного меню.
Практика
Как всегда мы будем писать максимально абстрактный код, чтобы его легко можно было использовать в других приложениях. Для хранения настроек будем использовать массивы, а для их инициализации – процедуру Hotkey_Init().
const
HOTKEY_COUNT = 4; // число горячих клавиш
var
HotKey_Code: array of byte; // виртуальный код
HotKey_Shift: array of boolean; // флаг нажатия Shift
HotKey_Alt: array of boolean; // флаг нажатия Alt
HotKey_Ctrl: array of boolean; // флаг нажатия Ctrl
HotKey_Command: array of string; // выполняемая команда: название кнопки или пункта меню
Code language: Delphi (delphi)
Инициализация выглядит громоздко, возможно в дальнейшем она будет выполняться из базы. Вероятно, в будущем может понадобиться несколько вариантов обработки для разных форм, но пока достаточно и этого:
procedure Hotkey_Init(Sender:TObject);
// подключение к форме
// Sender - форма, для которой подключается система горячих клавиш
var
tmpForm:TAForm;
i:integer;
begin
tmpForm := TAForm(Sender);
tmpForm.KeyPreview := True;
AssignEvents(tmpForm);
tmpForm.dbOnKeyDown := 'Hotkey_OnKeyDown';
// инициализация массивов
SetLength(HotKey_Code,HOTKEY_COUNT);
SetLength(HotKey_Shift,HOTKEY_COUNT);
SetLength(HotKey_Alt,HOTKEY_COUNT);
SetLength(HotKey_Ctrl,HOTKEY_COUNT);
SetLength(HotKey_Command,HOTKEY_COUNT);
// настройка горячих клавиш
i := 0;
// добавить новую запись
HotKey_Code[i] := VK_F2;
HotKey_Shift[i] := False;
HotKey_Alt[i] := False;
HotKey_Ctrl[i] := False;
HotKey_Command[i] := 'btnNew';
inc(i);
// редактировать запись
HotKey_Code[i] := VK_F4;
HotKey_Shift[i] := False;
HotKey_Alt[i] := False;
HotKey_Ctrl[i] := False;
HotKey_Command[i] := 'btnEdit';
inc(i);
// удалить запись
HotKey_Code[i] := VK_F8;
HotKey_Shift[i] := False;
HotKey_Alt[i] := False;
HotKey_Ctrl[i] := False;
HotKey_Command[i] := 'btnDelete';
inc(i);
// показать окно "О программе"
HotKey_Code[i] := VK_F11;
HotKey_Shift[i] := False;
HotKey_Alt[i] := False;
HotKey_Ctrl[i] := False;
HotKey_Command[i] := 'mniAbout';
inc(i);
//
end;
Code language: Delphi (delphi)
И наконец, сам обработчик нажатия – Hotkey_OnKeyDown(). Обратите внимание, что для поиска в меню используется глобальная переменная MainForm, в которой хранится ссылка на главную форму приложения. Главную в том смысле, что на ней находится системное меню и служебные компоненты My Visual Database. Если же в дальнейшем понадобится поиск в меню, которое было создано для формы, на которую добавили данных обработчик, то искать нужно будет с использованием значения переменной tmpForm (строка 30).
procedure Hotkey_OnKeyDown (Sender: TObject; var Key: Word; Shift, Alt, Ctrl: boolean);
// обработка горячих клавиш
var
tmpForm:TForm;
tmpButton: TdbButton;
tmpName: string;
tmpComponent: TComponent;
i:integer;
begin
tmpForm := TForm(Sender);
tmpName := '';
for i := 0 to HOTKEY_COUNT-1 do
begin
// найдено совпадение
if (Key = HotKey_Code[i]) and (Shift =HotKey_Shift[i]) and (Alt = HotKey_Alt[i]) and (Ctrl = HotKey_Ctrl[i]) then
begin
tmpName := HotKey_Command[i];
// ищем кнопку
FindC(tmpForm,tmpName,tmpComponent,False);
if tmpComponent <> nil then
begin
if tmpComponent is TdbButton then
TdbButton(tmpComponent).Click
else
if tmpComponent is TMenuItem then
TMenuItem(tmpComponent).Click
end
else // ищем в главном меню...
begin
FindC(MainForm,tmpName,tmpComponent,False);
if tmpComponent <> nil then
begin
if tmpComponent is TMenuItem then
TMenuItem(tmpComponent).Click
end
end;
break;
end;
end;
end;
Code language: Delphi (delphi)
Чтобы система заработала, необходимо вызвать процедуру Hotkey_Init() при инициализации приложения:
procedure frmMain_OnShow (Sender: TObject; Action: string);
// отображение главной формы
begin
CE_Init(MainForm); // главное меню находится на главной форме, но отображается там, где нужно
Hotkey_Init(Sender); // подключить горячие клавиши
UserApp_InitBase; // инициализация базы данных
frmMain.pgcMain.ActivePage := frmMain.tshNavigation; // открыть вкладку "Навигация"
frmMain.pgcNavigation.ActivePage := frmMain.tshTask; // открыть вкладку "Задачи"
end;
Code language: Delphi (delphi)