Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];




Вниз

HotKey 


bloodman   (2003-06-08 01:05) [0]

Есть ли компонент , который может перехватывать нажатие клавиши Win
Стандартный компонент Hotkey ее , почему-то , не перехватывает.Компонент от JEDI тоже.



bloodman   (2003-06-08 02:38) [1]

Ну или как перехватить нажатие этой клавиши.RegisterHotKey не в счет.А в событии OnKeyDown компонента,у свойства Shift: TShiftState
нету значения для клавиши Win.
МАСТЕРА! ПОМОГИТЕ PLEASE!



Armen   (2003-06-08 14:38) [2]

Компонентки конечно не найдешь, т.к. это делается по другому.

создаешь dll.
в dll-е:

uses
Windows,
Messages;

var
HookHandle: hHook = 0;

{$R *.res}

function HookProc(Code: integer; wParam: Word; lParam: Longint): Longint; stdcall;
var
PMsg: ^TMsg;
i: integer;
begin
result:= 0;
If Code = HC_ACTION then
begin
PMsg:= Pointer(lParam);
// Disable Hot Keys
if (PMsg^.message = WM_HOTKEY) then
begin
// Disable Win
if (Loword(PMsg^.lParam) = MOD_WIN) then
begin
PMsg^.message:= WM_NULL;
exit;
end;
end;
end else CallNextHookEx(HookHandle, Code, wParam , lParam);
end;

procedure StopHook; export; stdcall;
begin
if HookHandle<>0 then
begin
UnhookWindowsHookEx(HookHandle) ;
HookHandle:= 0;
end;
end;

procedure StartHook; export; stdcall;
begin
LoadConfig;
HookHandle := SetWindowsHookEx(WH_GETMESSAGE, @HookProc , HInstance , 0 ) ;
if HookHandle = 0 then
MessageBox(0, "Unable to set hook!", "Error", mb_Ok)
end;

exports StartHook name "StartHook",
StopHook name "StopHook";

begin
end.

В программе:

procedure StartHook; external "KeyLocker.dll";
procedure StopHook; external "KeyLocker.dll";

procedure TForm1.FormCreate(Sender: TObject);
begin
StartHook;
end;

procedure TForm1.FormDestroy(Sender: TObject)
begin
StopHook;
end;

(Не успел проверить но должен работать)



Armen   (2003-06-08 14:45) [3]

LoadConfig; - эту строчку конечно убери

Это я скопировал с другой программы. По заказу одного Интернет Кафе я когда то писал прогу полного контролья клавиатуры, это оттуда.



bloodman   (2003-06-08 15:55) [4]

>Armen Закод большое спасибо.Но это не то , что нужно.Врятли для такой простой операции надо в память загружать отдельную dll и ловить сообщение WM_HOTKEY.Но с кодом поработаю может че нить и получится.

НО Мне не нужно блокировать кнопка , опишу точнее:
Есть компонент ( TEdit) , когда он находится в фокусе,то когда пользователь нажимает комбинацию клавишь (например Ctrl+Win+R) , то в нем должно появиться соответственно Ctrl-Win-R.Есть подобные компоненты, но они не перехватывают нажатие клавиши Win а в данном случае там бы появилось Ctrl-R .



theodor_iv   (2003-06-08 16:35) [5]

Нет необходимости все это писать в dll, все это можно написать прямо в программе. Также нет необходимости перехватывать ВСЕ СООБЩЕНИЯ системы при помощи WH_GETMESSAGE, когда нужна только клавиатура. Нужно использовать WH_KEYBOARD.


var
Hook: HHook;

function KeyboardHook(Code: Integer; VirtualKeyCode: WParam; Info: LParam): Integer; stdcall;
var
KbdState: TKeyboardState;
Modifiers: byte;
begin
if Code < 0
then Result := CallNextHookEx(Hook, Code, VirtualKeyCode, Info)
else begin
if VirtualKeyCode in [$10, $11, $12, $5B, $5C] // modifier
then begin
GetKeyboardState(KbdState);
Modifiers :=
(((KbdState[VK_LWIN] and $80) or (KbdState[VK_RWIN] and $80)) shr 4) or
((KbdState[VK_SHIFT] and $80) shr 5) or
((KbdState[VK_CONTROL] and $80) shr 6) or
((KbdState[VK_MENU] and $80) shr 7);
FrmHKEdit.Caption := IntToHex(Modifiers, 2);
end
else begin
if (Info and $80000000 <> 0) and Assigned(
then begin
FrmHKEdit.Caption := IntToHex(VirtualKeyCode, 2);
end;
end;
Result := 1;
end;
end;

procedure TFrmHKEdit.FormShow(Sender: TObject);
begin
Hook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHook, 0, GetCurrentThreadId);
end;

procedure TFrmHKEdit.FormHide(Sender: TObject);
begin
UnhookWindowsHookEx(Hook);
end;


Можно еще в обработчике события TEdit.OnKeyDown/OnKeyUp использовать функцию GetKeyboardState



Armen   (2003-06-08 17:20) [6]

>theodor_iv ©
> Нет необходимости все это писать в dll

Если писать это в программе, то ты будешь ловить только те сообщения, которые адресованы программе, а не System Wide.!!!!!

А System Wide Hook получится только с dll.

>Нужно использовать WH_KEYBOARD.
Насчет этого ты прав. Этот кусок я скопировал с другой прграммы, там надо было WH_GETMESSAGE.



theodor_iv   (2003-06-08 17:41) [7]

2 Armen: Разумеется, а ему и нужны сообщения адресованые программе, а совсем не system wide. Ему нужен компонент типа THotKey, только чтобы еще и клавишу Win понимал.



Armen   (2003-06-08 17:50) [8]

> theodor_iv ©

Согласен.
Тогда Hook вообще не нужен, хватит и KeyDown.



Pattern   (2003-06-08 19:21) [9]

В OnKeyDown впиши
if ((ssCtrl in Shift) and (Key = 91) and (Key = ord("S")) then ...



bloodman   (2003-06-08 22:25) [10]

> Pattern © (08.06.03 19:21)
И что это будет? Это какие клавиши нажаты Ctrl+Shift+Win+S ???

>Armen (08.06.03 17:50)
Нет , KeyDown не хватит- там нету клавиши Win

>theodor_iv © (08.06.03 17:41)
ТЫ правльно меня понял . Именно компонент типа hotkey



Armen   (2003-06-08 22:46) [11]

Вы хотите сказать что WM_KEYDOWN не ловит MOD_WIN??????

В TForm1- private пишем:
procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;

в implementation:
procedure TForm1.WMKeyDown(var Message: TWMKeyDown);
begin
ShowMessage("");
inherited;
end;

запускаем, нажимаем на win i ???????
Поймали?????
Все проще чем мы думаем.



bloodman   (2003-06-09 14:59) [12]

>Armen
Я Думал,что вы имеете в виду событие OnKeyDown.
А как в сообщении WMKeyDown Определить какие клавиши зажаты?



Pattern   (2003-06-09 15:46) [13]


> bloodman © (08.06.03 22:25)

Пардон, глюк это будет, не продумал сразу... А вообще (ssCtrl is Shift) - это нажатая клавиша Ctrl (работает в OnKeyDown и в OnKeyUp), а 91(dec), она же $5B(hex) - это код клавиши Win.
Есть один такой забавный примерчик, с помощью которого твоя программа будет отлавливать нажатые клавиши:
Ставишь на форму Timer и делаешь ему интервал 100 (для более частого отлавливания можешь сделать время и меньше. В обработчике события OnTimer пишешь:
if GetAsyncKeyState(13) <> 0 then ShowMessage("Нажата Enter");
Думаю не стоит объяснять, что 13 - код клавиши Enter (она же Return, она же $0D(hex)). Думаю, тебе хватит этих дрожжей для брожения, ы?



bloodman   (2003-06-09 16:12) [14]

Засеч нажатие клавиши вин я могу, но мне -то нужно другое - засеч КОМБИНАЦИЮ клавиш в которой она участвует т.е. Ctrl+WIN+R А если я буду успользовать твой метод , то я засеку Ctrl+Win, а затем R НО не вместе.



Pattern   (2003-06-09 16:51) [15]

Ологическом "И" когда нить слышал? Чего не понятного то?
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if ((GetAsyncKeyState(17) <> 0)
and (GetAsyncKeyState(91) <> 0)
and (GetAsyncKeyState(ord("R")) <> 0))
then Label1.Caption := "Ctrl-Win-R";
end;



theodor_iv   (2003-06-09 17:34) [16]

Клавиша Win прекрасно перехватывается в OnKeyDown. Чтобы определить нажата она или нет, можно использовать функцию GetKeyboardState. Пример см. в theodor_iv © (08.06.03 16:35) Там можно даже левую и правую Win различать!



bloodman   (2003-06-09 21:19) [17]

ДА,Я думаю твой вариант лучше , т.к. если я бы использовал вариант
Pattern © (09.06.03 16:51) ,то мне бы пришлось описывать 1274 ситуации :)
Только плиз объясни КАК точно это сделать как в примере Pattern © (09.06.03 16:51).Т.к. Я пока никак не могу понять все эти or and .(в данном случае).




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.76 MB
Время: 0.049 c
4-84849           Xeon                  2003-04-27 08:26  2003.06.26  
Запуск просторонних приложений.


1-84166           Muskat                2003-06-11 13:54  2003.06.26  
pchar


1-84110           mao                   2003-06-10 17:06  2003.06.26  
Помогите свернуть форму


1-84123           Переяслов Григорий    2003-06-08 14:24  2003.06.26  
FolderDialog


6-84477           Em(022000)            2003-04-21 04:14  2003.06.26  
Как установить соединение с провайдером?