窗口重画ONPaint
来源:互联网 发布:yum 搜索rpm 编辑:程序博客网 时间:2024/06/08 06:05
WM_PAINT源头:第一次创建窗口,窗口最大、最小化,窗口大小改变、窗口移动,无效区等动作,以及调用Invalidate、InvalidateRect或InvalidateRgn、Updateindow等函数。
每个窗口(HWND)实例,在windows操作系统中,都有个上下文记录区,其中记录着当前窗口的无效区域数据。系统内核利用空闲时间检查所有窗口的无效区,如果非空,就产生一个WM_PAINT发送给此线程再转发到当前窗口来处理。当然此时,此窗口的无效区域还是存在的,通过在WM_PAINT中执行BeginPaint,就将此无效区域清空(使用ValidateRect一样效果),在执行具体的绘制操作。(这些执行都在窗口的Default中执行了,MS不给你看具体的过程,所以在MFC的系统代码中看不到。)。如果不将无效区域清空,系统将周而复始的产生WM_PAINT消息,导致OnIdle不能被执行,且当前程序CPU占用差不多100%。(由于是空闲时间处理,所以对话框的其他消息处理没被阻塞,可以按按钮等操作)。
I、拖动窗口,将被全部重新绘制,因为拖动的操作调用了RedrawWindow函数,此函数不光产生整个窗口的 Invalide调用,同时接下来还直接执行窗口的绘制操作(读取窗口的无效区,如果不屏蔽CDialog::OnPaint,就在OnPaint里面绘制了)。
II、如果是被另外一个对话框覆盖,那个对话框将会向其下的窗口(默认的窗口Z轴顺序)发生设置无效区域的指令
相关函数简介:
InvalidateRect(hWnd,&rect,TRUE): 向hWnd窗体发出WM_PAINT的消息,强制客户区域重绘制,是通过线程的消息队列来发送刷新消息,是最常用的
Invalidate:标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行WM_PAINT.
UpdateWindow: 直接调用窗口函数立即响应刷新消息,使窗口刷新消息优先被响应(消息队列中如果没有WM_PAINT消息就什么都不执行),UpdateWindow()只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT.一般是在ShowWindow之后调用。
RedrawWindow:
BOOL RedrawWindow( LPCRECT lpRectUpdate = NULL, CRgn* prgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE );
根据fuRedraw旗标的设置,重画全部或部分窗口,相当于先调用InvalidateRect,紧接着又调用UpdateWindow,此外RedrawWindow还提供了一些前两者没法做到的功能。
附录A 设置窗口位置大小的2个函数:
I、void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE );
II、
BOOL SetWindowPos( const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );
附录B:静态切分窗口:当窗口第一次被创建时,窗格就已经被切分了,窗格数目、次序不在改变。
I 重载函数OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext);
II 在里面添加窗口静态切分函数CreateStatic(CWnd*,int,int,DWORD,UINT);
III 为静态窗格指定一个视图类CreateView(int,col,CRuntimeClass*,SIZE,CCreateContext*);
例子:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext)
{
// TODO: Add your specialized code here and/or call the base class
CRect rect;
GetWindowRect(&rect);
BOOL bRes=m_wndSplitter.CreateStatic(this,2,1);
m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CBombAppView),CSize(rect.Width(),rect.Height()/10),pContext);
m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(CBombAppView1),CSize(rect.Width(),rect.Height()),pContext);
// m_wndSplitter.SetColumnInfo(0,rect.Height()/2,10); //设置列长
// m_wndSplitter.SetColumnInfo(1,rect.Height()/2,10);
m_wndSplitter.RecalcLayout();
return bRes;
}
附录c http://hi.baidu.com/ouanan/blog/item/ad90dacf559dd13af9dc616b.html
http://baike.baidu.com/view/1226797.htm
http://baike.baidu.com/view/1226818.htm
http://www.cppblog.com/OnTheWay2008/archive/2009/06/03/86615.aspx
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xiven/archive/2009/06/15/4271387.aspx
- 窗口重画ONPaint
- 窗口重画ONPaint
- 窗体重画(OnPaint)
- WM_PIANT消息与窗口重画
- WM_PIANT消息与窗口重画
- 强制和防止窗口重画
- 关于窗口重画的初级问题
- 已知HWND或HDC 重画窗口
- OnPaint()
- OnPaint
- OnPaint
- 不要在OnPaint()中使用Invalidate()来刷新窗口
- 如何让窗口重画——Invalidate()、SendMessage(WM_PAINT)和UpdateWindow()
- 网格重画
- 图片重画
- 控件OnPaint,导致主窗口的对话框弹出时无法显示
- 对话框窗口不刷新,不进入OnPaint(不进WM_PAINT)
- 重画系列:双色Button
- IT技术员职业生涯的红色警报
- VMWare 6.5 安装 Red Hat Linux 9
- 认识JAVA
- PHP5:this, self, parent
- 一行、多行文本垂直居中的CSS实例说明
- 窗口重画ONPaint
- 实现个人网站盈利的初步探讨
- 午后
- write solid code 心得
- cs
- Oracle字符集相关知识(查询,修改,dmp字符集)
- c++关键字explicit使用指南
- 8 张思维导图学习 Javascript —— javascript流程语句
- 如果是真爱 请永不放弃