Seltsames Problem mit GetDlgItemText
-
Vielen dank, dass hilft mir schonmal sehr weiter. Weißt du ob es eine Möglichkeit gibt das alte string Format wieder einzustellen ? Und wenn ja wie mache ich das ?
Danke vorab,
Gruß Ben.
-
An die Admins!
Mir scheint, daß der Unicode bzw. die fehlende Kompiler-Einstellung eine erhebliche Fehlerquelle ist. Darüber sollte man mal etwas in die FAQ schreiben!
-
Jo ich fand bisher nichts darüber in Google und ich hab wirklich schon mehrere Tage nach einer Lösung gesucht bevor ich gepostet habe.
Is aber nun egal ich mache es nun so:
BOOL appendString(HWND hwnd, int iControlID, TCHAR tString[]) { TCHAR buffer[] = {NULL}; GetDlgItemText(hwnd, iControlID, buffer, sizeof(buffer)/sizeof(TCHAR)); _tcscat(buffer, TEXT("\r\n")); _tcscat(buffer, tString); SetDlgItemText(hwnd,iControlID,buffer); return TRUE; }
Das soll meine Append-Funktion werden, die ich so aufrufen will:
appendString(hwnd, IDC_EDIT_DEBUG, TEXT("Test"));
Allerdings schmiert mir das App jetzt leider ab.....
Sieht jemand meine Fehler ?`
Danke für eure Hilfe.Ben.
-
8 bit -> 16 bit:
MultiByteToWideChar()
andersrum:
WideCharToMultiByte() (oder so ähnlich)
mehr s. msdn
-
So ich hab mein Problem jetzt gelöst, danke für eure Hilfe.
Hier meine funktionierende Lösung:
BOOL appendString(HWND hwnd, int iControlID, TCHAR tString[]) { TCHAR buffer[] = {0}; GetDlgItemText(hwnd, iControlID, buffer, sizeof(buffer)/sizeof(TCHAR)); if((buffer[0] != '\0')) _tcscat(buffer, TEXT("\r\n")); _tcscat(buffer, tString); SetDlgItemText(hwnd,iControlID,buffer); return TRUE; }
Und so wird sie aufgerufen...
TCHAR test[] = TEXT("test0"); appendString(hwnd, IDC_EDIT_DEBUG, test); appendString(hwnd, IDC_EDIT_DEBUG, TEXT("test2"));
Damit bin ich eigentlich ganz zufrieden, obwohl man die Funktion sicher noch verbessern kann.
Regards,
GBen.
-
Sorry ich hab gerade Mist gepastet.
Ich hatte eigentlich diese Funktion hier...BOOL appendString(HWND hwnd, int iControlID, TCHAR tString[]) { TCHAR buffer[1024] = {0}; GetDlgItemText(hwnd, iControlID, buffer, sizeof(buffer)/sizeof(TCHAR)); if((buffer[0] != '\0')) _tcscat(buffer, TEXT("\r\n")); _tcscat(buffer, tString); SetDlgItemText(hwnd,iControlID,buffer); return TRUE; }
Jetzt ist mir aber noch ein Problem aufgefallen. Da mein buffer ja nur 1024 groß kann mein debug text edit nicht sehr viel aufnehmen. Hat jemand ein Beispiel wie man das dynamisch machen könnte ?
Also das man theoretisch unbegrenzt Text appenden könnte ?Danke nochmal,
Gruß Ben.
-
Hi,
Jo so:
BOOL AppendString(HWND hWnd, int iControlID, PTCHAR pszString, bool fNewLine) { if(hWnd == NULL || pszString == NULL) return (FALSE); PTCHAR pszBuffer; UINT uiStrLen = GetWindowTextLength(hWnd) + 1; UINT uiAddedLength = lstrlen(pszString) + 1; pszBuffer = new TCHAR[uiStrLen + uiAddedLength]; GetDlgItemText(hWnd, iControlID, pszBuffer, uiStrLen); if(fNewLine) lstrcat(pszBuffer, TEXT("\r\n")); lstrcat(pszBuffer, pszString); SetDlgItemText(hWnd, iControlID, pszBuffer); delete [] pszBuffer; return (TRUE); }
-
Cool !!!!! Danke
-
Jo kein Problem...
Wie du siehst hab ich die Funktion n bissl verschönert...hoffe das war Recht
-
Ähm Cody...
CodeFinder schrieb:
BOOL AppendString( HWND hWnd, int iControlID, PTCHAR pszString, bool fNewLine ) // warum verwendest du den WinAPI möchtegern-Boolean BOOL!? // Verwendest du persönlich die UN? { if( hWnd == NULL || pszString == NULL ) // hWnd == NULL ist wohl nicht angebracht. return (FALSE); PTCHAR pszBuffer; // Ich find ja, LPTSTR kling logischer (..STR[ing]) // BTW: du mixt (schon wieder?) Datentypen aus <tchar.h> und // Stringfunktionen ( lstrlen( ), lstrcat( ) ) die nicht wirklich // dazu passen... UINT uiStrLen = GetWindowTextLength( hWnd ) + 1; // den Text will keiner. Der OP wollte doch den Text des mit iControlID spezifizierten // Controls ändern!? UINT uiAddedLength = lstrlen( pszString ) + 1; // Wieso verwendest du dafür eine extra Variable? pszBuffer = new TCHAR[ uiStrLen + uiAddedLength ]; // Hm, jetzt hast du in pszBuffer Platz für die Caption von hWnd (die keiner will), // pszString und 2 mal '\0'... GetDlgItemText( hWnd, iControlID, pszBuffer, uiStrLen ); // Jetzt ließt du den string den OP will, aber ob pszBuffer dafür ausreichend // groß ist steht in den Sternen. if( fNewLine ) lstrcat( pszBuffer, TEXT( "\r\n" ) ); // Jetzt "quetscht" du nochmal zwei Zeichen in pszBuffer 'rein, für die du garantiert // keinen Platz kalkuliert hast... lstrcat( pszBuffer, pszString ); SetDlgItemText( hWnd, iControlID, pszBuffer ); delete [] pszBuffer; return (TRUE); }
eher (ungetestet):
#include <new> #define UNICODE #define _UNICODE #include <windows.h> #include <tchar.h> using namespace std; bool AppendString( HWND window, int control_id, LPTSTR string, bool insert_newline ) throw( ... ) { HWND control; if( ( !IsWindow( window ) ) || ( !string ) || ( !( control = GetDlgItem( window, control_id ) ) ) ) { return false; } HWND control = GetDlgItem( window, control_id ); if( !control ) { return false; } size_t buffer_size = GetWindowTextLength( control ) + _tcslen( string ) + ( insert_newline ) ? ( 2 ) : ( 0 ) + // "\r\n" sizeof( TCHAR ); // "\0" LPTSTR buffer; try { buffer = new TCHAR[ buffer_size ]; } catch( bad_alloc &e ) { throw e; } GetWindowText( control, buffer, buffer_size ); if( insert_newline ) { _tcscat( buffer, _T( "\r\n" ) ); } _tcscat( buffer, string ); SetWindowText( control, buffer ); delete [ ] buffer; return true; }
Greetz, Swordfish
-
Ähhm Swordy...
...:
Swordfish schrieb:
// warum verwendest du den WinAPI möchtegern-Boolean BOOL!?
// Verwendest du persönlich die UN?Hab ich nur übernommen, wirst in meiner Klasse sehen...normerweise nehm ich immer bool statt BOOL ^^
Swordfish schrieb:
// hWnd == NULL ist wohl nicht angebracht.
Ist ne Minimalversion der Handleüberprüfung...
Swordfish schrieb:
// Ich find ja, LPTSTR kling logischer (..STR[ing])
// BTW: du mixt (schon wieder?) Datentypen aus <tchar.h> und
// Stringfunktionen ( lstrlen( ), lstrcat( ) ) die nicht wirklich
// dazu passen...- Naja was logischer klingt und was nit is wohl Ansichtsache...
- TCHAR ist immer noch in WINNT.H definiert...
- Die Stringfunktionen passen schon, da sie sowohl für UNICODE als auch ANSI ausgelegt sind; Außerdem sind sie in WINBASE.H deklariert ich benutze ALSO IMMER NOCH KEIN TCHAR.H HEADER ...siehe auch hier:MSDN schrieb:
lstrlen(...)
[...]
Header: Declared in winbase.h.
[...]Swordfish schrieb:
// den Text will keiner. Der OP wollte doch den Text des mit iControlID spezifizierten Controls ändern!?
Zum Anhängen musst du den alten ermitteln, der neuen (übergebenen) Text dranhängen und dann alles wieder dem Control hinzufügen...
Swordfish schrieb:
// Wieso verwendest du dafür eine extra Variable?
Wegen Übersichtlichkeit
Swordfish schrieb:
// Hm, jetzt hast du in pszBuffer Platz für die Caption von hWnd (die keiner will),
Doch siehe oben...-> 'Anhängen' ...
Swordfish schrieb:
// pszString und 2 mal '\0'...
Nein!, Einmal für das (logischerweise einzige) '\0' plus das möglicherweise hinzukommende \r\n (siehe Funktionsparameter 'bool fNewLine') BTW: Hier sieht man das ich normalerweie bool statt BOOL verwende :p
Swordfish schrieb:
// Jetzt ließt du den string den OP will, aber ob pszBuffer dafür ausreichend
// groß ist steht in den Sternen.Also groß genug ist der ganz sicherlich...OK, klar wenn da n NewHandler ausgelößt wird, den ich ja nun nicht abgefangen habe...dann sollte man sich aber andere Sorgen machen
... nicht oder ?!
Swordfish schrieb:
// Jetzt "quetscht" du nochmal zwei Zeichen in pszBuffer 'rein, für die du garantiert
// keinen Platz kalkuliert hast...Tze Tze Tze, doch doch doch, hab ich, siehe oben...
Meine Güte was hab ich nur verbrochen...
noch Fragen ?
-
-
CodeFinder schrieb:
Meine Güte was hab ich nur verbrochen...
noch Fragen ?
Ja:
CodeFinder schrieb:
[BOOL] Hab ich nur übernommen, [...]
Ok.
CodeFinder schrieb:
Swordfish schrieb:
// hWnd == NULL ist wohl nicht angebracht.
Ist ne Minimalversion der Handleüberprüfung...
Damit ist noch lange nicht sichergestellt, das das Fenster auch existiert
CodeFinder schrieb:
Swordfish schrieb:
// Ich find ja, LPTSTR kling logischer (..STR[ing])
[...]
- Naja was logischer klingt und was nit is wohl Ansichtsache...Natürlich.
CodeFinder schrieb:
Swordfish schrieb:
// BTW: du mixt (schon wieder?) Datentypen aus <tchar.h> und
// Stringfunktionen ( lstrlen( ), lstrcat( ) ) die nicht wirklich
// dazu passen...Entschuldige, hab' mich vertan.
Swordfish schrieb:
// den Text will keiner. Der OP wollte doch den Text des mit iControlID spezifizierten Controls ändern!?
Zum Anhängen musst du den alten ermitteln, der neuen (übergebenen) Text dranhängen und dann alles wieder dem Control hinzufügen...
Richtig. Tust du aber nicht.
Ich mal dir mal ein Bild:
+---+--------------------------------------------------+ \ | @ | Window Caption [_][O][X]| | +---+--------------------------------------------------+ | | +-------------------- iControlID | | | | | +-------------------------------------|------+ | | | | ein tolles was auch immer Control | | | H | +--------------------------------------------+ | | W | | | N | | | D | | | | | | h | | | W | | | n | | | d | | | | | | | | | | | | +------------------------------------------------------+ /
du machst (verkürzt):
BOOL AppendString( HWND hWnd, int iControlID, PTCHAR pszString, bool fNewLine ) { PTCHAR pszBuffer; UINT uiStrLen = GetWindowTextLength( hWnd ) + 1; // damit kriegst du die Länge von "Window Caption", der Caption des Fensters hWnd GetDlgItemText( hWnd, iControlID, pszBuffer, uiStrLen ); // jetzt ließt du den Text des Controlls iControllID, was nicht mit uiStrLen zusammenpasst. lstrcat( pszBuffer, pszString ); SetDlgItemText( hWnd, iControlID, pszBuffer ); return TRUE; }
Weißt du, was ich meine??
CodeFinder schrieb:
Swordfish schrieb:
Wieso verwendest du dafür eine extra Variable?
Wegen Übersichtlichkeit
Ok.
CodeFinder schrieb:
Swordfish schrieb:
// Hm, jetzt hast du in pszBuffer Platz für die Caption von hWnd (die keiner will),
Doch siehe oben...-> 'Anhängen' ...
Swordfish schrieb:
// pszString und 2 mal '\0'...
Nein!, Einmal für das (logischerweise einzige) '\0' plus das möglicherweise hinzukommende \r\n [...]
Swordfish schrieb:
// Jetzt ließt du den string den OP will, aber ob pszBuffer dafür ausreichend
// groß ist steht in den Sternen.Also groß genug ist der ganz sicherlich...OK [...]
Swordfish schrieb:
// Jetzt "quetscht" du nochmal zwei Zeichen in pszBuffer 'rein, für die du garantiert
// keinen Platz kalkuliert hast...Tze Tze Tze, doch doch doch, hab ich, siehe oben...
Tja, anhängen ist schon klar (nur was an was nicht
).
du machst (wieder verkürzt):
BOOL AppendString( HWND hWnd, int iControlID, PTCHAR pszString, bool fNewLine ) { // nehmen wir mal an pszString = "Hallo" UINT uiStrLen = GetWindowTextLength( hWnd ) + 1; // Die länge eines Textes, den keiner will. In meiner obigen Zeichnung gibt das 14 + 1 = 15 UINT uiAddedLength = lstrlen( pszString ) + 1; // Ok, macht 5 + 1 = 6 pszBuffer = new TCHAR[ uiStrLen + uiAddedLength ]; // Jetzt reservierst du Platz für 15 + 6 = 21 Zeichen. GetDlgItemText( hWnd, iControlID, pszBuffer, uiStrLen ); // Jetzt lädst du den String "ein tolles was auch immer Control", welcher // 33 Zeichen lang ist. Siehste? passt nicht ;) if( fNewLine ) lstrcat( pszBuffer, TEXT( "\r\n" ) ); // jetzt noch mal 2 Zeichen drüber... lstrcat( pszBuffer, pszString ); // und noch die 5 vom Hello... // Das macht dann 33 + 2 + 5 = 40 Zeichen in einen reservierten // Speicherbereich von 21 Zeichen! SetDlgItemText( hWnd, iControlID, pszBuffer ); return TRUE; }
Verstehst du mich?
Greetz, Swordfish
-
Swordfish schrieb:
Verstehst du mich?
Nein. ^^ ...Denn:
BOOL AppendString(HWND hWnd, int iControlID, PTCHAR pszString, bool fNewLine) { // [...] // Vorraussetzung: // - pszString = "du da" also 6 Zeichen // - Fenstertext = "Hallo" also auch 6 Zeichen PTCHAR pszBuffer; // Länge der Fenstertextes ermitteln an den pszString angehängt werden soll: UINT uiStrLen = GetWindowTextLength(hWnd) + 1; // bei "Hallo" -> 6 // Länge von pszString ermitteln: UINT uiAddedLength = lstrlen(pszString) + 1; // bei "du da" -> 7 // Speicher für den Fenstertext, pszString und möglichweise 'fNewLine' allokieren: pszBuffer = new TCHAR[uiStrLen + uiAddedLength]; // platz für 13 // // Nur den Fenstertext ermitteln, also bleibt uiAddedLength noch FREI! GetDlgItemText(hWnd, iControlID, pszBuffer, uiStrLen); // nur 6 belegt // Neue zeile...?... if(fNewLine) lstrcat(pszBuffer, TEXT("\r\n")); // maximal 7 belegt // Erst jetzt ist die Pufferkapazität erschöpft, da nun zu dem Fenstertext auch noch der // übergebene bzw hinzuzufügene Text(String) angehängt wurde: lstrcat(pszBuffer, pszString); // zu den 7 kommen jez maximal 6 ("du da") // --> Also passt das, BTW: ich habs mittlerweile auch getestet, und // es funktioniert einwandfrei. SetDlgItemText(hWnd, iControlID, pszBuffer); // Text setzen delete [] pszBuffer; // speicher deallokieren return (TRUE); }
EDIT: Aber mit fällt grad auf, einem Punkt hassu recht es muss heißen:
UINT uiAddedLength = lstrlen(pszString) + 2; // bei "du da" -> 7
Dann kommt dat auch mit der 7 hinten wieder hin, dachte lstrlen würde dir Null-Terminierung mitzählen, sry, mein Fault! ...Aber der Rest stimmt.
-
Ich bin damit klargekommen für meine Bedürfnisse hats vollauf gereicht, danke nochmal
Aloha.