Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > RegisterHotKey


Автор: _8989 14.11.2003, 21:01
Здравствуйте!

Помогите зарегистрировать комбинацию клавишь или одну горячую клавишу.

Программа записывает в реестр комбинацию клавишь или одну горячую клавишу (в зависимости от выбора юзера) в виде DWORD-параметра. Позже считывает и заносит в переменную wHotKey (word). Вопрос, как теперь зарегистрировать с помощью функции RegisterHotKey комбинацию клавишь или одну горячую клавишу? Я думал MAKEWORD мне поможет, но не вышло:

Код
RegisterHotKey(0, ID_HOTKEY, MAKEWORD(0, wHotKey), MAKEWORD(wHotKey, 0));


Помогите!!!

Автор: Gloomy 14.11.2003, 22:28
Я писал небольшую статейку http://ipb.ovl.ru/forum/topic242.html.
З.Ы. Это не реклама! Просто не хочу переписывать одно и то же еще раз.

Автор: _8989 15.11.2003, 09:00
Статью прочитал. Это всё понятно, но вопрос-то в другом...

Автор: <Spawn> 15.11.2003, 09:47
_8989 Вот тебе примерчик:

Код
 scShiftA:= TextToShortCut('Shift+A');
 dwAtom:= GlobalAddAtom(PAnsiChar('MyHotKey'));
 RegisterHotKey(Handle, dwAtom, MOD_SHIFT, WordRec(scShiftA).Lo);


Видимо ты не то значение передавал в 3-ий параметр функции - MAKEWORD(0, wHotKey)

Автор: _8989 15.11.2003, 11:34
Последний параметр (WordRec(scShiftA).Lo) распознаеться легко, а нужно распознать и первый (MOD_SHIFT). А в твоем примере прямо подставляеться первый параметр. А если пользователь ввёл не SHIFT, а SHIFT+ALT? Мне нужно распознать оба параметра!

Автор: <Spawn> 15.11.2003, 13:15
Тогда можешь поступить одним из следующих способов:

Код
 Modifiers:=0;
 case scMyHotKey shr 11 of
   MOD_SHIFT: Modifiers:= MOD_SHIFT;
   MOD_ALT: Modifiers:= MOD_ALT;
   MOD_CONTROL: Modifiers:= MOD_CONTROL;
  end;
 RegisterHotKey(Handle, dwAtom, Modifiers, WordRec(scMyHotKey).Lo);


или

Код
if (scMyHotKey and scShift) <> 0 then
    Modifiers:= MOD_SHIFT
  else
  if (scMyHotKey and scAlt) <> 0 then
    Modifiers:= MOD_ALT
  else
  if (scMyHotKey and scCtrl ) <> 0 then
    Modifiers:= MOD_CONTROL;
 RegisterHotKey(Handle, dwAtom, Modifiers, WordRec(scMyHotKey).Lo);

Автор: <Spawn> 15.11.2003, 13:17
Если же ты будешь использовать комбинации типа Shift + Ctrl, то маленько переделать этот код нужно будет, например так:

Код
  if (scMyHotKey and scShift) <> 0 then
    Modifiers:=Modifiers or MOD_SHIFT;
  if (scMyHotKey and scAlt) <> 0 then
    Modifiers:=Modifiers or MOD_ALT;
  if (scMyHotKey and scCtrl ) <> 0 then
    Modifiers:=Modifiers or MOD_CONTROL;


А потом в WM_HOTKEY сравнивать с этим Modifier:
Код

...
if (Msg.LParamLo = Modifiers)  and ....
...

Автор: _8989 15.11.2003, 13:29
Дело в том, что не я буду устанавливать комбинацию клавишь, а пользователь. А что он поставит - не знает и Бог.

Автор: <Spawn> 15.11.2003, 13:44
_8989 ну я же показал тебе как нужна сделать. Вот более полный пример:

Код
var
 Form1: TForm1;
 dwAtom:DWORD = 0;
 Modifiers:Cardinal = 0;
implementation

{$R *.dfm}

procedure TForm1.HotKey(var Msg:TMessage);
begin
if (Msg.LParamHi = WordRec(hkUserKey.HotKey).Lo)and
  (Msg.LParamLo = Modifiers) then
    Showmessage('Hot key pressed');
end;

procedure TForm1.Button1Click(Sender: TObject);

begin
if dwAtom = 0 then
begin
 dwAtom:= GlobalAddAtom(PAnsiChar('MyHotKey'));
 Modifiers:=0;

 if (hkUserKey.HotKey and scShift) <> 0 then
   Modifiers:=Modifiers or MOD_SHIFT;
 if (hkUserKey.HotKey and scAlt) <> 0 then
   Modifiers:=Modifiers or MOD_ALT;
 if (hkUserKey.HotKey and scCtrl ) <> 0 then
   Modifiers:=Modifiers or MOD_CONTROL;

 RegisterHotKey(Handle, dwAtom, Modifiers, WordRec(hkUserKey.HotKey).Lo);
end
else ShowMessage('Hotkey already registred');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 dwAtom:= 0;
 GlobalDeleteAtom(dwAtom);
 UnRegisterHotKey(Handle, dwAtom);
end;


Клик на Button1 решистрирут новый Хоткей, клик на Button2 делает обратное действие. HotKey вводится в hkUserKey(компонент THotKey)

Автор: Vex 15.11.2003, 14:12
8989, я писал для себя подобную программку для открывагния папок по горячим клавишам, если хочешь, я тебе дам исходники. У меня там правда сочетания запоминаются в текстовый файл. И код написан коряво. smile.gif

Автор: _8989 17.11.2003, 15:04
Код
var
wHotKey: Word
begin
//Считываю значение из компонента msctls_hotkey32 (ID - 303)
wHotKey := SendMessage(GetDlgItem(hwnd, 303), HKM_GETHOTKEY, 0, 0);

if (wHotKey and scShift) <> 0 then Modifiers := Modifiers or MOD_SHIFT;
if (wHotKey and scAlt) <> 0 then Modifiers := Modifiers or MOD_ALT;
if (wHotKey and scCtrl ) <> 0 then Modifiers := Modifiers or MOD_CONTROL;

//Пытаюсь зарегистрировать
RegisterHotKey(0, ID_HOTKEY1, Modifiers, WordRec(wHotKey).Lo);

//Вывожу результат
MessageBox(hwnd,PChar(ShortCutToText(Modifiers)),'',MB_OK);



Здесь WordRec(wHotKey).Lo считывается нормально, а Modifiers не распознаёться. Что не так?

P.S. Программа пишеться без использования VCL.

Автор: <Spawn> 17.11.2003, 15:22
_8989 Попробуй сделать Modifiers: = 0;

Автор: _8989 17.11.2003, 16:29
Бесполезно!

Автор: <Spawn> 17.11.2003, 16:35
Тогда, скорее всего, в wHotKey используются другие биты для идентификации нажатия Ctrl, Alt и т.д.

Автор: _8989 17.11.2003, 20:42
2Vex

Представь свой код здесь, пожалуйста.

Автор: Vex 17.11.2003, 21:14
Цитата
Представь свой код здесь, пожалуйста.


Я делал стандартно - через атомы. Только я не очень понял в чем тут проблема - зарегить ОДНУ клавишу или записать и прочитать все это с реестра?

Автор: <Spawn> 17.11.2003, 22:04
_8989 Ради интереса можно было справку посмотреть smile.gif . Открываем Windows SDK> вводим HKM_GETHOTKEY. Видим, что модификаторы указываются в старшем байте. И видим что эти модификаторы обозначены как HOTKEYF_ALT, HOTKEYF_CONTROL и т.д. Отсюда следует, что нужно подключить к своей проге CommCtrl или самому написать значения для этих констант и проделать ту же самую операцию для нахождения битов, установленных в 1.

Автор: _8989 18.11.2003, 18:08
Это бесполезно!

Автор: <Spawn> 19.11.2003, 06:31
_8989 Значит ты что то не то делаешь

Автор: _8989 19.11.2003, 15:06
2<Spawn>

Твой пример (Дата 15.11.2003, 13:44) работает, если использовать VCL. А если писать на чистом WIN32API, то не хочет.

Автор: <Spawn> 19.11.2003, 16:08
_8989 Дак тот пример проверяет наличие совсем других битов в переменной. Посмотри на это:

Код
 scShift = $2000;
 scCtrl = $4000;
 scAlt = $8000;
 scNone = 0;


и на это:

Код
 {$EXTERNALSYM HOTKEYF_SHIFT}
 HOTKEYF_SHIFT           = $01;
 {$EXTERNALSYM HOTKEYF_CONTROL}
 HOTKEYF_CONTROL         = $02;
 {$EXTERNALSYM HOTKEYF_ALT}
 HOTKEYF_ALT             = $04;
 {$EXTERNALSYM HOTKEYF_EXT}
 HOTKEYF_EXT             = $08;


Не правда ли они различаются?

Автор: _8989 19.11.2003, 16:57
Подставлял и такие HOTKEYF_SHIFT и т.д. Результата никакого.

Автор: <Spawn> 19.11.2003, 22:05
Значит не правильно подставлял

Автор: _8989 19.11.2003, 22:08
А как правильно?

Автор: <Spawn> 19.11.2003, 22:35
Не знаю, т.к. не видел твоего кода smile.gif

Автор: _8989 22.11.2003, 20:05
Я ж его уже представлял ранее...

Автор: _8989 25.11.2003, 10:53
Код

var
 wHotKey: word;
 Modifiers:Cardinal = 0;

wHotKey := SendMessage(GetDlgItem(hwnd, 303), HKM_GETHOTKEY, 0, 0);

 if (wHotKey and scShift) <> 0 then Modifiers:=Modifiers or HOTKEYF_SHIFT;
if (wHotKey and scAlt) <> 0 then Modifiers:=Modifiers or HOTKEYF_ALT;
if (wHotKey and scCtrl ) <> 0 then Modifiers:=Modifiers or HOTKEYF_CONTROL;

RegisterHotKey(0, ID_HOTKEY1, Modifiers, WordRec(wHotKey).Lo);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)