onpaint学习
来源:互联网 发布:cdn只能加速80端口嘛 编辑:程序博客网 时间:2024/06/07 02:25
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
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xiven/archive/2009/07/12/4341988.aspx
- onpaint学习
- OnPaint()
- OnPaint
- OnPaint
- MFC学习笔记之OnPaint和OnDraw之间的关系
- 重载OnPaint
- onPaint&onDraw
- MFC OnPaint
- wxwidget onpaint
- OnDraw OnPaint
- C# OnPaint
- VC|MFC学习笔记十一:GetWindowRect()和GetClientRect();OnPaint()和OnDraw()等
- OnEraseBkGnd()与OnPaint()的区别与联系,醍醐灌顶般的学习。。
- OnDraw和OnPaint (转载)
- tell OnDraw()&OnPaint()
- OnDraw()和OnPaint()兄弟
- OnDraw()和OnPaint()
- OnDraw()和OnPaint()
- leave archermind
- UVa 131 The Psychic Poker Player
- 使用 CMake 进行跨平台软件开发
- FTP原理
- 看之前你仰视英语,看之后你鄙视英语~ (转的)不过你要是不看,你就太亏了......
- onpaint学习
- 中毒不浅
- 删除MFC单文档默认菜单栏的两种方法
- 『转』如何为嵌入式开发建立交叉编译环境
- 飘动的文字
- 传智播客-Tree in SQL(译文)(3)
- ubuntu9.10下构建tftp服务(已验证)
- 2010-03-18
- OGRE配置——OGRE源码成功编译