win32汇编 屏幕截图保存BMP 学习笔记<第二篇>之东拼西凑

原创 2016年05月12日 12:28:06

接下来开始动手 先看raiky的代码

_GetCaptureBmp proc uses ebx esi edi
     LOCAL @hDc,@MemDc,@Data
     LOCAL @bi:BITMAPINFO

     invoke RtlZeroMemory,addr @bi,sizeof @bi
     mov ebx,sizeof BITMAPINFO
     mov @bi.bmiHeader.biSize,ebx
     invoke GetSystemMetrics,SM_CXSCREEN
     mov @bi.bmiHeader.biWidth,eax
     invoke GetSystemMetrics,SM_CYSCREEN
     mov @bi.bmiHeader.biHeight,eax
     mov @bi.bmiHeader.biPlanes,1
     mov @bi.bmiHeader.biBitCount,24
     invoke GetDC,NULL
     mov @hDc,eax
     invoke CreateCompatibleDC,@hDc
     mov @MemDc,eax
     invoke CreateDIBSection,@MemDc,addr @bi,DIB_RGB_COLORS,addr @Data,NULL,0

     mov hBmp,eax
     invoke SelectObject,@MemDc,hBmp
     invoke BitBlt,@MemDc,   0,   0,   @bi.bmiHeader.biWidth,   @bi.bmiHeader.biHeight,@hDc,   0,   0,   SRCCOPY 

     invoke ReleaseDC,NULL,   @hDc
     invoke DeleteDC,@MemDc  
   xor eax,eax
      ret
 _GetCaptureBmp endp

我看不出什么大的问题来
唯一值得商榷的是他对屏幕分辨率的侦测不适合DPI比较高的情况 比如我的笔记本DPI 150%分辨率会侦测不正确
这本身不是什么大问题
用GetDeviceCaps取代GetSystemMetrics即可

     invoke GetDC,NULL
     mov hDc,eax
     invoke RtlZeroMemory,addr bi,sizeof bi  ;ok
     mov ebx,sizeof BITMAPINFO
     mov bi.bmiHeader.biSize,ebx
    invoke GetDeviceCaps,hDc,DESKTOPHORZRES
     ;invoke GetSystemMetrics,SM_CXSCREEN  
     mov bi.bmiHeader.biWidth,eax
     print ustr$(eax),"DESKTOPVERTRES",13,10 ;debug 输出物理分辨率    
     invoke GetDeviceCaps,hDc,DESKTOPVERTRES
     ;invoke GetSystemMetrics,SM_CYSCREEN ;NG 高DPI下取分辨率值不正常
     mov bi.bmiHeader.biHeight,eax

     invoke ReleaseDC,NULL,   hDc ;--------------------------------------end of init for resolution detection

上面这段代码呢 就是完成屏幕分辨率的获取 这个比较简单

下面这段是初始化bmiHeader根据norains的解释 1,24这两个值没问题

 mov bi.bmiHeader.biPlanes,1
 mov bi.bmiHeader.biBitCount,24 
   ;norains 文章里提到一切从最简单做起,对于BMP而言,最简单的自然是24位位图,这就是为什么biPlanes和biBitCount分别设置为1和24的原因。  那这里不会有错

按照norains成功的范例来看整个流程应该是这样的
以下介绍有C的有汇编的混杂在一起 大家能懂这个意思就行 懒得move eax了 原谅我
1.首先要GetDC返回值传给hDc
HDC hDc = GetDC(NULL);
2. 然后以hDc为参数创建兼容的缓存DC 返回值为MemDc
MemDc= CreateCompatibleDC(hDc);
你问我什么是缓存DC 我现在也没参悟出这是什么鬼
3. 然后要用函数CreateDIBSection 这一步非常重要
invoke CreateDIBSection,MemDc,addr bi,DIB_RGB_COLORS,addr Data,NULL,0 ;OK
这里引用norains的描述
Data是分配的一个内存空间,将来用来存储HDC的内容,只不过现在一切都是空的。如果你将这数据保存出来,你会发现一团漆黑。
4. 将HBITMAP和HDC结合:
invoke SelectObject,MemDc,hBmp ;将HBITMAP和HDC结合: 至此为止,我们前期工作已经准备就绪,我们只需要将HDC的内容用BitBlt绘制到缓存中即可:
5. invoke BitBlt,MemDc, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight,hDc, 0, 0, SRCCOPY
;在调用该函数之后,Data所指向的内存缓冲区已经改变 这点我们下篇用debug的方式去验证

上面1到5的步骤完整代码如下

     invoke GetDC,NULL
     mov hDc,eax
     invoke CreateCompatibleDC,hDc
     mov MemDc,eax
     invoke CreateDIBSection,MemDc,addr bi,DIB_RGB_COLORS,addr Data,NULL,0 ;OK
     ;Data是分配的一个内存空间,将来用来存储HDC的内容,只不过现在一切都是空的。如果你将这数据保存出来,你会发现一团漆黑。
     mov hBmp,eax
     invoke SelectObject,MemDc,hBmp ;将HBITMAP和HDC结合: 至此为止,我们前期工作已经准备就绪,我们只需要将HDC的内容用BitBlt绘制到缓存中即可:
     invoke BitBlt,MemDc,   0,   0,   bi.bmiHeader.biWidth,   bi.bmiHeader.biHeight,hDc,   0,   0,   SRCCOPY 
        ;在调用该函数之后,Data所指向的内存缓冲区已经改变
     invoke ReleaseDC,NULL,   hDc
     invoke DeleteDC,MemDc      

到了这里 Data所指向的内存缓冲区已经改变。是的,没错,这些改变的数据就是我们所需要的。接下来我们所需要做的仅仅是,将这数据按BMP文件的格式,保存下来即可。 By Norains
真的吗 我怎么感觉有点不踏实呢
看起来 raiky的第一个函数其实已经完成了截图的大部分啊为什么大费周章的写那么长的第二个函数呢 这里先不管了

心里有点不塌实 我觉得还是用debug的软件实际查看下内存的内容来验证下实际状况到底怎么样吧 请看下篇

版权声明:本文为博主原创文章,未经博主允许不得转载。

win32汇编 屏幕截图保存BMP 学习笔记<第一篇>之资料搜集

背景 本人刚自学编程不久 会有很多初级错误 绕了很多弯路 记录下来也分享给各位网友 如有指教请在评论区留言 请轻拍 最近在做软件屏幕识别 考虑到计时效率选择了win32汇编 (其实是因为我还没有...
  • ppluer
  • ppluer
  • 2016年05月12日 12:10
  • 657

win32汇编 屏幕截图保存BMP 学习笔记<第三篇>之odbg调试

我们来回顾下raiky code 根据帖子里的讨论错误的疑点在于 1. 对每个像素所占字节的估算可能有误 wBitCount;位图中每个像素所占字节数 简单的赋值4 2. 涉及到后面的调色板的...
  • ppluer
  • ppluer
  • 2016年05月12日 12:52
  • 647

Win32汇编学习笔记(罗云彬)(二)

1.代码段的属性是由PE头部中的属性位决定的,通过编辑exe文件,把代码段的属性位改为可写,程序就允许修改自己的代码段。典型的应用如:这对可执行文件的压缩软件和加壳软件。 2.堆栈段的内存属性是可读...

win32汇编学习笔记3

分析简单的win32程序格式 根据以前的小程序样式来简单分析一下: .386 .model flat,stdcall   这一句是定义内存方式,语言格式 .option casemap:nom...

win32ASM截图保存为BMP

  • 2016年05月13日 16:05
  • 3KB
  • 下载

win32画图程序 可保存bmp 截图

  • 2017年05月21日 18:19
  • 15.42MB
  • 下载

Win32汇编学习笔记之基础篇

基础篇 第一章 背景知识 1.1 Win32的软硬件平台 1.1.1    80x86系列处理器简史 Win32可以在多种硬件平台上运行,但使用最广泛的硬件平台是基于In...

win32学习笔记

  • 2012年10月30日 21:33
  • 61KB
  • 下载

cocos2d-x学习笔记06:如何将win32移植到android

cocos2d-x学习笔记06:如何将win32移植到android 本文主要讨论如何将一个win32项目,移植到android上面,网上很多文章说的不一样,因为cocos2d-x的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:win32汇编 屏幕截图保存BMP 学习笔记<第二篇>之东拼西凑
举报原因:
原因补充:

(最多只允许输入30个字)