[SOLVED] TextOut stellt LPCWSTR nicht dar



  • Hallo zusammen,

    ich habe ein kleines Programm geschrieben, das aus einer Textdatei (eigene Endung, .msg) eine Nachricht einliest und diese ausgibt. Dabei habe ich auf fopen() verzichtet, weil das bei mir immer eine ziemliche Katastrophe 😉 ist, und habe die Filestreams (instream()) verwendet. Daraufhin konvertiere ich den std::string in einen LPCWSTR und übergeb ihn TextOutW(). Das funktioniert aber nicht, das Programmfenster bleibt leer. Die Textausgabe hatte früher schon einmal funktioniert, also an der TextOut wird es nicht liegen.
    Ich habe mit Debuggen herausgefunden, dass die richtigen Werte der Funktion übergeben werden.
    Mir ist es ein Rätsel.
    Hier der Code:

    char* n = "";
    	char* u = "";
    	std::string str1;
    	std::string str2;
    	std::ifstream in("message.msg");
    	LPCWSTR e[3] = {TEXT(""), TEXT(""), TEXT("")};
    	bool exit_for = false;
    	char x[3][15] = {"","",""};
    		in >> str1 >> str2;
    		n = const_cast<char*>(str1.c_str()); // :D const_cast, böse!!!
    		for(int l = 0; l < 3; l++)
    		{
    		for(int i = 0; i < 14; i++)
    		{
    			x[l][i] = n[l*14+i];
    			if(x[l][i] == '\0')
    			{
    				exit_for = true;
    				break;
    			}
    		}
    		if(exit_for)
    			break;
    		}
    		e[0] = A2BSTR(x[0]);
    		e[1] = A2BSTR(x[1]);
    		e[2] = A2BSTR(x[2]);
    		TextOut(hdc, 75, 10, e[0], strlen(x[0]));
    		TextOut(hdc, 75, 30, e[1], strlen(x[1]));
    		TextOut(hdc, 75, 50, e[2], strlen(x[2]));
    

    (Natürlich ist da außenrum noch das ganze WM_PAINT Zeug, was ich aber weggelassen habe).

    Habt ihr eine Idee?

    Viele Grüße,
    Lauritz 😞

    PS: In der message.msg wird, um Leerstellen darzustellen, ALT+0160 (0160 auf dem Ziffernpad). Kann das vielleicht Auslöser des Problems sein? Er zeigt nämlich beim Debuggen immer sowas wie "Bitte Ákalibirieren ÁSie Ádas ÁGeraet" an (korrekt wäre :"Bitte kalibrieren Sie das Geraet").



  • Dein Sourcecode sieht sehr nach bayrischem Wurstsalat aus. Mir fällt auf, da gibt es die initialisierten Pointer n und u, die wohl strings aufnehmen sollen, es aber nicht tun. Das ist doch mehr ANSI-C als ein Problem mit WinApi. Ich mag dir mit diesem Wurstansatz nicht helfen. Wann immer du einen String hast, kriegst du diesen mit TextOut() auch zu sehen! 🙂



  • berniebutt schrieb:

    Dein Sourcecode sieht sehr nach bayrischem Wurstsalat aus.

    ROFL!



  • loler schrieb:

    ROFL!

    loler: Wo ist jetzt dein konkreter Beitrag auf diese Frage? Die Zielsetzung erscheint mir unpräzise gefragt und der Lösungsansatz dafür zu umständlich!



  • Hast Du UNICODE *und* _UNICODE definiert?

    Und warum verwendest Du A2BSTR!? Verwende doch bitte CA2CW



  • @berniebutt: sry für den unleserlichen Code. u ist bestandteil eines noch nicht implementierten features, mit dem ich den pfad für eine bitmap einlese und diese dazu ausgebe 😉
    Außerdem:

    n = const_cast<char*>(str1.c_str());
    

    n nimmt sehr wohl einen String auf. Weiteren Gebrauch von n mache ich in Zeile 15:

    x[l][i] = n[l*14+i];
    

    .

    @Jochen

    Ja, ich habe UNICODE und _UNICODE definiert. CA2CW findet er bei mir nicht, obwohl ich atlbase.h, AtlBase.h und atlconv.h inkludiert habe (ich weiß, eines hätte gereicht), und die MSDN-Seite http://msdn2.microsoft.com/library/87zae4a3.aspx hat einen 500 internal server error 😉 .
    Ich denke, dass es einfach so ist, dass TextOut nicht mit den Zeichen umgehen kann, die es bekommt (am Anfang des eingelesenen Strings sind so Sachen wie í etc.) und deshalb einfach gar nichts ausgibt.

    char* n = "";
        std::string str1, str2;
        std::ifstream in("message.msg");
        LPCWSTR e[3] = {TEXT(""), TEXT(""), TEXT("")};
        bool exit_for = false;
        char x[3][15] = {"","",""};
        in >> str1 >> str2;
        n = const_cast<char*>(str1.c_str()); // :D const_cast, böse!!!
        for(int l = 0; l < 3; l++)
        {
            for(int i = 0; i < 14; i++)
            {
                x[l][i] = n[l*14+i];
                if(x[l][i] == '\0')
                {
                    exit_for = true;
                    break;
                }
            }
            if(exit_for)
                break;
       }
       e[0] = A2BSTR(x[0]);
       e[1] = A2BSTR(x[1]);
       e[2] = A2BSTR(x[2]);
       TextOut(hdc, 75, 10, e[0], strlen(x[0]));
       TextOut(hdc, 75, 30, e[1], strlen(x[1]));
       TextOut(hdc, 75, 50, e[2], strlen(x[2]));
    

    (versuchte Korrektur bayerischen Wurstcodes, oder so...)

    Grüße,
    Lauritz



  • LauritzG: Die Zielsetzung deiner Frage ist dann aber nicht mehr WinApi, sondern die Frage: Wie kriege ich einen Text aufbereitet, damit ich ihn mit der WinApi-Funktion TextOut() im aktuellen Fenster dargestellt bekomme? Ich steige durch deinen Sourcecode leider nicht voll durch. Vielleicht liegt das aber nur am Programmierstil?



  • berniebutt schrieb:

    Vielleicht liegt das aber nur am Programmierstil?

    Das mag sein. Ich habe inzwischen weitere Problemlösungsversuche unternommen, sodass ich nun eine ANSI-Datei einlese anstatt einer UTF-8-Datei. Das heißt, dass zumindest mal der Debugger die Strings ohne Fehler einliest. Angezeigt wird immer noch nichts. Ich sehe mal, ob das mit Unicode besser geht.

    Zur Erklärung meines Codes:

    char* n = "";
        std::string str1, str2;
        std::ifstream in("message.msg");
        LPCWSTR e[3] = {TEXT(""), TEXT(""), TEXT("")};
        bool exit_for = false;
        char x[3][15] = {"","",""};
    

    In die beiden Strings str1 und str2 wird über einen ifstream eingelesen. Dann wird str1 (str2 ist noch nicht implementiert 🤡 ) zu char* konvertiert, was es mir möglich macht, ihn in drei verschiedene char[]-Strings zu übertragen (const_cast, c_str()), die dann über A2BSTR zu LPCWSTR konvertiert werden. Diese LPCWSTRs werden dann mit TextOut() ausgegeben werden. Drei Strings deshalb, weil meine Ausgabe dreizeilig wird, und ich deshalb für jede Zeile TextOut einzeln mit einem anderen String aufrufe. Im Idealfall sieht das dann so aus:

    __________________

    Bitte kalibrieren <= Hier kann natürlich auch mitten im Wort abgebrochen werden...
    Sie das Geraet!
    __________________

    in >> str1 >> str2;
        n = const_cast<char*>(str1.c_str()); // :D const_cast, böse!!!
        for(int l = 0; l < 3; l++)
        {
            for(int i = 0; i < 14; i++)
            {
                x[l][i] = n[l*14+i];
                if(x[l][i] == '\0')
                {
                    exit_for = true;
                    break;
                }
            }
            if(exit_for)
                break;
       }
       e[0] = A2BSTR(x[0]);
       e[1] = A2BSTR(x[1]);
       e[2] = A2BSTR(x[2]);
       TextOut(hdc, 75, 10, e[0], strlen(x[0]));
       TextOut(hdc, 75, 30, e[1], strlen(x[1]));
       TextOut(hdc, 75, 50, e[2], strlen(x[2]));
    

    Viele Grüße,
    Lauritz 🙂



  • Meine Vorgehensweise wäre da:
    - Die Bytes der Textdatei in einen Puffer packen (CreateFile, ReadFile, CloseHandle)
    - Den Inhalt des Puffers via MultiByteToWideChar() in Widechars (LPWSTR) umwandeln.
    - Jetzt den String so aufsplitten wie du's brauchst (scheinbar maximal 14 Zeichen pro Zeile?)

    In MultiByteToWideChar() schmeißt du quasi nen Pointer auf die Quelltext-Bytes rein (lpMultiByteStr), sagst ihm welches Format der Quelltext hat (CodePage,z.B. UTF8) und die Funktion schmeißt das ganze dann als WideChars wieder raus (lpWideCharStr)



  • const_cast<char*>(str1.c_str());
    

    kannste ersetzen durch

    &str1[0]
    


  • Danke Icematix, ich habe das in meinen Code integriert.

    Ich habe das Problem inzwischen gelöst:

    Beim Programmstart wird WM_CREATE: ausgeführt. Dabei werden alle meine Variablen initialisiert. Daraufhin wird WM_PAINT ausgeführt (fehlendes break), obwohl noch kein Fenster zu sehen ist. Dann wird WM_PAINT noch einmal ausgeführt, während dann alle Variablenwerte gelöscht sind. Das habe ich behobnen, indem ich den WM_CREATE-Block in den WM_PAINT-Block migriert habe.

    Vielen Dank an euch alle!
    Grüße,
    Lauritz


Anmelden zum Antworten