Hallo.
Danke für eure Beiträge. Das Tool habe ich nicht ausprobiert, da es mir zu statisch vorkommt. Außerdem bin ich ja gerade dabei, ein eigenes kleines Tool zu schreiben, bei dem ich außerdem noch einiges über die
WinAPI dazulerne.
Ich habe jetzt folgendes gemacht:
- Die
DLL prüft nun intern, ob die Maustaste erlaubt ist oder nicht, deswegen ist jetzt kein "Frage-Antwort-Spiel" mit der Host-Applikation mehr nötig.
- Die
DLL übergibt der Host-Applikation folgende Messages, die z.B. für grafische Ereignisse/Hinweise verwendet werden können:
*
WM_LMB_LOCKED -- die linke Maustaste ist ab jetzt gesperrt (Host-App soll Systemzeiger in crNo verändern)
* Nach 3 Sekunden kommt dann automatisch:
WM_LMB_UNLOCKED -- die linke Maustaste ist ab jetzt wieder freigeschaltet (Host-App soll den Systemzeiger wiederherstellen)
*
WM_LMB_BLOCKED -- eine linke Maustaste wurde innerhalb der Sperrzeit gedrückt. Das Ereignis wurde geblockt! (z.B. Sound-Ereignis abspielen)
Aber es existieren folgende Bugs, bei denen ich nicht weiterkomme:
1. Host-App: Der Mauszeiger wird nicht nach crNo mittels SetSystemCursor() innerhalb der WndProc() geändert! Außerhalb der WndProc() funktioniert es seltsamerweiße!
Delphi-Quellcode:
procedure TForm1.WndProc(var Message:TMessage);
begin
if Message.Msg = WM_LMB_BLOCKED then
begin
label2.Caption := 'WM_LMB_BLOCKED ' + IntToStr(GetTickCount());
end
else if Message.Msg = WM_LMB_LOCKED then
begin
label1.Caption := 'WM_LMB_LOCKED';
// BUG 1!!! Mauszeiger verändern funktioniert nicht
cursor_backup := GetCursor;
SetSystemCursor(Screen.Cursors[crNo], OCR_NO);
end
else if Message.Msg = WM_LMB_UNLOCKED then
begin
label1.Caption := 'WM_LMB_UNLOCKED ' + IntToStr(GetTickCount());
SetSystemCursor(cursor_backup, OCR_NORMAL);
end;
inherited WndProc(Message);
end;
2.
DLL: Die Kontrolle, ob eine Strg-Taste gedrückt ist, funktioniert nicht!
3.
DLL: Der (einmalige) Timer, der nach
WM_LMB_LOCKED (neu)gestartet wird und nach 3 Sekunden zu
WM_LMB_UNLOCKED führen soll, funktioniert nicht! Er funktioniert nur, wenn man innerhalb der Host-Anwendung Tasten drückt. Tippt man in Notepad etwas ein, dann ist der Timer gleich 0.
Delphi-Quellcode:
var
lock_interval: Integer;
// wird bei dem DLL-Start gesetzt bzw. mit einer externen DLL-Funktion aktualisiert
last_timer: Cardinal;
procedure timerevent;
var
res: Cardinal;
begin
// Es soll ein einmaliger Timer sein
KillTimer(0, last_timer);
last_timer := 0;
SendMessageTimeOut(TargetHandle, WM_LMB_UNLOCKED, 0, 0,
SMTO_ABORTIFHUNG
or SMTO_BLOCK, MsgTimeOut, res);
end;
function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
stdcall;
var
res: Cardinal;
begin
Result := CallNextHookEx(Keyboard_HookHandle, nCode, wParam, lParam);
case nCode < 0
of
TRUE: exit;
FALSE:
begin
// BUG 2!!! VK_CONTROL-Kontrolle funktioniert nicht!
// Strg+Maustaste ist legitim für Mehrfachselektion
if GetKeyState(VK_CONTROL) = 0
then
begin
last_keyboard_input := GetTickCount();
SendMessageTimeOut(TargetHandle, WM_LMB_LOCKED, 0, 0,
SMTO_ABORTIFHUNG
or SMTO_BLOCK, MsgTimeOut, res);
// Jetzt: 3 Sekunden warten und dann WM_LMB_UNLOCKED senden, ggf. vorherigen Timer zurücksetzen
// BUG 3!!! Dieser Timer funktioniert nur, wenn man in der Anwendung
// was tippt. Tippt man z.B. im Notepad, hat der Timer
// ein Interval von 0 statt 3000.
// Den vorherigen Timer zurücksetzen
if last_timer <> 0
then KillTimer(0, last_timer);
last_timer := SetTimer(0, IDC_TIMER1, lock_interval, @timerevent);
end;
end;
end;
end;
Könnt ihr mit bitte weiterhelfen? Ich habe bei diesen 3 Bugs keine Lösung erzielen können.
Wenn ihr nochwas im Projekt findet, schreibt mir bitte Vorschläge!
Gruß
Daniel Marschall