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

Горячие клавиши (от англ. 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)

Ссылки

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *