AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Maus sperren während Tastatureingabe
Thema durchsuchen
Ansicht
Themen-Optionen

Maus sperren während Tastatureingabe

Ein Thema von blackdrake · begonnen am 17. Nov 2008 · letzter Beitrag vom 8. Apr 2010
Antwort Antwort
Seite 2 von 6     12 34     Letzte »    
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#11

Re: Maus sperren während Tastatureingabe

  Alt 17. Nov 2008, 21:16
Meinst du, es sollte so aussehen?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  h: hwnd;
begin
  h := WindowHandle;
  InstallHooks(h); // EXCEPTION
  WM_MOUSEHOOKMSG:=getprop(h,mousmsg);
  WM_KEYBHOOKMSG:=getprop(h,keybmsg);
end;
Wirft aber auch eine AV ab.

Das Problem ist, dass ich vom DP-Tutorial keine Belegung des hWnd's sehen konnte.

Dort wird nämlich die API-Funktion mittels
DialogBoxParam(HInstance, MAKEINTRESOURCE(DIALOG1), 0, @dlgfunc, 0); aufgerufen, jedoch kann ich dann nicht wirklich die dlgfunc-Parameter, die auch die hWnd enthält, sehen...

In sofern weiß ich nicht genau, welches Handle überhaupt verlangt ist...
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

Re: Maus sperren während Tastatureingabe

  Alt 17. Nov 2008, 21:18
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  h: hwnd;
begin
  h := Form1.Handle; // <--- Eher so ...
  InstallHooks(h); // EXCEPTION
  WM_MOUSEHOOKMSG:=getprop(h,mousmsg);
  WM_KEYBHOOKMSG:=getprop(h,keybmsg);
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#13

Re: Maus sperren während Tastatureingabe

  Alt 17. Nov 2008, 21:22
Hallo.

Funktioniert leider immer noch nicht.

Ich denke, die AV kommt aufgrund einer ungültigen DLL-Interaktion. Wäre nur das Handle falsch, würde das wahrscheinlich nicht zu einer AV führen.

Hast du eine Idee?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#14

Re: Maus sperren während Tastatureingabe

  Alt 17. Nov 2008, 23:56
Hallo,

Der Fehler lag beim GetProcAddress, da bei den 2 Tutorials einmal von *Hook und einmal von *Hooks die Rede war.

Ich habe jetzt einen fast funktionierenden Code, jedoch gibt es noch 2 Dinge, mit denen ich Probleme habe:

1. Die Strg-Taste wird auch als Taste angesehen ... hier muss sich dringend noch eine Allgemeine Lösung finden, weil Strg+Maustaste ja legitim sind
2. Das Sperren der Maustaste funktioniert nicht. Eigentlich dachte ich, es genüge, einfach das WndProc, das man verwerfen möchte, einfach nicht mehr per inherited weiterzureichen, doch es funktioniert einfach nicht.

Zum Testen: Ich habe während die Anwendung im Hintergrund läuft in einem Notepad etwas eingetippt. Das Fenster im Hintergrund zeigt als Debugausgabe "Gesperrt". Während der Eingabe klicke ich in meinen geschriebenen Text hinein. Nach der Eingabe werden die Textstellen markiert, weil scheinbar die Mausereignisse doch noch im Eingabepuffer waren und nicht durch die Hook-DLL verworfen wurden.

Code (DLL hooks.dll in den oberen Posts):

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    debug_tmr: TTimer;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure debug_tmrTimer(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  public
    last_keyboard_input: DWORD;
    procedure WndProc(var Message:TMessage); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TInstallHook = function(Hwnd: THandle): Boolean; stdcall;
  TUninstallHook = function: Boolean; stdcall;

var
  InstallHooks: TInstallHook;
  UninstallHooks: TUninstallHook;
  lib: Cardinal;
  WM_MOUSEHOOKMSG: Cardinal = 0;
  WM_KEYBHOOKMSG: Cardinal = 0;

const
  mousmsg='MouseHookMessage_Assarbad';
  keybmsg='KeyboardHookMessage_Assarbad';

const
  sperrdauer = 3000; // 3 Sekunden, später Variabel

// ToDo: Programm total lahm, wenn Delphi gestartet ist
// (auch außerhalb des Debuggers) ?
procedure TForm1.WndProc(var Message:TMessage);
var
  difference: DWORD;
begin
  if Message.Msg = WM_KEYBHOOKMSG then
  begin
    inherited WndProc(Message);

    // Eine Taste wurde gedrückt, wir merken uns den Zeitpunkt
    last_keyboard_input := GetTickCount();

    // ToDo: Tasten wie Strg dürfen nicht mitgezählt werden,
    // da diese in Kombination mit der Maustaste OK sind!
  end
  else if Message.Msg = WM_MOUSEHOOKMSG then
  begin
    difference := GetTickCount() - last_keyboard_input;

    if (difference <= sperrdauer) and
       ((Message.wParam = WM_LBUTTONDBLCLK) or
        (Message.wParam = WM_LBUTTONDOWN) or
        (Message.wParam = WM_LBUTTONUP)) then
    begin
      // Ereignis verwerfen, da linke Maustaste innerhalb
      // der Sperrzeit gedrückt wurde

      // Something ToDo ?

      // Debug: Zeigen, dass etwas gesperrt wurde
      label2.Caption := 'Sperrung: ' + IntToStr(GetTickCount());
    end
    else
    begin
      // Sonstiges Mausereignis bzw. Mausklick außerhalb
      // der Sperrzeit erlauben
      inherited WndProc(Message);
    end;
  end
  else
  begin
    // Andere Ereignisse durchlassen
    inherited WndProc(Message);
  end;
end;

procedure TForm1.debug_tmrTimer(Sender: TObject);
var
  difference: DWORD;
begin
  difference := GetTickCount() - last_keyboard_input;

  if difference > sperrdauer then
  begin
    label1.Caption := 'Freigegeben';
  end
  else
  begin
    label1.Caption := 'Gesperrt';
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnInstallHooks;
  WM_MOUSEHOOKMSG:=0;
  WM_KEYBHOOKMSG:=0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  lib := LoadLibrary('hooks.dll');
  if lib <> INVALID_HANDLE_VALUE then
  begin
    InstallHooks := GetProcAddress(lib, 'InstallHooks');
    UnInstallHooks := GetProcAddress(lib, 'UninstallHooks');
  end
  else
  begin
    ShowMessage('Hook could not be initialized. Please check "hooks.dll".');
    Application.Terminate;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeLibrary(lib);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  InstallHooks(Handle);
  WM_MOUSEHOOKMSG:=getprop(Handle, mousmsg);
  WM_KEYBHOOKMSG:=getprop(Handle, keybmsg);
end;

end.
Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#15

Re: Maus sperren während Tastatureingabe

  Alt 18. Nov 2008, 00:27
Zitat von blackdrake:
Hallo,

Der Fehler lag beim GetProcAddress, da bei den 2 Tutorials einmal von *Hook und einmal von *Hooks die Rede war.

Ich habe jetzt einen fast funktionierenden Code, jedoch gibt es noch 2 Dinge, mit denen ich Probleme habe:
Das sieht doch schon gut aus

Zitat von blackdrake:
1. Die Strg-Taste wird auch als Taste angesehen ... hier muss sich dringend noch eine Allgemeine Lösung finden, weil Strg+Maustaste ja legitim sind
Ich würde die STRG-Taste einfach aus der Betrachtung lassen:
a) ist sie sehr weit weg vom Mousepad
b) wird diese beim Schreiben von Text eher selten benötigt
c) wird beim Schreiben von Text innerhalb der Sperrzeit eine weitere Taste gedrückt. Nur mit der STRG-Taste ist es schwierig einen Text zu verfassen

Zitat von blackdrake:
2. Das Sperren der Maustaste funktioniert nicht. Eigentlich dachte ich, es genüge, einfach das WndProc, das man verwerfen möchte, einfach nicht mehr per inherited weiterzureichen, doch es funktioniert einfach nicht.
Da es sich um eine Message handelt, geht die bei Winows auch in und durch eine Warteschlange. Also muss man auch aktiv werden, wenn diese Message aus der Warteschlange raus soll.
Aber das weiß ich adhoc auch nicht ... vielleicht habe ich nachher, wenn der planet wieder scheint, etwas zeit, mir das mal anzusehen

Zitat von blackdrake:
Zum Testen: Ich habe während die Anwendung im Hintergrund läuft in einem Notepad etwas eingetippt. Das Fenster im Hintergrund zeigt als Debugausgabe "Gesperrt". Während der Eingabe klicke ich in meinen geschriebenen Text hinein. Nach der Eingabe werden die Textstellen markiert, weil scheinbar die Mausereignisse doch noch im Eingabepuffer waren und nicht durch die Hook-DLL verworfen wurden.
jo ...

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#16

Re: Maus sperren während Tastatureingabe

  Alt 18. Nov 2008, 17:35
Hallo.

Ich weiß nicht, wie ich hier die Maus-Aktion rückgängig machen soll.

Delphi-Quellcode:
function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
//es ist ebenfalls moeglich die Bearbeitung an eine Bedingung zu knuepfen
//it's possible to call CallNextHookEx conditional only.
  Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit; //wenn code kleiner 0 wird nix gemacht
                //if code smaller 0 nothing has to be done
    FALSE:
      begin
//Hier kann jetzt alles bearbeitet werden
//Here one can work with the parameters
        setprop(WindowHandle, 'mous_ncode', nCode);
        setprop(WindowHandle, 'mous_hwnd', PMOUSEHOOKSTRUCT(lParam)^.hwnd);
        setprop(WindowHandle, 'mous_hitt', PMOUSEHOOKSTRUCT(lParam)^.wHitTestCode);
        setprop(WindowHandle, 'mous_xpos', PMOUSEHOOKSTRUCT(lParam)^.pt.x);
        setprop(WindowHandle, 'mous_ypos', PMOUSEHOOKSTRUCT(lParam)^.pt.y);
        SendMessage(HWND_BROADCAST, WM_MOUSEHOOKMSG, wParam, lParam);
      end;
  end;
end;
Dieses Konstrukt der DLL sieht nicht aus wie eine WndProc-Schleife, bei der man eine nicht gebrauchte Message einfach nicht per inherited weiterreicht...

Ich glaube, dass ich nach SendMessage() das result neutralisieren muss, wenn ich das Ereignis verwerfen möchte.

Das Problem: Die Message WM_MOUSEHOOKMSG müsste dann ja auch noch ein Ergebnis zurückliefern, in dem steht, ob das WM_MOUSE* Ereignis gelöscht wird oder nicht.

Gibt es denn keine bessere Lösung, bei der ich das Maus-Links-Klick-Ereignis löschen kann, ohne die DLL unnötig zu erweitern?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#17

Re: Maus sperren während Tastatureingabe

  Alt 18. Nov 2008, 17:53
Vielleicht ist der Maushook dann der falsche Ansatz?! Es gibt auch Messagehooks
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#18

Re: Maus sperren während Tastatureingabe

  Alt 18. Nov 2008, 18:20
Och nö, wie soll denn das jetzt gehen?

Ich habe mal versucht, http://delphigeek.blogspot.com/2007/...in-delphi.html auf Left-Button zu übertragen, jedoch bekomme ich bei der Implementierung nur einen Programmfehler.

Außerdem wird nirgends beschrieben, WIE dieser Left-Mouse-Hook (im Link Middle-Mouse-Hook) nun angewandt wird, also dass der Hook sich tatsächlich als Ereignis auf meine Anwendung auswirkt.

Folgendes scheint nicht zu funktionieren:

Delphi-Quellcode:
public
  procedure Test(var msg: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
end;

procedure RunHook; stdcall; external 'left_mouse_hook.dllname 'RunHook';
procedure KillHook; stdcall; external 'left_mouse_hook.dllname 'KillHook';

procedure TForm1.Test(var msg: TWMNCLButtonDown);
begin
  Button1.Caption := IntToStr(GetTickCount());
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RunHook;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  KillHook;
end;
Kann mir bitte jemand helfen? Ich möchte ein systemglobales Maus-Hook mit der möglichkeit, das Mausereignis innerhalb meiner Anwendung (also nicht in der DLL) rückgängig zu machen.
Daniel Marschall
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#19

Re: Maus sperren während Tastatureingabe

  Alt 18. Nov 2008, 18:36
Erstelle eine MMF mit einem eindeutigen Namen (am besten ein GUID). In diese schreibst du von der Anwendung aus das Fensterhandle deines Forms. In der DLL öffnest du die MMF und schickst deine eigene Nachricht an das Fenster, am besten eine mit RegisterWindowMessage registrierte. Dieses Senden sollte unbedingt mit SendMessageTimeout erfolgen und mit den Flags SMTO_ABORTIFHUNG sowie SMTO_BLOCK! Alles andere kann dazu führen, dass das System nicht mehr zu gebrauchen ist. Dein Formular kann mit dem Nachrichten-Ergebnis mitteilen, ob der Hook die alte Nachricht weiterleiten oder verändern soll.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#20

Re: Maus sperren während Tastatureingabe

  Alt 18. Nov 2008, 18:39
Oh je, sowas kompliziertes habe ich noch nicht gehört Geht denn das nicht auch einfacher oder irgendwie als existierenden Code, den man umändern kann?
Daniel Marschall
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 6     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz