Autor Beitrag
menticore
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 24

Win XP
D7 Enterprise
BeitragVerfasst: Fr 03.10.08 10:53 
Guten Morgen,

ich habe dazu wieder ein Problem, dass sich auf den Thread Problem mit Hookchain? Oder anderes? bezieht. Mein Wunsch ist es, eine programmierbare Tastatur zu entwerfen und das klappt auch soweit, es können Programme gestartet werden oder Text eingefügt werden. Ich habe allerdings ein gravierendes Problem: der Explorer (und manchmal auch andere Programme) stürzen ab, sobald ich mein Programm beende und ich weiß nicht warum.

Kurz zur Funktionsweise:
Der Key-Hook wird eingebunden beim Programmstart. Die Tasten Rollen, Bild auf und Bild ab werden an mein Programm gesendet (Rollen-Taste aktiviert die programmierbare Tastatur, mit Bild auf und ab kann man zwischen den Kategorien wählen, z.B. öffnet "1" in der einen Kategorie Notepad, in der anderen etwas anderes). Die Funktionen der Tasten liegen in Dateien hinterlegt (jede Taste eine Datei, z.B. D:\MyPersKeyboard\data\KategorieA\49.dat)

Ich konnte schon folgendes feststellen:
Dieser Fehler (Absturz des Explorers) tritt nur auf, wenn ich Programme starte (also bsp drücken der Taste 1: Notepad öffnet sich, kann weiter arbeiten, und beim Schließen meines Programmes kommt der Fehler). Hat der Hook evt. ein Problem mit ShellExecute? Und warum tritt dieser Fehler auch erst auf, wenn ich mein Programm beende? Weiterhin scheint es auch aufzutreten, wenn SendMessage ausgeführt wird (also das Senden von vk_scroll, vk_next, vp_prior an mein Programm). Woran kann das liegen? Ich bin im Moment ziemlich ratlos...

Gruß,
menticore


ausblenden volle Höhe Delphi-Quelltext
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:
function KeyBoardProc(Code, wParam, lParam: integer): integer; stdcall;
var
  KeyUp, openProg: boolean;
  key, i: integer;
  myFile: TextFile;
  KeyboardState: TKeyboardState;
  datei, line, text: String;
begin
  result := 0

  case Code of
    HC_ACTION : begin //Hier werden die Tasten abgefangen
        //Key-up Botschaft?
        KeyUp := ((lParam AND (1 shl 31)) <> 0);
        key := wParam;

        //Steuertaste meinem Programm schicken
        if (KeyUp) and ((key=VK_SCROLL) or (key=VK_PRIOR) or (key=VK_NEXT)) then begin
          SendMessage(lpHookRec^.TheCtrlWinHandle, WM_USER + 1678, wParam, lParam);
        end else begin
          //Rollen aktiv?
          GetKeyboardState(KeyboardState);
          if KeyboardState[VK_SCROLL]=1 then begin
            //Pfad meiner Exe aus Datei auslesen
            if FileExists('C:\WINDOWS\Temp\myPK.tmp'then begin
              AssignFile(myFile, 'C:\WINDOWS\Temp\myPK.tmp');
              Reset(myFile);
              ReadLn(myFile, myPath);
              ReadLn(myFile, line);
              CloseFile(myFile);
              incNumPad := (line='1');
            end else begin
              //Diese Stelle sollte hoffentlich nie eintreten
              myPath := 'D:\MyPersKeyboard\data\Allgemein\';
              incNumPad := true;
            end;

            //Include Numpad, wenn eingestellt
            if incNumPad then begin
              case key of
                96..105: key := key-48//Numpad Zahlen auf normale Zahlen
                107: key := key+80//Numpad +
                109: key := key+80//Numpad -
                110: key := key+78//Numpad ,
              end;
            end;

            datei := myPath+inttostr(key)+'.dat';
            //MessageBox(0, PChar(datei), 'hook', MB_OK);

            if FileExists(datei) then begin
              if KeyUp then begin
                //Ließ Datei ein
                AssignFile(myFile, datei);
                Reset(myFile);
                for i:=0 to 1 do ReadLn(myFile, line); //2 Zeilen lesen
                openProg := (line='0');
                for i:=0 to 1 do ReadLn(myFile, line); //2 Zeilen lesen
                text := '';
                while not(EOF(myFile)) do begin
                  ReadLn(myFile, line);
                  text := text+line+#13#10;
                end;
                CloseFile(myFile);
                text := copy(text, 1, length(text)-2);

                //MessageBox(0, PChar(text), 'hook', MB_OK);
                //Nun setze den Befehl ab
                if openProg then begin
                  ShellExecute(lpHookRec^.TheCtrlWinHandle, 'open', PChar(text), NilNil, SW_NORMAL);
                  sleep(50);
                end else begin
                  Clipboard.Astext := text;
                  sendClipboard();
                end;
              end;
              //Swallow the keystroke
              result := -1;
              exit;
            end;
          end;
        end;
      end;
    HC_NOREMOVE : begin
      //This is a keystroke message, but the keystroke message
      //has not been removed from the message queue, since an
      //application has called PeekMessage() specifying PM_NOREMOVE
      result := 0;
      exit;
    end;
  end;

  if (Code<0then //Call the next hook in the hook chain
    result := CallNextHookEx(lpHookRec^.TheHookHandle, Code, wParam, lParam);
end;
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 03.10.08 13:55 
3 Dinge:

1. KEINE FEST CODIERTEN PFADANGABEN
2. KEINE AUSFÜHRBAREN DATEIEN IN TEMPORÄR VERZEICHNISSE
3. Beim Unloaden deines Programms solltest Du zuerst alle Hooks deinstallieren!

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
menticore Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 24

Win XP
D7 Enterprise
BeitragVerfasst: Fr 03.10.08 22:23 
Hey,

bitte nicht so laut...
zu den 3 Sachen:
1. ok
2. hab ich nicht, in dem temporären Verzeichnis liegt nur der Pfad zu meiner Exe (wusste das im Moment noch nicht besser umzusetzen, es ist schwierig für mich mit der dll zu reden und umgekehrt)
3. hab ich gemacht, also meinen Hook entfernen.

Das Problem ist, wie kann ich es besser umsetzen? Ich würde gerne flexibel sein, wenn ich Tasten eine Funktion zuweise. Wie kann ich meiner DLL beibringen, welche Tasten sie abfangen muss und welche nicht? Ich kann ja nicht einfach nach dem Senden einer Taste ein "Zurück" senden... Habe leider noch nicht viel Erfahrung mit solch Programmierung, aber ich hoffe, dass ich es besser verstehen kann.

Gruß,
menticore
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 03.10.08 23:38 
Schau Dir mal Inter-Prozess-Kommunikation an. Z.B. über Memory Mapped Files oder Pipes ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
menticore Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 24

Win XP
D7 Enterprise
BeitragVerfasst: So 05.10.08 11:55 
Dankeschön.

Habe folgenden Link dazu gefunden: Delphi-Praxis - MMF
Werde mich mal schlau lesen.

Gruß,
menticore