Autor Beitrag
JohnMcClane
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 09.05.04 15:00 
Hi,

Ich arbeite gerade an einem Komponentenpackage mit dem es möglich sein soll skinfähige Programme zu erstellen. Unter anderem ist auch ein HoverButton dabei, bei dem ich dann darauf gekommen bin, dass es nicht möglich ist herauszufinden, wann die maus die komp. verlässt bzw. mousemove messages zu erhalten, wenn sich die maus nicht über der eigenen Anwendung befindet. Da es in meiner Natur liegt, nicht alles immer gleich aufzugeben, habe ich ein bisschen gesucht und bin dann auf Hooks gestoßen (unter anderem Assarbad's Tut, welches ich aber nicht wirklich verstehe).

Ich habe es also mit einem Hook versucht, welchen ich in einer DLL ausgelagert habe (wie es ja sein soll), und erhalte auch Messages von dieser DLL, allerdings, und da liegt mein Problem, erhalte ich die Nachrichten weiterhin nur, wenn sich mit die Maus über der eigenen Anwendung befindet und ich kann da einfach keinen Fehler finden.

Meine dll:

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:
96:
97:
98:
library GraphicControls;

uses
  SysUtils,
  Windows,
  Messages,
  Classes;

function SetHook:Boolean; exportforward;
procedure UnHook; exportforward;
procedure SetWindowHandle(WindowHandle: HWND); exportforward;
function HookProc(nCode: Integer; WPARAM: wParam; LPARAM: lParam):LResult; stdcallforward;

exports
  SetHook index 1,
  UnHook index 2,
  SetWindowHandle index 3;

var H: HWND = 0;
    HookID: HHook;

function SetHook:Boolean;
begin
  HookID := SetWindowsHookEx(WH_MOUSE, @HookProc, hInstance, 0);
  if HookID <> 0 then
    Result := True
  else
    Result := False;
end;

procedure Unhook;
begin
  UnHookWindowsHookEx(HookID);
end;

procedure SetWindowHandle(WindowHandle: HWND);
begin
  H := WindowHandle;
end;

function HookProc(nCode: Integer; WPARAM: wParam; LPARAM: lParam): LResult; stdcall;
begin
  if nCode >= 0 then begin
    SendMessage(H, WM_MOUSEMOVE, WPARAM, LPARAM);
    Result := CallNextHookEx(WH_MOUSE, nCode, wParam, lParam);
  end
  else
    Result := CallNextHookEx(WH_MOUSE, nCode, wParam, lParam);
end;
[/code]

auszug aus meiner komponente (ich möchte hier nicht den ganzen quellcode zeigen):

[code]

type THoverButton = class(TCustomControl)
 ...
 ...   

implementation

function SetHook:Boolean; external 'C:\Programme\Borland\Delphi7\Lib\GraphicControls.dll';
procedure UnHook; external 'C:\Programme\Borland\Delphi7\Lib\GraphicControls.dll';
procedure SetWindowHandle(WindowHandle: HWND); external 'C:\Programme\Borland\Delphi7\Lib\GraphicControls.dll';
 
 ...

procedure THoverButton.SetParent(AParent: TWinControl);
begin
  inherited;
  if csDesigning in ComponentState then exit;
  ....
  ....
  if not FHooked then begin
    SetWindowHandle(Handle);
    SetHook;
    FHooked := True;
  end;
end;

 ...

constructor THoverButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  //Initialize variables
  ControlStyle := [csOpaque, csReplicatable, csDoubleClicks, csCaptureMouse, csClickEvents];
  ...
  FHooked := False;
end;

destructor THoverButton.Destroy;
begin
  // Free up resources
  ....
  inherited Destroy;
  if FHooked then Unhook;
end;


Ich habe versucht SetHook im constructor aufzurufen, doch dann erhalte ich immer die Fehlermeldung: CONTROL HAS NO PARENT....
Der selbe Fehler taucht auch auf, wenn ich UnHook vor inherited Destroy aufrufe - keine Ahnung warum. Wie gesagt so funktioniert der Code zwar, aber immer noch nur wenn ich mit der Maus über meiner Anwendung bin.

Ich hoffe, dass mir dabei jemand helfen kann, denn das Problem bereitet mir schon seit längerem großen Frust und Ärger :(

Moderiert von user profile iconMotzi: Code- durch Delphi-Tags ersetzt.
JohnMcClane Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 09.05.04 17:58 
Kommt schon, bitte - das is wirklich wichtig für mich. Irgendwer muss doch was wissen :cry:
bms
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 735

Win XP
Delphi 3, Delphi 6 PE, Delphi 2005 PE
BeitragVerfasst: So 09.05.04 18:18 
Ich veratte dir etwas ganz böses. Hier gib es ein geheimes Forum für alte Hasen. Da verschwören sich die alte Hasten gegen bestimmte Fragen.

Das ist auch der Grund wieso an einem Sonntag innerhalb von zwei Stunden keine Antworten auf bestimmte Fragen kommen.

:twisted: :twisted: :twisted:

_________________
VORSICHT: Ich behersche seit heute die Fünf-Finger-Handflächen-Herz-Explodier-Schlag-Kampf-Technik >:(
JohnMcClane Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 09.05.04 19:48 
Sehr witzig,

Ich hab mein Problem jetzt in den Griff bekommen, allerdings auf eine andere Art, die nicht ganz so umständlich ist, wie Hooks zu programmieren.
Für diejenigen, die es interessiert:

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:
type THoverButton = class(TCustomControl)
    ....
   procedure MouseLeavesTheForm(var m: TMessage);
    ....
end;

.....

procedure THoverButton.MouseLeavesTheForm(var m: TMessage);
begin
  inherited;
  ....
  FisTracking := False;
  m.Result := 1;
end;

....

procedure THoverButton.WMMouseMove(var Msg: TWMMouseMove);
begin
  inherited;
  if not FisTracking then begin
    TrackMouseEvent(FevtTrack);
    FisTracking := True;
  end;
end;

....

procedure THoverButton.SetParent(AParent: TWinControl);
begin
  inherited;
  if csDesigning in ComponentState then exit;
  if AParent <> nil then begin
  with FevtTrack do begin
    cbSize := sizeOf(tagTRACKMOUSEEVENT);
    dwFlags := TME_LEAVE;
    hwndTrack := Handle;
    dwHoverTime := HOVER_DEFAULT;
  end;
end;


Funktionieren tut es, aber wobei ich mir noch ziemlich unsicher bin, ist ob ich den Track Event auch wieder aufräumen muss oder nicht ?! :?:
JohnMcClane Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: So 09.05.04 20:48 
Zu früh gefreut, es funktioniert nicht mehr wenn man kleinere buttons hat ca. 20x20 pixel, und mit der maus sich zu schnell rausbewegt - vielleicht kann mir ja da einer helfen
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 09.05.04 20:59 
Hallo

da gibts schon etliche beiträge dazu im Forum, Suche in: Delphi-Forum, Delphi-Library CM_MOUSELEAVE Suche in: Delphi-Forum, Delphi-Library CM_MOUSEENTER, dort solltest du fündig werden.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
JohnMcClane Threadstarter
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Mo 10.05.04 09:17 
Nein da gibt es eben keine Beiträge dazu, ich habe bereits das Forum durchsucht. CM_MOUSELEAVE wird nur aufgerufen, wenn man die Maus aus der Komponente rausbewegt UND noch mit der Maus über der eigenen Anwendung oder Form ist. Hat man diese Komponente zb. am r. Rand der Form und BorderStyle der Form auf bsNone und bewegt anschliessend die Maus nach rechts, so verlässt man zwar die Komponente, ist aber NICHT mit der Maus über der eigenen Form -> d.h. es wird auch die CM_MOUSELEAVE NICHT aufgerufen.

Daher versuche ich es ja über Tracking :wink:

Ich hätte mir da eher Hilfe erhofft von Assarbad oder Luckie (der sich ja anscheinend ziemlich gut mit der WinAPI auskennt - zumindest wenn man das nach seinem Tut. beurteilt) :roll: