Fragen zur Texteinlesung mehrzeiliger Editfenster



  • Guten Abend.

    Ich hätte da mal Fragen zum im Titel genannten Thema.

    Um jede Zeile einzeln einlesen zu können, habe ich folgenden Code:

    Variablen:

    int zeilenlaenge=0;
    char zwischenspeicher[50];
    HWND hwndEdit=GetDlgItem(hDialog, IDC_EDT1);
    

    Einlesen:

    zeilenlaenge = (int)SendMessage(hwndEdit, EM_LINELENGTH, (WPARAM)SendMessage(hwndEdit, EM_LINEINDEX, (WPARAM)0, 0), 0); 
    SendMessage(hwndEdit, EM_GETLINE, (WPARAM)zeilenlaenge, (LPARAM)zwischenspeicher); 
    zwischenspeicher[zeilenlaenge]='\0';
    

    Funktioniert unter normalen Umständen, welche auch immer das sein mögen, dieser Code? Ich saß am Mittag Stunden daran, habe das Programm aber nicht zum laufen bekommen.
    Ich versuche zwischenspeicher mit TextOut auszugeben:

    HDC hdc;
    hdc=GetDC(hDialog);
    TextOut(hdc, 1, 1, zwischenspeicher, 10);
    ReleaseDC(hDialog, hdc);
    

    TextOut gibt mir in dem Beispiel 10 von den kleinen Rechtecken aus, die man, glaube ich, auch mit Null-Teminierung darstellen kann. Schade nur, dass ich nur am Zeilenende eine Null-Terminierung einfüge.
    Wo liegt der Fehler? Ermitteln wie viel Zeilen vorhanden sind, brauch ich nicht, da ich die genaue Anzahl weiß und diese auch vorher überprüft wird.
    Da nach stundenlangem selbst probieren, der Code ziemlich ähnlich von irgendwelchen Codes aus dem Petzold und aus dem Forum hier ist, wüsste ich nicht was zum Teufel da schief gelaufen sein könnte.
    GetLastError() gibt mir leider auch keine Hilfe dazu.

    Ansonsten hätte ich noch die Frage, auch wenn sie sich jetzt vielleicht sehr anfängerisch (wenn das Wort existiert) anhört, wieso ich bei SendMessage() noch für den 3. Parameter, wenn er beinhaltet, ein (WPARAM) bzw. beim 4. (LPARAM) zusätzlich eintragen muss? Der Compiler warnt mich dabei, aber ein richtiger Fehler ist es scheinbar doch nicht, da es auch ohne geht. Ohne kann ich es auch im Petzold finden, aber wieso erwartet der Compiler den Zusatz, der in meinen Augen überflüssig ist, da ja 3. und 4. Parameter für WPARAM bzw. LPARAM bestimmt ist.

    Mit freundlichen Grüßen
    Moadeh


  • Mod

    Das geht so nicht. DU hast die Doku nicht gelesen:
    lParam
    A pointer to the buffer that receives a copy of the line. Before sending the message, set the first word of this buffer to the size, in TCHARs, of the buffer. For ANSI text, this is the number of bytes; for Unicode text, this is the number of characters. The size in the first word is overwritten by the copied line.

    also:
    *reinterpret_cast<WORD*>(zwischenspeicher) = sizeof(zwischenspeicher);

    Und bitte Vorsicht, wenn die Zeilenlänge größer als Dein Speicher wird.



  • Wenn die Zeilenlänge größer als der Speicher ist, wird die Zeile doch abgeschnitten oder nicht?

    Zu dem Problem.
    Ich schreibe meine Programme in c.
    Wie heißt denn das Äquivalent *reinterpret_cast<WORD*>?

    Mit freundlichen Grüßen
    Moadeh



  • Moadeh schrieb:

    Wenn die Zeilenlänge größer als der Speicher ist, wird die Zeile doch abgeschnitten oder nicht?

    Wenn Du die korrekte Größe angibst wird auch kein Überlauf generiert, jap 😉 .

    Moadeh schrieb:

    Wie heißt denn das Äquivalent *reinterpret_cast<WORD*>?

    *((WORD*)Variable)
    

    Edit: Zitat korrigiert.



  • Danke schön euch beiden.

    Funktioniert nun.

    Mit freundlichen Grüßen
    Moadeh


  • Mod

    Moadeh schrieb:

    Wenn die Zeilenlänge größer als der Speicher ist, wird die Zeile doch abgeschnitten oder nicht?

    Nicht wenn Du so einen Blödsinn machst:
    zwischenspeicher[zeilenlaenge]='\0';

    Moadeh schrieb:

    Zu dem Problem.
    Ich schreibe meine Programme in c.
    Wie heißt denn das Äquivalent *reinterpret_cast<WORD*>?

    Und warum das bitte? Dem Compiler ist es egal ob er C++ oder C Code compiliert.



  • Solang das Projekt auch auf C++ eingestellt ist, nehme ich mal an.
    Aber sag mir mal bitte, wo der Vorteil ist wenn ich überhaupt kein C++ kann und dann einfach eine C++ Zeile da einbaue? Das macht meiner Ansicht nach wenig Sinn 😉
    Abgesehen davon hat sich mein Compiler beschwert.

    Und wieso ist die Zeile mit der Null-Terminierung Blödsinn?


  • Mod

    1. C++ ist nicht so viel anders als C.
    2. C++ ist härter und genauer in der Syntax. Deshalb vorzuziehen.
    3. Kannst Du den C++ Syntax durch Umbenennnen der Sourcen, bzw. Compiler Schalter (individuell je Datei) erreichen.
    4. Weil Du die Zeilenlänge anhand der realen Daten ermittelst. Aber Dein Puffer evtl. viel kleiner ist. Im Beispiel bei Dir. 50 ist Deine Puffergröße. Die Zeile mag aber 100 lang sein. In den Puffer wird nur soviel geladen wie Du willst. Diese Befehl
    zwischenspeicher[zeilenlaenge]='\0';
    geht aber über die Puffergrenze hinaus...



  • Ich bin totaler Programmieranfänger. Ich programmiere seit Juli meines Wissens nach und eher mäßig aktiv. Richtig aktiv habe ich erst die letzten 3 Wochen programmiert. Wenn ich jetzt in meinen C-Code plötzlich C++-Code einbaue, weiß ich jetzt schon, dass ich hinterher nur noch überfordert bin 😉
    Aber das ist auch eigendlich ziemlich egal. Du bist vielleicht überzeugter C++-Programmierer und ich bin ein Anfänger, der erstmal mit einen Sprache anfangen möchte.

    Und zu der Null-Terminierung:
    Da hast du wohl Recht. Nur ist das Editfenster nicht großgenug, um den Bereich zu überschreiten. Um genau zu sein ist der Bereich noch um 4 größer, als maximal in das Editfenster eingegeben werden könnte.


  • Mod

    Moadeh schrieb:

    Und zu der Null-Terminierung:
    Da hast du wohl Recht. Nur ist das Editfenster nicht großgenug, um den Bereich zu überschreiten. Um genau zu sein ist der Bereich noch um 4 größer, als maximal in das Editfenster eingegeben werden könnte.

    Du irrst, wenn enfach Daten eingegeben werden ohne das der User die Eingabe-Taste drückt wird ein automatischer Wrap durchgeführt. Die Zeile 4 im Text mag sich auf dem Bildschirm über mehrere Zeilen erstecken.



  • Okay, gut. Das stimmt wohl. Da das Editfenster aber dazu dient, einfach mit Copy&Paste Daten nach einem bestimmten Shema, welches auch vorher nachgeprüft wird, dort reinzukopieren, kann das Problem nicht auftreten. Sollte es also wirklich dazu kommen, dass das, was dort reinkopiert werden soll, zu lang ist, wird es ja nicht dort eingefügt. Zumindest nicht bei den Styles die ich dem Editfenster zugewiesen habe.


  • Mod

    Und wie kontrllierst Du das? Und wie kontrollierst Du, dass nicht ein User ein Zeilenende löscht und dadurch eine Zeile verlängert.

    Richtig wäre es hier eine maximal Abfrage zu machen...



  • Ich kontrolliere das durch Abfrage der Zeilenanzahl. Wenn eine Zeile zu wenig (zuviel ist nicht möglich) da ist, wird weiteres Behandeln der Eingabe nicht ermöglicht.
    Außerdem teste ich noch je das 1. Wort der einzelnen Zeilen, damit die Eingabe dem Shema gerecht wird. Das 2. Wort der Zeilen ergibt dann schon einen individuellen Wert, der gespeichert wird und Daten enthält, die mitkopiert werden. Somit muss ich dieses nicht testen.


Anmelden zum Antworten