Клавиатура в MS-DOS и Windows.
Следует заметить, что Windows значительно “строже” относится к использованию клавиатуры, чем MS-DOS. Это может вызывать проблемы при переносе игровых приложений, а также приложений, созданных с помощью FoxPro или Clipper, в среду Delphi.
Если вы захотите сохранить устоявшиеся приемы использования клавиатуры в новой разработке (а я настоятельно рекомендую сделать это), вам, возможно, придется перехватывать сообщения Windows, так как только таким способом программа сможет опознать факт нажатия на системные клавиши Alt, Tab, Shift и т. п. Нажатие на остальные клавиши можно анализировать с помощью перехвата сообщений от клавиатуры в обработчиках Опкеуххх формы при установленном значении True в ее свойство Keypreview. Например, пусть акселератор Alt+X используется в существующей программе для закрытия модального диалогового окна. Чтобы сконструированное вами окно закрывалось по этой команде, напишите для него такой Обработчик события OnKeyDown:
procedure TForm2.FormKeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState) ;
begin
if (Key = ord('X')) and (ssAlt in Shift) then Close
end;
Во многих случаях можно использовать собственные клавиши-акселераторы Windows. К сожалению, такими клавишами снабжаются лишь опции меню, но связанные с ними (опциями) обработчики OnClick выйолняются даже в том случае, когда опция меню не видна (ее свойство visible имеет значение False). Этим можно воспользоваться, чтобы вставить в главное меню окна фиктивные невидимые опции, связав их с нужными акселераторами. Пусть, например, клавиша Buttoni должна “нажиматься” при нажатии Ctrl+S. Поместите на форму главное меню (если его еще нет) и создайте в нем опцию-заголовок с произвольным именем, например, MyButton. В списке свойства Shortcut опции выберите Ctrl+S и установите False в ее свойство visible. Теперь можно связать ее обработчик события OnClick непосредственно с Button1Click или написать такой обработчик:
procedure TForm2.MyButtonClick(Sender: TObject);
begin
ButtonlClick(Self)
end;
И хотя опция MyButton главного меню не видна, нажатие связанных с ней клавиш Ctrl+S вызовет срабатывание нужного обработчика. В этом случае форма может не перехватывать клавиатурный ввод.
Как уже отмечалось, обработчики Опкеуххх не реагируют на нажатие системных клавиш Windows, в том числе - клавиш смещения курсора. Происходит это из-за того, что умалчиваемая оконная функция программы осуществляет стандартную обработку соответствующих сообщений Windows. Оконная функция связывается с каждым программным окном. Ее назначение - осуществлять связь программы с Windows. В оконную функцию главного окна программы Windows помещает сообщения о наступлении того или иного события, в том числе - о нажатии на клавишу. Оконная функция главного окна передает это сообщение оконной функции окна с фокусом ввода (см. ниже п. 17.6.4), а та, в свою очередь - функции сфокусированного оконного компонента. Чтобы получать все адресованные программе сообщения Windows, необходимо использовать метод HookMainwindow глобального объекта-программы Application или его обработчик события OnMessage. Единственным параметром обращения к методу Application. HookMainwindow является имя функции типа
TWindowHook = function(var Message: TMessage): Boolean of object;
которая будет получать сообщение Message. Возвращаемый ею результат и возможные изменения сообщения Message игнорируются. Фактически функция получает сообщение параллельно с иконной функцией и не может воздействовать на обработку сообщения. В отличие от этого обработчик Application. OnMessage
type
TMsg = packed record
hwnd: HWND; message: UINT; wParam: WPARAM; IParam: LPARAM;
time: DWORD; pt: TPoint;
end;
TMessageEvent = procedure (var Ms.g: TMsg;
var Handled: Boolean) of object-property OnMessage: TMessageEvent;
может запретить стандартную обработку сообщения. Для этого ему передается параметр Handled, в который следует установить True, если дальнейшая обработка сообщения не нужна.
В переменных типа TMsg ядро Windows передает программе так называемые сообщения - небольшие пакеты данных, оповещающие программу о наступлении того или иного события, будь то нажатие на клавишу, перемещение мыши или наступление нужного момента времени. Три параметра этого пакета используются следующим образом: Message - код события, wParam и lParam - уточняющие параметры. Для сообщения о нажатии клавиши код Message определен константой wm_KeyDown (256) или (при отпускании клавиши) wm_KeyUp (257), параметр wParam содержит виртуальный код нажатой клавиши, а IParam - дополнительные параметры, такие как количество нажатий клавиши с момента последнего обращения к функции перехвата, признак нажатой и удерживаемой Shift-клавиши и т. п.
Вот как, например, можно использовать клавиши курсора для смещения изображения (квадрата) в компоненте PaintBox:
type
TFormI = class (TForm)
PaintBoxl: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBoxIPaint(Sender: TObject);
private
{ Private declarations }
public .
{ Public declarations }
X, Y: Integer- procedure Hook(var Msg: TMsg; var Handled: Boolean);
end;
procedure TFormI.FormCreate(Sender: TObject);
{Регистрируем обработчик OnMessage в момент создания главного окна программы и устанавливаем начальное положение квадрата} begin
Application.OnMessage := Hook;
X := 100;
end;
procedure TFormI.Hook(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message<>wm_keyDown then //Сообщение от клавиатуры?
Exit; //Нет case Msg.wParam of
vk_Left: dec(X,10); //Смещение влево
vk_Right: inc(X,10); //Смещение вправо
vk Up: dec(Y,10); //Смещение вверх
vk_Down: inc(Y,10); //Смещение вниз end;
Paintboxl.Repaint;
Handled := True; //Блокируем дальнейшую обработку end;
procedure TFormI.PaintBoxIPaint(Sender: TObject);
(Вычерчиваем квадрат со стороной 20 пикселей и центром в точке X, Y} begin
with PaintBoxl.Canvas do
Rectangle(X-10,Y-10,X+10,Y+10)
end;
Примечание
В Delphi 5 и 6 специальный компонент TApplicationEvents, который существенно упрощает обработку любых сообщений Windows до торр, как они поступят в оконную функцию активной
Для клавиш определены следующие виртуальные коды:
Код
|
Значение
|
Клавиша
|
Код
|
Значение
|
Клавиша
|
vk Back
|
8
|
Backspace
|
vk A..vk Z
|
65..90
|
A. .Z
|
vk Tab
|
9
|
Tab
|
vk LWin
|
91
|
Левая Windows
|
vk Clear
|
12
|
[5]
|
vk RWin
|
92
|
Правая Windows
|
vk Return
|
13
|
Enter
|
vk NumpadO.. vk Numpad9
|
96..105
|
[О]..[9]
|
vk Shift
|
16
|
Shift
|
vk Multiply
|
106
|
[*]
|
vk Control
|
17
|
Ctti
|
vk Add
|
107
|
[+]
|
vk Menu
|
18
|
Alt
|
vk Subtract
|
109
|
[-]
|
vk Pause
|
19
|
Pause
|
vk Decimal
|
110
|
[Del]
|
vk Capital
|
20
|
Caps Lock
|
vk Divide
|
111
|
[/]
|
vk Escape
|
27
|
esc
|
vkFl..vkF12
|
112..123
|
Fl..F12
|
vk Space
|
32
|
Пробел
|
vk Numlock
|
144
|
Num Lock
|
vk Prior
|
33
|
Page Up
|
vk Scroll
|
145
|
Scroll Lock
|
vk Next
|
34
|
Page Down
|
|
186
|
|
vk End
|
35
|
End
|
|
187
|
+
|
vk Home
|
36
|
Home
|
|
188
|
<
|
vk Left
|
37
|
Курсор влево
|
|
189
|
-
|
vk Up
|
38
|
Курсор вверх
|
|
190
|
>
|
vk Right
|
39
|
Курсор вправо
|
|
191
|
•?
|
vk Down
|
40
|
Курсор вниз
|
|
192
|
~
|
vk Insert
|
45
|
Insert
|
|
219
|
[
|
vk Delete
|
46
|
Delete
|
|
220
|
\
|
vk 0..vk 9
|
48..57
|
0..9
|
|
221
|
]
|
Примечание
В квадратных скобках указаны клавиши из зоны дополнительных цифровых клавиш.
Учтите, что константы vk_A.. .vk_z и vk_0.. .vk_9 не определены в файле source | rtl | win | windows . pas и следовательно в модуле System, поэтому для них компилятор выдаст сообщение о неизвестном идентификаторе - в этом случае используйте собственные определения констант или их числовые эквиваленты. Замечу также, что с помощью анализа параметра мзд. lParam в обработчике OnMes-заде можно отличить нажатие левых клавиш Alt, Ctrl, Shift от нажатия одноименных правых и нажатие Enter в основной клавиатуре от нажатия Enter в дополнительной.
назад - Вперёд
|