我为MainForm添加了WS_CLIPCHILDREN风格,在主窗口大小变化时,子窗口不会闪烁,但是子窗口区域不会重绘,会有页面残留。我看别人做的都不会闪烁,为什么我的会呢?真是奇怪了,别人都没用WS_CLIPCHILDREN呢,求解啊!牛人求解啊OnSize方法:void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CRect clientRect;
GetClientRect(clientRect);
if(m_pageCtner.GetSafeHwnd() != NULL)
{
m_pageCtner.SetWindowPos(NULL,0,63,clientRect.Width(),clientRect.Height()-63,SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
}
if(m_bottomMenuBar != NULL)
{
m_bottomMenuBar->SetWindowPos(NULL,0,clientRect.Height()-63,clientRect.Width(),63,SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
}
if(m_topMenuBar != NULL)
{
m_topMenuBar->SetWindowPos(NULL,0,0,clientRect.Width(),63,SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
} CFrameWndEx::OnSize( nType, cx, cy);
}
PreCreate源代码:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWndEx::PreCreateWindow(cs) )
return FALSE;
// TODO: 在此处通过修改
//  CREATESTRUCT cs 来修改窗口类或样式
cs.style &= ~(LONG)FWS_ADDTOTITLE;
//去除边框
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
//cs.style |= WS_CLIPCHILDREN;
return TRUE;
}在OnCreate里创建控件的源代码:
//连接数据库
//实例程序没有连接数据库,暂时使用固定数据
UINT menuBtnId1 = HR_MENU_BUTTON_BEGIN;
UINT menuBtnId2 = HR_MENU_BUTTON_BEGIN + 1;
CString bitMapDir1 = _T(".\\Img\\sys_btnBk.bmp");
CString bitMapDir2 = _T(".\\Img\\sys_btnBk.bmp");
//页面集合1
vector<CHrBasePage*>    m_pagesVec1;
//页面集合2
vector<CHrBasePage*>    m_pagesVec2;

//增加上排菜单按钮
m_pageBtnMenu.AddMenuBtn(bitMapDir1,menuBtnId1,_T("WIP管理"));
m_pageBtnMenu.AddMenuBtn(bitMapDir2,menuBtnId2,_T("批次管理"));
m_pageBtnMenu.CreateButtonMenu(); if (!m_pageBtnMenu.m_pageMenu->Create(_T("菜单"),this,CRect(0,0,200,200),TRUE,3600,
 CBRS_TOP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,AFX_CBRS_REGULAR_TABS,AFX_CBRS_AUTOHIDE))
{
TRACE0("未能创建工具栏\n");
return;      // 未能创建
}
//增加下排菜单按钮
m_comOprMenu.CreateButtonMenu();
m_bottomMenuBar = m_comOprMenu.m_systemComMenu; //初始化中间的所有页面
m_pageCtner.AddPage(IDD_DIALOG1,_T("篮具查询"),RUNTIME_CLASS(CTest1));
m_pageCtner.AddPage(IDD_DIALOG2,_T("手动管理"),RUNTIME_CLASS(CTest2));
m_pageCtner.AddPage(IDD_DIALOG5,_T("测试页面"),RUNTIME_CLASS(CTest3));
m_pageCtner.AddPage(IDD_DIALOG3,_T("dummy更换"),RUNTIME_CLASS(CTest4));
m_pageCtner.AddPage(IDD_DIALOG4,_T("批次信息"),RUNTIME_CLASS(CTest5));
//为按钮分配页面ID
m_pageBtnMenu.AddPageForMenu(menuBtnId1,IDD_DIALOG1);
m_pageBtnMenu.AddPageForMenu(menuBtnId1,IDD_DIALOG2);
m_pageBtnMenu.AddPageForMenu(menuBtnId1,IDD_DIALOG3);
m_pageBtnMenu.AddPageForMenu(menuBtnId2,IDD_DIALOG4);
m_pageBtnMenu.AddPageForMenu(menuBtnId2,IDD_DIALOG5); m_topMenuBar = m_pageBtnMenu.m_pageMenu;
DockPane(m_topMenuBar); //创建底部菜单
if (!m_bottomMenuBar->Create(_T("常用工具"),this,CRect(0,0,200,200),TRUE,3600,
 CBRS_BOTTOM | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,AFX_CBRS_REGULAR_TABS,AFX_CBRS_AUTOHIDE))
{
TRACE0("未能创建底部常用功能工具栏\n");
return;      // 未能创建
}
m_bottomMenuBar->EnableDocking(CBRS_ALIGN_BOTTOM); //创建工具条
if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return;      // 未能创建
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));

DockPane(m_bottomMenuBar); if (!m_pageCtner.Create (_T("业务页面"), this, CRect (0,0, 200, 200),
TRUE , 0,
 CBRS_TOP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,AFX_CBRS_REGULAR_TABS,AFX_CBRS_AUTOHIDE))
{
TRACE0("Failed to create output bar\n");
return;      // fail to create
} DockPane(&m_pageCtner); m_pageCtner.SetTabAllowSwitch(FALSE);

解决方案 »

  1.   

    问题解决了,闪烁问题又很多因素引起,我找了很多资料,呵呵,以后可以总结下的。我的闪烁原因是因为控件自绘。为MainForm添加了WS_CLIPCHILDREN风格能绘制出子控件以外的其他区域,不负责子控件的绘制,而子控件的绘制就落在子控件自己身上了,我用的是VS2008的新控件,由于对其不是很熟悉,所以不明白起自绘背景色原理(绘制背景色有重写OnCtlColor,在OnPaint使用FillRect填充等),而VS2008的CDockablePane背景色使用的原色取自子窗口在父窗口当前区域的颜色,因为为MainForm添加了WS_CLIPCHILDREN风格,所以父窗口(MainForm)没有绘制子窗口所在部分,所以取的颜色会是透明的,或者其他页面残留。
    现在在子窗口(CDockablePane)的OnPaint方法里面使用FillRect填充背景,就能达到子窗口自绘背景的目的了。苦恼了好久,希望对大家有用呜呜呜