Ich habe eine relativ komplexe UI, die auch dynamisch Controls erzeugt. In diese Controls werden auch zum Teil Massen an Daten hineingeschoben. Damit alle Controls zeitgleich erst die Daten präsentieren verwende ich eine einfache Methode, die aus alten Windows Tagen stammt: CWnd::SetRedraw/WM_SETREDRAW. Man verwendet diese Nachricht zum Beispiel um das Flackern von Listboxen und Comboboxen zu verhindern, wenn man viele Daten einfügt.
Diese Nachricht wird von allen Fenstern unterstützt oder sollte unterstützt werden 😉
Meine Software macht nun folgendes:
- Zuerst hat meine Ladeprozedur für die Daten, zuerst alle Controls erzeugt, oder überflüssige vernichtet und positioniert, oder evtl. nur ausgeblendet (ShowWindow(SW_HIDE). D.h. nach dem ersten Laden der Daten ändert sich am Layout evtl. nichts mehr.
- Anschließend wurde an alle Controls CWnd::SetRedraw/WM_SETREDRAW mit FALSE gesendet.
- Dann die Daten geladen.
- Nach dem Laden wird einfach wieder CWnd::SetRedraw/WM_SETREDRAW mit TRUE gesendet und ein Invalidate durchgeführt.
Das funktioniert für alle Controls, mit einer Ausnahme: Das RTF Control. Wenn man WM_SETREDRAW TRUE an ein RTF Control sendet, das nicht sichtbar ist, dann wird dieses sichtbar. Der Stil WS_VISIBLE wird also verändert. 😮
Um das Problem zu isolieren habe ich hier ein kleines Testprogramm geschrieben. Der kritische Code sieht so aus. Das gesamte Projekt kann man hier auch herunterladen: Demoprojekt.
void CTestRTFSetRedrawDlg::OnBnClickedBtDoit()
{
bool bWasVisible = (m_wndEdRTF.GetStyle() & WS_VISIBLE)!=0;
m_wndEdRTF.SetRedraw(FALSE);
m_wndEdRTF.SetWindowText(_T("Line 1\r\nLine 2\r\nLine 3\r\nLine 4"));
m_wndEdRTF.SetSel(0,0);
m_wndEdRTF.SetRedraw(TRUE);
m_wndEdRTF.Invalidate();
bool bIsVisible = (m_wndEdRTF.GetStyle() & WS_VISIBLE)!=0;
// Check if the visible state changed
if (bIsVisible!=bWasVisible)
AfxMessageBox(_T("The visible state of the RTF control changed!"));
}
Nachtrag 16.01.2010 (Danke Sven für Deinen produktiven Kommentar):
Auch andere Controls wie Button-, Static– und Edit-Controls verändern den Visible Status wenn WM_SETREDRAW angewendet wird. Einzig Listbox– und Combobox-Controls behalten den Visiblestatus korrekt bei ❗