MFC,界面闪烁问题

wsxxdzlj 2018-09-09 12:00:01
我使用MFC创建对话框程序,在对话框属性中设置“复合”项为True,即使用双缓冲从下到上着色。
程序采用自定义的bmp图片作为背景,通过修改OnPaint()函数实现。通过修改OnCtlColor()函数使静态文本框背景为透明,静态文本框刷新速度为100ms刷新一次。

在程序最小化并最大化后,所有的显示控件均开始按其刷新频率闪烁,只要程序不最小化就不会闪烁。请问大神是什么原因导致的?该如何修改?

void CRTSDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (IsIconic())
{
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDC dcMem;
BITMAP bm;
CRect rect;

m_Background.GetBitmap(&bm);
GetClientRect(&rect);
dcMem.CreateCompatibleDC(&dc);
CBitmap *oldbitmap = dcMem.SelectObject(&m_Background);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(oldbitmap);
CDialogEx::OnPaint();
}
}


HBRUSH CRTSDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (CTLCOLOR_STATIC == nCtlColor)
{
switch (pWnd->GetDlgCtrlID())
{
default:
pDC->SetTextColor(RGB(0, 0, 0));
pDC->SetBkMode(TRANSPARENT);
hbr = (HBRUSH)GetStockObject(NULL_BRUSH);
return hbr;
}
}
else if (nCtlColor == CTLCOLOR_DLG)
return m_brush;
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return hbr;
}


最小化按钮使用的代码(换过多种方法,均无法解决闪烁问题):
WINDOWPLACEMENT lwndpl;
WINDOWPLACEMENT * lpwndpl;
lpwndpl = &lwndpl;
GetWindowPlacement(lpwndpl);
lpwndpl->showCmd = SW_SHOWMINIMIZED;
SetWindowPlacement(lpwndpl);
...全文
479 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
shen_wei 2018-09-20
  • 打赏
  • 举报
回复
推荐对话框背景使用 CBKDialogST 类。。
simoreg 2018-09-13
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
1、OnEraseBkgnd直接返回TRUE
2、窗口风格要包含WS_CLIPCHILD及WS_CLIPSIBLIINGS

绿色盒子 2018-09-13
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
1、OnEraseBkgnd直接返回TRUE
2、窗口风格要包含WS_CLIPCHILD及WS_CLIPSIBLIINGS

第二点很重要,让子对话框自己负责自己的绘制,父对话框不管
worldy 2018-09-12
  • 打赏
  • 举报
回复
1、OnEraseBkgnd直接返回TRUE
2、窗口风格要包含WS_CLIPCHILD及WS_CLIPSIBLIINGS
schlafenhamster 2018-09-12
  • 打赏
  • 举报
回复
"最小化按钮使用的代码"
不要响应最小化按钮, 使用 默认 代码 试试 。
wsxxdzlj 2018-09-12
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
BOOL CxxxxDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default

return TRUE;// CDialog::OnEraseBkgnd(pDC);
}


OnEraseBkgnd返回TRUE和FALSE,以及网上能搜到的一些方法都试过了,没有什么用。
主要问题是在整个程序不最小化的时候,一切都是正常的。只要最小化一次,再刷新某些控件的时候就会发生闪烁现象。不知道在最小化并恢复的过程中它经历了什么。
zgl7903 2018-09-09
  • 打赏
  • 举报
回复
OnPaint中 屏蔽掉 对父类函数的调用
//CDialogEx::OnPaint();
schlafenhamster 2018-09-09
  • 打赏
  • 举报
回复
BOOL CxxxxDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default

return TRUE;// CDialog::OnEraseBkgnd(pDC);
}

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧