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 GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zurück (https://www.delphipraxis.net/138493-getwindowplacement-getwindowrect-gibt-als-pos-immer-0-zurueck.html)

LokutusvB 11. Aug 2009 12:43


GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zurück
 
Hallo,

und schon wieder ein anderes Problem.

Ich benötige die Position eines Fensters, um es ein wenig auf dem Desktop zu verschieben. Aber egal, was ich anstelle, ich komme als Position immer "0" zurück. Das handle der externen Anwendung stimmt, daran kann es nicht liegen. Kann die fremde Anwendung das irgendwie verhindern, das ich die Position nicht festellen und verändern kann?

Ich habe folgendes probiert:
Delphi-Quellcode:
// Position auslesen und ändern
tw1Plct.length := SizeOf(tWindowPlacement);
if GetWindowPlacement(twhandle, @tw1Plct) then begin
 //ShowMessage('Links: ' + IntToStr(tw1Plct.rcNormalPosition.Left));
 //ShowMessage('Oben: ' + IntToStr(tw1Plct.rcNormalPosition.Top));
 //ShowMessage(IntToStr(tw1Plct.ptMinPosition.y));
 tw1Plct.rcNormalPosition.Left := tw1Plct.rcNormalPosition.Left + 50;
 tw1Plct.rcNormalPosition.Left := tw1Plct.rcNormalPosition.Top + 50;
 SetWindowPlacement(twH1, @tw1Plct);
end;
Selbst das geht nicht:
Delphi-Quellcode:
GetWindowRect(twhandle , tw1Rect);
für tw1Rect.left top right usw. bekomme ich ständig eine 0. Woran kann das liegen?

Luckie 11. Aug 2009 12:54

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Woher weißt du, dass das Handle für das Fenster stimmt? Und was sagt MSDN-Library durchsuchenGetLastError:
Zitat:

If the function fails, the return value is zero. To get extended error information, call GetLastError.

LokutusvB 11. Aug 2009 13:01

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
GetLastError sagt nix, daran habe ich auch schon gedacht und probiert. Ein Fehler wird hier nicht "geworfen".

Das das Handle stimmt, zeigt mir der Rest meiner Anwendung, ich kann das Fenster z.B. in den Vordergrund setzen, Abfragen ob es im Vordergrund ist und wieder suchen lassen. Zumindest gehe ich so davon aus, daß das Handle stimmt. Deswegen bin ich hier jetzt auch total ratlos :(.

Luckie 11. Aug 2009 13:07

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Was heißt "ein Fehler wird nicht geworfen"? Die Funktion gibt einen Fehlerwert zurück, da wird nichts "geworfen". Wie ist denn der Rückgabewert von der Funktion?

LokutusvB 11. Aug 2009 13:13

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Ich habe folgendes probiert:
Delphi-Quellcode:
if GetWindowPlacement(twHandle, @tw1Plct) then begin
  //ShowMessage('Links: ' + IntToStr(tw1Plct.rcNormalPosition.Left));
  //ShowMessage('Oben: ' + IntToStr(tw1Plct.rcNormalPosition.Top));
  //ShowMessage(IntToStr(tw1Plct.ptMinPosition.y));
  tw1Plct.rcNormalPosition.Left := tw1Plct.rcNormalPosition.Left + 50;
  tw1Plct.rcNormalPosition.Left := tw1Plct.rcNormalPosition.Top + 50;
  SetWindowPlacement(twHandle, @tw1Plct);
end else GetLastError;
Oder ist das verkehrt? Und hier wurde nichts angezeigt, keine Fehlermeldung.

Luckie 11. Aug 2009 13:16

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Hmpf, debug dochmal richtig. Geht er denn in den if-Zweig auch rein? Und GetlastError ist eine Funktion die den letzten gesetzten Fehlercode zurückgibt, wenn du den nicht auswertest, wir dir da wohl auch nichts angezeigt werden können:
Delphi-Quellcode:
SysErrorMessage(GetLastError);

LokutusvB 11. Aug 2009 13:21

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Ja, deswegen sind dort auch die ShowMessages auskommentiert, die habe ich schon zu Debug-zwecken genutzt.
Führe ich direkt nach dem SetWindowPlacement(twHandle, @tw1Plct); ein SysErrorMessage(GetLastError); aus, wird nichts angezeigt, kein Fehler. Was könnte ich noch prüfen?

r29d43 11. Aug 2009 21:55

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Eventuell, um auch den unwahrscheinlichen Fall noch auszuschließen, dass da immer noch irgendwo ein kleines Mißverständnis vorliegt: Ein SysErrorMessage(GetLastError) so ganz allein kann sich auch gar nicht bemerkbar machen, weil es nämlich nur die Rückgabe eines Strings ist. Ganz richtig müsste es also so heißen (natürlich):

Delphi-Quellcode:
if GetWindowPlacement(AHandle, @AWindowPlacement) then
begin
.
.
.
end
else showMessage(SysErrorMessage(GetLastError));
So würde dir u.a. dann auch angezeigt werden, wenn die übergebene Handle-Variable keine gültige Handle beinhaltet.

LokutusvB 12. Aug 2009 07:24

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Stimmt, habe ich ganz übersehen.

Das Problem bleibt trotzdem :(.

Jetzt sagt er mir nach dem SetWindowsplacement im True-Fall in der If-Anweisung, daß der Vorgang erfolgreich beendet wurde. Wieso sind dann die Punkte immer noch 0 bzw. Min / Max -1?

r29d43 12. Aug 2009 08:21

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
hast Du event. mehr Handles und hier nur das falsche genommen?

Außerdem, die PSDK erzählt bzgl. dieser Api-Funktionen immer von einem Rückgabewert =0 oder >0 und nichts von True oder False. Unter Umständen könnte hier ein Wert von z.B. 40 o. 5341009 nicht korrekt als True interpretiert werden. Das ist jetzt zwar einen reine Spekulation meinerseits aber in so einer Situation muss man eben einfach mal alles überhaupt nur mögliche kurz auschecken. Also anstatt

if GetWindowPlacement(HNotePad, @AWindowPlacement) then...

prüf doch auch mal auf

if integer(GetWindowPlacement(HNotePad, @AWindowPlacement)) > 0 then...

Ansonsten kann es eigentlich nur noch mehr an deinem Window liegen. Ist das irgendwie ein spezielles? Gemäß der PSDK und dem was da unter Remarks bzgl. der WINDOWPLACEMENT Structure steht könnte dann das Rückgabe-Ergebnis u.U. ein anderes sein als das erwartete. Du hast sie zwar oben schon erwähnt, aber im Zweifelsfall würde ich hier immer die einfachere GetWindowRect-Funktion nehmen.

LokutusvB 12. Aug 2009 08:29

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Und auch hier wird wieder in den True-Teil gesprungen und Anweisung für Anweisung durchgeführt, ohne Fehler.

Bei GetWindowsRect kommt ebenso immer eine 0 als Ergebnis.

Hierbei handelt es sich um ein Warenwirtschaftsprogramm, in diesem Fall um das CRM-Modul, von dem ich dir schon berichtet hatte, eine spezielle Entwicklung. Mit diesem Fenster habe ich unter anderem ja auch das Problem, wie an andere Stelle schon beschrieben, daß IsWindowVisible oder auch (GetWindowLong(twHandle, GWL_STYLE) and WS_VISIBLE <> 0) eindeutig Nicht sichtbar festellen, obwohl ich dieses Fenster auf dem Bildschirm sehe. Zum Verzweifeln ist das. Ist es möglich, das ein Programm derart die Windows-API "verarschen" kann? Oder liegt es doch am Handle, obwohl ich mit eben diesem Handle (Die Ermittlung kennst du ja) das Fenster in den Vordergrund setzen kann bzw. via Timer das Ende ermitteln oder aber das Vorhanden sein ermitteln kann.

Luckie 12. Aug 2009 08:35

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Handlet es sich bei dem Fenster um eine DElphi VLC Anwendung? Wenn ja, gibt es zwei Fenster, einmal das unsichtbare Anwendungsfenster und einmal das für den Benutzer sichtbare Fenster für die Oberfläche.

LokutusvB 12. Aug 2009 08:38

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
ich kann leider nicht sagen, mit was diese Anwendung entwickelt worden ist. Das ist ein eingekauftes Programm.

kann ich das von dir Beschriebene irgendwie festellen und entsprechend reagieren?

Luckie 12. Aug 2009 08:40

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Wenn die Fensterklassen mit "T" anfangen, wäre das ein Hinweis auf eine VCL-Anwendung.

r29d43 12. Aug 2009 08:50

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Mit den Programmen "Spy++" oder "Winspector Spy" müsste man eigentlich auch feststellen können, ob es noch mehrere Handles bzgl. deines Programms gibt. Also, u.U. mal danach googeln und dann downloaden.

LokutusvB 12. Aug 2009 08:52

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
WinSight sagt mir Folgendes nach dem Programmstart:

Overlapped {XXXmain} X.exe (0,0)-(0,0) "XXX Hauptmenü"
Overlapped {XXXcon} X.exe (hidden) "XXX for Win32"
Overlapped {#32770:Dialog} X.exe (177,150)-(1101,846) "XXX Hauptmenü"

So wie ich das sehe, ermittel ich immer das erste Handle, deswegen auch die 0 als Rückgabe. Wieso aber kann ich dann damit so gut arbeiten was das Bringen in den Vordergrund sowie die Kontrolle des noch aktiv sein betrifft? Wie könnte ich das "richtige" Handle, so wie ich das sehe ich das das 3., ermitteln?

r29d43 12. Aug 2009 09:13

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Die Handles findest Du immer wieder mit FindWindow bzw. wenn es sich um Child-Windows handelt mit FindWindowEx (bei letzterem musst Du dich dann eben immer wieder vom TopLevel-Window aus bis zu diesem ChildWindow durchhangeln). Wichtig hierfür ist, dass dabei immer der exakten ClassTyp des Programms als Parameter angeben werden muss (das scheint hier bei WinSight der Ausdruck in der ersten geschweiften Klammer zu sein) und den ebenfalls exakten Window-Namen (also die Überschrift in der Title-Bar des Windows) hier bei WinSight wahrscheinlich der Ausdruck in den Anführungsstrichen.

LokutusvB 12. Aug 2009 09:31

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Und da sehe ich leider das Problem.

Folgende Sachen ergeben immer ein ungültiges Fensterhandle:
FindWindowEx(twHandle, 0, nil, nil)
FindWindowEx(0, twHandle, nil, nil)
FindWindowEx(twHandle, 0, '#32770:Dialog', 'XXX Hauptmenü')
FindWindowEx(twHandle, 0, '#32770:Dialog', nil)
FindWindowEx(twHandle, 0, nil, nil)

Mit FindWindowEx(0, twH1, 'XXXmain', 'XXX Hauptmenü') ermittle bzw. suche ich nach einer zusätzlich vorhandenen Instanz. Das klappt ja auch, wenn ich das Progamm 2 oder 3 mal starte. Aber wieso findet der das Handle dieses Dialoges nicht?

r29d43 12. Aug 2009 09:52

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Ich kenne jetzt WinSight leider nicht und weiß daher auch nicht, wie das die ChildWindows darstellt (eingerückt oder wie?).

Wenn <<Overlapped {#32770:Dialog} X.exe (177,150)-(1101,846) "XXX Hauptmenü">> das direkte ChildWindow von <<Overlapped {XXXmain} X.exe (0,0)-(0,0) "XXX Hauptmenü" >> ist, dann müsste <<FindWindowEx(twH1, 0, '#32770:Dialog', 'XXX Hauptmenü')>> eigentlich ein richtiges Ergebnis bringen.

Wenn allerdings <<Overlapped {#32770:Dialog} X.exe (177,150)-(1101,846) "XXX Hauptmenü"
>> das ChildWindow von <<Overlapped {XXXcon} X.exe (hidden) "XXX for Win32">> ist, dann musst du natürlich zuerst nochmal nach der Handle dieses Windows suchen und danach FindWindowEx nochmal dann eben mit diesem Handle als ersten Parameter starten.

LokutusvB 12. Aug 2009 13:07

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Das haut alles hinten und vorn nicht in.

Egal wie ich es anstelle, suche ich nach '#32770:Dialog', findet er kein Handle. Sage ich, er soll das nächste Handle zu con finden, findet er main. Sage ich, er soll das nächste Handle zu main finden, findet er nichts. Setzte ich con oder main als parent an, findet es bei beiden keine Child-handle.

Flocke 12. Aug 2009 13:09

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Probiere mal nur '#32770' bzw. PChar(32770) für die Fensterklasse.

LokutusvB 12. Aug 2009 13:20

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Hätte ich mich mal mehr mit winsight beschäftigt, hätte ich euch hier nicht so nerven müssen, tut mir leid :(. Natürlich konnte ich mit PChar(32770) das richtige Handle ermitteln, die Position bestimmen und das Dialog-Haupt-Fenster der Anwendung verschieben.

Nochmals, tut mir leid für die Nerven, die ich gekostet habe :(.

Danke an alle Helfer!!!

Luckie 12. Aug 2009 21:38

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Zitat:

Zitat von Flocke
Probiere mal nur '#32770' bzw. PChar(32770) für die Fensterklasse.

Ähm, alle Dialog die mit dem Ressourceneditor vom VS erstellt wurden, habe diese Fensterklasse, Es ist also nicht unbedingt ein zuverlässiges Kriterium.

LokutusvB 12. Aug 2009 21:49

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Wenn ich dann aber zusätzlich den Fenstername kenne, und danach suche, sollte es doch sicher sein, oder?

Luckie 12. Aug 2009 22:01

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Dann sollte es passen.

Guido Eisenbeis 15. Aug 2009 02:25

Re: GetWindowPlacement/GetWindowRect gibt als Pos immer 0 zu
 
Zitat:

Zitat von LokutusvB
Wenn ich dann aber zusätzlich den Fenstername kenne, und danach suche, sollte es doch sicher sein, oder?

Kommt darauf an, wie sicher es sein soll. Ist das Programm nur zu deiner eigenen Verwendung zu Hause, oder wird es in einer Firma benutzt, auf dem lokalern Computer gestartet oder über Netzwerkresourcen, unter welchem Benutzer wurde es gestartet (RunAs), lässt das Programm mehrere Instanzen zu (dann wirst du auch mehrere Fenster mit dem gleichen Namen finden), zu welcher Anwendung gehört das gefundene Fenster, ...

Lass deiner Fantasie freien Lauf und sichere das ab, was du für nötig hälst. :wink:

Guido.


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