2 Stimmen

Wie kann ich das Rendern von Fenstern anhalten und später wieder fortsetzen?

Ich möchte verhindern, dass mein Fenster aktualisiert wird, bis ich die Daten vom Server erhalten und gerendert habe. Kann ich auf das WM_PAINT-Ereignis einhaken oder besser noch eine Win32API-Methode aufrufen, um zu verhindern, dass das Fenster aktualisiert wird, und es später auftauen?

Mehr Informationen: Im Zusammenhang mit einem in C# geschriebenen MMC-Snapin leidet unsere Anwendung unter störendem Flackern und doppeltem Sortierverhalten: Wir verwenden MMC's listViews, aber da wir das Sortierereignis abonnieren. MMC macht seine eigene Magie und sortiert die angezeigte Seite (und wir können das nicht außer Kraft setzen), und wenn wir eine Antwort von unserem Server erhalten, ändern wir die listView erneut. Jede Zeilenänderung wird sequentiell durchgeführt, es gibt kein beginUpdate usw. (AFAIK).

1voto

Daniel Rikowski Punkte 68643

Normalerweise wird der Haken in WM_PAINT ist der richtige Weg, aber stellen Sie sicher, dass Sie auch alle WM_ERASEBKGND Benachrichtigungen, sonst flackert es immer noch, weil Windows den Windows-Bereich für Sie löscht. (Geben Sie einen Wert ungleich Null zurück, um zu verhindern, dass Windows dies tut)

Eine weitere Möglichkeit ist die Verwendung der LockWindowUpdate Funktion, aber sie hat einige Nachteile:

  • Nur ein Fenster kann verriegelt werden
  • Beim Entsperren wird der gesamte Desktop und alle Unterfenster (d.h. alles) neu gezeichnet, was zu einem kurzen Aufblitzen des gesamten Desktops führt. (Es ist schlimmer auf XP als auf Vista)

1voto

ChrisW Punkte 53239

Einige Kontrollen haben BeginUpdate y EndUpdate APIs für diesen Zweck.

Wenn Sie etwas tun (z.B. Hook und Ignorieren von Paint-Ereignissen), um das Malen zu deaktivieren, dann ist eine Möglichkeit, später ein erneutes Malen zu erzwingen, den Aufruf der Invalidate Methode.

0voto

bgee Punkte 949

OK, nach allem Suchen und Prüfen habe ich herausgefunden, dass LockUpdateWindow eine schlechte Idee ist - siehe zum Beispiel Artikel von Raimond Chen OldNewThing . Aber selbst die Implementierung der Idee von SetRedrawWindow war nicht so einfach - denn was ich hatte, wurde nur vom IConsole2* pConsole->GetMainWindow() HWND-Handler des Hauptfensters empfangen. Indem ich es auf SetRedraw = FALSE setzte, verschwand es auf sehr seltsame Weise. Um die Prozedur jedoch nur für die TreeView und nicht für die gesamte Anwendung (unser linkes Panel) auszuführen, habe ich

EnumChildWindows(hWnd, SetChildRedraw, FALSE); //stopping redraw
//... here you do your operations
EnumChildWindows(hWnd, SetChildRedraw, TRUE); //restarting redraw

wobei der SetChildRedraw-Callback auf die folgende Weise definiert wurde:

#define DECLARE_STRING(str) TCHAR str[MAX_PATH]; ZeroMemory(str, sizeof(str));
BOOL CALLBACK SetChildRedraw(HWND hwndChild, LPARAM lParam) 
{ 
    RECT rcChildRect; ZeroMemory(&rcChildRect, sizeof(rcChildRect));
    DECLARE_STRING(sText)
    GetClassName(hwndChild, sText, MAX_PATH);
    if (wcsstr(sText, L"SysTreeView32") != NULL)
    {
        SetWindowRedraw(hwndChild, lParam);
        if (lParam == TRUE)
        {
            GetWindowRect(hwndChild, &rcChildRect);
            InvalidateRect(hwndChild, &rcChildRect, TRUE);
        }
    }
    return TRUE;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X