Timelesk - So 07.11.10 18:18
Titel: Eigene Komponente zu Handle finden
Hallo,
ich hole mir ein Handle einer Komponente die unter dem Mauszeiger liegt mit folgendem Code:
Delphi-Quelltext
1: 2: 3: 4:
| wnd := Form1.Handle; pt:= mouse.CursorPos; windows.ScreenToClient(wnd, pt); Label1.Caption := inttostr(ChildWindowFromPoint(wnd, pt)); |
Nun möchte ich den Namen der Komponente, dessen Handle gefunden wurde.
Aber wie "wandle" ich das Handle in eine Komponente um?
Ich hab da überhaupt nichts passendes gefunden. Ist es zu offensichtlich?
Vielen Dank.
gruß
Timelesk
Timelesk - So 07.11.10 18:40
Hi,
ich möchte eine Art Hilfe schreiben.
Dazu lasse ich eine Form als Overlay über der Hauptform mit AlphaBlending anzeigen und der Benutzer kann dann zur Anzeige der Hilfe auf die Komponente "klicken"
Edit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| var pt: TPoint; wnd: HWND; begin wnd := Main.Handle; pt:= mouse.CursorPos; windows.ScreenToClient(wnd, pt); Main.Caption := FindControl(ChildWindowFromPoint(wnd, pt)).Name; |
Das funktioniert nun soweit, dass er mir die richtige Komponente gibt, jedoch nicht in der Ebene.
Also wenn ich in einem Panel einen Button habe, gibt er mir den Namen des Panels, aber nicht des Buttons aus.
Weiß jemand, wie ich hier die nächste Ebene "erklimmen" kann?
Besten Dank.
@toms: Vielen Dank noch einmal für das "vor Augen führen" des Codes. Dadurch bin ich auf FindControl gestoßen.
gruß
Timelesk
Timelesk - So 07.11.10 19:19
Got it!
Es gibt die Funktion
RealWindowFromPoint von
Eugen Honeker.
Diese Funktion habe ich um ein Handle erweitert und umbenannt in
ComponentFromPoint
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:
| function ComponentFromPoint(wnd: HWND; pt: TPoint{$IFDEF RWFPCHOICE}; swinvis: boolean = true{$ENDIF}): HWND;
type PCHILDS_ENUM = ^CHILDS_ENUM; CHILDS_ENUM = record nDiff: integer; hWndFound: HWND; pt: TPoint; {$IFDEF RWFPCHOICE} showinvis: boolean; {$ENDIF RWFPCHOICE} end;
var ce: CHILDS_ENUM;
function EnumProc(hwndChild: HWND; lParam: LPARAM): Boolean; stdcall;
var rc: TRECT; begin GetWindowRect(hwndChild, rc);
with PCHILDS_ENUM(lParam)^, rc do {$IFDEF RWFPCHOICE} case showinvis of true: if (pt.x >= Left) and (pt.x < Right) and (pt.y >= Top) and (pt.y < Bottom) and (nDiff > (Right - Left) + (Bottom - Top)) then begin hWndFound := hwndChild; nDiff := (Right - Left) + (Bottom - Top); end; else if (pt.x >= Left) and (pt.x < Right) and (pt.y >= Top) and (pt.y < Bottom) and (nDiff > (Right - Left) + (Bottom - Top)) and IsWindowVisible(hwndChild) then begin hWndFound := hwndChild; nDiff := (Right - Left) + (Bottom - Top); end; end; {$ELSE RWFPCHOICE} if (pt.x >= Left) and (pt.x < Right) and (pt.y >= Top) and (pt.y < Bottom) and (nDiff > (Right - Left) + (Bottom - Top)) then begin hWndFound := hwndChild; nDiff := (Right - Left) + (Bottom - Top); end; {$ENDIF RWFPCHOICE} Result := True; end;
begin ce.nDiff := MAXLONG; ce.hWndFound := wnd; ce.pt.x := pt.x; ce.pt.y := pt.y; {$IFDEF RWFPCHOICE} ce.showinvis := swinvis; {$ENDIF RWFPCHOICE} if (ce.hWndFound <> 0) then begin if (GetWindowLong(ce.hWndFound, GWL_STYLE) and WS_CHILD <> 0) then ce.hwndFound := GetParent(ce.hwndFound); EnumChildWindows(ce.hWndFound, @EnumProc, Integer(@ce)); end; Result := ce.hwndFound; end; |
und dann einfach diesen Code irgendwo platzieren (FormClick, Timer):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| var pt: TPoint; wnd: HWND; begin wnd := Self.Handle; pt:= mouse.CursorPos; Label1.Caption := FindControl(ControlFromPoint(wnd, pt)).Name; |