| Autor |
Beitrag |
AndrewPoison
      
Beiträge: 17
Turbo Delphi 2006, Delphi 2009
|
Verfasst: So 14.09.08 10:46
Hallo, nachdem ich mich ein wenig mit Hooks beschäftigt habe, kam nun am Ende ein Programm heraus das global wunderbar Tastenanschläge verfolgt. Das Problem: trotz Einbindung der CallNextHookEx-Funktion werden die Tasten, auf die ich reagiere, zwar abgefangen, aber nicht mehr weitergeleitet.
Hier der Code der Hook-DLL:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
| function KeyBoardProc(Code : integer; wParam : integer; lParam : integer): integer; stdcall; begin result := 0; result := CallNextHookEx(lpHookRec^.TheHookHandle,Code,wParam,lParam);
case Code of HC_ACTION : begin
PostMessage(lpHookRec^.TheCtrlWinHandle,WM_KEYDOWN,wParam,lParam); PostMessage(lpHookRec^.TheCtrlWinHandle,WM_KEYUP,wParam,lParam);
result := 0;
end; HC_NOREMOVE : begin result := 0; exit; end; end; result := CallNextHookEx(lpHookRec^.TheHookHandle,Code,wParam,lParam); end; |
und hier die Funktion, die beim Eintreffen des Events (korrekt) ausgelöst wird:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.WmHotkey(var Msg: TMessage); begin if Msg.WParam = HK1 then OnSoftButtonsCB(1); if Msg.WParam = HK2 then OnSoftButtonsCB(2); if Msg.WParam = HK3 then OnSoftButtonsCB(4); if Msg.WParam = HK4 then OnSoftButtonsCB(8); end; |
Ich habe in dem DLL-Quelltext bereits die Funktion CallNextHookEx an verschiedenen Stellen angesetzt, so dass sie zumindest einmal durchlaufen werden muss, oder auch in der Handling-Funktion das Msg.Result auf 0 gesetzt (zum testen). Hat nicht so wirklich was gebracht. Wie gesagt, zuerst war ich der Ansicht, das es an der Hookchain liegt, allerdings glaube ich zunehmend auch das es daran nicht liegen kann: denn dann würden ja alle Tastenanschläge nicht weitergeleitet, nicht nur nicht diejenigen, auf die ich im Programm am Ende reagiere. Zur Eingabe, welcher "Hotkey" (eine einzelne Taste, z.B. "A" oder "7") verwendet werden soll um daraufhin eine Aktion durchzuführen, verwende ich eine THotKey-Komponente. Kann es sein, dass diese irgendwie den Fehler verursacht und die Tasten dann als Hotkey registriert und nicht mehr an andere Programme weiterleitet? Oder was ganz anderes?
Das Problem äußert sich halt z.B. darin, dass ich, wenn mein Programm läuft, keine der vier Tasten die als Hotkey definiert wurden in anderen Programmen mehr verwenden kann (z.B. erscheinen die Tasten dann nicht mehr hier beim schreiben des Posts, oder wenn ich die Taste einem anderen Hotkey zuweisen will klappts auch nicht).
/edit:
Problem hat sich gelöst. In einer anderen Unit war noch Quelltext von einem vorherigen Versuch enthalten, der mittel RegisterHotKey gearbeitet hat - und die Funktion scheint das ganze lahmgelegt zu haben. Nachdem ich den Part rausgeworfen hatte, läuft nun wieder alles. Liegt also weder an der Hookchain noch an der THotKey-Komponente. War einfach mein Fehler :/
Moderiert von Narses: Code- durch Delphi-Tags ersetzt
|
|
menticore
      
Beiträge: 24
Win XP
D7 Enterprise
|
Verfasst: Do 18.09.08 22:14
Titel: Ähnliches Problem
Hallo zusammen,
ich habe fast denselben Code, möchte aber das Gegenteil bewirken: Ich möchte eine programmierbare Tastatur entwerfen und Tasten abfangen. Wenn die Taste Rollen gedrückt wurde, sollen die Tasten abgefangen und verändert werden. Der globale Key-Hook funktioniert einwandfrei (von jemandem übernommen, daher die englischen Kommentare), dennoch werden die Tasten bsp. an Notepad weitergereicht. Ich habe mich schon mit diversen Tutorials auseinandergesetzt und gesucht, aber nichts dazu gefunden. Bin froh, dass der Hook erstmal läuft.
Aber wie kann ich die Tasten verändern? Wo liegt da bei mir der Denkfehler?
Quellcode ist unten...
Lieben Gruß,
menticore
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114:
| library hooklib;
uses Windows, Messages, SysUtils;
type PHookRec = ^THookRec; THookRec = record AppHnd: Integer; end;
const memFile: PAnsiChar = 'Global7v9k'; var Hooked: Boolean; hKeyHook, hMemFile, hApp: HWND; PHookRec1: PHookRec;
function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall; var KeyboardState: TKeyBoardState; begin Result := 0; if Code = HC_NOREMOVE then Exit;
GetKeyboardState(KeyboardState); if KeyboardState[VK_SCROLL]=1 then begin Result := CallNextHookEx(hKeyHook, Code, 48, KeyStroke); end else begin Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke); end;
if Code<0 then Exit;
if Code = HC_ACTION then begin if ((KeyStroke and (1 shl 30)) <> 0) then begin if not IsWindow(hApp) then begin hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, memFile); PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
if PHookRec1<>nil then hApp := PHookRec1.AppHnd; end;
SendMessage(hApp, WM_USER + 1678, VirtualKey, KeyStroke); end; end; end; function StartHook(AppHandle: HWND): Byte; export; begin Result := 0;
if Hooked then begin Result := 1; Exit; end;
hKeyHook := SetWindowsHookEx(WH_KEYBOARD, KeyHookFunc, hInstance, 0); if hKeyHook>0 then begin hMemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(THookRec), memFile); PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0); hApp := AppHandle; PHookRec1.AppHnd := AppHandle; Hooked := True; end else Result := 2; end;
function StopHook: Boolean; export; begin if PHookRec1<>nil then begin UnmapViewOfFile(PHookRec1); CloseHandle(hMemFile); PHookRec1 := nil; end;
if Hooked then Result := UnhookWindowsHookEx(hKeyHook) else Result := True; Hooked := False; end;
procedure EntryProc(dwReason: DWORD); begin if dwReason=Dll_Process_Detach then begin if PHookRec1 <> nil then begin UnmapViewOfFile(PHookRec1); CloseHandle(hMemFile); end; UnhookWindowsHookEx(hKeyHook); end; end;
exports StartHook, StopHook;
begin PHookRec1 := nil; Hooked := False; hKeyHook := 0; DLLProc := @EntryProc; EntryProc(Dll_Process_Attach); end. |
|
|
AndrewPoison 
      
Beiträge: 17
Turbo Delphi 2006, Delphi 2009
|
Verfasst: Do 18.09.08 23:23
Meinen Hook hab ich von groups.google.com/gr...msg/ceb5818acd623a24
dort siehst du auch, wie man eine Taste verändern kann (die Sache, als er aus einem VK_LEFT ein VK_RIGHT macht). Hoffe damit konnte ich schon helfen
Im Grunde macht er nichts anderes als abzufangen welche Taste gedrückt wurde (über wParam) und dann eine andere Message an dein Programm zu schicken.
Du rufst ja die CallNextHookEx-Funktion mit dem neuen Wert auf. Ob das überhaupt so funktionieren kann weiss ich nicht, aber ich denk mal ned, denn damit rufst du ja nur das nächste Hook-Handling auf, schickst die Message aber nicht an dein Programm - wie gesagt der verlinkte Code funktioniert zumindest. Natürlich müsstest du ihn halt auf deine Bedürfnisse anpassen.
|
|
menticore
      
Beiträge: 24
Win XP
D7 Enterprise
|
Verfasst: Fr 19.09.08 14:40
Danke dir.
Ich musste in der Funktion nur den Wert -1 zurückgeben und das wars auch schon.
Delphi-Quelltext 1: 2: 3: 4: 5:
| GetKeyboardState(KeyboardState); if KeyboardState[VK_SCROLL]=1 then begin Result := -1; exit; end; |
Nochmals danke und Gruß,
menticore
|
|
|