CreateWindow, Parameter 1 und 2 typecasten???



  • CodeFinder schrieb:

    Aber welche Funktionen sind denn bspw. in tchar.h deklariert (für die es sich lohnt diese Datei zu inkludieren) ?

    Die Datei zu verwenden ist immer dann sinnvoll, wenn du TCHAR verwendest. Für praktisch alle char/wchar_t Standard Funktionen, wie zB strlen, strcpy, sprintf, etc.pp, gibt es entsprechende TCHAR Gegenstücke. Allerdings sind diese Sachen nicht offiziell, deshalb beginnen die Bezeichner auch mit einem Unterstrich. Aber wenn du MinGW oder den MSC verwendest, ist die Datei verfügbar. Windows selbst stellt ebenfalls TCHAR Funktionen bereit. Diese beginnen mit l, zB lstrcpy. Dies ist aber bei weitem nicht so umfangreich, und kann zudem nicht statisch zur Anwendung gelinkt werden, da diese Funktionen in einer DLL liegen (kernel32).

    Und um nochmal darauf zurückzukommen:

    CodeFinder schrieb:

    Das macht der Compiler automatisch.

    Der Compiler macht hier nichts automatisch. Der verarbeitet im Endeffekt nur ...A und ...W Funktionen. Bevor es soweit ist, kommt der Präprozessor zum Zuge. Der macht, abhängig davon, ob das Makro UNICODE definiert ist (bei <tchar.h> ist es übrigens _UNICODE), aus "Bezeichner" entweder "BezeichnerA" (UNICODE nicht definiert) oder "BezeichnerW" (UNICODE definiert). Deshalb sollte man möglichst immer auf eine der folgenden Möglichkeiten zurückgreifen, um Inkonsistenzen zu vermeiden.

    // 1) ANSI only
    CreateWindowA("Klasse1", "Titel", //...);
    // 2) Unicode only
    CreateWindowW(L"Klasse1", L"Titel", //...);
    // 3) ANSI/Unicode
    CreateWindow(TEXT("Klasse1"), TEXT("Titel"), //...);
    //    bzw. mit <tchar.h>
    CreateWindow(_T("Klasse1"), _T("Titel"), //...);
    

    Alles andere ist nicht zu empfehlen. Das kann sogar soweit gehen, dass das Projekt überhaupt nicht mehr kompiliert werden kann.
    Stell dir vor, an einer Stelle steht

    CreateWindow("Klasse1", "Titel", //...);
    

    und an anderer Stelle

    CreateWindow(L"Klasse1", L"Titel", //...);
    

    Dann kannst du in den Projekteinstellungen Unicode ein- und ausschalten wie du willst, das wird dir nicht helfen.

    Wieso man dieses ANSI/Unicode portable Konzept eingeführt hat, kann sicherlich hinterfragt werden. Fakt ist aber, dass gerade ältere Windows Betriebssysteme nur begrenzten Support für Unicode haben. Dort wird idR ANSI kompiliert, bei einem aktuellen Windows ist natürlich Unicode sinnvoll. Und da ist es definitiv praktischer, man legt einfach nur einen Hebel um und alles funktionert, anstatt ständig zwei Projekte zu pflegen.
    Natürlich kann man, wenn man einen Zeichensatz nicht braucht bzw. nicht unterstützen will, diesen verwerfen. Dann sollte man sich aber auch über die Konsequenzen im Klaren sein, und das Projekt diesbzgl. absichern, zB mit

    #ifndef UNICODE
        #error Projekt darf nur mit Unicode kompiliert werden!
    #endif
    

    oder Ähnlichem.



  • @groovemaster:
    Danke für den ausführliche und informativen Post...aber...das wusste ich eigentlich schon...das der Präprozessor auch Präprozessor-Direktiven (alá '#include') verarbeitet (bzw ersetzt) und nicht der Compiler ist mir klar; War wohl n bissl woanders...trotzdem DANKE! 😉



  • Dass du das weisst, konnte ich mir schon denken. 🙂 War auch vielmehr als Erklärung für den OP gedacht, dem das vielleicht nicht so ganz klar war.



  • Also der Beitrag, der lange, der war es echt. Kenn mich jetzt soweit aus, dass ich meine Fehler selber finde, vielen Dank dafür!

    Nur eine Frage noch zu den "neuen" Befehlen.
    Du hast gesagt, dass meistens "einfach nur ein l" davor steht, das funktioniert zum Beispiel mit lstrcpy perfekt, nur gibt es kein lsizeof weswegen Dinge wie

    sizeof(keyStroke) / sizeof(wchar_t) - 1
    

    entstehen, gibts da keine schönere Lösung.

    Außerdem funktioniert das bei mir nicht richtig.

    Was ich inetwa habe:

    Ein Fenster, in dem, in einem Rechteck, ein Text angezeigt werden soll. Jener Text zeigt an, ob eine Pfeiltaste gedrückt wurde, wenn nicht steht "No Arrow pressed".

    Relevante Codeausschnitte sehen bei mir so aus:

    //Membervariable
    wchar_t keyStroke[] = TEXT("Nothing pressed yet ...");
    
    // ...
    
    //wird eine Taste gedrückt (WM_KEYDOWN)
    
    switch(wParam)
    			{
    				case VK_LEFT:
    					lstrcpy(keyStroke,TEXT("Arrow: Left"));
    					break;
    
    //und so weiter
    
    // ...
    
    //wird das Fenster gezeichnet findet sich folgender Befehl
    DrawText(myHDC, keyStroke, sizeof(keyStroke) / sizeof(wchar_t) - 1, &myRect, DT_CENTER|DT_TOP);
    

    Das funktioniert ansich perfekt, außer das ich wieder Dinge wie "Arrow:Left|||||" zu sehen bekomme.

    Deswegen frage ich nach einer Variante like lsizeof.

    Gibt es irgendwo eine Liste mit all diesen Befehlen? Thx 4 help!



  • wenn unicode an kannste doch einfach lstrlen() nehmen ?

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/strings/stringreference/stringfunctions/lstrlen.asp
    (Links in der navi stehen weitere String Funktionen, das ganze ist auch in der Platform SDK Doku drin...)



  • Okay, das ist natürlich einfacher, vielen Dank.



  • D!3ce schrieb:

    Nur eine Frage noch zu den "neuen" Befehlen.
    Du hast gesagt, dass meistens "einfach nur ein l" davor steht, das funktioniert zum Beispiel mit lstrcpy perfekt, nur gibt es kein lsizeof

    Das mit dem "l" bezog sich ja auch nur auf Funktionen, welche explizit TCHAR Argumente verwenden. Welche Funktionen es gibt, kann man in der Platform SDK Dokumentation nachlesen. sizeof ist ein C bzw. C++ Schlüsselwort, und funktioniert daher vollkommen unabhängig davon. Zudem sind diese "l" Bezeichner WinAPI spezifisch, sizeof jedoch Standard. Dh, sie existieren in vollkommen anderen "Welten".

    D!3ce schrieb:

    Das funktioniert ansich perfekt, außer das ich wieder Dinge wie "Arrow:Left|||||" zu sehen bekomme.

    Mal ganz abgesehen davon, sollte die Definition des Arrays mit TCHAR erfolgen.

    TCHAR keyStroke[] = TEXT("Nothing pressed yet ...");
    

    Wenn du wchar_t verwendest, legst du dich auf Unicode fest, und dann sollten auch entsprechende Literale (L"...") und WinAPI Funktionen (...W) verwendet werden.

    Das Problem ist nun, dass mit

    sizeof(keyStroke) / sizeof(wchar_t)
    

    die Anzahl der Elemente im Array berechnet werden, dh diesem Array

    wchar_t keyStroke[] = TEXT("Nothing pressed yet ...");
    

    Wenn du mal die Zeichen + das abschliessende Nullzeichen durchzählst, kommst du auf das Ergebnis 24. Damit werden beim Aufruf von DrawText auch 24 Zeichen ausgegeben. Nun steht aber bereits ein ganz anderer String im Array (du solltest übrigens auch darauf achten, _niemals_ mehr als 24 Zeichen in dieses Array zu schreiben), nämlich

    "Arrow: Left"
    

    was letztendlich nur 12 Zeichen sind. Du sagst DrawText trotzdem, dass 24 Zeichen ausgegeben werden sollen. Dementsprechend steht am Ende irgendwelcher Müll.
    Du solltest also eine Funktion wie lstrlen benutzen, damit es korrekt funktioniert. Oder du setzt den Parameter entsprechend der Dokumentation

    If nCount is 1, then the lpString parameter is assumed to be a pointer to a null-terminated string and DrawText computes the character count automatically.


Anmelden zum Antworten