博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
位图复制操作
阅读量:6656 次
发布时间:2019-06-25

本文共 2092 字,大约阅读时间需要 6 分钟。

这一篇是针对推箱子小游戏写的,有很多细节在其它文章已记录,但还是再写一篇,我一直觉得知识需要反反复复的锤炼才能理解,尤其对于windows程序设计,它不难,但是非常琐碎!每一句代码都有其意思,为什么这样为什么那样,一句代码不明白,就是一个知识点不明白,能允许不能解释的代码存在吗?我们总要给其一个解释,至少能自圆其说!

首先考虑的是位图怎么显示在屏幕上。

当获取或创建一个设备对象时,该设备对象中包含有一个位图,该位图所使用的内存是输出设备在输出图形时所使用的内存(例如,显示器的显示缓冲区),这样,GDI函数在该内存中所绘制的图形同时可以在显示器上可见。

这段话的意思大概是,如果不进行任何的操作,只是得到一个hdc显示位图,位图就处在显示器的显示缓冲区中。

接下来就是内存设备对象,也就是在内存中创建一个设备对象,在这个设备对象上画图,然后再把这个位图送到其它显示设备上显示。唯一需要的是,创建的这个内存设备对象得兼容其它的显示设备对象,比如hdc等等。

这里需要注意的一个问题,创建内存设备对象初始时,其位图尺寸只有1x1(即一个像素),需要扩大显示表面才能容纳位图,采用的方法是创建一个兼容位图去填充内存设备对象。如图所示:

针对推箱子游戏的代码:

hdc=GetDC(hWnd);mdc=CreateCompatibleDC(hdc);//创建兼容的内存设备对象bg=CreateCompatibleBitmap(hdc,Border*COL,Border*ROW);//兼容位图,即是推箱子客户区的大小SelectObject(mdc,bg);//选入位图进入内存设备对象,同时也就扩大了内存设备对象的显示表面

上图说明了如何复制的流程,观察这三个dc,尺寸是不一样的,hdc=mdc=客户区的大小,而bufdc=images的大小。

这里出现一个问题,为什么不直接把图块放在mdc中,然后再复制mdc到hdc,还要创建一个bufdc呢? 可以这样理解,实在的位图和内存块之间如何复制?至少现在知道是不行的,比如说BitBlt函数,是在内存块之间复制,不是位图和内存之间复制,所以还是建立一个bufdc,将位图放在其中,这样位图就相当于“内存块”了,于是就可以利用BitBlt位块操作,将bufdc的某个区域复制到mdc,最后将完整的mdc复制到hdc。

需要注意的几个问题

创建内存设备对象初始时只有1个像素,可以先扩大其显示表面。

第二个,观察SelectObject这个函数,假如直接将一幅存在的位图选入到某个DC中,那这个DC直接就具有了这个图像。比如:

        mdc=CreateCompatibleDC(hdc);                hBitmap=(HBITMAP)LoadImage(NULL,"fg.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);                    SelectObject(mdc,hBitmap);

第三个,是BitBlt函数。

这个函数是位块复制函数,位块就是在内存块之间转移。从源到目的复制多大,取决于前面设置的宽和高,也就是说,源只提供坐标,从哪开始,而目的提供宽度和高度。

SelectObject和BitBlt的一点微妙关系

前面提到的,创建一个内存设备对象,初始时,是1像素,既然这么小,为什么SelectObject将一幅位图选进后,它就自动变的位图一样大呢?这个通过程序可以验证的。

按照这种思路,在创建mdc的时候,我不扩大其显示表面,被动的等待其它位块来填充,这样可行吗?验证是不行的。

这两者的对比就说明一个问题,进行SelectObject操作时,可以不指定内存设备对象的大小,直接复制。而BitBlt是位块复制,目标尺寸必须大于源的尺寸,这一点还是奇怪的。用图表示:

正是因为这个区别,在创建mdc的时候,还要多出一步,扩大其显示表面,以用于后面的复制操作!

代码表示:

hdc=GetDC(hWnd);    mdc=CreateCompatibleDC(hdc);    bufdc=CreateCompatibleDC(hdc);//bufdc不需要扩大,因为其用于SelectObject...    bg=CreateCompatibleBitmap(hdc,Border*COL,Border*ROW);    images= (HBITMAP)LoadImage(NULL,"box.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);//直接从硬盘读取位图    SelectObject(mdc,bg);//扩大mdc的显示表面,mdc是用于复制的...

——————————————————————————————————————————————————————————————————

 

转载于:https://www.cnblogs.com/tinaluo/p/5439965.html

你可能感兴趣的文章
draggable布局 vue_vue-draggable
查看>>
python要什么电脑配置_学Python需要什么配置的电脑?
查看>>
pythonif条件语句实例_Python基础之条件控制操作实例【if语句】
查看>>
excel操作题_Excel|操作题第4套
查看>>
i5-1135g7相当于什么水平_剑桥英语I优加-剑桥pet相当于国内什么水平
查看>>
mysql8.0150安装教程_MySQL8安装Installer版的图文教程
查看>>
mysql 缓冲区_mysql 系列 缓冲区
查看>>
mysql tablespaces_MySQL8.0-MySQLTablespace
查看>>
mysql enum创建_mysql – 如何在SQLite中创建ENUM类型?
查看>>
mysql5.5.7无法创建.pid_MySQL启动创建不了pid怎么办
查看>>
通信原理知识点总结_通信原理课程总结(一)
查看>>
python字频统计软件_python统计文本中字频的方法
查看>>
java数据类型有哪几种_java数据类型有哪些
查看>>
java 什么是内部类_什么是JAVA内部类?
查看>>
java获取图片分辨率_java获取远程图片分辨率
查看>>
java label 超链接_java – 如何在JLabel中添加超链接?
查看>>
java http请求分发_Java实现利用HttpClient和配置文件实现集群模式下的文件同步分发-Go语言中文社区...
查看>>
java log4j 使用_java日志之log4j简单使用
查看>>
java oracle分页查询语句_oracle 分页语句
查看>>
java 连接sqlserver_java连接sqlserver报错
查看>>