java repaint 重画图形,学习笔记:WINDOWS的图形重绘基础

OnPaint()与OnDraw()的区别:

OnPaint是WM_PAINT的消息响应函数,在MFC的基类里OnPaint函数调用了OnDraw()函数。

OnPaint函数另外还调用了OnPrepareDC()函数。

如果在窗口子类覆盖了OnPaint函数,当MFC调用我们重写的OnPaint函数时,就调不到OnDraw()函数了,

除非我们去调用OnDraw()函数。

Invalidate函数族介绍:

函数: Invalidate(BOOL bErase = TRUE)

函数: InvalidateRect(CRect* rect,BOOL bErase = TRUE)

函数: InvalidateRgn(CRgn* rgn,BOOL bErase = TRUE)

将一个区域放入Update Region中。[Update

Region]是窗口的无效区域。[无效区域]是需要重绘的区域。

为何需要重绘呢?

第1类事件:当需要展现某窗口的“新的”区域时,就需要重绘。

当创建一个窗口时;当把窗口从另一个窗口的背后弹到前面时;当从图标化到最大化转变时;

当滚动式的窗口,发生滚动事件时;当把遮挡在前面的窗口一点一点拖开,

让被遮挡的窗口一点一点的露出时

就需要重绘。这些动作都是由WINDOWS系统管理的,系统会很肯定的认为,在上述事件发生时,必须重绘。

注:如果把被遮挡的窗口,一点一点的遮盖住,就不需要重绘。

第2类事件:当有业务数据改变的事件发生时。

窗口是用来显示业务数据的。比如我的窗口正在显示一个椭圆,后台将业务数据变成

了三角形,我需要显示这个三角形,这时就需要重绘了。对于第2类事件,

WINDOWS不可能感知到你需要重绘。

例如:我有一个变量 int m_shape=1; 1代表椭圆,2代表三角形。

我需要让窗口的图形显示m_shape代表的形状

当我把m_shape的值由1变成2时,WINDOWS根本不知道我需要重绘一个三角形。

对于第1类事件,WINDOWS会自动发出WM_PAINT消息,窗口的对应处理函数OnPaint()就会被调用。

程序员不必关心“在何时”和“在何地”重绘。对于第2类事件,程序员必须通知WINDOWS,在何地重绘。

至于“何时”重绘,WINDOWS会挑选一个合适的时机。

Invalidate函数族同第2类事件有关。通过调用Invalidate函数族,通知windows系统,

我有一些窗口区域需要重绘。CWnd::Invalidate()是说整个窗口都需要重绘。

CWnd::InvalidateRect()是说窗口的某个矩形区域需要

重绘。CWnd::InvalidateRgn是说窗口的某个不规则区域需要重绘。

“不规则区域”可以是任意多边形,椭圆形,当然也包括矩形。

用伪代码说明上述三个函数的等价关系。

CRgn rgn;

rgn.CreateRectRgn(...);

CWnd::InvalidateRgn(&rgn,...);

等价于

CRect rect;

CWnd::InvalidateRect(&rect,...);

CRect rect;

GetClientRect(&rect);

CWnd::InvalidateRect(&rect,...);

等价于

CWnd::Invalidate(...);

Invalidate函数族中,都有一个bErase参数。此参数的含义:bErase=TRUE擦除背景,

bErase=FALSE不擦除背景

何为背景:想象窗口就是小朋友的画纸。当你把这张画纸给另一个小朋友画画时,

前一个小朋友画的东西就是

“背景”。一般我们不希望两个小朋友画的东西夹杂在一起。我们就需要擦除前一个小朋友画的“背景”。

用什么擦除背景呢?WINDOWS允许我们设置“背景刷”,就是用某种颜色的刷子把整个画纸涂抹一遍,

有点像刷白墙。

Invalidate函数族的调用不会立刻引发窗口重绘。Invalidate函数族只是累积和标记需要重绘的区域。

下一次"WM_PAINT message

occurs"时(MSDN语),一次性处理累积和标记的所有需要重绘的区域。显然从

Invalidate调用,到实际的重绘动作是异步调用的。人类视觉有延迟现象,一秒连续播放24帧就可以认为是

“动画”了,所以上述重绘方式人类是察觉不出异样的。假设每次Invalidate都同步的引发重绘OnPaint,有两个不良后果:一是程序效率太差,二是可能让人察觉出闪烁感。

那么何时下一次"WM_PAINT message occurs"呢?

当应用的消息队列没有其他消息时,并且窗口的[Update Region]不为空时,

系统就会自动产生WM_PAINT消息。

例子:演示“失效区域”是如何起作用的。

//每次重绘,会交替展现两个不同的椭圆形。

void XXX::OnPaint()

{

CPaintDC dc(this);

static

int x=0;

if

(x==0){

dc.Ellipse (0, 0, 100, 200);

//横向的椭圆形

x=1;

}

else{

dc.Ellipse (0, 0, 200, 100);

//竖向的椭圆形

x=0;

}

}

某CButton中,OnBnClicked伪代码:

CRect rect;

XXX->GetClientRect(&rect);

rect.bottom = rect.bottom/2;

XXX->InvalidateRect(&rect,true);

//擦除背景

即使我擦除了背景,仍旧能看到前一个椭圆。因为我设定的“非法区域”只是rect的上半部分。

CRect rect;

XXX->GetClientRect(&rect);

XXX->InvalidateRect(&rect,true);

//擦除背景

可以正常的展现,能交替展现两个不同的椭圆形。

Validate函数族:

作用同Invalidate函数族相反,将一个区域从[Update Region]排除,这样就不会被重绘。

当然了,Validate要在下一次"WM_PAINT message occurs"之前的调用才能起作用。

如果发生了第1类事件,会造成大面积的区域变成“需重绘区域”,Validate设定的“不需重绘区域”

又会变成“需重绘区域了”。

UpdateWindow函数:

UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息。

UpdateWindow可以绕开应用程序消息循环,直接发送WM_PAINT消息给窗口。

RedrawWindows函数:

可以简单理解为Invlidate + UpdateWindow,但是功能更强大一些。

SetRedraw函数:

可以阻止窗口重绘。是解决窗口闪烁的一个办法

MSDN的一个例子:

m_List.SetRedraw(FALSE); //暂时阻止窗口m_List重绘

...//大规模对m_List改头换面

m_List.SetRedraw(TRUE);

//解除阻止窗口m_List重绘

m_List.Invalidate();

m_List.UpdateWindow();  //触发WM_PAINT消息

SetRedraw函数好像是戏台的前幕,后面切换场景时,先遮挡一下。

<>介绍了图形密集型程序“闪”的原因。

主要技术为:1 选用黑色背景或者背景同前景相近的颜色,作为背景刷。

2 双缓冲技术,就是先在内存设备DC里准备好需要显示的内容,然后拷贝到屏幕设备DC

3 剪裁区域的合理利用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529362.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php定义数据表类,phpwind中的数据库操作类

phpwind中的数据库操作类2021-01-22 20:12:15141/*来源&#xff1a;phpwind.net*/ClassDB{var$query_num0;functionDB($dbhost,$dbuser,$dbpw,$dbname,$pconnect0){$this->connect($dbhost,$dbuser,$dbpw,$dbname,$pconnect);}functionconnect($dbhost,$dbuser,$dbpw,$dbnam…

涡轮机叶片matlab强度分析论文,一种基于MATLAB及Pro_E的涡轮建模方法

自动化与控制与二一种基于&#xff2d;&#xff21;&#xff34;&#xff2c;&#xff21;&#xff22;及&#xff30;&#xff52;&#xff4f;&#xff0f;&#xff25;的涡轮建模方法王智明(中海油服油田技术事业部北京&#xff11;&#xff10;&#xff11;&#xff11;&am…

基于matlab的传热学虚拟实验开发,基于MATLAB的传热学课程虚拟实验软件的开发

215教育现代化2018 年 12 月第 49 期 教育信息技术 基于 MATLAB 的传热学课程虚拟实验软件的开发 周永利&#xff0c;李友荣&#xff0c;石万元&#xff0c;张力元&#xff0c;杨晨&#xff0c;卞煜&#xff0c;王国强&#xff0c;李俊&#xff0c;包键 ( 重庆大学 低品位能源利…

java做 binggo,Linux启动与停止spring boot工程的脚本示例

在springboot项目启动有三种方式&#xff1a;1、运行主方法程序2、使用命令mvn spring-boot:run 在命令行运行3、使用 mvn packpage打包位jar文件以后&#xff0c;使用java -jar yourapp.jar命令行运行一般我们在开发的时候经常使用的是前面两种运行方式&#xff0c;在部署实施…

php计划任务 框架,计划任务的使用 ThinkCMF内容管理框架,做最简约的ThinkPHP开源软件...

1、先不管是是否是独立分组&#xff0c;必须在Application\common\项目名下的Conf文件夹内创建2个文件一个是tags.php(项目默认有&#xff0c;直接加入需要执行的代码即可) 一个是 crons.php。注意这两个文件名为thinkphp标准文件名&#xff0c;不可以改变tages.php内容是&…

php按文章评论数排序,zblog获取分类文章排序按指定的时间排序、评论数量排序、浏览数量排序...

Zblog PHP在1.8版本的时候想要调用多个分类的文章&#xff0c;并且按照自己的需求去排序是很简单的事情&#xff0c;很多博友也利用这个方法进行最新文章排行、热门评论文章排行等等操作&#xff0c;现在随着ZblogPHP版本的升级&#xff0c;已经封装了数据库语句&#xff0c;导…

蚁群算法matlab vrp问题车辆限重,蚁群算法MATLAB解VRP问题

Excel exp12_3_2.xls内容&#xff1a;ANT_VRP函数&#xff1a;function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]ANT_VRP(D,Demand,Cap,iter_max,m,Alpha,Beta,Rho,Q)%% R_best 各代最佳路线%% L_best 各代最佳路线的长度%% L_ave 各代平均距离%% Shortest_Rout…

java线程6种状态转换,Java线程的生命周期和各种状态转换详解

在Java中&#xff0c;任何对象都有生命周期&#xff0c;线程也不例外&#xff0c;它也有自己的生命周期。当Thread对象创建完成时&#xff0c;线程的生命周期便开始了&#xff0c;当线程任务中代码正常执行完毕或者线程抛出一个未捕获的异常(Exception)或者错误(Error)时&#…

window10怎么卸载php,window_win10怎么卸载程序?win10卸载程序教程,当win10正式版发布以后,不少 - phpStudy...

win10怎么卸载程序&#xff1f;win10卸载程序教程当win10正式版发布以后&#xff0c;不少用户将电脑升级为Windows10系统后&#xff0c;不知道该如何卸载程序&#xff0c;本篇将为大家带来win10卸载程序教程&#xff0c;希望能够帮助到大家。win10怎么卸载程序方法一&#xff1…

matlab里dcgain,制系统的时域分析

一个动态系统的性能常用典型输入作用下的响应来描述。响应是指零初始值条件下某种典型的输入函数作用下对象的响应&#xff0c;控制系统常用的输入函数为单位阶跃函数和脉冲激励函数(即冲激函数)。在MATLAB的控制系统工具箱中提供了求取这两种输入下系统响应的函数。一、时域分…

php 添加音乐,PHP网站插入音乐

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼你找对地方了&#xff0c;我是IT之家大神光卡蒋一欣。我把代码发给你&#xff0c;直接运行即可entrance\01.gif......\........\02.gif......\........\03.jpg......\........\04.jpg......\........\05.jpg......\........\06.jpg…

在oracle数据库中显示异常,Oracle数据库出现ORA-01034错误的解决方案

类型&#xff1a;数据库类大小&#xff1a;42.1M语言&#xff1a;中文 评分&#xff1a;5.0标签&#xff1a;立即下载使用Oracle数据库的朋友经常会碰到的错误ORA-3113 "end of fileon communication channel" 就是这样的一个&#xff0c;我们可以简单的把这个错误理…

oracle数据库内核,深入内核:Oracle数据库里SELECT操作Hang解析

崔华&#xff0c;网名 dbsnakeOracle ACE Director&#xff0c;ACOUG 核心专家编辑手记&#xff1a;感谢崔华授权我们独家转载其精品文章&#xff0c;也欢迎大家向“Oracle”社区投稿。我们都知道在 Oracle 数据库里是“读不阻塞写&#xff0c;写不阻塞读”&#xff0c;那么是否…

oracle 如何形成死锁,Oracle数据表中的死锁情况解决方法

在进行数据库管理的过程中,经常会出现数据表被用户的一些不合理操作而导致表被锁定的情况,以下主要介绍如何查找哪些表被哪个用户所锁定,以及如何解除锁定:1.查找被锁定的表:select object_name,session_id,os_user_name,oracle_username,process,locked_mode,statusfrom v$loc…

php 分布式数据库查询,分布式数据库 · Thinkphp5.0完全开发手册 · 看云

# 分布式数据库ThinkPHP内置了分布式数据库的支持&#xff0c;包括主从式数据库的读写分离&#xff0c;但是分布式数据库必须是相同的数据库类型。配置database.deploy 为1 可以采用分布式数据库支持。如果采用分布式数据库&#xff0c;定义数据库配置信息的方式如下&#xff1…

matlab 电力系统动态仿真,基于Matlab的电力系统动态仿真分析

本文通过两个简单实例介绍了利用 !"#$"% &’(! )*, -./对电力系统进行仿真研究的方法! 包括"热工自动调节控制系统的仿真分析和电力电器系统的仿真分析# 0 热工调节控制系统仿真分析 对热工调节控制系统的性能分析包括静态特性和动态特性两个方面# 这里主要…

oracle read by other session,AWR报告中,read by other session ,如何解决?

你看你的top sql里全是动态采样的sql&#xff0c;默认10g以后optimizer_dynamic_sampling参数为level 2&#xff0c;一般为缺失统计信息会造成每次使用动态采样&#xff0c;虽然动态采样会在表频繁发生大批量改变时&#xff0c;一般可以生成更好的执行计划&#xff0c;但是也不…

oracle insert into as select,比较create table as select * 与 insert into table select *

实验环境&#xff1a;SYSaaron> select * from v$version;BANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - ProductionPL/SQL Release 11.2.0.1.0 - ProductionCORE …

unix 安装oracle,linux上安装Oracle

当前位置:我的异常网 Linux/Unix linux上安装Oraclelinux上安装Oraclewww.myexceptions.net 网友分享于&#xff1a;2013-09-03 浏览&#xff1a;26次linux下安装Oracle1.Linux下安装 jdk(Linux)建议从sun的主页上下载bin文件,运行后在/usr/会建立好java目录的Linux下相关命…

linux ftp用户指定多个目录,linux ftp服务器下用户限制目录的方法

我们使用服务器都要站在安全方面进行考虑&#xff0c;有必要将ftp服务下的用户限制在适当的范围内&#xff0c;那么linux ftp服务器下用户限制目录的方法有哪些呢?一起跟着爱站技术频道小编的步伐来了解一下吧!linux ftp服务器下用户只能在自己目录下的方法&#xff1a;第一步…