Win32 GUI мерцает при изменении размера - PullRequest
5 голосов
/ 10 января 2010

У меня есть программа Win32 GUI с элементом управления вкладками, каждая вкладка имеет элемент управления представлением списка. При изменении размера окна происходит сильное мерцание. Я пробовал следующие вещи:

  • Обработка WM_ERASEBKGND в главном wndproc и возврат TRUE. Без эффекта.
  • Фильтрация всех сообщений WM_ERASEBKGND в цикле событий. Нет эффекта.
  • Установка стиля WM_CLIPCHILDREN в главном окне. Теперь при изменении размера окна элемент управления представления списка просто стирается на белом фоне и не перерисовывается.
  • Использование DefWindowPos вместо MoveWindow. Нет эффекта.
  • Передача FALSE для bRepaint в MoveWindow. Тот же эффект, что и при настройке WS_CLIPCHILDREN (см. Выше).

Вот код RegisterClassEx:

memset(&wcex, 0, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = PhMainWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = PhInstanceHandle;
wcex.hIcon = LoadIcon(PhInstanceHandle, MAKEINTRESOURCE(IDI_PROCESSHACKER));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
//wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MAINWND);
wcex.lpszClassName = PhWindowClassName;
wcex.hIconSm = (HICON)LoadImage(PhInstanceHandle, MAKEINTRESOURCE(IDI_PROCESSHACKER), IMAGE_ICON, 16, 16, 0);

Обработчик WM_SIZE:

RECT rect;

// Resize the tab control.

GetClientRect(PhMainWndHandle, &rect);
MoveWindow(TabControlHandle, rect.left, rect.top,
    rect.right - rect.left, rect.bottom - rect.top, TRUE);

// Resize the list view.

TabCtrl_AdjustRect(TabControlHandle, FALSE, &rect);

MoveWindow(ListViewHandle, rect.left, rect.top,
    rect.right - rect.left, rect.bottom - rect.top, TRUE);

Стили следующие:

  • Главное окно: WS_OVERLAPPEDWINDOW
  • Управление вкладкой: WS_CHILDWS_VISIBLE)
  • Управление представлением списка: WS_CHILD | WS_BORDER | LVS_REPORTWS_VISIBLE)

Ответы [ 4 ]

4 голосов
/ 15 января 2010

Оказалось, что была проблема с Z-упорядочением - вызов BringWindowToTop в представлении списка решил проблему.

2 голосов
/ 10 января 2010

Windows поддерживает пакетную операцию изменения размера, которая предназначена для предотвращения мерцания, вызванного изменением размера множества дочерних окон. См. BeginDeferWindowPos для получения дополнительной информации об этом.

Если это не работает, попробуйте сообщение WM_SETREDRAW . Похоже, можно остановить рисование родительского окна - что запретит все дочерние элементы управления, затем, когда макет закончится, снова включите рисование и вызовите RedrawWindow, чтобы перекрасить все окно за один проход. Я скорее думал, что это то, что позиционирование Отложенного окна будет использовать внутри.

1 голос
/ 10 января 2010

Я могу констатировать очевидное, но я подумал, что двойная буферизация - это решение мерцаний Win32. Я Java-разработчик, и я уже давно пишу win32, поэтому, пожалуйста, дайте мне знать, если я говорю чепуху

Вот как: http://www.gamedev.net/community/forums/topic.asp?topic_id=411559

Вот код sampe: http://www.codeproject.com/KB/cpp/DoubleBuffering.aspx

Вот эквивалентный вопрос .NET (?): Как предотвратить мигание текстового поля Windows Forms при изменении размера?

0 голосов
/ 10 января 2010

Когда ListView пристыкован, как в Windows Explorer (и у вас достаточно элементов), изменение размера главной формы приведет к мерцанию всех элементов.http://www.codeproject.com/KB/list/listviewxp.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...