Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   lokaler Hook wird immer doppelt durchlaufen? (https://www.delphipraxis.net/189073-lokaler-hook-wird-immer-doppelt-durchlaufen.html)

r29d43 30. Apr 2016 13:10

lokaler Hook wird immer doppelt durchlaufen?
 
Hallo, weil ich seit langem mal wieder einen lokalen Hook brauche, konstruierte ich mir erstmal einen solchen in Form eines quasi simpelst möglichen getMsg-Hooks. Allerdings habe ich bei dem jetzt das kuriose Prob, dass alle Messages, die an das Panel1 gehen und auf dem ich mit der Maus jetzt gerade herumklicke, diesen Hook irgendwie doppelt durchlaufen, also dann auch in der Case-Anweisung im Code doppelt gezählt werden.

Delphi-Quellcode:
function GetMsgProc (nCode: Integer; wParam, lParam: Longint): Longint; stdcall;
type MSG = record
       hwnd : HWND;
       message : UINT;
       wParam : DWord;
       lParam : DWord;
       time : DWORD;
       pt : TPOINT;
     end;
     PMSG = ^MSG;
begin
{ }
  if nCode = HC_ACTION
//  if not nCode < 0
  then begin

    with form4 do
    if PMSG(lParam)^.hwnd = Form4.panel1.handle then
    case PMSG(lParam)^.message of
      WM_LBUTTONDOWN :
                       begin
                         inc(LButtonDownCounter);
                         label1.caption := IntToStr(LButtonDownCounter)
                       end;
      WM_LBUTTONUP :
                       begin
                         inc(LButtonUpCounter);
                         label2.caption := IntToStr(LButtonUpCounter)
                       end;
      WM_LBUTTONDBLCLK :
                       begin
                         inc(DoppelklickCounter);
                         label3.caption := IntToStr(DoppelklickCounter)
                       end;
    end; { of case }
  end;

  Result := CallNextHookEx(Form4.HookID, nCode, wParam, lParam);
end;


procedure TForm4.FormCreate(Sender: TObject);
begin
  HookID := SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc , 0, GetCurrentThreadId());
  LButtonDownCounter := 0;
  LButtonUpCounter := 0;
  DoppelklickCounter := 0;
end;


procedure TForm4.FormDestroy(Sender: TObject);
begin
  if HookID <> 0 then UnHookWindowsHookEx(HookID);
end;

Irgendwo muss hier doch noch ein winzig kleiner Fehler stecken, nur wo?
(leider habe ich gerade 2 dicke Tomaten auf den Augen).

Zacherl 30. Apr 2016 15:35

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Kann auf den ersten Blick auch keinen Fehler sehen. Aber warum verwendest du überhaupt MSDN-Library durchsuchenSetWindowsHookEx? Das ist doch für einen lokalen Hook etwas mit Kanonen auf Spatzen geschossen.

Für die gezeigten Aktionen könntest du doch einfach die entsprechenden Events des Panels (OnDblClick, OnMouseDown, OnMouseUp, etc) nutzen. Wenn du mehr Messages brauchst, wäre die saubere Lösung eine eigene Panel Klasse vom TCustomPanel abzuleiten. Alternativ könntest du auch Subclassing verwenden, um die WndProc lokal umzubiegen.

r29d43 30. Apr 2016 16:11

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Thx für die Anregung, aber der von mir angezeigte Code war ja nur ein einfachst mögliches Testprog, um den lokalen Hook für mich intern jetzt erstmal wieder kurz reaktiviert zu haben. Nachher möchte ich so einen Hook für ein Programm nutzen, das aus vielen Formularen besteht, und wo ich mittels des Hooks dann alle Positionsänderungen dieser einzelnen Formulare mittels wm_move o. wm_moving kontrollieren (protokollieren, speziell verändern o. ganz verhindern) kann.

Außerdem geht's mir hier auch noch ein kleines bisschen ums Prinzip. So ein Hook hatte bei mir bisher nämlich eigentlich immer ganz gut geklappt, und jetzt auf einmal nicht mehr? Warum???

Uwe Raabe 30. Apr 2016 16:22

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Ist sicher gestellt, daß
Delphi-Quellcode:
TForm4.FormCreate
nicht zweimal aufgerufen wird?

Zacherl 30. Apr 2016 16:28

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Zitat:

Zitat von r29d43 (Beitrag 1337199)
So ein Hook hatte bei mir bisher nämlich eigentlich immer ganz gut geklappt, und jetzt auf einmal nicht mehr? Warum???

Bei mir tritt das selbe Problem auf. Wenn ich testweise aber mal direkt das Formular überwache, dann kommen die Messages bei Click auf die Client-Area ebenfalls doppelt an. Clicks in die Titelleiste allerdings nur einmal.

Ich vermute mal, dass die VCL da intern irgendwie mit den Messages hantiert und dadurch verursacht, dass diese manchmal doppelt verschickt werden.

r29d43 30. Apr 2016 17:00

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Zitat:

Ist sicher gestellt, daß TForm4.FormCreate nicht zweimal aufgerufen wird?
Das sollte eigentlich nicht passiert sein. Und da Zacherl den Code auchmal kurz gestest hat, hätte er ja quasi einen solchen gleichen Fehler auch gemacht, was wohl ziemlich unwahrscheinlich sein dürfte.

Zitat:

Bei mir tritt das selbe Problem auf. Wenn ich testweise aber mal direkt das Formular überwache, dann kommen die Messages bei Click auf die Client-Area ebenfalls doppelt an. Clicks in die Titelleiste allerdings nur einmal.

Ich vermute mal, dass die VCL da intern irgendwie mit den Messages hantiert und dadurch verursacht, dass diese manchmal doppelt verschickt werden.
Ersteres kann ich bestätigen. Die LButtonUp-Message wird beim Klick auf die Titelleiste auch nur 1 mal gezählt (die LButtonDown-Message 0 mal). Bezüglich der Verursachung dieses Effektes glaube ich allerdings eher an eine irgendwie eigene Verursachung. Ansonsten wäre so eine imo dicke Fehlersache doch sicher schon längst bekannt und behoben worden.

Delphi-Laie 30. Apr 2016 21:52

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Zitat:

Zitat von r29d43 (Beitrag 1337203)
Zitat:

Ist sicher gestellt, daß TForm4.FormCreate nicht zweimal aufgerufen wird?
Das sollte eigentlich nicht passiert sein. Und da Zacherl den Code auchmal kurz gestest hat, hätte er ja quasi einen solchen gleichen Fehler auch gemacht, was wohl ziemlich unwahrscheinlich sein dürfte.

Sollte, hätte und dürfte ist Konjunktiv II. Entscheidend ist hier aber nur der Indikativ.

Mit z.B. einem simplen

Delphi-Quellcode:
showmessage('TForm4.FormCreate')


oder einem Piepton mit Zufallsfrequenz

Delphi-Quellcode:
windows.beep(200+random(1000),100)


irgendwo in der FormCreate-Prozedur ließe (huch, Konjunktiv II) sich das einfach verifizieren oder falsifizieren. Dann könnte (huch, schon wieder Konjunktiv II) man auch auf den Konjunktiv II in den Antworten verzichten.

r29d43 30. Apr 2016 23:42

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Damit auch für die Grammatikprofis :shock: alle Zweifel restlos ausgeräumt sind: Es blieb bei nur einem Meldungsfenster bzw. auch bei nur einem Ton.

Delphi-Laie 30. Apr 2016 23:49

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Zitat:

Zitat von r29d43 (Beitrag 1337215)
Damit auch für die Grammatikprofis :shock: alle Zweifel restlos ausgeräumt sind: Es blieb bei nur einem Meldungsfenster bzw. auch bei nur einem Ton.

Na, das ist doch eine klare - indikative! - Ansage, warum nicht gleich so?

Das waren nur zwei Beispiele, wie man schnell - ohne Debugger - das Durchlaufen von Code feststellen kann, ich benutze derlei jedenfalls ziemlich oft. Vielleicht gibt es noch mehr und geeignetere Methoden?!

Uwe Raabe 1. Mai 2016 08:50

AW: lokaler Hook wird immer doppelt durchlaufen?
 
Hast du schon mal einen Haltepunkt gesetzt und den Aufruf-Stack angeschaut?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:19 Uhr.
Seite 1 von 2  1 2      

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