2016-03-20 14 views
0

Ich erstelle eine Win32-App und ich habe ein logIn-Formular, aber ich kann nicht einen Wert Bearbeitungsfenster erhalten. Ich habe es so gemacht, aber nichts bekommen. Wo ist mein Fehler?Warum OutputDebugString leer ist

#define passwordWindowId 2 

HWND passwordWindowHandle = CreateWindow(TEXT("EDIT"), TEXT(""), WS_VISIBLE | WS_CHILD, 10, 80, 150, 20, hWnd, (HMENU)passwordWindowId, NULL, NULL); 
int len = GetWindowTextLength(GetDlgItem(passwordWindowHandle, passwordEditId)); 
LPWSTR passwordWindowValue; 

GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1); 
OutputDebugString(passwordWindowValue); 

Aber wenn ich OutputDebugString(L"test"); sehe ich test in Register Ausgabe.

+1

'passwordWindowValue' ist ein nicht initialisierter Zeiger, er kann nichts empfangen. Auch Ihr Bearbeitungsfeld ist leer (zweiter Parameter in CreateWindow ist der Text). GetWindowText erhält also eine leere Zeichenfolge. Es klappt alles. –

+0

Sie müssen lernen, auf Fehler zu prüfen. Lesen Sie die Dokumentation der Funktionen, die Sie anrufen. Sie prüfen überhaupt nicht auf Fehler. –

Antwort

4

Viele Fehler in Ihrem Code, einige subtile und andere fatal.

#define passwordWindowId 2 

Einige des niedrigen Steuer-IDs werden vom Dialogmanager verwendet, und nicht mit benutzerdefinierten Kontrollen überlastet werden soll. Eine übliche Konvention besteht darin, Zahlen ab 100 zu vergeben (siehe Why do dialog editors start assigning control IDs with 100?).

Eine andere übliche Konvention besteht darin, alle Großbuchstaben für Präprozessorsymbole zu verwenden.

HWND passwordWindowHandle = CreateWindow(TEXT("EDIT"), TEXT(""), ... 

Dies schafft eine leer Bearbeitungssteuer (den zweiten Parameter von CreateWindow sehen). Dies ist kein Fehler, aber Sie können nicht davon ausgehen, dass das Steuerelement Text enthält.

Wieder ist kein Fehler, aber die Verwendung der generischen Textzuordnungen ist im Allgemeinen nicht hilfreich. Verwenden Sie die Unicode-Versionen der APIs zusammen mit breiten Zeichenfolgen und Zeichenfolgenliteralen: HWND passwordWindowHandle = CreateWindowW(L"EDIT", L"", ....

LPWSTR passwordWindowValue; 

LPWSTR ist ein typedef für wchar_t*, so definiert der oben einen Zeiger, ohne sie zu initialisieren. Nicht ein Fehler an sich, aber wenn Sie anfangen, diesen Zeiger zu benutzen, geraten Sie in undefiniertes Verhalten. Sie müssen Speicher für den folgenden Aufruf an GetWindowText zuweisen, indem Sie entweder ein lokales Array mit fester Größe erstellen, wenn Sie die maximale Größe im Voraus kennen, oder einen dynamisch großen Container verwenden (z. B. std::vector<wchar_t> buffer(len + 1);).

GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1); 

Dies ist, wo die Dinge brechen: Sie einen API-Aufruf fordern, um nicht zugewiesenen Speicher zu schreiben, wies von einem nicht initialisierten Zeiger auf. Wie bereits oben erwähnt, müssen Sie Speicher reservieren, bevor Sie GetWindowText aufrufen. Außerdem rufen Sie die generische Textzuordnung auf, übergeben aber explizite breite Zeichenfolgenarten. Verwenden Sie stattdessen GetWindowTextW.

OutputDebugString(passwordWindowValue); 

Das Argument ist immer noch ein nicht initialisierter Zeiger. Selbst wenn dies nicht der Fall wäre, würde der Speicher, auf den gezeigt wird, eine leere Zeichenfolge sein, da der Steuertext leer ist. Auch hier rufen Sie ein generisches Text-Mapping auf, während Sie eine explizite breite Zeichenfolge übergeben. Verwenden Sie stattdessen OutputDebugStringW.

Plus, Sie überprüfen überhaupt nicht auf Fehler.Alle Windows-API-Aufrufe, die Sie verwenden, können fehlschlagen, und Sie müssen auf Fehler prüfen. Informationen dazu, wie Sie bei jedem API-Aufruf nach Fehlern suchen können, finden Sie in der Dokumentation.

+0

Vielen Dank! – rel1x

3

Aktualisiert !!

LPWSTR passwordWindowValue; 
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1); 

sollte diese

sein
LPWSTR passwordWindowValue = new wchar_t[len + 1]; 
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1); 

Sie passieren einen uninitalised Zeiger auf GetWindowText

und löschen [] passwordWindowValue, nachdem Sie fertig sind.

+0

Ich habe jetzt 2 Fehler: 'int len ​​- Ausdruck muss konstanten Wert haben 'und' WSTR ist undefined'. Meinst du gemein 'wstring'? Ich kann nicht finden mit Header hat 'WSTR' – rel1x

+0

Verwenden Sie wchar_t anstelle von WSTR (was ich denke @ user93353 nur erfunden :) –

+0

Auch unterstützt C++ dynamische Länge Arrays, das ist eine C-Funktion. –