GetWindowTextLengthW gibt immer 0 zurück
-
Guten Tag liebe Gemeinde,
ich wende mich in voller Verzweiflung an euch! Und zwar hat ein Kollege folgenden Code geschrieben:
static HWND HANDLE_ID; LPSTR lpstr_var = new TCHAR[256]; int len; wchar_t text[256]; //... lpstr_var = OpenFileDialog(hwnd); if (!strcmp(lpstr_var, ""))break; SetWindowText(HANDLE_ID, lpstr_var); len = GetWindowTextLengthW(HANDLE_ID) + 1; GetWindowTextW(HANDLE_ID, text, len); fpath = (CString)text;
Der Punkt ist der: Der Code läuft auf allen Rechnern, nur auf meinem nicht. Ich hab schon einiges ausprobiert, aber ich komm einfach nicht darauf, was falsch ist.
Warum der Text erst ins Fenster geschrieben und danach sofort wieder ausgelesen wird, das soll jetzt hier nicht zur Debatte stehen. Das ist quasi nur beispielhaft für das Problem.
Jedenfalls bekomme ich für den Rückgabewert von GetWindowTextLengthW immer 0, während auf jedem anderen Rechner (bei gleichen Projekteinstellungen von VS & gleichem Code) immer der richtige Wert rauskommt.
Ich kenne mich nicht so sehr aus mit WinAPI, aber ich tippe - da es auf anderen Rechnern funktioniert - auf eine Einstellungsgeschichte: entweder global und nicht projektspezifisch in VS oder vllt. in den Windows-Einstellungen (?). Vllt. dass Windows eine falsche DLL nimmt (32-bit vs. 64-bit?).
Falls mir nicht direkt geholfen werden kann, hoffe ich sehr wenigstens auf einen Tipp oder ein paar Stichworte, wonach ich weitersuchen könnte. Ich weiß leider nicht, nach welchen Stichworten ich überhaupt suchen soll. "GetWindowTextLengthW" bei Google bringt mich zu Microsoft-Referenzen, die leider nicht sehr aufschlussreich sind.
Weiß irgendjemand was dazu oder hatte vllt. das gleiche Problem?
-
Falsches Fensterhandle....
-
Martin Richter schrieb:
Falsches Fensterhandle....
Ich verstehe nicht ganz. Kannst du das vllt. etwas weiter ausführen?
-
Ist
HANDLE_ID
gültig?
-
Mr. B schrieb:
"GetWindowTextLengthW" bei Google bringt mich zu Microsoft-Referenzen, die leider nicht sehr aufschlussreich sind.
Ich weiss nicht, was daran nicht aufschlussreich sein soll:
GetWindowTextLength function schrieb:
If the window has no text, the return value is zero. To get extended error information, call GetLastError.
Ruf doch einfach mal GetLastError auf, um zu sehen, warum du eine 0 zurückbekommst.
Die System Fehler Codes findest du hier:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
-
Martin Richter schrieb:
Falsches Fensterhandle....
Nein, wieso? Es wird doch erst in HANDLE_ID geschrieben und genau eine Zeile später wieder aus selbigem ausgelesen?!
theta schrieb:
Ist
HANDLE_ID
gültig?IsWindow(.) gibt zumindest immer 1 zurück.
-
Burkhi schrieb:
Mr. B schrieb:
"GetWindowTextLengthW" bei Google bringt mich zu Microsoft-Referenzen, die leider nicht sehr aufschlussreich sind.
Ich weiss nicht, was daran nicht aufschlussreich sein soll:
GetWindowTextLength function schrieb:
If the window has no text, the return value is zero. To get extended error information, call GetLastError.
Ruf doch einfach mal GetLastError auf, um zu sehen, warum du eine 0 zurückbekommst.
Die System Fehler Codes findest du hier:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspxHabe ich getan, der Rückgabewert von SetWindowText(.) ist 1 = successful. Der Rückgabewert von GetLastError() ist 0 = auch successful.
-
Ich bin bei weitem kein Experte für WinAPI, aber ich fürchte, das geht in die falsche Richtung. Derselbe Code funktioniert auf allen Rechnern, nur auf meinem nicht. Daher tippe ich eher auf eine Einstellung von VS, Windows oder vllt. beschädigte DLLs? Nur weiß ich nicht, ob und wo man etwas Derartiges einstellen kann. (Ich kann mich natürlich auch irren, aber wieso zum ... sollte es sonst nur auf meinem Rechner nicht funktionieren? Das geht nicht in meinen Kopf )
Meine neusten Erkenntisse beim Debuggen:
- Z. 8 ist lpstr_var noch völlig i. O. (steht ein normaler String drin, zB "Keks")
- nach Z. 9 ist der Rückgabewert der Fkt. SetWindowText(.) ist 1 für successful. Dennoch ist lpstr_var plötzlich leer -> "". GetLastError() = 0.
- Z. 10 ergibt len = 0 (bzw. 1, weil +1). Auch hier ist GetLastError() = 0.Mich irritiert wie gesagt zu sehr, dass es nur auf einem Rechner so ist...
-
Da wäre dann erst mal die Frage, wo die Unterschiede zwischen deinem Rechner und den anderen sind. Startest du z.B. dein Programm in der Entwicklungsumgebung, und die anderen haben die Release-Version?
Eine andere Frage wäre, was da in deiner Zeile 8 passiert: was genau gibt deine Funktion OpenFileDialog() denn zurück?
Dein lpstr_var ist ein Zeiger auf ein char, der zuerst auf ein 256 Bytes langes Stück Speicher auf dem Stack zeigt. Ich würde stark vermuten, dass hier nicht, wie du es vermutlich willst, ein Text dorthin kopiert wird. D.h. dein Text auf dem Stack auch wirklich bis zum Funktionsende überlebt. Ich könnte mir eher vorstellen, dass lpstr_var umgebogen wird auf eine Adresse, wo dein Text vorübergehend mal stand und dessen Inhalt sich anschließend ändert. Zeigt dein lpstr_var konstant auf dieselbe Adresse?
-
Der Code des TE läuft bei mir in einer W32API-Anwendung. Für HANDLE_ID habe ich das Handle (hwnd) des Hauptfensters genommen. Ich benutze MinGW/GCC und mußte im Code einiges anpassen (z.B. OpenFileDialog() gibt es hier nicht). Hinweis: Symbole UNICODE und _UNICODE sind bei mir nicht definiert!
-
FSK schrieb:
Eine andere Frage wäre, was da in deiner Zeile 8 passiert: was genau gibt deine Funktion OpenFileDialog() denn zurück?
Dein lpstr_var ist ein Zeiger auf ein char, der zuerst auf ein 256 Bytes langes Stück Speicher auf dem Stack zeigt. Ich würde stark vermuten, dass hier nicht, wie du es vermutlich willst, ein Text dorthin kopiert wird. D.h. dein Text auf dem Stack auch wirklich bis zum Funktionsende überlebt. Ich könnte mir eher vorstellen, dass lpstr_var umgebogen wird auf eine Adresse, wo dein Text vorübergehend mal stand und dessen Inhalt sich anschließend ändert. Zeigt dein lpstr_var konstant auf dieselbe Adresse?
Exakt. Ein Traum! Es ist genau so, wie du es beschrieben hast! Ich habe es behoben und es funktioniert. Jetzt die große Frage: Wieso war mein Rechner der einzige, der diesen Fehler tatsächlich wie einen behandelt hat, während alle anderen ihn haben durchgehen lassen und es seltsamerweise trotz Fehlers richtig funktioniert? Genau diese Symptomatik hat mich ja fehlgeleitet zu der Diagnose, dass der Code richtig und irgendwas ausschließlich an meinem Computer falsch laufen müsse.
FSK schrieb:
Da wäre dann erst mal die Frage, wo die Unterschiede zwischen deinem Rechner und den anderen sind. Startest du z.B. dein Programm in der Entwicklungsumgebung, und die anderen haben die Release-Version?
Alle benutzen die gleiche Entwicklungsumgebung, alle haben die gleiche Version von Visual Studio, alle Win32 im Debug-Modus. Ich versteh es einfach nicht!
Vielen Dank für die Hilfe im ersten Punkt - das hat mich schon enorm weitergebracht. Jetzt kommt als Sahnehäubchen oben drauf Punkt 2
-
Ja, manchmal hängts an Kleinigkeiten... schön, dass es jetzt weitergehen kann.
Zu Punkt 2 kann ich nur spekulieren. Vermutlich war der Text in deiner Funktion OpenFileDialog() irgendwo lokal auf dem Stack angelegt, und der wurde mit Verlassen der Funktion zerstört. Dann hast du mit einem Zeiger auf einen wieder freigegebenen Speicherblock weitergearbeitet. Und das ist ein klassischer Fall von undefiniertem Verhalten.
Ich könnte mir vorstellen, dass auf deinem Rechner der Stack der Funktion nach dem Verlassen genullt wurde, sodass auch der Text verschwunden ist. Und das ist vielleicht auf den anderen Rechnern unterblieben, sodass der alte Inhalt dort zufällig noch stand. Warum das so ist? Keine Ahnung, das kann irgendeine Einstellung in deiner IDE sein oder ein installiertes Addin, oder ... ?