Как я могу остановить рендеринг окна и позже возобновить? - PullRequest
2 голосов
/ 11 октября 2009

Я бы хотел запретить обновление моего окна, пока я не закончу получать данные с сервера и отображать их. Могу ли я подключить событие WM_PAINT или, что еще лучше, вызвать какой-нибудь метод Win32API, чтобы предотвратить обновление окна и разморозить его позже?

Подробнее: В контексте оснастки MMC, написанной на C #, наше приложение страдает от раздражающего мерцания и двойной сортировки: Мы используем MMC listViews, но так как мы подписываемся на событие сортировки. MMC делает свое собственное волшебство и сортирует отображаемую страницу (и мы не можем переопределить это), и когда мы получаем ответ от нашего сервера, мы снова меняем listView. каждое изменение строки выполняется последовательно, нет никаких атрибутов beginUpdate и т. д. (AFAIK).

Ответы [ 3 ]

1 голос
/ 11 октября 2009

Некоторые элементы управления имеют API-интерфейсы BeginUpdate и EndUpdate для этой цели.

Если вы что-то делаете (например, перехватываете и игнорируете события рисования), отключаете рисование, то способ заставить перерисовку позже вызвать метод Invalidate.

1 голос
/ 11 октября 2009

Обычно нужно подключиться к WM_PAINT, но убедитесь, что вы также игнорируете все уведомления WM_ERASEBKGND, иначе вы все равно будете мерцать, потому что Windows стирает область Windows для вас. (Верните ненулевое значение, чтобы Windows не делала этого)

Еще одна возможность - использовать функцию LockWindowUpdate, но у нее есть некоторые недостатки:

  • Только одно окно может быть заблокировано
  • После разблокировки весь рабочий стол и все подокна (то есть все) перекрашиваются, что приводит к короткому миганию всего рабочего стола. (В XP это хуже, чем в Vista)
0 голосов
/ 15 декабря 2010

ОК, после всех поисков и проверок я обнаружил, что LockUpdateWindow - плохая идея - см., Например, статьи Раймонда Чена OldNewThing . Но даже реализовать идею SetRedrawWindow было не так просто - потому что то, что я получил, было получено только из обработчика HWND главного окна IConsole2 * pConsole-> GetMainWindow (). Установив его в SetRedraw = FALSE, он исчез очень странным образом. Хотя, чтобы процедура запускалась только для TreeView, а не для всего приложения (наша левая панель), я запустил

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

где обратный вызов SetChildRedraw был определен следующим образом:

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