How can I stop rendering the window and resume later?

I would like my window to not refresh until after I get the data from the server and do it. Can I hook into the WM_PAINT event, or better yet, call some Win32API method to prevent the window from updating and unfreezing later?

More info: In the context of Snapin MMC written in C #, our application suffers from annoying flickering and double sorting: We are using listViews MMC, but since we are subscribing to the sort event. MMC owns the magic and sorts the rendered page (and we cannot override it) and when we get a response from our server, we change the listView again. each line change is done sequentially, no beginUpdate, etc. (AFAIK).

+2


source to share


3 answers


Usually connecting to WM_PAINT

is the way to go, but make sure you ignore everything as well WM_ERASEBKGND

, otherwise you will still flicker because Windows erases the Windows area for you. (Return nonzero to prevent Windows from doing this)

Another possibility is to use the function LockWindowUpdate

, but it has some disadvantages:



  • Only one window can be locked
  • Once unlocked, the entire desktop and all sub-windows (i.e. all) are repainted, resulting in a brief flash of the entire desktop. (This is worse on XP than Vista)
+1


source


Some controls have BeginUpdate

and EndUpdate

API for this purpose.



If you do something (for example, intercept and ignore paint events), disable painting, then the way to force redraw later is to call the method Invalidate

.

+1


source


OK, after all searching and checking, I found that LockUpdateWindow is a bad idea - see Raimond Chen OldNewThing articles for example . But even implementing the idea of โ€‹โ€‹SetRedrawWindow was not so easy - because what I got was only received from the IConsole2 * pConsole-> GetMainWindow () HWND main window handler. By setting it to SetRedraw = FALSE, it disappeared in a very strange way. Although in order to make the procedure only work for the TreeView and not for the entire application (our left pane), I ran

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

      

where the SetChildRedraw callback was defined like this:

#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;
}

      

0


source







All Articles