Text "effektiv" in eine Winapi-Textbox einfügen



  • so ich habe unterdessen selbst eine Lösung gefunden:

    void AddText(HWND hwnd, string text, COLORREF farbe)
    {
    	int länge=GetWindowTextLength(hwnd);
    	SendMessage(textbox, EM_SETSEL, länge, länge);
    
    	char buf[1000];
    	strcpy(buf, text.c_str());
    
    	WCHAR buf2[1000];
    
    	_USE(cout.getloc(), ctype<wchar_t>).widen(buf, buf+strlen(text.c_str()), buf2);//konvertieren...
    
    	buf2[text.length()]=TEXT('\0');//null-terminieren...
    
    	SendMessage(textbox, EM_REPLACESEL, true, (LPARAM) buf2);//in chatbox schreiben...
    
    	//NEU:
    	CHARFORMAT cf;
    	cf.cbSize=sizeof(CHARFORMAT);
    	cf.dwMask      = CFM_COLOR | CFM_UNDERLINE | CFM_BOLD; 
    	cf.dwEffects   = (unsigned long)~(CFE_AUTOCOLOR | CFE_UNDERLINE | CFE_BOLD); 
    	cf.crTextColor = farbe; 
    
    	int l=GetWindowTextLength(hwnd);
    	SendMessage(textbox, EM_SETSEL, l, länge);
    
    	SendMessage(hwnd, EM_SETCHARFORMAT, (WPARAM)(UINT)SCF_SELECTION, (LPARAM)&cf); 
    }
    

    edit: ich habe doch noch eine Frage zu dieser Zeile:

    cf.dwEffects   = (unsigned long)~(CFE_AUTOCOLOR | CFE_UNDERLINE | CFE_BOLD);
    

    wenn man die benutzt wird es farbig, aber nicht fett und nicht unterstrichen...

    wenn ich stattdessen

    cf.dwEffects   =   CFE_AUTOCOLOR | CFE_UNDERLINE | CFE_BOLD
    

    benutze wird es unterstrichen, aber nicht farbig und nicht fett.

    kriegt man die Zeile irgendwie farbig, unterstrichen und fett?

    geblieben ist nur diese "grässliche Konvertierung" weil soweit ich weiß in der Express-Version von VisualStudio kein ATL verfügbar ist - korrigiert mich bitte wenn ich falsch liege!

    btw: wenn jemand eine bessere Konvertierungsmöglichkeit hat übernehme ich die gerne, nur ohne ATL kenne ich keine andere 🙄

    lg,
    andi01.


  • Mod

    Korrekt ATL/MFC sind in der EE nicht drin!



  • andi01 schrieb:

    wegen der Konvertierung: ...

    #include <atlconv.h> // für A2W
    ..
    // ATL
    USES_CONVERSION; // ich persönlich mag dieses Makro nicht
    SendMessage(textbox, EM_REPLACESEL, true, reinterpret_cast<LPARAM>(A2W(text.c_str()));
    
    // oder, da du C++ verwendest
    #include <vector>
    std::vector<wchar_t> wstr(str.length()+1,0);
    MultiByteToWideChar(CP_ACP,0,str.c_str(),str.length(),&wstr[0],str.length());
    SendMessage(textbox, EM_REPLACESEL, true, reinterpret_cast<LPARAM>(&wstr[0]);
    

    Edit: Das mit der ATL-Version hat sich damit sowieso erledigt



  • ok, die zweite Konvertierungsmöglichkeit werde ich dann mal übernehmen...

    bleibt nur noch die Frage von oben wie ich gleichzeitig farbig, fett und unterstrichen hinkriege. wäre schön wenn das auch noch funktioniert 🙂

    lg,
    andi01.



  • Ich habe es nicht ausprobiert, aber diese Zeile kommt mir verdächtig vor

    cf.dwEffects = (unsigned long)~(CFE_AUTOCOLOR | CFE_UNDERLINE | CFE_BOLD);
    // vielleicht so?
    // Ich habe gerade erst gesehen, dass cf.dwEffects nicht initialisiert wurde, also
    // vor Bitoperationen
    cd.dwEffedcts = 0;
    // die nächste Zeile ist damit überflüssig
    cf.dwEffects &= ~CFE_AUTOCOLOR;
    cf.dwEffects |= (CFE_UNDERLINE | CFE_BOLD);
    

    Wie geschrieben, nicht getestet...

    Edit: Tag missraten



  • ich habe es gerade getestet. jetzt ist es farbig und unterstrichen.

    von wenn man BOLD weglässt merkt man aber keinen Unterschied - allerdings weiß ich nicht ob es einfach daran liegt dass eine RichTextbox das nicht besser darstellen kann oder daran dass es nicht funktioniert.

    btw: sowas habe ich ja noch nie gesehen:

    cf.dwEffects &= ~CFE_AUTOCOLOR;
    cf.dwEffects |= (CFE_UNDERLINE | CFE_BOLD);
    

    wo liegt denn da der Unterschied zu

    cf.dwEffects = (unsigned long)~(CFE_AUTOCOLOR | CFE_UNDERLINE | CFE_BOLD);
    

    edit: hier mal 2 screens:

    mit boult: http://img842.imageshack.us/img842/1466/boult.png
    ohne boult: http://img600.imageshack.us/img600/8324/nichtboult.png

    ich sehe da keinen unterschied...

    lg,
    andi01.



  • Ich habe noch einen Edit reingeschrieben.

    dw = 2;
    dw &= ~(1<<1); // löscht das Bit
    dw |= ((1<<2)|(1<<3));
    // bei dw sind nun die Bits 2 und 3 gesetzt-> dw hat den Wert 12.
    


  • also hier mal der komplette code beider versionen:

    Version 1:

    void AddText(HWND hwnd, string text, COLORREF farbe)
    {
    	int länge=GetWindowTextLength(hwnd);
    	SendMessage(textbox, EM_SETSEL, länge, länge);
    
    	char buf[1000];
    	strcpy(buf, text.c_str());
    
    	WCHAR buf2[1000];
    
    	_USE(cout.getloc(), ctype<wchar_t>).widen(buf, buf+strlen(text.c_str()), buf2);//konvertieren...
    
    	buf2[text.length()]=TEXT('\0');//null-terminieren...
    
    	SendMessage(textbox, EM_REPLACESEL, true, (LPARAM) buf2);//in chatbox schreiben...
    
    	//NEU:
    	CHARFORMAT cf;
    	cf.cbSize=sizeof(CHARFORMAT);
    	cf.dwMask      = CFM_COLOR | CFM_UNDERLINE | CFM_BOLD; 
    	cf.dwEffects =0;
    	cf.dwEffects &= ~CFE_AUTOCOLOR;
    	cf.dwEffects|= (CFE_UNDERLINE | CFE_BOLD); 
    	cf.crTextColor = farbe; 
    
    	int l=GetWindowTextLength(hwnd);
    	SendMessage(textbox, EM_SETSEL, l, länge);
    
    	SendMessage(hwnd, EM_SETCHARFORMAT, (WPARAM)(UINT)SCF_SELECTION, (LPARAM)&cf); 
    }
    

    version 2:

    void AddText(HWND hwnd, string text, COLORREF farbe)
    {
    	int länge=GetWindowTextLength(hwnd);
    	SendMessage(textbox, EM_SETSEL, länge, länge);
    
    	char buf[1000];
    	strcpy(buf, text.c_str());
    
    	WCHAR buf2[1000];
    
    	_USE(cout.getloc(), ctype<wchar_t>).widen(buf, buf+strlen(text.c_str()), buf2);//konvertieren...
    
    	buf2[text.length()]=TEXT('\0');//null-terminieren...
    
    	SendMessage(textbox, EM_REPLACESEL, true, (LPARAM) buf2);//in chatbox schreiben...
    
    	//NEU:
    	CHARFORMAT cf;
    	cf.cbSize=sizeof(CHARFORMAT);
    	cf.dwMask      = CFM_COLOR | CFM_UNDERLINE | CFM_BOLD; 
    	cf.dwEffects =2;
    	cf.dwEffects &= ~(1<<1); // löscht das Bit
    	cf.dwEffects|= ((1<<2)|(1<<3));// bei dw sind nun die Bits 2 und 3 gesetzt-> dw hat den Wert 12.
    	cf.crTextColor = farbe; 
    
    	int l=GetWindowTextLength(hwnd);
    	SendMessage(textbox, EM_SETSEL, l, länge);
    
    	SendMessage(hwnd, EM_SETCHARFORMAT, (WPARAM)(UINT)SCF_SELECTION, (LPARAM)&cf); 
    }
    

    bei beiden Versionen sieht man keinen Unterschied:

    das Wort chatbox war der Text mit dem die chatbox initialisiert wurde, vermutlich nicht bold.
    hallo ist das mit AddText() reingeschriebene Wort.

    Version 1: http://img23.imageshack.us/img23/299/version1q.jpg
    Version 2: http://img204.imageshack.us/img204/4088/version2h.jpg

    mit und ohne boult sehen beider versionen gleich aus, deshalb reicht 1 screen pro version.

    ich sehe noch immer keinen Unterschied... könte das daran liegen dass immer boult print verwendet wird?
    **
    bleiben noch ein paar Fragen:
    1.liegt das mit dem Bould am RichEdit oder dem Code?
    2.Wieso kriegt mein RichEdit (v1.0) eigentlich kein VSCROLL hin?? selbst ein normales Edit schafft das doch! im Windowstyle habe ich auch WS_HSCROLL|WS_VSROLL|WS_AUTOHSCROLL|WS_AUTOVSCROLL angegeben...
    3. könnte man auch die Schriftgröße noch ändern?
    4.trotz dem Windowstyle WS_THICKFRAME sieht man keine dicke Abgrenzung zum restliche Fenster, erst nachdem man die Größe des RichEditfelds geändert hat. Wie kriegt man es hin dass man die sofort sieht?
    **
    edit: auch zu Frage 4 mal screens:

    vor Größenänderung: http://img88.imageshack.us/img88/1285/vorherm.jpg
    nach Größenänderung: http://img148.imageshack.us/img148/963/nachher.jpg

    wie schaffe ich es dass es gleich wie am 2. screen (nachher) aussieht?

    lg,
    andi01.



  • Es war nur ein Beispiel auf deine Frage nach den Bitmanipulationen.
    Was ein Wert von 12 bei cfEffects bewirkt, dass weiß ich nicht.
    Die doku schreibt

    CFM_COLOR
    The crTextColor member and the CFE_AUTOCOLOR value of the dwEffects member are valid.

    Zu dwEffects:

    CFE_AUTOCOLOR
    The text color is the return value of GetSysColor(COLOR_WINDOWTEXT).

    Hmm..

    CHARFORMAT cf;
    memset(&cf,0,sizeof(CHARFORMAT);
    cf.cbSize=sizeof(CHARFORMAT);
    cf.dwMask      = CFM_COLOR | CFM_UNDERLINE | CFM_BOLD; // probeweise mal CFM_COLOR rausnehmen
    cf.dwEffects = (CFE_UNDERLINE | CFE_BOLD);
    

    Am Besten, du spielst einmal ein wenig an dwMask und dwEffects herum.

    Zu Bitmanipulationen findest du hier eine kurze Erläuterung.



  • thx für den Link mit den Bitoperationen, hat wirklich geholfen obigen code zu verstehen 👍

    ok das mit dem bould hat sich wohl erledigt: wenn man den Ausschnitt ganz klein setzt und ungefähr um Faktor 20 im Bildbearbeitungsprogramm vergrößert erkennt man doch tatsächlich mit Spezialmarkierung dass der grüne Text 1 Pixel breiter ist 👍 damit wäre das "Problem" gelöst, das soll fett sein 😉

    edit: hier ein screen vom 20-fachen zoom xD: http://img176.imageshack.us/img176/6926/ultrazoomq.jpg

    das eine Pixel bringts jetzt 😃

    edit: bleibt noch ein problem: wenn ich ES_MULTILINE als WindowSTYLE nehme geht hscreoll und kein vscroll, wenn ihch es nicht nehme geht vscroll und kein hscroll -.- kann man es irgendwie schaffen dass beides geht?

    lg,
    andi01.



  • edit: ok, Problem gelöst: wenn man die RichTextBox (v1.0) mit Buchstaben vollschreibet gehen alle scrolls perfekt. wenn man stattdessen nur leerzeichen verwendet verhält sich die editbox reichlich komisch: es erscheinen keine scrollbalken, man kann einfach über die grenze der textbox hinausschreiben und autoscroll geht schon gleich gar nicht... sobald ich einen buchstaben einfüge normalisiert sich alles.

    auch wenn ich keine Ahnung habe warum das so ist, aber egal... ich will die editbox sowieso nicht nur mit leerzeichen füllen 🙂

    danke an alle,
    andi01.


Anmelden zum Antworten