Помощь - Поиск - Пользователи - Календарь
Полная версия: Нормальная ловушка для клавиш...
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
Dim
Лююди, человеки, подскажите плиз ламеру:

Событием TForm.FormKeyDown(трям-пам-пам...) я получаю Key:Word... далее я его могу преобразовать chr()'ом или FloatToStr()'ом... в первом случае получается белеберда для системных клавиш(шифт, котрл итд), во втором я получаю вроде нормальный byte код клавиши... но мне нужно получить еще и буквенное обозначение. Тоесть, нажал 'Ctrl' --> получил что-то типа 'Key_Ctrl' или 'ssCtrl', 'Enter' --> 'Key_Enter', 'Z' --> 'Key_Z' итд..Я пытался сам разобраться и понял, что для этого нужно использовать юнит Qt! Но как это сделать??? Или может есть какой другой способ получить одновременно и буквенное и символьное обозначение клавиш, нажатых на клавиатуре?

Для чего это нужно: в программе юзер должен иметь возможность забиндить любую клавишу для определенного действия! Для этого он нажимает кнопку на форме, появляется stayontop окошко, которое реагирует на нажатие кнопок клавиатуры. Когда пользователь нажал кнопку - ее код пишеться в реестр, а символьное обозначение (например LeftCtrl) выводится на форме в label... Вот blink.gif

Огромное спасибо!
volvo
Dim, давай не будем изобретать велосипед:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
{ проверяем на совместное с Ctrl нажатие }
if (ssCtrl in Shift) and (key <> VK_CONTROL) then
Label1.Caption := ' Key: '+'( '+'Ctrl + '+Chr(Key)+' )'

{ иначе - проверяем на Alt + что-то }
else
if (ssAlt in Shift) and (key <> VK_MENU) then
Label1.Caption := ' Key: '+'( '+'Alt + '+Chr(Key)+' )'
else {значит просто нажатие на клавишу }

{ вначале проверяй на Enter, Tab и Escape, ну а потом - }
Label1.Caption := ' Key: ' + Chr(Key);
end;

Чем такое решение не устраивает?

Цитата
Когда пользователь нажал кнопку - ее код пишеться в реестр
А вот тут - поподробнее: какой именно код? Ты это уже придумал, или еще нет? "Alt + X" и "Ctrl + X" будут какими кодами представлены? Код "X" один и тот же... Придется писать в реестр не Word, а DWord и к нему еще присоединять состояние Alt и Ctrl ...
Dim
Спасибо огромное за ответ! По-порядку:
Цитата(volvo @ 5.08.05 17:11)
Dim, давай не будем изобретать велосипед:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  { проверяем на совместное с Ctrl нажатие }
  if (ssCtrl in Shift) and (key <> VK_CONTROL) then
    Label1.Caption := '  Key: '+'( '+'Ctrl + '+Chr(Key)+' )'

  { иначе - проверяем на Alt + что-то }
  else
    if (ssAlt in Shift) and (key <> VK_MENU) then
      Label1.Caption := '  Key: '+'( '+'Alt + '+Chr(Key)+' )'
    else {значит просто нажатие на клавишу }

      { вначале проверяй на Enter, Tab и Escape, ну а потом -  }
      Label1.Caption := '  Key: ' + Chr(Key);
end;

Чем такое решение не устраивает?
Да как сказать, боюсь без велосипеда или на крайняк самоката тут не обойтись((((
Дело в том, что мне нужно отловить не комбинацию а одну клавишу (Ctrl, Alt, Shift, Tab, F1..F12, Enter, цифровые и буквенные кнопы, BackSpace итд)... Поэтому проверка на совместное нажатие не нужна! Искал в базах ДРКБ, Королевстве Делфи и DelphiWorld - видел подобные примеры, но это немного не то! Можно конечно написать для буквенных клавиш обработку chr()'ом, а для остальных зафигачить огромный кейс по word коду, но как-то совсем по-ламерски это((( Если более элегантного решения не найдется - сделаю так...
Цитата(volvo @ 5.08.05 17:11)
А вот тут - поподробнее: какой именно код? Ты это уже придумал, или еще нет? "Alt + X" и "Ctrl + X" будут какими кодами представлены? Код "X" один и тот же... Придется писать в реестр не Word, а DWord и к нему еще присоединять состояние Alt и Ctrl ...
Тут все просто. Хочу сделать так примерно так:
Код

Key: Word;
...
RegFile.WriteInteger('Options', 'HotKeyCode', FloatToStr(Key));
...

А потом считала прога с реестра ключик и по табличке вывела его буквенное знчение...

Не знаю насколько внятно разьяснил чего я хочу но старался :p2:
Еще раз спасибо!
Dim
И еще вопрос до кучи:
Сделал деинсталлятор программы, который удаляет ее модули и должен удалять все ее записи в реестре. И все бы хорошо, но не получается удалить корневую секцию программы в реестре HKEY_CURRENT_USER\Software\MyProgram huh.gif Делал вот так:
Код

Создаю
...
proc TfrmSetup.FormShow...
RegFile:=TRegIniFile.Create('Software\MyProgram');
...
Удаляю
...
proc TfrmSetup.UninstallClick...
begin
RegFile.EraseSection('Software\MyProgram');
...
Все вроде правильно, но таким способом я могу удалить только вложенные секции в основную! А как удалить главную секцию проги MyProgram?!
Dim
Есть тут кто живой? smile.gif
Вобщем второй вопрос снимается - сам разобрался.
Оказалось все дело в том, что забыл слеш влепить перед именем! Сижу, думаю что с делфей и с миром происходит а тут :D

ЗЫ: А по ловушке для клавы буду признателен за подсказку!
hiv
Так чем тебе переменная Key не подходит?
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key>0 then ShowMessage('Key: '+Char(Lo(Key))+' ('+IntToStr(Key)+')')
end;
Malice
Цитата(hiv @ 12.08.05 13:39)
Так чем тебе переменная Key не подходит?

Человек хочет получить названия клавиш (Ctrl, F1 и т.д.)

Dim, делай case, подругому никак. Не так их уж и много, F-ки одной строкой можно свернуть.
hiv
Если ему нужны соответствие кодов кнопкам, то пусть полезет в папку Delphi\Source\Rtl. Там есть исходник windows.pas и в нем все константы виртуальных кнопок определены:
Код
........
 { Virtual Keys, Standard Set }
 {$EXTERNALSYM VK_LBUTTON}
 VK_LBUTTON = 1;
 {$EXTERNALSYM VK_RBUTTON}
 VK_RBUTTON = 2;
 {$EXTERNALSYM VK_CANCEL}
 VK_CANCEL = 3;
 {$EXTERNALSYM VK_MBUTTON}
 VK_MBUTTON = 4;  { NOT contiguous with L & RBUTTON }
 {$EXTERNALSYM VK_BACK}
 VK_BACK = 8;
 {$EXTERNALSYM VK_TAB}
 VK_TAB = 9;
 {$EXTERNALSYM VK_CLEAR}
 VK_CLEAR = 12;
 {$EXTERNALSYM VK_RETURN}
 VK_RETURN = 13;
 {$EXTERNALSYM VK_SHIFT}
 VK_SHIFT = $10;
 {$EXTERNALSYM VK_CONTROL}
 VK_CONTROL = 17;
 {$EXTERNALSYM VK_MENU}
 VK_MENU = 18;
 {$EXTERNALSYM VK_PAUSE}
 VK_PAUSE = 19;
.........

Хау. Я все сказал...
Malice
Цитата(hiv @ 12.08.05 15:17)
Хау. Я все сказал...


Ма-ла-дец! :D а где соответствия кодов названиям ?

так надо:
case key of
vk_tab: s:='TAB';
112..123: s:='F'+floattostr(key-111);
.......
else s:=floattostr(key);
hiv
Цитата(Malice @ 12.08.05 16:39)
а где соответствия кодов названиям ?

В хелпе: Virtual key codes
Malice
Цитата(hiv @ 15.08.05 8:23)
В хелпе: Virtual key codes

Так, шутки шутками, но вот что надо автору:
Цитата(dim)
Тоесть, нажал 'Ctrl' --> получил что-то типа 'Key_Ctrl' или 'ssCtrl', 'Enter' --> 'Key_Enter'
....
Когда пользователь нажал кнопку - ее код пишеться в реестр, а символьное обозначение (например LeftCtrl) выводится на форме в label... Вот


Приведи пример, как ты это сделаешь и покончим с этим smile.gif
Dim
Цитата(Malice @ 15.08.05 12:48)
Так, шутки шутками, но вот что надо автору:
Приведи пример, как ты это сделаешь и покончим с этим smile.gif
Покончим с этим! :D
Вот как это сделал я (может кому понадобится чтоб кучу кода не набирать!):
function ConvertKey(CKey: Word): String;
var
i: Byte;
begin
case CKey of
48..57 : Result := chr(CKey); {0..9}
65..90 : Result := chr(CKey); {A..Z}
186 : Result := '; :';
187 : Result := '= +';
188 : Result := ', <';
189 : Result := '- _';
190 : Result := '. >';
191 : Result := '/ ?';
192 : Result := '` ~';
219 : Result := '[ {';
220 : Result := '\ |';
221 : Result := '] }';
222 : Result := ''''+' "';
96..105 : for i := 0 to 9 do if CKey = 96+i then Result := 'Num ' + IntToStr(i); {Num 0..Num 9}
106 : Result := 'Num *';
107 : Result := 'Num +';
109 : Result := 'Num -';
110 : Result := 'Num .';
111 : Result := 'Num /';
112..123 : for i := 1 to 12 do if CKey = 111+i then Result := 'F' + IntToStr(i); {F1..F12}
VK_SPACE : Result := 'Space';
VK_BACK : Result := 'BackSpace';
VK_TAB : Result := 'Tab';
VK_RETURN : Result := 'Enter';
VK_SHIFT : Result := 'Shift';
VK_CONTROL : Result := 'Ctrl';
VK_MENU : Result := 'Alt';
VK_INSERT : Result := 'Insert';
VK_PRIOR : Result := 'PageUp';
VK_Next : Result := 'PageDown';
VK_End : Result := 'End';
VK_HOME : Result := 'Home';
VK_LEFT : Result := 'Left';
VK_UP : Result := 'Up';
VK_RIGHT : Result := 'Right';
VK_DOWN : Result := 'Down';
VK_DELETE : Result := 'Delete';
VK_PAUSE : Result := 'Pause';
VK_CAPITAL : Result := 'CapsLock';
VK_SCROLL : Result := 'ScrollLock';
VK_NUMLOCK : Result := 'NumLock';
VK_ESCAPE : Result := 'Esc';
end;
end;
Не хотелось так писать, как-то по-ламеряцки совсем, но я ж ламер! Мне можно :D

ЗЫ: думал вопрос мой утонул уже давно, а тут... Молодцы ребята! smile.gif
Dim
Цитата(Malice @ 12.08.05 15:39)
так надо:
case key of
vk_tab: s:='TAB';
112..123: s:='F'+floattostr(key-111);
.......
else s:=floattostr(key);

Отэта я лоханулся! Можно было и без фора обойтись! :molitva:
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.