MFC:关于窗口重绘的问题
最近在学MFC,关于窗口重绘有点不理解,比如说,我用向导建立了一个单文档程序,书上说,如果想在View窗口(就是下面的一大片空白区域)中输出文字,并且窗口大小改变后文字还...
最近在学MFC,关于窗口重绘有点不理解,比如说,我用向导建立了一个单文档程序,书上说,如果想在View窗口(就是下面的一大片空白区域)中输出文字,并且窗口大小改变后文字还能在上面,就要在OnDraw成员函数中写TextOut( )之类的代码,以便窗口重绘时还能显示文字,但是目前我有这样一个疑惑
-------------------------------我是分割线哦-------------------------------------------
书上说,如果想在View窗口中创建一个插入符(就是那个一闪一闪的一根棒棒),就要在OnCreate成员函数中写CreateSolidCaret( )之类的代码,但是我疑惑了,这样写的确能显示出插入符,但是为什么当我改变窗口大小的时候,这个插入符还在呢?这个插入符只在窗口建立的时候创建了啊,当窗口大小改变时,插入符也没有重绘,为什么还在呢?还有啊,如果说窗口大小改变要发生重绘的话,那岂不是连工具栏,菜单栏,上面的按钮,文本框等东东都要写到OnDraw中,以便窗口重绘吗?那OnDraw的任务量岂不是很大 展开
-------------------------------我是分割线哦-------------------------------------------
书上说,如果想在View窗口中创建一个插入符(就是那个一闪一闪的一根棒棒),就要在OnCreate成员函数中写CreateSolidCaret( )之类的代码,但是我疑惑了,这样写的确能显示出插入符,但是为什么当我改变窗口大小的时候,这个插入符还在呢?这个插入符只在窗口建立的时候创建了啊,当窗口大小改变时,插入符也没有重绘,为什么还在呢?还有啊,如果说窗口大小改变要发生重绘的话,那岂不是连工具栏,菜单栏,上面的按钮,文本框等东东都要写到OnDraw中,以便窗口重绘吗?那OnDraw的任务量岂不是很大 展开
展开全部
1. OnDraw只负责客户区的部分,所有的工具栏,菜单栏都不属于客户区;
2. Windows虽然会发送WM_PAINT但是他并不一定会要求重绘全部的内容,如果你只更改的一点大小,那么Windows发送WM_PAINT的时候你通过BeginPaint(该API函数由MFC自动调用)获得的失效区域就只有这个大小,而即便你在OnDraw里面画了整个区域,也只有失效的区域是会被Windows更新到显示器上去,其他的部分它就直接忽略了。原因就是因为绘图相对其他计算比较慢,所以能不多画就不多画。在MFC中,通过CDC::GetClipBox可以获得本次绘图的失效区域,如果你绘图内容很多,就需要根据失效区域来选择性的绘图,不需要绘全部,否则可能会很慢。
3. Windows会自动在一些情况下设置失效区域,比如你从最小化还原窗口的时候,它设置整个客户区都失效,你改变大小的时候,它设置影响到的部分失效。你在程序里面也可以自己设置失效区域,Invalidate设置整个客户区都失效,InvalidateRect设置一部分失效,失效的部分会Windows在下一次发送WM_PAINT的时候更新。所以认为Invalidate是让窗口重绘是不对的,有可能发生你Invalidate之后窗口根本就没有重绘,因为Windows可能觉得没必要发送WM_PAINT,因为WM_PAINT是优先级比较低的消息,Windows优先发送其他消息。
4. 如何强迫Windows立刻发送一个WM_PAINT? 通过调用UpdateWindow,UpdateWindow做两个事情,首先他检查当前窗口是不是有失效的区域,若有它就立刻发送WM_PAINT,若没有它什么也不做。所以很多时候,可以看到,更新窗口的代码是两条连在一起的:
Invalidate(TRUE);
UpdateWindow();
Invalidate的参数告诉Windows是否需要在发送WM_PAINT之前发送WM_ERASEBKGND,该消息负责重画客户区背景。默认的是画成白色。
5. 你也可以手工设定某个区域有效,通过ValidateRect即可。在你运行完OnDraw之后,MFC会自动调用EndPaint函数,该函数会自动将客户区全部设为有效。
2. Windows虽然会发送WM_PAINT但是他并不一定会要求重绘全部的内容,如果你只更改的一点大小,那么Windows发送WM_PAINT的时候你通过BeginPaint(该API函数由MFC自动调用)获得的失效区域就只有这个大小,而即便你在OnDraw里面画了整个区域,也只有失效的区域是会被Windows更新到显示器上去,其他的部分它就直接忽略了。原因就是因为绘图相对其他计算比较慢,所以能不多画就不多画。在MFC中,通过CDC::GetClipBox可以获得本次绘图的失效区域,如果你绘图内容很多,就需要根据失效区域来选择性的绘图,不需要绘全部,否则可能会很慢。
3. Windows会自动在一些情况下设置失效区域,比如你从最小化还原窗口的时候,它设置整个客户区都失效,你改变大小的时候,它设置影响到的部分失效。你在程序里面也可以自己设置失效区域,Invalidate设置整个客户区都失效,InvalidateRect设置一部分失效,失效的部分会Windows在下一次发送WM_PAINT的时候更新。所以认为Invalidate是让窗口重绘是不对的,有可能发生你Invalidate之后窗口根本就没有重绘,因为Windows可能觉得没必要发送WM_PAINT,因为WM_PAINT是优先级比较低的消息,Windows优先发送其他消息。
4. 如何强迫Windows立刻发送一个WM_PAINT? 通过调用UpdateWindow,UpdateWindow做两个事情,首先他检查当前窗口是不是有失效的区域,若有它就立刻发送WM_PAINT,若没有它什么也不做。所以很多时候,可以看到,更新窗口的代码是两条连在一起的:
Invalidate(TRUE);
UpdateWindow();
Invalidate的参数告诉Windows是否需要在发送WM_PAINT之前发送WM_ERASEBKGND,该消息负责重画客户区背景。默认的是画成白色。
5. 你也可以手工设定某个区域有效,通过ValidateRect即可。在你运行完OnDraw之后,MFC会自动调用EndPaint函数,该函数会自动将客户区全部设为有效。
展开全部
这个要了解MFC原理才能明白,一般来说是因为出发了WM_PAINT消息,这个消息会通知GUI的各个部分进行重绘,窗口大小改变也会触发WM_PAINT,经过一系列动作,最后调用到View的OnDraw函数而已,所以插入符号还在,至于工具栏,菜单栏,上面的按钮,这部分不是用户代码来维护的,或者由父类负责或者是其它消息负责,比如边框重绘是消息调用对应消息函数NcOnPaint
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2011-03-31
展开全部
ondraw只重绘view部分,工具栏菜单栏属于框架类,
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
ondraw只重绘view部分,就是一开始生成的白的部分,俗称客户区,工作区。工具栏菜单栏属于框架类。ondraw绘制的部分不但显示在屏幕上而且可以输出到打印机等其他输出设备上,onpaint是处理窗口在标准输出(显示器)重绘的。因此光标的处理不应该在ondraw中(除显示器外其他输出设备是不应显示光标的)。
别着急,慢慢来,等你对mfc基本结构有了了解再翻回来看,慢慢你会明白的。
别着急,慢慢来,等你对mfc基本结构有了了解再翻回来看,慢慢你会明白的。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
RedrawWindow()是重画全部或者部分窗口的,UpdataWindow()和Invalidate()都有重画的功能 你试一下吧 不知道你是不是需要这样的功能
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询