调整TAB大小控制闪烁问题

Resizing TAB control flickering issue

本文关键字:闪烁 问题 控制 TAB 调整      更新时间:2023-10-16

由于我使用WX_EX_COMPOSITED后出现问题,我被迫将其关闭,因为它与设置了报告类型的listview不兼容。

禁用桌面合成导致选项卡控制闪烁

现在,每当我调整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控件有很多闪烁。

通过向默认窗口过程返回true,我已经关闭了WM_ERASEBKGND消息。

.elseif uMsg == WM_ERASEBKGND
MOV EAX,1
RET

以及使用我从Microsoft读到的这篇文章来处理WM_PRINT消息。

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函数似乎工作得很好,因为如果我省略了对它的调用,则在调整大小以扩展主对话框的宽度时会出现绘图问题——新区域只是黑色的。但如果我调用paint,那么调整大小后的新区域就会被正确绘制。但是有大量的闪烁。

我有3个对话框,一个是通过DialogBoxParamneneneba API 调用的主对话框

其他2个只是无模式对话框(没有标题,其样式设置为DS_SYSMODAL)这些对话框将通过CreateDialogParamAPI调用附加到TAB控件,每个对话框都有自己唯一的DlgProc

现在我该怎么做才能避免控件大小调整闪烁?我应该对要调整大小的控件进行子类处理吗?并分别为每个控件禁用WM_ERASEBKGND

禁用WM_ERASEBKGND消息是否只需要在主对话框中执行,或者也需要在所有无模式对话框中执行?

有人能帮上忙吗?

问题是通过在Listview上使用SetParent解决的,父集是主对话框而不是子对话框,当在选项卡之间切换以单击列表视图选项卡之外的其他选项卡时,我基本上再次使用SetParent将列表视图的父级返回到子对话框,因此代码仍然使用1ShowWindow隐藏它。现在Listview总是显示在顶部。即使WM_ERASEBKGND未被禁用,也不会有任何闪烁。现在,我可以在listview、Tab控件和Main对话框上设置WS_EX_COMPOSITED标志,而不会出现报表类型中listview的不可见框架的问题。我认为主要的问题是因为双缓冲使用自下而上的绘制方法。