重画的时候,如果上面有很多按钮/CheckBox/RadioButton等的画,如果这些按钮重画速度不是很快(主要是自绘的),就会导致整个画的过程有一个明显的闪动(是一个接一个画导致的结果),不知道那个大侠有比较好的解决方案。
我的意思是能否用类似“锁住”对话框等方法,让所有的子控件都画完了,然后一次显示出来?
欢迎大家一起讨论,一起提高。
我的意思是能否用类似“锁住”对话框等方法,让所有的子控件都画完了,然后一次显示出来?
欢迎大家一起讨论,一起提高。
解决方案 »
- 负责Listen的CAsyncSocket,在OnAceept函数里 Accept(里面的*psocket不能运行OnReceive)
- ADO Command返回的RecordSet无法使用
- 网络端口问题?
- 救急!结构体内容COPY的问题。在线给分!
- local function definitions are illegal错误一般是什么造成的?
- 提问!如何讲HBITMAP转换为HICON!在线等待
- 关于进制的转换,快帮忙!谢
- 寻人:wwwllg兄
- 在com中对unicode字符进行过写文件处理时碰到的问题
- 怎样计算两个日期之间的工作日(主要是除去星期6和星期7)
- 双缓冲黑屏问题
- 我开发了windowxp的Gina,挺好使,可是! 通过windowsxp自带的 远程桌面连接 ,就出问题了,连接不上,说...
DeferWindowPos
EndDeferWindowPos
这几个windows api函数应该能实现你想要的功能.
具体使用看msdn帮助
void CMyPropertySheet::OnSize(UINT nType, int cx, int cy)
{
CRect r1;
CPropertySheet::OnSize(nType, cx, cy); if (m_bNeedInit)
return; CTabCtrl *pTab = GetTabControl();
ASSERT(NULL != pTab && IsWindow(pTab->m_hWnd));
int dx = cx - m_rCrt.Width();
int dy = cy - m_rCrt.Height();
GetClientRect(&m_rCrt); HDWP hDWP = ::BeginDeferWindowPos(5); pTab->GetClientRect(&r1);
r1.right += dx; r1.bottom += dy;
::DeferWindowPos(hDWP, pTab->m_hWnd, NULL,
0, 0, r1.Width(), r1.Height(),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); // Move all buttons with the lower right sides
for (CWnd *pChild = GetWindow(GW_CHILD);
pChild != NULL;
pChild = pChild->GetWindow(GW_HWNDNEXT))
{
if (pChild->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
{
pChild->GetWindowRect(&r1); ScreenToClient(&r1);
r1.top += dy; r1.bottom += dy; r1.left+= dx; r1.right += dx;
::DeferWindowPos(hDWP, pChild->m_hWnd, NULL,
r1.left, r1.top, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
}
// Resize everything else...
else
{
pChild->GetClientRect(&r1);
r1.right += dx; r1.bottom += dy;
::DeferWindowPos(hDWP, pChild->m_hWnd, NULL, 0, 0, r1.Width(), r1.Height(),SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
} } ::EndDeferWindowPos(hDWP);
}
你说的这几个函数好像在MoveWindow导致的闪烁的时候比较有有,现在我是仅仅重画所有的窗口就有这个问题了。
加一个WS_EX_COMPOSITED属性
所以,如果对话框没有背景图片的话:
响应WM_ERASEBKGND消息,获得对话框区域CRgn,去除控件所占的区域,然后用背景色填充所剩余的区域,最后返回TRUE。
* 刷新函数。刷新除编辑框,背景色选择框,滚动条以外的区域
*/
void CYourDlg::Invalidate(BOOL bErase)
{
/**
* 整个客户区域
*/
CRect rcClient;
GetClientRect(rcClient);
CRect rcDraw=rcClient;
CRgn rgn;
rgn.CreateRectRgnIndirect (rcDraw); /**
* 减掉编辑框区域
*/
CRgn rgnCtrl;
CRect rcWnd;
if(m_Edit.IsWindowVisible())
{
m_Edit.GetWindowRect(rcWnd);
this->ScreenToClient(rcWnd);
rgnCtrl.CreateRectRgnIndirect(rcWnd);
rgn.CombineRgn(&rgn,&rgnCtrl,RGN_DIFF);
rgnCtrl.DeleteObject();
} /**
* 减掉编颜色选择区域
*/
if(m_StaticClrs.IsWindowVisible())
{
m_StaticClrs.GetWindowRect(rcWnd);
this->ScreenToClient(rcWnd);
rgnCtrl.CreateRectRgnIndirect(rcWnd);
rgn.CombineRgn(&rgn,&rgnCtrl,RGN_DIFF);
rgnCtrl.DeleteObject();
} /**
* 减掉滚动条区域
*/
if(m_ScrollBar.IsWindowVisible())
{
m_ScrollBar.GetWindowRect(rcWnd);
this->ScreenToClient(rcWnd);
rgnCtrl.CreateRectRgnIndirect(rcWnd);
rgn.CombineRgn(&rgn,&rgnCtrl,RGN_DIFF);
rgnCtrl.DeleteObject();
}
/**
* 区域更新
*/
InvalidateRgn(&rgn,bErase);
}
所以,如果对话框没有背景图片的话:
响应WM_ERASEBKGND消息,获得对话框区域CRgn,去除控件所占的区域,然后用背景色填充所剩余的区域,最后返回TRUE。
CClientDC dc(this);
CDC pDC;
pDC.CreateCompatibleDC(&dc); CRect rect;
GetClientRect(&rect);
CBitmap bitmap, *pOldBmp;
bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
pOldBmp = pDC.SelectObject(&bitmap);
.
.
dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
&pDC,rect.left,rect.top,SRCCOPY);.....
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
这是直接从定义OnPaint处获得,因为可能在事件中又把DC使用了,
主程序定义的DC和你定义的DC会导致绘制对象不一致,可能会闪
这时候直接使用主程序的DC就不会出现以上的问题