![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как отследить двойное нажатие клавиши Shift [D6, WinXP]
leonidus © (2005-06-27 08:26:00)Мастера подскажите плиз, мне нужно отследить двойное нажатие клавищи Shift в любом приложении. Причем тут должно быть именно двойное нажатие а не просто долговременное удержание.
Я делаю так, по таймеру:
if HiWord(GetKeyState(VK_SHIFT)) <> 0 then
begin
Timer_Profile_Detector.Tag:=Timer_Profile_Detector.Tag+1;
if Timer_Profile_Detector.tag=2 then
begin
DoSomething;
end;
end
else Timer_Profile_Detector.Tag:=0;
Смысл тут в том, что если два тика подрят программа засекла нажатый Shift значит типа двойное нажатие. На самом деле это не так, достаточно просто подержать Shift что бы запустилась процедура DoSomething, а как перехватить именно Shift+Shift ?
alpet (2005-06-27 14:43:00) [1]Дык вот - для любого приложения (возможности теже):
function PressedKey (var shift: boolean): Boolean;
var n: dword;
begin
result := false;
shift := false;
for n := 8 to 255 do
if (GetAsyncKeyState (n) and $F000 <> 0) then
begin
// key := n;
result := true;
shift := (n = VK_SHIFT) or
(n = VK_LSHIFT) or
(n = VK_RSHIFT);
if not shift then exit; // other key detected!
end
end; // PressedKey
procedure TForm1.Timer1Timer(Sender: TObject);
var p, s: Boolean;
k: Byte;
begin
{ Timer.Interval = 10 default
Flag declared in TForm1.private as Boolean
nShift declared in TForm1.private as Dword
timeOut declared on TForm1.private as Dword
}
p := PressedKey (s); // retrieve press key
if not p and flag then
begin
inc (nShift, 1); // one shift pressed
timeOut := 50; // startup delay
end;
flag := s;
if p xor s then nShift := 0; // some other key pressed
if timeOut <> 0 then
begin
dec (timeOut);
if timeOut = 0 then nShift := 0;
end;
if (nShift > 1) then
begin
nShift := 0;
ShowMessage ('Two shift pressed!');
end;
end;
default (2005-06-27 14:39:00) [2]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if GetAsyncKeyState(VK_SHIFT) and $8000 <> 0 then begin
if not Odd(Timer1.Tag) then Timer1.Tag := Timer1.Tag + 1;
end else begin
if Odd(Timer1.Tag) then begin
Timer1.Tag := Timer1.Tag + 1;
if Timer1.Tag = 4 then begin
Caption := IntToStr(Random(1000));
Timer1.Tag := 0
end;
end;
end;
end;
нужно GetAsyncKeyState для "отследить двойное нажатие клавищи Shift в любом приложении"
default (2005-06-27 14:03:00) [3]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if GetKeyState(VK_SHIFT) and $8000 <> 0 then begin
if Timer1.Tag mod 2 = 0 then Timer1.Tag := Timer1.Tag + 1;
end else begin
if Timer1.Tag mod 2 <> 0 then begin
Timer1.Tag := Timer1.Tag + 1;
if Timer1.Tag = 4 then begin
Caption := IntToStr(Random(1000));
Timer1.Tag := 0
end;
end;
end;
end;
P.S. чуть лучше
alpet (2005-06-27 14:02:00) [4]Более сложный код. Проверяется, что не нажимались другие клавиши, и что Shift нажимается монопольно (т.е. без других клавиш).
function PressedKey (var key: Byte; var shift: boolean): Boolean;
var ks: TKeyboardState;
n: dword;
begin
result := false;
GetKeyboardState (ks);
shift := false;
for n := 8 to 255 do
if (ks [n] and $80 <> 0) then
begin
key := n;
result := true;
shift := (n = VK_SHIFT) or
(n = VK_LSHIFT) or
(n = VK_RSHIFT);
if not shift then exit; // other key detected!
end
end; // PressedKey
procedure TForm1.Timer1Timer(Sender: TObject);
var p, s: Boolean;
k: Byte;
begin
{ Timer.Interval = 10 default
Flag declared in TForm1.private as Boolean
nShift declared in TForm1.private as Dword
timeOut declared on TForm1.private as Dword
}
p := PressedKey (k, s); // retrieve press key
if not p and flag then
begin
inc (nShift, 1); // one shift pressed
timeOut := 50; // startup delay
end;
flag := s;
if p xor s then nShift := 0; // some other key pressed
if timeOut <> 0 then
begin
dec (timeOut);
if timeOut = 0 then nShift := 0;
end;
if (nShift > 1) then
begin
nShift := 0;
ShowMessage ('Two shift pressed!');
end;
end;
default (2005-06-27 13:43:00) [5]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if GetKeyState(VK_SHIFT) and $8000 <> 0 then begin
if Timer1.Tag mod 2 = 0 then Timer1.Tag := Timer1.Tag + 1;
end else begin
if Timer1.Tag mod 2 <> 0 then Timer1.Tag := Timer1.Tag + 1;
if Timer1.Tag = 4 then begin
Caption := IntToStr(Random(1000));
Timer1.Tag := 0
end;
end;
end;
вот с использованием одной переменной...
Digitman (2005-06-27 13:10:00) [6]OnKeyDown + OnKeyUp + таймер
default (2005-06-27 13:06:00) [7]leonidus © (27.06.05 13:02) [3]
"если нужно просто отследить последовательное нажатие двух любых шифтов, то см. хелп по GetKeyState, из неё можно узнавать нажата или отпущена клавиша"
неужели сам не сообразишь...
leonidus (2005-06-27 13:02:00) [8]Речь идет именно о двух подряд нажатых Shift`ах не важно левых или правых.
default (2005-06-27 09:22:00) [9]GetKeyState имеет результатом значение типа SmallInt-это два байта
о каком HiWord может быть речь
default (2005-06-27 09:21:00) [10]что значит Shift+Shift?
если это нажатие левого и правого шифта, то к сожалению не NT винда не реагирует на VK_LSHIFT, VK_RSHIFT константы в GetKeyState
если нужно просто отследить последовательное нажатие двух любых шифтов, то см. хелп по GetKeyState, из неё можно узнавать нажата или отпущена клавиша