win32 7.1 设备环境

  1. DOS和WINDOWS图形输出区别:
    1. DOS:在DOS系统中,如果在文本模式下显示信息,只需要把内容拷贝到 B8000h 处的内存中;显示图形信息,可以把图形拷贝到 A0000h 处的内存中。
    2. WHindows中,GDI接口把程序和硬件分割开来,在Win32编程中,再也不能通过直接向视频缓冲区拷贝数据的办法来显示信息了,那通过什么? 答案是通过“设备环境”来输出信息。
  2. “设备环境”介绍:
    1. 代码效果演示:(该效果在虚拟机中(windows7 64位)显示不出来,所以以照片的形式现实,代码照样解读就好)在这里插入图片描述
    2. 代码初步解读:
      这里,有很多地方我们之后会介绍,先说一下原理,首先创建窗口,绘制窗口,绘制窗口时会发送WM_PAINT消息,接收该消息会初始化中间一个字符串。然后设置定时器,定时器每0.1秒把右边窗口的图像绘制到左边去,注意,定时器过程里面的绘制图像函数,其直接绘制不通过WM_PAINT消息,所以,在窗口过程中也不会发现其更新代码。
    3. “环境设备理解”:
      1. 现在用其他程序将右边窗口的客户区的一部分覆盖掉,通过左边窗口的变化可以惊奇地发现,右边窗口客户区的内容并不是程序自己输出到客户区的那句文本,而是以客户区为矩形区域的屏幕上的内容,它竟然包括其他窗口覆盖在上面的内容。这就意味着,扫雷游戏和纸牌游戏通过自己的客户区对应的设备环境图形,图形数据竟然画到了 DcCopy 窗口客户区对应的设备环境。
      2. 这个例子验证了“设备环境”只是“环境”而不是“设备”,它并不存储发给它的图形数据,图形数据透过它所描述的“设备”上,每个窗口客户区的“设备环境”对应的设备都是屏幕,但由于它们在位置上可能重叠,所以向一个窗口的客户区写数据相当于同时写了下层窗口的客户区。
        理解这句话:“每个窗口客户区的’设备环境'对应的设备都是屏幕”,其每个设备都有一个“设备环境”,向环境设备中写入数据,就相当于向屏幕上写入内容,这样就能做到很好的隔离,其通过设备环境句柄来进行写入操作,写入并不代表一定能输出,最后还有一层过滤装置,在决定谁能输出到屏幕上。注意:设备环境并不存储数据,你可以认为“窗口向设备环境写入就相当于屏幕写入,但是中间加了一层Windows过滤”。
        在这里插入图片描述
      3. 深入理解:
        1. 经过Windows过滤,并不是所有内容都会写道屏幕上,只有没有背其他窗口覆盖的才会写到屏幕上。
        2. “设备环境”只是一个环境,是设备属性的一组定义,程序输出的图形数据透过“设备环境”定向到了具体设备上,“设备环境”本身不存储这些数据。
        3. 桌面不是一层层纸,而是一个用粉笔写的公告黑板,一个窗口相当于划了一块空间写公告,写另一个告示时需要把牢告示的内容擦去一部分以便写新内容,擦去的内容也就不存在了,如果要恢复老告示,那么必须把擦去的部分重新写上去。
          注意:去“图形数据”是“数据”而不是“图画”,所以,发送的时候当然是全部发送,而不是只发送无效区域的图像,
          所以,从这个角度来讲,其相当于一张张纸发送给操作系统,操作系统作为管理员根据实际情况绘制到黑板上,当
          黑板需要修改一个区域,操作系统根据新的纸张重新绘制。对应窗口来说,其根本不关系如何绘制,绘制成啥样,
          它只负责将图形数据完好无损的发送给操作系统,剩下的由操作系统来解决。
          
  3. 获取设备环境句柄:
    1. 介绍:
      想要对任何设备绘图,首先必须获取设备的“设备环境句柄”(hDC),几乎所有的GDI绘制的操作目标都是 hDC,在程序中获得一个hDC有以下几种方法。
    2. 获取hDC的方法:
      1. BeginPaint 函数得到hdc:最常用的方法是WM_PAINT消息中用 BeginPaint 函数得到hdc,下面是WM_PAINT的一般操作:
        在这里插入图片描述
        函数解读:
        1. 该函数返回的仅仅是需要刷新区域的hDC,即无效区域的hDC, 无法用它绘制到其他地方去。
        2. 由于窗口过程每次接收的WM_PAINT消息时无效区域可能都不同,所以这个hDC的值仅仅在 WM_PAINT 消息中有效,程序不应该保存它并在其WM_PAINT以外的代码中使用。
        3. 基于同样的道理,BeginPaint和EndPaint函数只能在WM_PAINT消息中使用,因为只有这时候才有无效区域。
      2. GetDC获取 hDC:程序中常常有这种需求,就是在非WM_PAINT消息中主动绘画客户区,由于BeginPaint和EndPaint函数必须在WM_PAINT消息中使用,所以这时必须采用另外的方法获取hDC,可以采用以下方法:
        在这里插入图片描述
        函数解读:
        1. GetDC函数返回的 hDC 对应窗口的整个客户区,当时用完毕的时候,hDC 必须用 ReleaseDC 函数释放。
        2. 对于GetDC获取的 hDC, Windows 建议使用的范围仅限于单条消息内,即程序处理某条消息,“获取-使用-释放”,当下次消息,再“获取-使用-释放”。
        1. CreateDC 函数 创建一个DC:上面两种方法都是获取窗口的hDC,如果要操作的是其他的对象,如打印机、位图等,就不能使用上面这两种函数了。当绘图的对象是一个设备的时候,可以用 CreateDC函数来建立一个DC:
          在这里插入图片描述
          1. pwszDriver 指向设备名称,如显示设备的设备名是DISPLAY,打印机一般的设备名是WINSPOOL。
          2. 下面这几句代码建立的DC是对应着整个屏幕:
            在这里插入图片描述
        2. CreateCompatibleDC 创建一个与位图对象关联的句柄:当绘图对象是位图的时候,同样需要一个与位图句柄相联系的DC,这时可以用函数CreateCompatibleDC 来创建一个显示表面且仅存在于内存中的DC:
          在这里插入图片描述
          参数中的hDC是一个参考的DC句柄,如果指定的参数为NULL,那么建立的DC将和当前的设置兼容,为了用 CreateCompatibleDC 建立的DC 绘制一个位图,还需要用 selectObject 函数将 hDC 和位图句柄联系起来。在这之后,通过hDC进行的挥之操作将像素更新到位图中。
        3. DeleteDC删除:用 CreateDC 和 CreateCompatibleDC 函数建立的 hDC 在使用结束后,必须用 DeleteDC函数删除,注意这里不能用 ReleaseDC,这个函数是GetDC配合实用的。
        4. 函数使用时间:用 BeginPaint 和 EndPaint,以及GetDC 获取的 hDC 的使用时间不能超过本条消息,而 CreateDC 和 CreateCompatibleDC 建立的 hDC 则没有这种限制,可以在任何适合建立它并且一直使用到不再需要为止。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
××××××××××××××××××××××××××× × 《Windows环境下32位汇编语言程序设计》 × × 附书代码说明 × ××××××××××××××××××××××××××× 1. 编译器和链接器 本附书代码全部采用 MASM 格式编写,推荐使用 MASM32 软 件包作为编译环境,MASM32 软件包可以在以下地址下载: MASM32官方站点: http://www.masm32.com 安装及开发的操作系统建议采用32位的Windows 7,在64位操作系统 上安装 MASM32 软件包,安装生成的Lib文件可能不兼容。 安装完成以后请将本光盘根目录下的环境设置批处理文件Var.bat 拷贝到 Masm32\bin 目录下,并根据 MASM32 的安装位置编辑修改 Var.bat 文件中的相关目录名称。 2. 代码维护工具 每个例子都包括了描述编译、链接方法的 makefile 文件, 使用 nmake 工具可以自动根据此文件进行编译链接,nmake 工 具可以从 Visual C++ 的 bin 目录中找到,也可以从作者的网 站中下载。 3. 编译环境和编译方法 建议使用命令行方式进行编译,以编译 Chapter02\Test 目录中 Test.asm 为例,步骤是: I. 打开一个“命令提示符”窗口。 II. 进入环境设置批处理文件 Var.bat 所在目录并执行 它,以后就可以使用这个“命令提示符”窗口编译 文件了。 x: cd \masm32\bin var III. 进入源代码目录: cd \chapter02\test IV. 使用 nmake 工具进行编译链接: nmake V. 执行编译好的可执行文件。 如果需要对源代码进行修改,不必关闭“命令提示符”窗口, 只要切换到编辑器窗口,在修改 *.asm 文件后重复进行第 IV 和 第 V 步骤即可。 # 特别注意:将光盘中的代码拷贝到硬盘后,必须将文件的只读属性去除! 4. 本光盘所包含目录的说明 根目录下的 *.pdf ;附录A、B、C的电子版文档 Chapter02\Test ;测试编译环境 Chapter03\HelloWorld ;Hello World Chapter04\FirstWindow ;用Win32汇编写第一个窗口 Chapter04\FirstWindow-1 ;用Win32汇编写第一个窗口 Chapter04\SendMessage ;窗口间的消息互发 Chapter04\SendMessage-1 ;窗口间的消息互发 Chapter05\Menu ;使用资源 - 使用菜单 Chapter05\Icon ;使用资源 - 使用图标 Chapter05\Dialog ;使用资源 - 使用对话框 Chapter05\Listbox ;使用资源 - 使用列表框 Chapter05\Control ;使用资源 - 使用子窗口控件 Chapter05\ShowVersionInfo ;使用资源 - 显示版本信息资源的程序 Chapter05\VersionInfo ;使用资源 - 使用版本信息资源 Chapter06\Timer ;定时器的使用 Chapter07\DcCopy ;在两个窗口的 DC 间互相拷贝屏幕 Chapter07\Clock ;模拟时钟程序 Chapter07\BmpClock ;用 Bitmap 图片做背景的模拟时钟程序 Chapter07\TestObject ;一些常见的绘图操作 Chapter08\CommDlg ;使用通用对话框 Chapter09\Toolbar ;使用工具栏 Chapter09\StatusBar ;使用状态栏 Chapter09\Richedit ;使用丰富编辑控件 Chapter09\Wordpad ;一个完整的文本编辑器例子 Chapter09\SubClass ;窗口的子类化例子 Chapter09\SuperClass ;窗口的超类化例子 Chapter10\MemInfo ;显示当前内存的使用情况 Chapter10\FindFile ;全盘查找文件的例子 Chapter10\FormatText ;文件读写例子 Chapter10\FormatText\FileMap ;使用内存映射文件进行文件读写的例子 Chapter10\MMFShare ;使用内存映射文件进行进程间数据共享 Chapter11\Dll\Dll ;最简单的动态链接库例子 - 编写 DLL Chapter11\Dll\MASM Sample ;最简单的动态链接库例子 - 使用 DLL Chapter11\Dll\VC++ Sample ;最简单的动态链接库例子 - 在VC++中使用汇编编写的DLL Chapter11\KeyHook ;Windows 钩子的例子 - 监听键盘动作 Chapter11\RecHook ;Windows 日志记录钩子的例子 - 监听键盘动作 Chapter12\Counter ;有问题的程序 - 一个计数程序 Chapter12\Thread ;用多线程的方式解决上一个程序的问题 Chapter12\Event ;使用事件对象 Chapter12\ThreadSynErr ;一个存在同步问题的多线程程序 Chapter12\ThreadSyn\UseCriticalSection ;使用临界区对象解决多线程同步问题 Chapter12\ThreadSyn\UseEvent ;使用事件对象解决多线程同步问题 Chapter12\ThreadSyn\UseMutex ;使用互斥对象解决多线程同步问题 Chapter12\ThreadSyn\UseSemaphore ;使用信号灯对象解决多线程同步问题 Chapter13\CmdLine ;使用命令行参数 Chapter13\Process ;创建进程的例子 Chapter13\ProcessList ;显示系统中运行的进程列表 Chapter13\Patch1 ;一个内存补丁程序 Chapter13\Patch2 ;一个内存补丁程序 Chapter13\Patch3 ;一个内存补丁程序 Chapter13\HideProcess9x ;Windows 9x下的进程隐藏 Chapter13\RemoteThreadDll ;用 DLL 注入的方法实现远程进程 Chapter13\RemoteThread ;不依靠任何外部文件实现远程进程 Chapter14\TopHandler ;使用筛选器处理异常 Chapter14\SEH01 ;最基本结构化异常处理例子 Chapter14\SEH02 ;改进后的结构化异常处理例子 Chapter14\Unwind ;异常处理中的展开操作例子 Chapter15\Ini ;使用 INI 文件 Chapter15\Reg ;操作注册表的例子 Chapter15\Associate ;操作注册表实现文件关联 Chapter16\TcpEcho ;实现 TCP 服务器端的简单例子 Chapter16\Chat-TCP ;用 TCP 协议实现的聊天室例子 Chapter17\PeInfo ;查看 PE 文件的基本信息 Chapter17\Import ;查看 PE 文件的导入表 Chapter17\Export ;查看 PE 文件的导出表 Chapter17\Resource ;查看 PE 文件的资源列表 Chapter17\Reloc ;查看 PE 文件的重定位信息 Chapter17\NoImport ;不使用导入表调用 API 函数 Chapter17\AddCode ;在 PE 文件上附加可执行代码的例子 Chapter18\OdbcSample ;用ODBC操作数据库的例子 Appendix A\EchoLine ;控制台输入输出的例子 Appendix B\MsgWindow01 ;消息机制试验 1 Appendix B\MsgWindow02 ;消息机制试验 2 Appendix B\MsgWindow03 ;消息机制试验 3 Appendix B\MsgWindow04 ;消息机制试验 4 Appendix C\BrowseFolder ;浏览目录对话框 6. 联系作者 虽然本书中所有的例子代码都已经在32位的Windows 98、Windows 2000、 Windows XP、Windows Vista和Windows 7下测试通过,但也有存在Bug的可能,如果 发现代码存在错误或者有其它问题,请告知作者,联系方法: E-mail:luoyunbin@hotmail.com 感谢您的支持! 作者:罗云彬
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值