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).
source to share
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)
source to share
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;
}
source to share