调整TAB控制闪烁问题的大小

时间:2017-10-17 23:41:54

标签: c++ assembly drawing masm flicker

由于使用 WX_EX_COMPOSITED 后出现问题,因此我不得不将其关闭,因为它与列表视图的报告类型设置不兼容。

Disabling desktop composition causes flickering on Tab Control

现在每当我调整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个对话框,一个是通过 DialogBoxParam API

调用的主对话框

另外2个只是无模式对话框(没有标题,并且它的样式设置为 DS_SYSMODAL )这些对话框将通过 CreateDialogParam附加到TAB控件 API调用每个人都拥有自己唯一的 DlgProc

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

是否只能在主对话框中或所有无模式对话框中禁用 WM_ERASEBKGND 消息?

任何人都可以帮忙解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

通过在Listview上使用 SetParent 修复问题,并且父设置是主对话框而不是子对话框,当在标签之间切换以单击除列表视图选项卡之外的其他选项卡时我基本上使用 SetParent 再次将listview的父级返回到子对话框,以便代码仍然使用 ShowWindow 隐藏它。现在,Listview始终显示在最顶层。即使未禁用 WM_ERASEBKGND ,也不会闪烁。现在我可以将 WS_EX_COMPOSITED 标志放在listview,Tab控件和Main对话框上,而不会出现报表类型中listview的不可见帧的问题。我认为主要问题是因为双缓冲使用从底部到顶部的绘图方法。