GetWindowRect()和GetClientRect();OnPaint()和OnDraw()等

来源:互联网 发布:自动对下联软件 编辑:程序博客网 时间:2024/06/06 11:45

1.GetWindowRect()和GetClientRect()

GetWindowRect()是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置。

GetClientRect()取得窗口客户区(不包括非客户区)在客户区坐标系下的RECT坐标,可以得到窗口的大小,而不能得到相对屏幕的位置,因为这个矩阵是在客户区坐标系下(相对于窗口客户区的左上角)的。  

ClientToScreen()把客户区坐标系下的RECT坐标转换为屏幕坐标系下的RECT坐标.

ScreenToClient()把屏幕坐标系下的RECT坐标转换为客户区坐标系下的RECT坐标.     

我们对同一个窗口先GetWindowRect取得一个RECT,再用ScreenToClient转换到客户坐标系。然后 GetClientRect取得一个RECT,再用ClientToScreen转换到屏幕坐标系。显然,GetWindowRect取得的矩阵不小于 GetClientRect取得的矩阵。因为前者包含了非客户区,而后仅包括了客户区。   

  对GetWindowRect取得的矩阵ScreenToClient后,矩阵的大小没有变小,(-3,-29)是窗口的左上角的坐标,相对窗口客户区左上角。对GetClientRect取得的矩阵ClientToScreen后,矩阵也没有变大,新得到的矩阵是窗口客户区在屏幕坐标系上的RECT。


2.OnPaint()和OnDraw()

当窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows会发送两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成,这就需要OnDraw()或OnPaint()来重画窗口。

OnDraw()和OnPaint()有什么区别呢?首先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是CView类的一个纯虚函数,没有响应消息的功能,要使用必须重载它。

其次,要想在屏幕上绘图或显示图形,首先需要建立设备环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。

当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。可见在OnPaint()里调用了OnDraw()。通常我们不必编写重写的OnPaint处理成员函数,而由于OnDraw是虚拟函数,可以自己改写,所以就实现了不同的绘图目的。

///CView默认的标准OnPaint()

void CView::OnPaint()
{

CPaintDC dc(this);

OnPreparDC(&dc);

OnDraw(&dc); //调用了OnDraw
}

//自己写的OnDraw()

///视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
void CMyView::OnDraw( CDC* pDC )
{

CMyDoc* pDoc = GetDocument();

CString s = pDoc->GetData(); // Returns a Cstring

CRect rect;

GetClientRect( &rect );

pDC->SetTextAlign( TA_BASELINE | TA_CENTER );

pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );

}

因此我们一般用OnPaint维护窗口的客户区(例如在窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如通过鼠标在视图中画图)。

补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口。

3. Invalidate()和UpdateAllViews()

Invalidate()是让程序重画窗口,使系统向其发WM_PAINT消息,使的程序的OnPaint被调用重画客户区。

UpdateAllViews()是在DOC/VIEW结构中,当一个视图的数据改变后,通知所有视图作相应的改变。UpdateAllViews()是文档与视之间的联系,调用从它会使程序与此文档相关的所有视的UpdateView被调用,至于是否重画以及怎么画是由各视的UpdateView来决定的。

Invalidate()是Cwnd的成员函数,与DOC-VIEW无关;

UpdateAllViews()是CDocument的成员函数,具体体现DOC-VIEW的精神。

Invalidate()函数产生一条WM_PAINT消息,并送入windows消息队列中,是窗口产生重画。而UpdateAllViews 并不进入windows消息队列中,直接产生重画。

如果仅重画当前窗口用 this->Invalidate();如果通知所有和当前文档相关的窗口重画用GetDocument()->UpdateAllViews()(在View中)或this->UpdateAllViews()(在Doc中)。

还有一个函数:ONERASEBKGND()画背景用的,先于OnPaint()运行。

4. UpdateData(true)和UpdateData(false)

如果你为控件分配了变量:

UpdateData(true): 是使用户输入的数据能够反映到变量上,在函数调用之后变量才被赋值。

UpdateData(false): 是当你给控件对应的变量赋过值之后,在控件上体现出来,在函数调用之前,控件的值是不会随变量变化的。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq的一些重要数据被清理怎么办 华为p9微信听筒声音小怎么办 win10我的电脑图标没了怎么办 小米5x里的微信头像不清楚怎么办 微信头像换了总是模糊怎么办 找到老公暧昧对象的微信怎么办 朋友欠我钱一直拖找借口怎么办 陌陌附近的人不按距离排序怎么办 老婆一直要管我的钱怎么办 老公不肯把钱交给老婆管怎么办 愿意和做朋友不愿意做情侣怎么办 欠信用卡碰到第三方不愿协调怎么办 qq密码忘记了申诉不回来怎么办 当你老公烦你了你该怎么办 自己有漂亮媳妇还经常想去嫖怎么办 微信号封了找不到好友解封怎么办 别人总是提起你的黑历史怎么办 换了手机微信登录不上怎么办 qq不小心清空了聊天记录怎么办 人家介绍了外地媳妇跑了怎么办 火锅想吃香菜牛肉没有签子串怎么办 想读外省大学但家人反对怎么办 13岁被同学忽视他不知道怎么办 老婆发现老公在微信暧昧聊天怎么办 老婆微信和别人聊天暧昧我该怎么办 淘宝修改标题宝贝被删了怎么办 百度网盘上的相片变的模糊怎么办 微信2不小心删了怎么办 房屋没交接前给钥匙出现问题怎么办 微信银行卡注销零钱没了怎么办 贴小广告电话被城管上报停机怎么办 没有id密码怎么办已经锁死了屏幕 电信电话卡注销了里面的钱怎么办 支付宝绑定的手机号成空号了怎么办 支付宝绑定的手机号空号了怎么办 支付宝绑定的手机号码空号了怎么办 注册支付宝的手机号成空号了怎么办 银行保本理财回执单丢了怎么办 电脑连不上网ip地址错误怎么办 邮箱填错了没收到面试通知怎么办 电信烽火网络机顶盒零配置中怎么办