老问题:MFC 大量MoveWindow移动控件导致界面闪烁的问题

marslycan 2019-02-26 09:58:28
封装了一个窗口类class CDynamicFilterSettingFrame : public CWnd{};
主要功能如下图,每次点击+-按钮对应的增加删除一组按钮,考虑到插入的操作,因此在刷新时有大量的MoveWidow来改变控件位置

实际操作时,发现会有界面闪烁现象产生,以前做绘图我知道通过双缓冲来解决绘图闪烁,但是这个动态创建控件....Emmm...抓狂完全没方向...目前我是通过设置SetRedraw()(用这个方式减缓了闪烁现象,但是还是有):

BOOL CDynamicFilterSettingFrame::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
//return CWnd::OnEraseBkgnd(pDC);
}
void CDynamicFilterSettingFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
dc.SetBkMode(TRANSPARENT); //设置背景透明
dc.FillSolidRect(0, 0, m_nViewWidth, m_nViewHeight, RGB(240, 240, 240));
}
void CDynamicFilterSettingFrame::CreateDynamicCtrl()
{
SetRedraw(FALSE);

//LockWindowUpdate();
CreateAddButton();
CreateReduceButton();

CreateLeftBraceRadiobutton();
CreateRightBraceRadiobutton();

CreateLeftBraceStatic(); // 左括号静态文本
CreateRightBraceStatic(); // 右括号静态文本
CreateColNameCombox(); // 字段选择Combox
CreateOperatorCombox(); // 运算符选择Combox
CreateValueAEdit(); // 值A 编辑框
CreateValueBEdit(); // 值A 编辑框
CreateLogicalConnectorCombox(); // 逻辑连接符选择Combox


UpdateVScroll();
SetRedraw(TRUE);
//
// CRect rect;
// GetClientRect(&rect);
this->RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}

完全混乱的逻辑。。。求大神指点方向
...全文
1053 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
marslycan 2019-02-26
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
大量移动前 对话框 先 LockWindowUpdate, 以后 Unlock
我用的是SetRedraw()这对函数,参照帖子https://www.topomel.com/archives/972.html
zgl7903 2019-02-26
  • 打赏
  • 举报
回复
Create 之前将坐标算好, 这样就不需要移动了,
或者先不要 WS_VISIBLE, 移动完了再ShowWindow

schlafenhamster 2019-02-26
  • 打赏
  • 举报
回复 1
大量移动前 对话框 先 LockWindowUpdate, 以后 Unlock
marslycan 2019-02-26
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
MoveWindow 最后一个参数 BOOL bRepaint 默认是 TRUE ,就是移动后重绘,
可以把这个参数设置为FALSE, 全部移动完成后调用一次 Invalidate
非常感谢指导,以前都没注意过这个参数;但是加上Flase还是有点闪烁,是否是因为我的Create控件导致的呢?
void CDynamicFilterSettingFrame::CreateRightBraceStatic()
{
CRect BaseRect;
m_BaseStaticPtr[3]->GetWindowRect(BaseRect);
ScreenToClient(&BaseRect);

int nLeft = BaseRect.left + VALUE_EDIT_WIDTH/* + BASE_DISTANCE_X*/;
int nTop = BaseRect.top + (BASE_HEIGHT + BASE_DISTANCE_Y) * (m_nNewAddRowIdx + 1)/* - m_iCurrentScrollPos*/;
int nRight = nLeft + BRACE_STATIC_WIDTH;
int nBottom = nTop + BASE_HEIGHT;

DWORD bn_dwStyle = WS_CHILD | WS_VISIBLE | SS_RIGHT| SS_CENTERIMAGE;
CStatic *pstatic = new CStatic;
pstatic->Create(_T(""), bn_dwStyle, CRect(nLeft, nTop, nRight, nBottom), this, IDC_STATIC_DYNAMIC_RIGHT_BRACE_BEGIN + m_vecUsedBaseID[m_nNewAddRowIdx]);//Button的创建语句
pstatic->SetFont(&m_fontbase);
// 保存控件指针
m_RightBraceStaticPtr.insert(m_RightBraceStaticPtr.begin() + m_nNewAddRowIdx, pstatic);

// 更新控件坐标
if (m_nNewAddRowIdx < m_vecUsedBaseID.size() - 1)
{
int nOffSetY = BASE_HEIGHT + BASE_DISTANCE_Y;

for (int i = m_nNewAddRowIdx + 1; i < m_vecUsedBaseID.size(); i++)
{
// 先获取旧的位置,然后直接整体平移一层
m_RightBraceStaticPtr[i]->GetWindowRect(BaseRect);
ScreenToClient(&BaseRect);

m_RightBraceStaticPtr[i]->MoveWindow(BaseRect.left, BaseRect.top + nOffSetY, BaseRect.Width(), BASE_HEIGHT, FALSE);
}
}
}
zgl7903 2019-02-26
  • 打赏
  • 举报
回复
MoveWindow 最后一个参数 BOOL bRepaint 默认是 TRUE ,就是移动后重绘,
可以把这个参数设置为FALSE, 全部移动完成后调用一次 Invalidate

marslycan 2019-02-26
  • 打赏
  • 举报
回复
引用 7 楼 sichuanwww 的回复:
marslycan 2019-02-26
  • 打赏
  • 举报
回复
引用 4 楼 zgl7903 的回复:
Create 之前将坐标算好, 这样就不需要移动了,
或者先不要 WS_VISIBLE, 移动完了再ShowWindow
还是不行 我在研究一下是不是因为我的滚动条刷新的问题
一些VC编程的技巧 Visual C++编程技巧精选(缺57-67) 1. 如何获取应用程序的实例句柄? 2. 如何通过代码获得应用程序主窗口的指针? 3.如何在程序中获得其他程序的图标? 4.如何编程结束应用程序?如何编程控制windows的重新引导? 5.怎样加载其他的应用程序? 6. 确定应用程序的路径 7. 获得各种目录信息 8. 如何自定义消息 9. 如何改变窗口的图标? 10. 如何改变窗口的缺省风格? 11. 如何将窗口居中显示? 12. 如何让窗口和 MDI窗口一启动就最大化和最小化? 13. 如何使程序保持极小状态? 14. 如何限制窗口的大小? 15. 如何使窗口不可见? 16. 如何使窗口始终在最前方? 17、如何创建一个字回绕的CEditView 18、通用控件的显示窗口 19、移动窗口 20、重置窗口的大小 21、如何单击除了窗口标题栏以外的区域使窗口移动 22、如何改变视窗的背景颜色 23、如何改变窗口标题 24、如何防止主框窗口在其说明中显示活动的文档名 25、如何获取有关窗口正在处理的当前消息的信息 26、如何创建一个不规则形状的窗口 27、如何在代码中获取工具条和状态条的指针 28、如何使能和禁止工具条的工具提示 29、如何设置工具条标题 30、如何创建和使用无模式对话框 31、如何在对话框中显示一个位图 32、如何改变对话或窗体视窗的背景颜色 33、如何获取一个对话控件的指针 34、如何禁止和使能控件 35、如何改变控件的字体 36、如何在OLE控件中使用OLE_COLOR数据类型 37、在不使用通用文件打开对话的情况下如何显示一个文件列表 38、为什么旋转按钮控件看起来倒转 39 为什么旋转按钮控件不能自动地更新它下面的编辑控件 40、如何用位图显示下压按钮 41、如何一个创建三态下压按钮 42、如何动态创建控件 43、如何限制编辑框中的准许字符 44、如何改变控件的颜色 45、当向列表框中添加多个项时如何防止闪烁 46、如何向编辑控件中添加文本 47、如何访问预定义的GDI对象 48、如何获取GDI对象的属性信息   49、如何实现一个橡皮区矩形 50、如何更新翻转背景颜色的文本 51、如何创建一个具有特定点大小的字体 52、如何计算一个串的大小 53、如何显示旋转文本 54、如何正确显示包含标签字符的串 55、串太长时如何在其末尾显示一个省略号 56、如何快速地格式化一个CString对象 68. VC1.5下如何跳到第一事例? 69. 为什么VC++2.0中使用文件对话框会死机? 70. 在VC++1.5中如何new一个大数组? 71. 在VC1.5中,如何得到子窗口在主窗口中的相对坐标? 72. VC1.5 如何调用进程? 73. VC++1.5编Win3.1程序能否实现全局跳转? 74. 如何在DLL用自定义窗口? 75. 如何让TOOLTIP的字体变大? 76.怎样更换wallpaper. 77.写打印机Preview需要用什么函数? 78.用MFC写了一个控件,如何在另一个县城里发事件? 79.关于DIADOG背景图象 80.如何显示随光标移动的提示窗口 81.怎么用VC++5.0来编写图像打印程序,我的程序是基于对话框的 82.请问怎样象Winzip一样,给Win95自己的PopMenu中添加Item. 83.问如何在Tree空件上实现点右健选中Item并下拉出菜单,如同VC5中的Workspce窗口. 84.我想在CDialog类中的树控件中响应右键弹起这一消息 85.怎样在程序中启动缺省浏览器,并进入某一网址 86.建立一束特殊效果的黑光在 Direct3D 87.列表显示所有网上邻居 88.怎样在一个应用程序中加载另一个应用程序 89.如何获得当前时间

15,980

社区成员

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

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