Personalmente me hice más cambios en el código.
Ahora código consgue llegar precionar la tecla de repetición y mantenga.
Hay distinción entre KeyDown y KeyUp
siguiente
Código Delphi
[-]
library HookTeclado;
uses
Messages,
Dialogs,
Windows;
{$R *.RES}
const
mapName: PChar = 'k9i:f$d8aR1';
KeyMsg: Integer = WM_USER+1627;
MseMsg: Integer = WM_USER+1628;
var
hKeyHook, hMseHook, hMemFile: THandle;
Hooked: Boolean = False;
pFHandle: PHandle = nil;
Acento1, Acento2, Dieresis, Angulo, ShiftDWN, AltDWN, AltGrDWN : Boolean;
KeyState1: TKeyBoardState;
procedure CloseMap;
begin
if pFHandle = nil then Exit;
UnmapViewOfFile(pFHandle);
CloseHandle(hMemFile);
pFHandle := nil;
end;
function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall;
var
AryChar : array[1..10] of AnsiChar; Count : Integer;
begin
Result := 0;
if Code = HC_NOREMOVE then Exit;
Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke);
if (Code < 0) or (Code <> HC_ACTION) or IsBadCodePtr(pFHandle) then Exit;
GetKeyboardState(KeyState1);
case (KeyStroke shr 16) of
42, 54 : ShiftDWN := True;
49194, 49206 : ShiftDWN := False;
8248, 12344 : AltDWN := True;
49208 : AltDWN := False;
end;
if AltDWN then exit;
if GetKeyState(VK_LMENU) = 1 then
AltGrDWN := True;
if ShiftDWN then
KeyState1[VK_SHIFT] := 128 else
KeyState1[VK_SHIFT] := 0;
if AltGrDWN then
KeyState1[VK_LMENU] := 128 else
KeyState1[VK_LMENU] := 0;
if not AltDWN then
KeyState1[VK_RMENU] := 0;
Count := ToAscii(VirtualKey, KeyStroke, KeyState1, @AryChar[1], 0);
ToAscii(VirtualKey, KeyStroke, KeyState1, @AryChar[1], 0);
case Count of
1 :
begin
if Acento1 then
begin
Acento1 := false;
case AryChar[1] of
' ' : AryChar[1] := '´';
'a' : AryChar[1] := 'á';
'e' : AryChar[1] := 'é';
'i' : AryChar[1] := 'í';
'o' : AryChar[1] := 'ó';
'u' : AryChar[1] := 'ú';
'A' : AryChar[1] := 'Á';
'E' : AryChar[1] := 'É';
'I' : AryChar[1] := 'Í';
'O' : AryChar[1] := 'Ó';
'U' : AryChar[1] := 'Ú';
end;
end;
if Acento2 then
begin
Acento2 := false;
case AryChar[1] of
' ' : AryChar[1] := '`';
'a' : AryChar[1] := 'à';
'e' : AryChar[1] := 'è';
'i' : AryChar[1] := 'ì';
'o' : AryChar[1] := 'ò';
'u' : AryChar[1] := 'ù';
'A' : AryChar[1] := 'À';
'E' : AryChar[1] := 'È';
'I' : AryChar[1] := 'Ì';
'O' : AryChar[1] := 'Ò';
'U' : AryChar[1] := 'Ù';
end;
end;
if Dieresis then
begin
Dieresis := False;
case AryChar[1] of
' ' : AryChar[1] := '¨';
'a' : AryChar[1] := 'ä';
'e' : AryChar[1] := 'ë';
'i' : AryChar[1] := 'ï';
'o' : AryChar[1] := 'ö';
'u' : AryChar[1] := 'ü';
'A' : AryChar[1] := 'Ä';
'E' : AryChar[1] := 'Ë';
'I' : AryChar[1] := 'Ï';
'O' : AryChar[1] := 'Ö';
'U' : AryChar[1] := 'Ü';
end;
end;
if Angulo then
begin
Angulo := false;
case AryChar[1] of
' ' : AryChar[1] := '^';
'a' : AryChar[1] := 'â';
'e' : AryChar[1] := 'ê';
'i' : AryChar[1] := 'ê';
'o' : AryChar[1] := 'î';
'u' : AryChar[1] := 'ô';
'A' : AryChar[1] := 'Â';
'E' : AryChar[1] := 'Ê';
'I' : AryChar[1] := 'Î';
'O' : AryChar[1] := 'Ô';
'U' : AryChar[1] := 'Û';
end;
end;
SendMessage(pFHandle^, KeyMsg, Ord(AryChar[1]), KeyStroke); end;
2 :
begin
case AryChar[1] of
'´' : Acento1 := true;
'`' : Acento2 := true;
'¨' : Dieresis := true;
'^' : Angulo := true; end;
end;
end;
end;
function MseHookFunc(Code, mMsg: Integer; var MouseRec: TMOUSEHOOKSTRUCT): Integer; stdcall;
var
Pos: Integer;
reVal: SmallInt;
begin
Result := 0;
if Code = HC_NOREMOVE then Exit;
Result := CallNextHookEx(0, Code, mMsg, Integer(@MouseRec));
if (Code < 0) or (Code <> HC_ACTION) or IsBadCodePtr(pFHandle) then Exit;
reVal := MouseRec.pt.x;
Pos := Word(reVal);
reVal := MouseRec.pt.y;
Pos := Pos or (Word(reVal) shl 16); mMsg := mMsg or (Integer(MouseRec.dwExtraInfo) shl 16); PostMessage(pFHandle^, MseMsg, mMsg, Pos);
end;
function StartHook(FormHandle: THandle): Integer; export;
begin
Result := 1;
if Hooked then Exit;
if not IsWindow(FormHandle) then
begin
Result := 2;
Exit;
end;
hMemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(THandle), mapName); pFHandle := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
if pFHandle = nil then
begin
CloseHandle(hMemFile);
Result := 3;
Exit;
end;
hKeyHook := SetWindowsHookEx(WH_KEYBOARD, @KeyHookFunc, hInstance, 0);
if hKeyHook = 0 then
begin
CloseMap;
Result := 6;
Exit;
end;
hMseHook := SetWindowsHookEx(WH_MOUSE, @MseHookFunc, hInstance, 0);
if hMseHook = 0 then
begin
CloseMap;
UnhookWindowsHookEx(hKeyHook);
Result := 5;
Exit;
end;
Acento1 := False;
Acento2 := False;
Dieresis := False;
Angulo := False;
Hooked := True;
pFHandle^ := FormHandle;
Result := 0;
end;
function StopHook: Boolean; export; begin
if Hooked then
begin
Result := UnhookWindowsHookEx(hKeyHook) and UnhookWindowsHookEx(hMseHook);
end else
Result := True;
if Result then
begin
CloseMap;
hKeyHook := 0;
hMseHook := 0;
Hooked := False;
end;
end;
procedure EntryProc(Reason: Cardinal);
begin
if (Reason = Dll_Process_Detach) then
begin
CloseMap;
if Hooked then
begin
UnhookWindowsHookEx(hMseHook);
UnhookWindowsHookEx(hKeyHook);
end;
end;
end;
exports
StartHook, StopHook;
begin
DLLProc := @EntryProc;
hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, mapName);
if hMemFile <> 0 then
pFHandle := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
end.
Aplication Delphi
Código Delphi
[-]procedure TForm1.HookMsgKey(var Msg1: TMessage);
Var Acao : String;
begin
if ((Msg1.lParam shr 31) and 1) = 1 then Begin
Acao := 'Soltou';
End else
if ((Msg1.lParam shr 30) and 1) = 1 Then Begin
Acao := 'Repetindo';
End else Begin
Acao := 'Precionou';
End;
Memo1.lines.Add(Acao + ' ' + Char(Msg1.wParam));
end;