Проблема мерцания элемента управления TAB при изменении размера

Из-за проблемы, возникшей после того, как я использовал WX_EX_COMPOSITED, я был вынужден отключить его, так как он не был совместим с просмотром списка с установленным типом отчета.

Отключение композиции рабочего стола приводит к мерцанию в элементе управления вкладками

Теперь всякий раз, когда я изменяю размер элемента управления TAB вместе с изменением размера основного диалогового окна в ответ на любое из сообщений Сообщения WM_SIZE,WM_SIZING,WM_WINDOWPOSCHANGED

invoke GetClientRect,hWnd,addr CLRECT
LEA EAX, CLRECT
invoke MoveWindow,MainTabHandle,NULL,NULL,[EAX].RECT.right,[EAX].RECT.bottom,TRUE

Элемент управления TAB часто мерцает.

Я уже отключил сообщение WM_ERASEBKGND, вернув true оконной процедуре по умолчанию.

.elseif uMsg == WM_ERASEBKGND
            MOV EAX,1
            RET

и самостоятельно обрабатывать сообщение WM_PRINT, используя эту статью, которую я прочитал в Microsoft.

https://msdn.microsoft.com/en-us/library/ms969905.aspx

Обработчик сообщений WM_PRINT

invoke BeginPaint,hWnd,addr PS
invoke Paint,hWnd,addr PS
invoke EndPaint,hWnd,addr PS ;PS is just a LOCAL PAINTSTRUCT structure used for painting

Процедура рисования после того, как я перенес ее с C++ на MASM

Paint Proc hWnd:DWORD,  pPAINTSTRUCT:PPAINTSTRUCT
LOCAL rc:RECT ;
LOCAL hdcMem:HDC ;
LOCAL hBITMAP:HANDLE
LOCAL hbmMem:HANDLE
LOCAL hbmOld:HANDLE

LOCAL hbrBkGnd:HBRUSH ;
LOCAL hfntOld:HFONT ;


invoke GetClientRect,hWnd,addr rc
MOV EAX,pPAINTSTRUCT
invoke CreateCompatibleDC,[EAX].PAINTSTRUCT.hdc
MOV hdcMem ,EAX
MOV EAX,pPAINTSTRUCT

invoke CreateCompatibleBitmap,[EAX].PAINTSTRUCT.hdc,rc.right,rc.bottom
MOV hbmMem,EAX
invoke SelectObject,hdcMem,hbmMem
MOV hbmOld,EAX
invoke GetSysColor,COLOR_WINDOW
invoke CreateSolidBrush,EAX
MOV hbrBkGnd,EAX
invoke FillRect,hdcMem,addr rc,hbrBkGnd
invoke DeleteObject,hbrBkGnd

 .if hfnt
    invoke SelectObject,hdcMem,hfnt
    MOV hfntOld,EAX
 .endif
    


invoke SetBkMode,hdcMem,TRANSPARENT
invoke GetSysColor,COLOR_WINDOWTEXT
invoke SetTextColor,hdcMem,EAX


invoke DrawText,hdcMem,addr szCaption,-1,addr rc,DT_CENTER

 
    invoke SelectObject,hdcMem,hfntOld

         
MOV EAX,pPAINTSTRUCT
LEA EBX,rc
MOV EDX,[EBX].RECT.right
SUB EDX,[EBX].RECT.left

MOV ECX,[EBX].RECT.bottom
SUB ECX,[EBX].RECT.top

invoke BitBlt,[EAX].PAINTSTRUCT.hdc,rc.left,rc.top,EDX,ECX,hdcMem,0, 0,SRCCOPY
invoke SelectObject,hdcMem, hbmOld

invoke DeleteObject,hbmMem;
invoke DeleteDC,hdcMem;

Функция Paint, похоже, работает нормально, поскольку, если я пропущу ее вызов, возникнет проблема с рисованием при изменении размера для увеличения ширины основного диалогового окна, новая область будет просто черной. Но если я вызову краску, то новая область после изменения размера будет отрисована правильно. Но есть огромное количество мерцания.

У меня есть 3 диалоговых окна, одно из которых является основным диалоговым окном, вызываемым через DialogBoxParam API.

А остальные 2 являются просто немодальными диалоговыми окнами (без заголовка, и для его стиля установлено значение DS_SYSMODAL). Эти диалоговые окна будут прикреплены к элементу управления TAB с помощью API-вызова CreateDialogParam каждый у одного есть собственный уникальный DlgProc.

Теперь, что я должен сделать, чтобы избежать мерцания при изменении размера элемента управления? Должен ли я делать подклассы для элемента управления, размер которого я хочу изменить? и отключить WM_ERASEBKGND для каждого элемента управления в отдельности?

Нужно ли отключать сообщение WM_ERASEBKGND только в основном диалоговом окне или также для всех немодальных диалоговых окон?

Кто-нибудь может помочь в этом вопросе?


person a man in love    schedule 17.10.2017    source источник
comment
Я нашел способ обойти это, используя флаг WS_EX_COMPOSITED на вкладке, а не в самом диалоговом окне, и используя WS_CLIPCHILDREN в главном диалоговом окне. Это устранило проблему мерцания при изменении размера вкладки. Однако теперь дочерние элементы управления не отображаются должным образом и исчезают после изменения размера вкладки. В сообщении WM_SIZING я использую API MoveWindow для элемента управления вкладками с bRepaint, для которого установлено значение true, как мне заставить дочерние элементы управления правильно рисовать, не теряя их после изменения размера?   -  person a man in love    schedule 18.10.2017


Ответы (1)


Проблема устранена с помощью SetParent в Listview, а родительский набор является основным диалоговым окном, а не вспомогательным диалоговым окном, и при переключении между вкладками, чтобы щелкнуть другую вкладку, а не вкладку списка, я в основном использовал SetParent еще раз, чтобы вернуть родителя списка во вложенный диалог, чтобы код по-прежнему скрывал его с помощью ShowWindow. Теперь Listview всегда отображается сверху. Никакого мерцания, хотя WM_ERASEBKGND не отключен. Теперь я могу установить флаг WS_EX_COMPOSITED в списке, элементе управления вкладками и главном диалоговом окне без проблем с невидимыми кадрами списка в типе отчета. Я думаю, что основная проблема заключается в том, что двойная буферизация с использованием метода рисования снизу вверх.

person a man in love    schedule 21.10.2017
comment
Это все еще отдельный вопрос от вашего предыдущего stackoverflow.com/questions/46760792/, или это должно быть закрыто как дубликат? (Я не использую графический интерфейс Windows, поэтому я не пытался по-настоящему прочитать или понять ни вопрос, ни ответ, я просто вижу, что они очень похожи.) Спасибо, что поделились решениями ваших проблем на SO; Я просто стараюсь поддерживать чистоту и порядок :) - person Peter Cordes; 21.10.2017
comment
Привет, друг. Вы можете закрыть любой вопрос. Похоже да пардон. - person a man in love; 21.10.2017
comment
Не беспокойтесь об этом, иногда вы думаете, что это отдельная проблема, а оказывается, что это не так. - person Peter Cordes; 21.10.2017