Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Probleme mit Hooks (https://www.delphipraxis.net/34539-probleme-mit-hooks.html)

Alex_ITA01 24. Nov 2004 14:12


Probleme mit Hooks
 
Hallo erstmal,
habe grade angefangen mich mit Hooks zu beschäftigen und würde ganz einfach gerne in einem Label auf meiner Form, die MousePosition ausgeben.Egal ob sich die Maus auf meiner Form oder im Nirvana (Sprich irgendwo auf dem Desktop) befindet. Könnt ihr mir da ein Beispiel zeigen wie ich das realisiere?
Ehrlich gesagt komme ich mit den vorhanden Tutorials nicht zurecht...
Ich hoffe ihr könnt mir da helfen?!!

MFG Alex

Ultimator 24. Nov 2004 14:17

Re: Probleme mit Hooks
 
Für das mit der Mausposition brauchst du keinen Hook ;-)
dafür kannst du Delphi-Referenz durchsuchenGetCursorPos benutzen ;-)

jim_raynor 24. Nov 2004 14:18

Re: Probleme mit Hooks
 
Nimm einen Timer stell den auf 50ms oder so und lese über Mouse.CursorPos die Position der Maus aus ;)

Dafür braucht man noch keine Hooks.

Alex_ITA01 24. Nov 2004 14:23

Re: Probleme mit Hooks
 
ja ich weiß das es mit Timer geht, aber ich will das eben versuchen mit Hooks zu realisieren weil dann später ja mehr dazu kommt. Und bei den späteren Vorstellungen von mir reichen die Timer nicht mehr...
Trotzdem danke für die Antworten

MFG Alex

czapie 24. Nov 2004 14:29

Re: Probleme mit Hooks
 
Hast du dir schonmal die Tutorials von Assarbad angeguckt?
Assarbad

Alex_ITA01 24. Nov 2004 14:34

Re: Probleme mit Hooks
 
ja habe ich schon angeguckt nur weiß ich nicht so recht, wo der Fehler in meinem Prog ist?!!

Delphi-Quellcode:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure WMNCHITTEST(var Message: TWMMouseMove); message WM_NCHITTEST;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;  
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  hMouseHook: HHOOK;

function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): Integer; stdcall;

implementation

{$R *.dfm}

function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): Integer; stdcall;
var
  CTRLID : Word;
begin
  case nCode < HC_ACTION of
    True: Result := CallNextHookEx(hMouseHook,nCode,wParam,lParam);
  else
    CTRLID := GetDlgCtrlID(PMOUSEHOOKSTRUCT(lParam)^.hwnd);
    //if CTRLID <> 0 then
    begin
      SendMessage(Application.Handle,WM_MOUSEMOVE,wParam,lParam);
    end;
    Result := CallNextHookEx(hMouseHook,nCode,wParam,lParam);
  end;
end;

procedure TForm1.CMMouseEnter(var Message: TMessage);
begin
end;

procedure TForm1.CMMouseLeave(var Message: TMessage);
begin
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Self.Top := 0;
  hMouseHook := SetWindowsHookEx(WH_MOUSE,@MouseHookProc,0,GetCurrentThreadId());
end;

procedure TForm1.WMNCHITTEST(var Message: TWMMouseMove);
begin
  inherited;
  Label1.Caption := IntToStr(Message.XPos) + ' x ' + IntToStr(Message.YPos);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnhookWindowsHookEx(hMouseHook);
end;

procedure TForm1.WMMouseMove(var Message: TWMMouseMove);
begin
  Label1.Caption := IntToStr(Message.XPos) + ' x ' + IntToStr(Message.YPos);
end;

end.

Ultimator 24. Nov 2004 14:39

Re: Probleme mit Hooks
 
Wie immer die Frage: Was passiert bzw. was passiert nicht? :roll:

Alex_ITA01 24. Nov 2004 14:40

Re: Probleme mit Hooks
 
er zeigt mir nur die MousePos an, wenn ich über dem Formular bin. Ich möchte aber auch alle anderen Positionen außerhalb meiner Anwendung. Und das zeigt er nicht an (in dem Label)

Luckie 24. Nov 2004 14:46

Re: Probleme mit Hooks
 
Ist der Hook in einer DLL?

czapie 24. Nov 2004 14:46

Re: Probleme mit Hooks
 
nun ja ich bin der Meinung, dass systemweite Hooks nur durch .dll relaisiert werden können.
Vielleicht solltest du da nocheinmal ansetzen.
[Edit]Mist zu langsam![/Edit]

Alex_ITA01 24. Nov 2004 14:52

Re: Probleme mit Hooks
 
bin auch grade auf die Spur gekommen, das systemweite Hooks in DLL's müssen.
Okay habe auch ein Beispiel im Netz gefunden von -Assarbad-

Danke nochmals

MFg Alex

Luckie 24. Nov 2004 14:57

Re: Probleme mit Hooks
 
Zitat:

Zitat von Alex_ITA01
bin auch grade auf die Spur gekommen, das systemweite Hooks in DLL's müssen.

Äh, wir sind davon ausgegangen, dass so etwas grundlegendes über Hooks bekannt ist. :gruebel:

Alex_ITA01 26. Nov 2004 13:44

Re: Probleme mit Hooks
 
Liste der Anhänge anzeigen (Anzahl: 1)
da bin ich wieder... :-)
hab jetzt mal versucht den Hook in eine DLL einzubinden.
Nur leider weiß ich echt nicht, was ich falsch mache.Das Programm zeigt mir einfach keine X und Y Koordinaten an.Bitte helft mir (klingt ja fast wie: "Bitte melde dich" *ggg*)

Wäre echt toll wenn ihr mir ein Rat geben könntet woran es liegt.
Source für DLL und Formular liegt bei.

Assarbad ich habe nur von deinem Tutorial ein wenig abgespeckt. Ich gebe zu, das der Source von dir stammt :-D

MFG Alex

Alex_ITA01 2. Dez 2004 15:39

Re: Probleme mit Hooks
 
ich wollte mal fragen, wenn ich jetzt ein NICHT-Systemweiten Hook habe, brauche ich den ja nicht in eine DLL einbinden oder?

Funktioniert das, dass ich ein Hook in eine Komponente einbinde?
Ich habe es so probiert:

Delphi-Quellcode:
unit HintCheckBox;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Messages, Windows, Graphics, ExtCtrls;

type
  THintCheckBox = class(TCheckBox)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    MouseHook : HHOOK;
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
  published
    { Published-Deklarationen }
  end;

  function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;

{ ---------------------------------------------------------------------------- }
procedure Register;
{ ---------------------------------------------------------------------------- }
implementation
{ ---------------------------------------------------------------------------- }
procedure Register;
begin
  RegisterComponents('Beispiele', [THintCheckBox]);
end;
{ ---------------------------------------------------------------------------- }
{ THintCheckBox }
{ ---------------------------------------------------------------------------- }
function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;
begin
  case nCode < HC_ACTION of
    True :
      Result := CallNextHookEx(MouseHook, nCode, wParam, lParam);
  else
     //.....IRGENDWAS
    Result := CallNextHookEx(MouseHook, nCode, wParam, lParam);
  end;
end;
{ ---------------------------------------------------------------------------- }
constructor THintCheckBox.Create(AOwner: TComponent);
begin
  inherited;
  MouseHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, GetCurrentThreadId());
end;
Nur leider kennt er die Variable MouseHook in der Funktion "MouseProc" nicht. Ist ja logisch aber wenn ich die Funktion selber mit in den PRIVATE-Teil schreibe dann meckert der Compiler bei folgender Zeile:

Delphi-Quellcode:
  MouseHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, GetCurrentThreadId());
Variable erwartet an der Stelle: @MouseProc


Ich hoffe ihr könnt mir helfen...
MFG Alex

Muetze1 2. Dez 2004 17:56

Re: Probleme mit Hooks
 
Moin!

Ein Journalhook ist auch systemweit, benötigt aber keine DLL und kann in der Application eingebunden werden. Daher ist das mit der DLL keine zwingende Vorraussetzung.

MfG
Muetze1

Alex_ITA01 3. Dez 2004 13:45

Re: Probleme mit Hooks
 
also ich bin jetzt auf dem Stand, das ich in der Hook-Funktion eine Message an meine Komponente schicken will.Nur leider kenne ich das Handle der Komponente nicht.Könnt ihr mir bitte helfen?

Delphi-Quellcode:
unit HintCBx;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Messages, Windows, Graphics, ExtCtrls;

const
  WM_HINT = WM_USER + 1;

type
  THintCBx = class(TCheckBox)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    procedure WMHint(var Message: TWMMouseMove); message WM_HINT;

    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
  published
    { Published-Deklarationen }
  end;

  function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;

var
  MouseHook    : HHOOK;
{ ---------------------------------------------------------------------------- }
procedure Register;
{ ---------------------------------------------------------------------------- }
implementation
{ ---------------------------------------------------------------------------- }
procedure Register;
begin
  RegisterComponents('Beispiele', [THintCBx]);
end;
{ ---------------------------------------------------------------------------- }
{ THintCBx }
{ ---------------------------------------------------------------------------- }
function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;
begin
  if (wParam = WM_MOUSEMOVE) then
  begin
    if ControlHandle <> 0 then
    begin
      //SendMessage(ControlHandle,WM_MOUSEMOVE,wParam,lParam);
      SendMessage(HANDLE,WM_HINT,wParam,lParam);
    end;
  end;
  Result := CallNextHookEx(MouseHook,nCode,wParam,lParam);
end;
{ ---------------------------------------------------------------------------- }
constructor THintCBx.Create(AOwner: TComponent);
begin
  inherited;
  MouseHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, GetCurrentThreadId());
end;
{ ---------------------------------------------------------------------------- }
destructor THintCBx.Destroy;
begin
  if MouseHook <> 0 then
    UnhookWindowsHookEx(MouseHook);
  inherited;
end;
In WM_HINT erfolgt dann meine Auswertung...
Nur ich brauche das Komponenten-Handle für SendMessage?!
Hoffe ihr könnt mir helfen

MFG Alex

Alex_ITA01 4. Dez 2004 16:49

Re: Probleme mit Hooks
 
[push!!!]

Hat keiner eine Idee, wie ich an das "Komponenten-handle" herankomme um SendMessage in dem MouseHook zu verwenden?!
Ich wäre über jeden Lösungsvorschlag erfreut....

MFG Alex

Assarbad 5. Dez 2004 21:19

Re: Probleme mit Hooks
 
@Muetze: Journal-Hooks sind aber ursprünglich als Accessibility-Feature gedacht gewesen (also zur Erleichterung für Behinderte), nicht um sie als Maushook zu mißbrauchen. Hooks haben negativen Einfluß auf die Systemperformance (wenn auch nur gering), deshalb sollte man den passenden benutzen.

@Alex: Problem Problem ... du verstehst offenbar noch nicht, wie Klassen im Speicher liegen. Man kann auch statische Funktionen (sowas brauchst du für die Callback) in einem Objekt haben, dies ist aber absolut nicht zu empfehlen. Stattdessen sollte eine Callback-Funktion außerhalb des Objektes liegen und mit dem Objekt über dessen Interfaces kommunizieren. Das Problem mit Methoden von Klassen/Objekten ist, daß man deren Position im Speicher mit @ nicht zuverlässig ermitteln kann!

Zitat:

Zitat von Alex_ITA01
Assarbad ich habe nur von deinem Tutorial ein wenig abgespeckt. Ich gebe zu, das der Source von dir stammt :-D

Der Source ist mit Absicht frei. Also gibt's sicher kein Problem, solange man sich an die Lizenzvorgaben hält :-D

Zitat:

Zitat von Alex_ITA01
also ich bin jetzt auf dem Stand, das ich in der Hook-Funktion eine Message an meine Komponente schicken will.Nur leider kenne ich das Handle der Komponente nicht.Könnt ihr mir bitte helfen?

...

In WM_HINT erfolgt dann meine Auswertung...
Nur ich brauche das Komponenten-Handle für SendMessage?!
Hoffe ihr könnt mir helfen

Ganz simpel. TCheckBox hat ein Handle, also mußt du in deiner Komponente diese Eigenschaft nur als Public deklarieren, einen Wrapper schreiben oder eine Readonly-Property einführen, die den Wert zurückgibt. Dennoch gilt obiges für statische Funktionen.

Alex_ITA01 6. Dez 2004 07:17

Re: Probleme mit Hooks
 
okay danke @Assarbad...
also ich werde jetzt das CheckBox-Handle "veröffentlichen" und darüber kann ich dann also zugreifen? Ich hoffe das funktioniert so einfach wie es sich anhört :-))
also danke nochmal,werde es dann gleich mal testen
MFG Alex

Alex_ITA01 6. Dez 2004 07:47

Re: Probleme mit Hooks
 
also das Handle lasse ich mir jetzt so geben:

Delphi-Quellcode:
type
  THintCBx = class(TCheckBox)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    function GetHandle : HWND;
    //...
  end;

function THintCBx.GetHandle: HWND;
begin
  Result := Self.Handle;
end;
Kann ich da in meinem MouseHook jetzt so darauf zugreifen oder wie mache ich das jetzt?

Delphi-Quellcode:
var
  Test : THintCBx;
begin
  if (wParam = WM_MOUSEMOVE) then
  begin
    if Test.GetHandle <> 0 then
    begin
      //SendMessage(ControlHandle,WM_MOUSEMOVE,wParam,lParam);
      SendMessage(Test.GetHandle,WM_HINT,wParam,lParam);
    end;
  end;
  Result := CallNextHookEx(MouseHook,nCode,wParam,lParam);
MFG Alex

Assarbad 6. Dez 2004 08:28

Re: Probleme mit Hooks
 
Also das mit dem Kapseln in der Funktion ist schonmal richtig. Aber ob du direkt vom Hook aus darauf zugreifen kannst, weiß ich nicht. Der Normale Weg sollte ja sein, daß der Hook unabhängig von Code in einer Anwendung ist. Zumindest weitgehend. Also würde ich zB innerhalb der DLL immer während der Initialisierung eine Variable mit dem Fensterhandle setzen - danach dann auf diese lokale Variable zugreifen. Meinetwegen noch mit Checks wie: IsWindow(hWindowHandle) ...

Alex_ITA01 6. Dez 2004 09:20

Re: Probleme mit Hooks
 
ich dachte, ich brauche keine DLL?!
Ich habe doch nur in der Komponente den MouseHook und ich brauche ihn ja auch nur dort.Daher wäre eine DLL nicht angebracht (denke ich zumindest...).
Ich weiß auch noch nicht so ganz wie ich daran komme...
Ich kannte mal eine Funktion, die mir glaube ich ein TControl zurückgibt, wo sich die Maus grade darüber befindet.Nur weiß ich nicht mehr wie die hieß....

MFG Alex

Assarbad 6. Dez 2004 10:04

Re: Probleme mit Hooks
 
Ist ja korrekt, du brauchst auch keine DLL. Ich kenne aber deine Implementierung nicht, daher kann ich ja nur mutmaßen.

Alex_ITA01 6. Dez 2004 10:09

Re: Probleme mit Hooks
 
ich habe doch oben den kompletten source stehen...
Ich werde ihn nochmal Posten:

Delphi-Quellcode:
unit HintCBx;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Messages, Windows, Graphics, ExtCtrls;

const
  WM_HINT = WM_USER + 1;

type
  THintCBx = class(TCheckBox)
  private
    { Private-Deklarationen }
    HintWnd : THintWindow;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    function GetHandle : HWND;

    procedure WMHint(var Message: TWMMouseMove); message WM_HINT;

    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
    procedure Loaded; override;
  published
    { Published-Deklarationen }
  end;

  function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;

var
  MouseHook    : HHOOK;
{ ---------------------------------------------------------------------------- }
procedure Register;
{ ---------------------------------------------------------------------------- }
implementation
{ ---------------------------------------------------------------------------- }
procedure Register;
begin
  RegisterComponents('Beispiele', [THintCBx]);
end;
{ ---------------------------------------------------------------------------- }
{ THintCBx }
{ ---------------------------------------------------------------------------- }
function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;
var
  MPos : TPoint;
  Komp : TControl;
begin
  if (wParam = WM_MOUSEMOVE) then
  begin
    GetCursorPos(MPos);
   
    Komp := FindDragTarget(MPos, True);

    if Test.GetHandle <> 0 then
    begin
      //SendMessage(ControlHandle,WM_MOUSEMOVE,wParam,lParam);
      SendMessage(Test.GetHandle,WM_HINT,wParam,lParam);
    end;
  end;
  Result := CallNextHookEx(MouseHook,nCode,wParam,lParam);
end;
{ ---------------------------------------------------------------------------- }
constructor THintCBx.Create(AOwner: TComponent);
begin
  inherited;
  HintWnd := THintWindow.Create(Self);
  HintWnd.Color := clInfoBk;
  ShowHint := True;
  MouseHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, GetCurrentThreadId());
end;
{ ---------------------------------------------------------------------------- }
destructor THintCBx.Destroy;
begin
  HintWnd.Free;
  if MouseHook <> 0 then
    UnhookWindowsHookEx(MouseHook);
  inherited;
end;
{ ---------------------------------------------------------------------------- }
function THintCBx.GetHandle: HWND;
begin
  Result := Self.Handle;
end;
{ ---------------------------------------------------------------------------- }
procedure THintCBx.Loaded;
begin
  Inherited Loaded;
  if ComponentState = [csDesigning] then Exit;
end;
{ ---------------------------------------------------------------------------- }
procedure THintCBx.WMHint(var Message: TWMMouseMove);
var
  rec : TRect;
  MPos: TPoint;
  tmpHint : String;
begin
  if Assigned(HintWnd) then
  begin
    tmpHint := Hint;
    GetCursorPos(MPos);
    MPos := ScreenToClient(MPos);

    rec := Rect(Self.Left, Self.Top, Self.Left + Self.Width, Self.Top + Self.Height);
    if (PtInRect(rec, point(MPos.X + Self.Left, MPos.Y + Self.Top))) and (not Self.Enabled) and (Self.ShowHint) then
    begin
      GetCursorPos(MPos);
      HintWnd.Color := clInfoBk;
      HintWnd.ActivateHint(Rect(MPos.X + 15, MPos.Y, MPos.X + 20 + HintWnd.Canvas.TextWidth(tmpHint), MPos.Y + 15), tmpHint);
    end
    else
      HintWnd.ReleaseHandle;
  end;
  Message.Result := 1;
end;
{ ---------------------------------------------------------------------------- }

{ ---------------------------------------------------------------------------- }
end.
In der MouseProc experiementiere ich grade noch rum, daher geht das nicht zu compilieren...
Ich brauche dieses Handle der Komponente...

MFG Alex

Alex_ITA01 6. Dez 2004 11:06

Re: Probleme mit Hooks
 
also wie gesagt, ich brauche in der MouseProc nur das Handle damit ich meine Komponente informieren kann...
Die Komponente wertet dann die Werte aus :-)

Hoffe du kannst mir helfen Assarbad...

MFG Alex

Assarbad 6. Dez 2004 11:54

Re: Probleme mit Hooks
 
Immer mit der Ruhe, ein alter Mann ist kein D-Zug ;) ... ich schau vermutlich am späten Nachmittag mal drauf. Hab schließlich auch andere Sachen zu tun.

Alex_ITA01 6. Dez 2004 12:25

Re: Probleme mit Hooks
 
ja ist okay, wollte dich nicht hetzen :-)
bis dann, alex

Assarbad 6. Dez 2004 20:30

Re: Probleme mit Hooks
 
Tja, zum eigentlichen Problem (Callback als Methode) gibt es hier einen schönen Artikel:
http://bdn.borland.com/article/0,1410,22225,00.html

Laut Implementierung in Forms.pas könnte man das auch an deinen Fall anpassen. Fehlt mir aber aktuell die Zeit für solche Späßchen.

Die relevanten Funktionen aus Forms.pas sind:
function MakeObjectInstance(Method: TWndMethod): Pointer;
procedure FreeObjectInstance(ObjectInstance: Pointer);

Problem sind Kleinigkeiten in der Implementierung und der Typ "TWndMethod" ... die angepaßt werden müssten. TWndMethod hat nämlich 4 Parameter + Rückgabe ... eine HookProc nur 3 + Rückgabe.

Alex_ITA01 7. Dez 2004 07:35

Re: Probleme mit Hooks
 
okay danke @Assarbad
werde es bei gelegenheit mal probieren.

Ich dachte, dass Problem sei einfacher zu lösen :-)))) aber naja ich werde mich da mal reinfitzen.
Danke nochmals.
Schön Tag noch
MFG Alex

SirThornberry 7. Dez 2004 09:19

Re: Probleme mit Hooks
 
Du bekommst die Mausposition nicht angezeigt weil die DLL in jedes Programm eingebunden wird. Das heißt die DLL wird merhmals geladen. Somit musst du in der DLL die Informationen erst zu deiner Anwendung schicken (welche du natürlich davor erstmal finden musst)

Assarbad 7. Dez 2004 10:08

Re: Probleme mit Hooks
 
Er benutzt ja keine DLL sondern einen lokalen Hook.

Alex_ITA01 7. Dez 2004 10:16

Re: Probleme mit Hooks
 
jup, das ist richtig @Assarbad.
Ich hatte aber noch keine Zeit das zu testen was du mir geschickt hast (den Link).Werde es heute Abend mal probieren.
Hast du sowas schonmal gemacht mit dem "übergeben" einer Methode?

Assarbad 7. Dez 2004 10:43

Re: Probleme mit Hooks
 
Ja, finde es aber nciht mehr. Ich hatte damals nur eine Lösung für eine einzige Instanz gemacht.

Apropos: vielleicht hilft dir auch WM_MOUSEHOVER und WM_MOUSELEAVE ... dann brauchst du nur diese beiden Nachrichten abfangen! Einziges Problem: es geht erst ab NT 4.0 und Windows 98. Also keine Lösung für Windows 95.

Kannst ja auch mal in den VCL-Sourcen schauen, wie die OnEnter und OnLeave implementiert haben.

Alex_ITA01 7. Dez 2004 10:50

Re: Probleme mit Hooks
 
das Problem ist ja, dass eine "disabledte" Komponente keine WM_MOUSEMOVE, LEAVE oder ENTER-Events erhält...
Daher habe ich mir ja die eigene Nachricht erstellt, die auch nur ausgeführt wird, wenn eben die Komponente auch wirklich disabled ist.Ansonsten treffen ja alle anderen Windows-Nachrichten ein.
Weißt du zufällig wie man dieses Verhalten "abschalten" könnte? Das z.B. die Nachrichten nicht mehr eintreffen nur wenn die Kompo disabled ist?

MFG Alex

Alex_ITA01 7. Dez 2004 11:48

Re: Probleme mit Hooks
 
Habs grade mal getestet:

Delphi-Quellcode:
unit HintCBx;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Messages, Windows, Graphics, ExtCtrls;

const
  WM_HINT = WM_USER + 1;

type
  THintCBx = class(TCheckBox)
  private
    { Private-Deklarationen }
    HintWnd : THintWindow;
    OldWndProc: Pointer;
    NewWndProc: Pointer;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    function GetHandle : HWND;

    procedure WMHint(var Message: TMessage); message WM_HINT;

    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
    procedure Loaded; override;
  published
    { Published-Deklarationen }
  end;

  function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;

var
  MouseHook : HHOOK;
{ ---------------------------------------------------------------------------- }
procedure Register;
{ ---------------------------------------------------------------------------- }
implementation
{ ---------------------------------------------------------------------------- }
procedure Register;
begin
  RegisterComponents('Beispiele', [THintCBx]);
end;
{ ---------------------------------------------------------------------------- }
{ THintCBx }
{ ---------------------------------------------------------------------------- }
function MouseProc(nCode : Integer; wParam: WPARAM; lParam : LPARAM): LRESULT; stdcall;
var
  MPos : TPoint;
  Komp : TControl;
  Test : THintCBx;
begin
  if (wParam = WM_MOUSEMOVE) then
  begin
    //GetCursorPos(MPos);
    MPos.X := 105;
    MPos.Y := 18;
    Komp := FindDragTarget(MPos, True);
    if Komp is THintCBx then
    begin
      Test := Komp as THintCBx;
      if Test.GetHandle <> 0 then
      begin
        //SendMessage(ControlHandle,WM_MOUSEMOVE,wParam,lParam);
        SendMessage(Test.GetHandle,WM_HINT,wParam,lParam);
      end;
    end;
  end;
  Result := CallNextHookEx(MouseHook,nCode,wParam,lParam);
end;
{ ---------------------------------------------------------------------------- }
constructor THintCBx.Create(AOwner: TComponent);
begin
  inherited;
  HintWnd := THintWindow.Create(Self);
  HintWnd.Color := clInfoBk;
  ShowHint := True;

  MouseHook := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, GetCurrentThreadId());
end;
{ ---------------------------------------------------------------------------- }
destructor THintCBx.Destroy;
begin
  SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(OldWndProc));
  FreeObjectInstance(NewWndProc);

  HintWnd.Free;
  if MouseHook <> 0 then
    UnhookWindowsHookEx(MouseHook);
  inherited;
end;
{ ---------------------------------------------------------------------------- }
function THintCBx.GetHandle: HWND;
begin
  Result := Self.Handle;
end;
{ ---------------------------------------------------------------------------- }
procedure THintCBx.Loaded;
begin
  Inherited Loaded;
  if ComponentState = [csDesigning] then Exit;
  NewWndProc := MakeObjectInstance(WMHint);
  OldWndProc := TFNWndProc(GetWindowLong(Self.Handle, GWL_WNDPROC));
  SetWindowLong(Self.Handle, GWL_WNDPROC, Longint(NewWndProc));
end;
{ ---------------------------------------------------------------------------- }
procedure THintCBx.WMHint(var Message: TMessage);
var
  rec : TRect;
  MPos: TPoint;
  tmpHint : String;
begin
  if Assigned(HintWnd) then
  begin
    tmpHint := Hint;
    GetCursorPos(MPos);
    MPos := ScreenToClient(MPos);

    rec := Rect(Self.Left, Self.Top, Self.Left + Self.Width, Self.Top + Self.Height);
    if (PtInRect(rec, point(MPos.X + Self.Left, MPos.Y + Self.Top))) and (not Self.Enabled) and (Self.ShowHint) then
    begin
      GetCursorPos(MPos);
      HintWnd.Color := clInfoBk;
      HintWnd.ActivateHint(Rect(MPos.X + 15, MPos.Y, MPos.X + 20 + HintWnd.Canvas.TextWidth(tmpHint), MPos.Y + 15), tmpHint);
    end
    else
      HintWnd.ReleaseHandle;
  end;
  //Message.Result := 1;
  Message.Result := DefWindowProc(Self.Handle, Message.Msg, Message.WParam, Message.LParam);
end;
{ ---------------------------------------------------------------------------- }

{ ---------------------------------------------------------------------------- }
end.
Das ist die kompo jetzt.Leider wird sie nicht richtig dargestellt. Ich habe auf der Form ein durchsichtigen Teil (wo sich im Designer die Kompo befindet) wo ich mein Desktop durchsehen kann.Und beim Beenden der Anwendung kommt ein Fehler.
Es wäre super nett von dir Assarbad, wenn du mal ein Blick drauf werfen könntest und mir vielleicht sagen könntest, wo der Fehler liegt...

MFg Alex

Alex_ITA01 13. Dez 2004 11:17

Re: Probleme mit Hooks
 
@assarbad: Könntest du mir vielleicht ein kleines Testprogramm zeigen, wie man eine VCL Klassen-Funktion als Win32 callback verwendet?
Ich bekomme es einfach nicht hin...
Es wäre echt nett wenn mir da jemand helfen könnte...
MFG Alex

stoxx 13. Dez 2004 17:32

Re: Probleme mit Hooks
 
Zitat:

Zitat von Alex_ITA01
Könntest du mir vielleicht ein kleines Testprogramm zeigen, wie man eine VCL Klassen-Funktion als Win32 callback verwendet?

MFG Alex



Schau hier Seite 2:

http://www.delphipraxis.net/internal...ct.php?t=17992
Gruß stoxx


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:38 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz