Kleiner Exzess mit Multiline edit

Thomasio

Erfahrenes Mitglied
Es fing alles ganz harmlos an mit einem edit Feld, Multiline, readonly
(Einige haben vielleicht ein paar meiner Fragen dazu verfolgt, weiter unten in diesem Forum)

Ich fang gar nicht erst an Code zu posten, das Ganze hat inzwischen über 3000 Zeilen

Dann hatte ich die Idee ihm einen farbigen Hintergrund zu geben
Also case WM_CTLCOLORSTATIC:, SetBkMode, SetTextColor, return brush, ganz einfach

Das Ganze ging so lange gut, bis ich festgestellt habe, dass das Ganze unter Vista flackert
Auf der Suche nach der Ursache fand ich das Problem beim Style des Hauptfensters
Wo XP mit dem Style WS_EX_COMPOSITED automatisch double buffering fürs ganze Fenster macht, da hat Vista sowas wie eine eigebaute Automatik, die den Style überschreibt und fragmichnichtwas stattdessen verwendet
Angeblich soll das ein Flackern verhindern, nur bei mir flackert es trotzdem heftig

Nachdem ich dann ein paar Tage rumprobiert habe, mit erasebackground abfangen, clipchildren und regions setzen, verschiedene styles probiert, bin ich irgendwann bei zu der Überzeugung gekommen, wenn es gescheit werden soll, dann mach ichs von Grund auf selber

Also los, alles was nach Windows Automatik riecht abgeschaltet, abgefangen, subclassed und zu Fuss meine eigene Version eingebaut

wc.style = 0
CreateWindow, schon im Hauptfenster gar kein Ex mehr dazu, mach ich dann eh selber
WS_POPUP, ohne Kopfzeile, ohne Menü, von Rahmen über Icon bis Closebutton, alles selber gemacht
Statt Composited das Double buffering selber eingebaut
Clipchildren oder sonstwas brauchts nicht mehr, erasebackround abgefangen und alle WM_PAINT auf minimale update region beschränkt

Ein grösseres Problem hatte ich dann mit einer Listbox
Nach einigen erfolglosen Versuchen eine standard Windows Listbox so weit zu modifizieren dass sie mir passt, habe ich auch das aufgegeben und mir in einem stinknormalen Child Fenster eine komplette Listbox inkl selbstgemachtem Scrollbalken und eigener Sortierfunktion selber geschrieben

... und dann kam das edit Feld

Angefangen als standard "edit" readonly, einfach weiss, sämtliche Funktionen Windows überlassen
Das funktioniert, selbst unter Vista ohne flackern, weil mein eigenes double buffering von Vista nicht abgefangen werden kann
Nicht ganz so schön ist, dass es als readonly nur unter XP leicht grau gefärbt wird, unter Vista aber schneeweiss bleibt, aber das kann man noch verkraften

Aber dann gings los, erstes Problem:
Wenn ich im WM_CTLCOLORSTATIC farbigen Hintergrund setzen will und das Feld mehr Inhalt als Platz hat, also scrollen muss, macht er zwar den Hintergrund sauber neu, löscht aber den Text in den Zeilen nicht, so dass beim scrollen immer mehrere Buchstaben übereinander geschrieben erscheinen
Also subclassen, eigene WM_PAINT schreiben, schön ordentlich mit double buffer, schon geht das

Problem 2:
Die Scrollbar, die Windows dem Fenster gibt interessiert sich nicht für meine eigene WM_PAINT, sondern scrollt die Zeilen unsichtbar rein
Also auch die WM_VSCROLL selber machen, kein Thema, kenne ich ja schon von der Listbox

An dieser Stelle hatte ich es 99% perfekt, völlig ohne flackern, sauber scrollen, farbiger Hintergrund, transparenter Text
Nur eine winzige Kleinigkeit hat gefehlt

Problem 3:
Wenn man mit Maus oder Tastatur den Text im Feld markieren wollte hat er den markierten Text nicht mehr andersfarbig gemacht, man konnte zwar markieren, auch Rechtsklick - kopieren, aber man hat die Markierung nicht gesehen
Ich habe stundenlang probiert, wie ich GetSel in meine WM_PAINT einbauen könnte, aber GetSel gibt die Nummer des ersten und (nach-) letzten markierten Zeichens aus, ohne Koordinaten, die muss ich aus Scrollposition und Font Metric selber ausrechnen
Selbst das habe ich geschafft und mit Hilfe einer selbstgebauten Funktion konnte ich sogar Textfarbe und Hintergrund der Markierung selber gestalten

Ich dachte schon fast ich habs fertig, bis ich dann versucht habe den markierten Text mit Maus - Rechtsklick zu kopieren und in einen Editor einfügen, da kam

Problem 4:
Wenn die Maus in den Editor klickt, verliert mein edit Feld den Focus, und auch KILLFOCUS interessiert sich nicht für meine selber gemachte WM_PAINT sonder macht gnadenlos den markierten Text unsichtbar
Nach eingen Versuchen mit NOHIDESEL, SetFocus und Anderem hatte ich es dann soweit, dass er die Markierung stehen liess
Aber wenn ich zurück ins edit Feld bin um was Anderes zu markieren hat er die vorherige Markierung wieder unsichtbar gemacht
Also habe ich angefangen die Maus-Events in die Subclass einzubauen, auch das geht, aber man muss sie schon alle abfangen, bis hin zu MOUSEMOVE
Dumm ist nur, wenn man sie alle abfängt, macht meine selber gebaute Markierung zwar noch mit, aber Windows erfährt davon nichts mehr, ich muss also auch SetSel und weitere Sachen selber machen und dabei gerate ich an meine Grenzen
Ich habe dann noch versucht herauszufinden, welche weiteren Events alle von dem edit Feld verarbeitet werden, bis hin zu diversen Tastatur Eingaben, mit wechselndem Erfolg in verschiedenen Teilen, aber ich bringe es nicht 100% zustande
Entweder es flackert, oder markierter Text ändert sich in der Farbe nicht, oder irgendwas wird unter bestimmten Umständen unsichtbar

Kurz gesagt, ich habe es aufgegeben
Entweder ich lasse es bei einfach weiss (das ging ja, aber passt absolut nicht zum Rest von der Anwendung), oder ich muss auch dies ganz ohne Windows machen und mir aus einem normalen Fenster selber ein edit control bauen

ABER

Das ist zum Teil völliges Neuland für mich
Fenster mit double buffer, eigenem Paint, eigenem Scroll, sogar eigene Markierung, das schaffe ich noch
Aber wie kann ich dann meine Markierung aus Koordinaten in Text umrechnen, solange ich nicht weiss welcher Text da steht kann ich auch mit Font Metric nicht berechnen wieviele Buchstaben innerhalb der Markierung sind
Wie kann ich ins Markieren noch einen Scroll einbauen, wenn man mehr markieren will als auf einmal ins Fenster passt und woher nehme ich auf Rechtsklick ein Menü mit den passenden Funktionen für die Zwischenablage?

Auf den Verdacht hin, dass ich mich hier gerade hoffnungslos in eine fixe Idee verrannt habe, Zusatzfrage:
Wie sonst kann man unter Vista ein flackerfreies edit Feld mit farbigem Hintergrund erstellen?

Achja, falls es jemandem nicht klar ist, ich mache das alles in API plain, Code::Blocks mit MinGW und GCC++, kein MFC, kein .NET, kein Virtual Gedöns
 
Zurück