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 Control Handle unter dem Mauscursor (https://www.delphipraxis.net/165475-control-handle-unter-dem-mauscursor.html)

Neotracer 2. Jan 2012 01:26

Control Handle unter dem Mauscursor
 
Hallo,

ich habe folgenden Code um das Window Handle vom Control unter der Maus herauszufinden:
(calc.exe als Beispiel)

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  ahwnd: HWND;
  aPoint: Tpoint;
begin
  ahwnd := FindWindow('CalcFrame','Rechner');

  aPoint := Mouse.CursorPos;
  Windows.ScreenToClient(ahwnd,aPoint);

  Label1.Caption := 'X: '+IntToStr(aPoint.X);
  Label2.Caption := 'Y: '+IntToStr(aPoint.Y);

  aHwnd := ChildWindowFromPoint(ahwnd,aPoint);
  Edit1.Text := IntToStr(aHwnd);
end;
Allerdings bekomme ich nur das Window von einem Panel tiefer, aber nicht die Handle vom Button selbst.
Hier sieht man's:

http://www.abload.de/img/failzgajj.jpg

Was mache ich falsch?

Danke schonmal.

Bummi 2. Jan 2012 07:23

AW: Control Handle unter dem Mauscursor
 
nimm statt ChildWindowFromPoint die Funktion WindowFromPoint ...

Neotracer 2. Jan 2012 14:33

AW: Control Handle unter dem Mauscursor
 
Stimmt, das geht. :shock:

Aber ich wollte ja eigentlich von Client Koordinaten + Client Window -> Control Handle kommen.
Jetz habe ich Screen Koordinaten -> Control Handle. :|

DeddyH 2. Jan 2012 14:42

AW: Control Handle unter dem Mauscursor
 
Könnte man nicht mit MSDN-Library durchsuchenGetParent und MSDN-Library durchsuchenGetWindowRect die Koordinaten des übergeordneten Fensters holen und so die Client-Koordinaten selber berechnen?

Neotracer 2. Jan 2012 14:51

AW: Control Handle unter dem Mauscursor
 
Aber das erste übergeordnete Fenster von dem Control was ich kriege, muss ja nicht unbedingt das Fenster sein, von dem ich ausgehen will?

Wobei: Ich könnte solange GetParent loopen bis ich das Client Window hab, von dem ich ausgehen will. Das könnte ich probieren. Danke.

Neotracer 2. Jan 2012 16:30

AW: Control Handle unter dem Mauscursor
 
Irgendetwas stimmt noch nicht ganz.

Hab mir jetzt folgendes gebastelt:

Delphi-Quellcode:
function WindowFromRelativePoint(wnd: HWND; pt: TPoint): HWND;
var
  r: TRect;
begin
  GetWindowRect(wnd,r);
  pt.X := pt.X + r.Left;
  pt.Y := pt.Y + r.Top;

  //Form1.Label3.Caption := 'X: '+IntToStr(pt.X);
  //Form1.Label4.Caption := 'Y: '+IntToStr(pt.Y);

  result := WindowFromPoint(pt);
end;
Die Funktion rufe ich so auf:

Delphi-Quellcode:
  ahwnd := FindWindow('CalcFrame','Rechner');

  aPoint := Mouse.CursorPos;

  //Label1.Caption := 'X: '+IntToStr(aPoint.X);
  //Label2.Caption := 'Y: '+IntToStr(aPoint.Y);

  Windows.ScreenToClient(ahwnd,aPoint);

  aHwnd := WindowFromRelativePoint(ahwnd, aPoint);

Folgendes passiert:
- absolute Mauskoordinaten werden geholt
- Umgerechnet auf ClientKoordinaten des Fensters von calc.exe (ScreenToClient)
- Relative Koordinaten werden meiner Funktion übergeben
- Meine Funktion holt sich das WindowRect und rechnet wieder in absolute Koordinaten um, damit WindowFromPoint funktioniert.

So. Als Test habe ich nun beides mal in Labels die Koordinaten ausgegeben.
- Einmal die absoluten Koordinaten der Maus direkt
- beim zweiten mal in der Funktion, wo die relativen wieder zu absoluten Koordinaten umgerechnet werden sollen.

Also müssten am Ende beide Label-Paare die gleichen Koordinaten ausgeben, richtig?
Ist blöderweise nicht sooo...
Wenn ich die Maus ganz oben links in die Ecke schiebe, dann habe ich beim ersten Labelpaar (0,0) aber beim zweiten irgendetwas anderes?! (-3,-41)

Übrigens auch unabhängig davon wo ich das Fenster von calc.exe hinschiebe. :?

Was mache ich falsch? Man muss doch von absoluten zu Client-Koordinaten und wieder zurückrechnen können, ohne, dass da solche Ungenauigkeiten auftreten?

//EDIT:
Es geht jetzt mit ClientToScreen anstatt selbst zu rechnen. Wäre trotzdem interessant zu wissen, was an der Rechnung falsch ist.

Neotracer 2. Jan 2012 17:43

AW: Control Handle unter dem Mauscursor
 
ScreenToClient/ClientToScreen baut irgendwie Mist. :roll:
Ich übergebe das MainWindow und er rechnet mit dem ersten Child... bei calc.exe zumindest.

Habe mit jetzt eigene Funktionen geschrieben. Geht wunderbar.

Delphi-Quellcode:
procedure ScreenToClient2(wnd: HWND; var pt: TPoint);
var
  r: TRect;
begin
  if GetWindowRect(wnd, r) then
  begin
    pt.X := pt.X - r.Left;
    pt.Y := pt.Y - r.Top;
  end;
end;

procedure ClientToScreen2(wnd: HWND; var pt: TPoint);
var
  r: TRect;
begin
  if GetWindowRect(wnd, r) then
  begin
    pt.X := pt.X + r.Left;
    pt.Y := pt.Y + r.Top;
  end;
end;

function WindowFromRelativePoint(wnd: HWND; pt: TPoint): HWND;
begin
  ClientToScreen2(wnd,pt);
  result := WindowFromPoint(pt);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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