Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi ClassName / Caption von Objekt erhalten (https://www.delphipraxis.net/168891-classname-caption-von-objekt-erhalten.html)

Destroyer446 16. Jun 2012 19:45

ClassName / Caption von Objekt erhalten
 
Hey Com,
ich kann mit WindowFromPoint() die Caption und den Klassennamen eines Fensters auslesen,
nun will ich aber von einem Objekt auf dem Fenster die Caption + Klasse auslesen...
Wie bekomm ich das hin?
Gibt es etwas in der Richtung "ObjectFromPoint()"?

Das mit allen Objekten anzeigen lassen hat bei mir iwie nicht so richtig funktioniert...

Mfg, Destroyer446

Popov 16. Jun 2012 19:55

AW: ClassName / Caption von Objekt erhalten
 
Aus einem Beispiel rauskopiert, zumindest schon mal die Klasse:

Delphi-Quellcode:
var
  hWnd: THandle;
  aName: array [0..255] of Char;

procedure TForm1.ShowHwndAndClassName(CrPos: TPoint);
begin
  hWnd := WindowFromPoint(CrPos);
  Label1.Caption := 'Handle : ' + IntToStr(hWnd);

  if Boolean(GetClassName(hWnd, aName, 256))
  then Label2.Caption := 'ClassName : ' + String(aName)
  else Label2.Caption := 'ClassName : not found';
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  rPos: TPoint;
begin
  if Boolean(GetCursorPos(rPos)) then ShowHwndAndClassName(rPos);
end;

mkinzler 16. Jun 2012 19:56

AW: ClassName / Caption von Objekt erhalten
 
Wenn es sich um ein Windowselement handelt, solltest du dieses mit der Methode .ControlAtPos() ermitteln können.

NickelM 16. Jun 2012 20:02

AW: ClassName / Caption von Objekt erhalten
 
Naja was meinst du mit Objekten?
Du kannst nur die sogenannten ChildWindows auslesen. Also Controls, die einen HWND besitzen.
Diese kannst du mit ChildWindowFromPoint auslesen. In etwa so:
Delphi-Quellcode:
ChildHWND := ChildWindowFromPoint(ParentHWnd,Pos);
//ParentHWnd = Ist das Fenster-Handle
//Pos = Point von der Pos
Das hättest du aber auch durch bischen google finden können :-D
In der MSDN hier steht unten dabei das du ChildWindows mit ChildWindowFromPoint auslesen kannst. Also Fenster auf diesem Fenster :-D
Ist nicht böse gemeint. Nur man findet sowas leicht, wenn man sich die MSDN-Hilfe mal genauer durchliesst. Ist nur ein Tipp fürs nächste mal.

Gruß NickelM

himitsu 16. Jun 2012 20:03

AW: ClassName / Caption von Objekt erhalten
 
Delphi-Referenz durchsuchenFindControl, wenn man schon ein Handle hat.

Destroyer446 16. Jun 2012 20:31

AW: ClassName / Caption von Objekt erhalten
 
Keine Lösung hat bei mir funktioniert... ich mach anscheinend irgendwas falsch...
Meine Lösungen:

1. Popov:
Gibt bei dem Fenster, was ich brauche, nur den Parent-Namen usw zurück

2. mkinzler:
Bekomme ich AccessViolation Fehler.

3. NickelM:
Siehe 1.

4. himitsu:
Siehe 2.
PS: Code bei 4:
Delphi-Quellcode:
function getWindowCaption(hWnd:Integer):String;
var
tmpInt1:SmallInt;
tmpInt2:Word;
tmpString1:String;
begin
if Windows.IsWindow(hWnd) then
begin
tmpInt1:=Windows.GetWindowTextLength(hWnd);
tmpString1:='';
for tmpInt2:=1 to tmpInt1 do
 begin
tmpString1:=System.Concat(tmpString1,'?');
 end;
Windows.GetWindowText(hWnd, System.Addr(tmpString1[1]),tmpInt1+1);
result:=tmpString1;
end
else
begin
Result:='';
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 p: TPoint;
 Mainbuffer: array [0..255] of Char;
 MainWndCaption, ChildWndCaption, Childbuffer: String;
 ParentHWND: THandle;
 ChildHWND: TControl;
begin
 ShowMessage('Du hast jetzt 5 Sekunden um den Mauszeiger über die Hauptform zu bringen.');
 Sleep(5000);
 GetCursorPos(p);  
 ParentHWND := WindowFromPoint(p);
 If ParentHWND = 0 then
 begin
  ShowMessage('Das Fenster konnte nicht ermittelt werden!');
  Exit;
 end;
 GetClassName(ParentHWND, Mainbuffer, length(Mainbuffer));
 MainWndCaption := GetWindowCaption(ParentHWND);
 Label1.Caption := 'MainWindow: ClassName: '+string(Mainbuffer)+'; Caption: '+MainWndCaption;
 ShowMessage('Klassenname: '+string(Mainbuffer)+#10+'Bezeichnung: '+MainWndCaption+#10+'Du hast jetzt 5 Sekunden Zeit um den Mauszeiger über das Objekt zu bringen.');
 Sleep(5000);
 GetCursorPos(p);
 ChildHWND := FindControl(ParentHWND);
 Childbuffer := ChildHWND.ClassName;
 ChildWndCaption := ChildHWND.Name;
 Label2.Caption := 'ChildWindow: ClassName: '+Childbuffer+'; Caption: '+ChildWndCaption;
end;
... Habt ihr dazu Ideen?

Bummi 16. Jun 2012 21:16

AW: ClassName / Caption von Objekt erhalten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hatte für ein "Fernsteuerprogramm" eine Hilfsprojekt zum Suchen aufgesetzt.
Da ist vieles drin was mit Deinem Problem nichts zu tun hat.
Ich habe gerade nicht den Nerv nur das benötigte rauszusuchen und lade einfach mal das Projekt so hoch wie es ist.
Aus dem Form werden auf 2 Label die Klassennamen und wenn greifbar die Captions beim überfahren angezeigt (den Rest ignorieren, der funktioniert nur wenn eine spezifische Software läuft)

himitsu 16. Jun 2012 21:46

AW: ClassName / Caption von Objekt erhalten
 
FindControl und ControlAtPos, oder was sonst noch am Ende auf FindControl zugreift,
funktioniert natürlich nur programmintern.

Andere Programme und auch eigene DLL, solange sie nicht mit Laufzeitpackages kompiliert wurden, können nicht ausgelesen werden.



Du versuchst es doch hoffentlich nur programmintern?

NickelM 16. Jun 2012 22:29

AW: ClassName / Caption von Objekt erhalten
 
Was willst du den jetzt konkret alles haben?
So wie ich es verstanden habe willst du folgendes, bitte Koregiere mich wenn ich falsch liege.

- Mouse auf ein Fenster (Ich denke mal du meinst damit eine Form bzw. ein Fenster mit Titel-Bar)
- Fenster Klasse and Caption auslesen (Fensterklasse und Titelbar-Text.)
- Mouse auf ein Objekt (Was meinst du mit Objekt? Ein Control, wie z.b. ein Label, ein "Child-Window" wie z.b ein Memo,Edit,ComboBox usw. ,ein Control was halt ein HWND hat.
Das Ding ist nämlich, dass VCL-Komponenten nicht zwangsläufig einen HWND haben.
- Fenster Klasse and Caption auslesen (Fensterklasse ist klar, aber was meinst du mit Caption?
Meinst du z.b. wenn du über ein Label gehst, das Caption davon?
Und wenn du über ein Memo gehst, was soll er dir dan geben für Caption? Den Memo-Text?

Klassennamen kannst du für alles bekommen was ein HWND (Fenster-Handle, was z.b. ein Edit oder ComboBox oder ein Fenster hat). Wenn wie schon erwähnt,wenn du es nur intern brauchst, benutze ControlAtPos.
Wenn du Windowsweit haben willst, kannst du dir nur Fenster-Handles holen und auch nur von denen die Klassennamen auslesen.

Gruß NickelM

Destroyer446 17. Jun 2012 13:09

AW: ClassName / Caption von Objekt erhalten
 
Ich habe:
FensterCaption des fremden Fensters

Ich will:
Button auf anderem Fenster drücken -> Dazu muss ich ja den Namen wissen

Und nein, ich will es nicht nur Programmintern machen.
PS: Das mit der Maus usw war nur zu Testzwecken, um zu prüfen, wie ich den Namen rausbekommen kann.

Mfg, Destroyer446

DeddyH 17. Jun 2012 13:30

AW: ClassName / Caption von Objekt erhalten
 
Lass Dir doch den Code zum Ermitteln des Button-Handles von WinSpy generieren. Dem schickst Du dann ein BM_CLICK (oder BN_CLICKED, ich weiß es gerade nicht genau, Code sollte im Forum zu finden sein).

NickelM 17. Jun 2012 16:28

AW: ClassName / Caption von Objekt erhalten
 
Hier der Link zum Thread, für die faulen :-D
http://www.delphipraxis.net/15388-wi...6-09-08-a.html

Bummi 17. Jun 2012 18:15

AW: ClassName / Caption von Objekt erhalten
 
das was ich hochgeladen hatte tut unter anderem genau dies....

NickelM 18. Jun 2012 01:20

AW: ClassName / Caption von Objekt erhalten
 
Gut, wenn du das Caption des Fensters schon hast, musst du das Fenster mit FindWindow suchen, dort kannst du das Caption als "Suchparameter" eingeben. Damit bekommst du das HWND, womit du weitermachen kannst.
Für den Button zufinden gibt es 2 Möglichkeiten:
- Einmal, mit FindWindowEx, falls du Klasse oder Button-Text hast. Klasse wird schwer, da man Subclassing machen kann, und somit der Button keinen "festen" Klassenname hat. Button-Text, falls du einen Button mit einem bestimmten Text drücken willst, der sich nicht ändert.
- Das zweite wäre, dass du mit EnumChildWindows, alle Child-Handles (also sozusagen "Controls") durchgehst und überprüfst, indem du dir zu jedem den Klasennamen oder Text geben lässt. Das würde dann so funktionieren:
Delphi-Quellcode:
function EnumChildProc(hHandle : HWND; lParam : Integer) : Boolean; stdcall;
begin
  //Überprüfe hier, was du brauchst. Du kannst alle Infos von diesem Child mit dem Parameter hHandle holen.
  //Wenn du das Fenster gefunden hast, gib False zurück, wenn nicht True.
end;

//Aufruf
EnumChildWindows(hParentHWND,@EnumChildProc,0); //In den letzen Parameter kannst du eine eigene Zahl, Pointer übergeben. Diesen Wert findest du in der EnumChildProc im lParam wieder. Funktioniert wie mit SendMessage.
So damit solltest du das denk ich jetzt hinbekommen. Dies ist alles aus dem Kopf geschrieben, hoffe das funkt so.

Gruß NickelM

Destroyer446 18. Jun 2012 14:19

AW: ClassName / Caption von Objekt erhalten
 
Ich weiß nicht was ich falsch mache, aber bei dem "EnumChildWindows" passiert bei mir einfach nichts...
Code:
Delphi-Quellcode:
function EnumChildProc(hHandle : HWND; lParam : Integer) : Boolean; stdcall;
begin
 ShowMessage('-');
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 hParentHWND: HWND;
begin
 hParentHWND := FindWindow(nil, 'Fenstername');
 if hParentHWND = 0 then
 begin
  ShowMessage('Fenster nicht gefunden.');
  Application.Terminate;
 end;
 EnumChildWindows(hParentHWND, @EnumChildProc,0); //In den letzen Parameter kannst du eine eigene Zahl, Pointer übergeben. Diesen Wert findest du in der EnumChildProc im lParam wieder. Funktioniert wie mit SendMessage.
end;
Ist am Code irgendwas falsch?! ...

Mfg, Destroyer446

Bummi 18. Jun 2012 14:48

AW: ClassName / Caption von Objekt erhalten
 
Beispiel mit Notepad und enthaltenem Text
Delphi-Quellcode:
Function GetTextFromHandle(hwd:THandle):String;
const
  MyMaxText = 10000;
begin
  SetLength(Result, MyMaxText);
  SetLength(Result, SendMessage(hwd, WM_GETTEXT, MyMaxText, lParam(PChar(Result))));
end;

function EnumChildProc(hHandle : HWND; lParam : Integer) : Boolean; stdcall;
const
  MyMaxName = 255;
  MyMaxText = 255;
var
  ClassName: string;

begin
  Result := True;
  SetLength(ClassName, MyMaxName);
  SetLength(ClassName, GetClassName(hHandle, PChar(ClassName), MyMaxName));
  Showmessage(ClassName+' - '+GetTextFromHandle(hHandle));
end;
procedure TForm5.Button1Click(Sender: TObject);
var
 hParentHWND: HWND;
begin
 hParentHWND := FindWindow(nil,'Unbenannt - Editor');
 if hParentHWND = 0 then
 begin
  ShowMessage('Fenster nicht gefunden.');
 end else
 EnumChildWindows(hParentHWND, @EnumChildProc,0);
end;

Destroyer446 19. Jun 2012 08:06

AW: ClassName / Caption von Objekt erhalten
 
Bei Notepad gibts kein Problem, nur bei dem Programm schon, aber das liegt nicht am Code.. denk ich mal...
Naja, bei dem Proggi gehts wohl nicht.

Danke,

Destroyer446


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