WinCam32:Window Camera for Windows Operating System

作者:马健
邮箱:stronghorse@163.net
主页:http://stronghorse.yeah.net

FAQ
快速入门
    一、用户设置   
    二、拷贝静态图形
    三、拷贝文字
    四、拷贝动态图形
密技曝光
    一、WindowFromPoint陷井
    二、非矩形窗口及图形的拷贝
    三、DIB vs. DDB
附录 版本更新记录

FAQ

Q:WinCam32是什么?
WinCam32是一个屏幕捕捉软件,能够实现如下功能:

  1. 捕捉屏幕上的静态图形,将结果以位图(Bitmap)格式存入剪贴板(clipboard),或以PNG、BMP格式存为磁盘文件。该静态图形可以是某个窗口的显示区,也可以是屏幕上任意指定的一个矩形区。在98/Me/NT/2k/XP下,可以指定是否捕捉光标。
  2. 捕捉屏幕上的动态图形,将结果存入指定的AVI文件。
  3. 捕捉控件文字、窗口标题,将结果以文本(text)格式存入剪贴板。这个功能其实就是Windows API中的GetWindowText功能,在MSDN中对此函数的描述如下:The GetWindowText function copies the text of the specified window's title bar (if it has one) into a buffer. If the specified window is a control, the text of the control is copied. 因此不要指望它象金山词霸一样能将任何窗口的内容都抓出来,不过抓抓对话框中的内容还是可以的(最初的WinCam16位版就是为写软件说明书而设计的)。另外也可以用来抓对话框中被*号遮住的密码,在Windows 2000、Windows XP下也能用,但是网页中的密码还无法抓到。

Q:WinCam32收费吗?
A:WinCam32是一个“友情软件”(Friendware),用户在承诺不用于商业目的,也不对文件及其附件进行任何更改的条件下,不需要为使用该软件负任何费用,最多是在年节时给我发个email问声好(所以叫“友情软件”)。我承诺绝不在程序中暗藏任何商业广告、木马,但不承诺为使用WinCam32的后果承担任何责任。如果您需要将它用于商业目的,或加入您的网站,请与我联系,否则保留追究一切责任的权利。

Q:如何在Word文件中嵌入高质量、低容量的界面图片?
A:在写软件使用说明书时,需要在Word文档中嵌入大量界面截图,如果图片格式不合适,会导致Word文件急剧膨胀,不仅浪费空间,而且降低操作速度。下面分别讨论常见的几种方法:
1、直接将界面截到剪贴板,然后粘贴到Word文档中,这是最常用的方法。由于这种方式粘贴的是未压缩的BMP格式图片,因此文件长度也是最大的,很快就可以达到MB级。
2、先将界面截图存为高压缩比的JPEG、GIF、PNG文件,然后在Word中选择“插入->图片->来自文件”,插入图片。这种方式可以有效抑止文件长度的膨胀。在这几种文件格式中,JPEG一般适用于表现自然图片,表现软件界面的时候会在文字边缘产生碎片;GIF适合表示256色图片,对通常高彩下截获的界面表现不佳;PNG可以完整表达真彩界面,而且不会出现JPEG有损压缩造成的碎片,压缩率也不错,因此是最适合存储界面截图的文件格式。
因此,最适合的操作方式是:进入WinCam32的Option界面,选择“Save result into file”和“Overwrite the same file”,然后选择选择目标PNG文件的存放路径,点OK返回。以后截取界面后将PNG文件插入Word文档即可。

快速入门

一、用户设置

本软件的大部分功能依赖于用户设置,包括激活各功能的热键、存盘路径等。因此如果忘了怎么用本软件,只需将用户设置界面调出即可。

为了显示用户设置界面,请将鼠标光标移动到屏幕右下角的WinCam32图标上,单击鼠标右键,在弹出的菜单中选择Option项,系统将显示Option对话框,供用户进行设置。各设置项的含意参见下面的说明。


二、拷贝静态图形

  1. 纯鼠标操作:单击屏幕右下角Tray区域的WinCam32图标,系统显示一个有眼睛图案的小方框;将鼠标光标移动到眼睛图案上,按下鼠标左键,这时鼠标光标也变成眼睛形状;按住鼠标左键,拖动鼠标,则系统自动将鼠标所在的窗口区域加框显示;当欲拷贝的区域加框显示时,放开鼠标左键拷贝图形,或单击鼠标右键放弃拷贝。
  2. 热键操作:按下在Option对话框中指定的热键(缺省为Ctrl+Print Screen),屏幕会闪一下,然后将鼠标所在的窗口区域加框显示。这时如果要拷贝的是窗口图形,则将鼠标光标移动到该窗口上,单击鼠标左键;如果要拷贝的是一个自定义的矩形区,则按住鼠标左键,拖动鼠标选择矩形区,再放开鼠标左键进行拷贝;单击鼠标右键则取消拷贝。
  3. 固定区域的连续拷贝:先在Option对话框中指定热键(缺省为Print Screen)及矩形区(通过Browse按钮选择,选择过程同上),以后每次按下热键均将该矩形区域拷贝到剪贴板或文件,类似于高档相机的连续拍摄功能。
  4. 将拷贝结果存入磁盘:选中Option对话框中的“Save Result into File”复选框(checkbox),然后选择存盘方式:

a. Overwrite the same file(所有图片保存到同一个文件,新的覆盖旧的)
按“...”按钮选择存盘路径。
b. Save into files(顺序保存,自动编号)
按“...”按钮选择存盘目录,填写Prefix(文件名前缀)、Base Number(文件名编号的起始数字)、Digits(文件名中数字的位数),选择Type(文件类型),则以后每次拷贝静态图形的结果均自动存入磁盘文件,文件自动顺序编号。

如果不需要存盘,只需清除“Save Result into File”复选框即可。

如果Option对话框中的“Include Cursor”项被选中(缺省未选中),则拷贝的静态图形上会带光标,否则没有光标。

“纯鼠标操作”与“热键操作”的区别:

  1. “纯鼠标操作”只有在任务条(task bar)可见时才能使用,如果任务条被某个全屏幕窗口挡住则不能使用;“热键操作”不受任务条的限制。
  2. “纯鼠标操作”只能拷贝某个窗口所占据的矩形区,“热键操作”可以拷贝任意指定的矩形区。
  3. “纯鼠标操作”与“热键操作”使用不同的算法来判断鼠标所在的窗口,详见“密技曝光”部分。总的来说,前者可能识别不出某些窗口,后者则是“宁枉勿纵”。
  4. 为了防止重复拷贝,“热键操作”时在按下第一次按键后,系统延迟2秒再开始检测下一次按键,这期间的所有按键均视为无效。

注意:
在存盘时,系统没有对“磁盘满”等错误进行处理,因此请您在选择存盘目录时注意确保该路径所在磁盘具有足够的剩余空间,并且您具有在该目录中创建、写入文件的权限。

三、拷贝文字

  1. 纯鼠标操作:同“静态图形拷贝”,但是在按下鼠标左键时需先按住Ctrl键。
  2. 热键操作:同“静态图形拷贝”,但是在按下鼠标左键时需先按住Ctrl键。如果选择的是一个任意矩形,而不是某个窗口,则操作无效。

四、拷贝动态图形

在Option对话框中:

  1. 按“Save AVI into”旁边的Browse按钮输入AVI文件路径。注意:在存盘时,系统没有对“磁盘满”等错误进行处理,因此请您在选择时注意确保该路径所在磁盘具有足够的剩余空间,并且您具有在该目录中创建、写入文件的权限。
  2. 按“AVI Rectangle”旁边的按钮选择欲拷贝的动态图形所在的矩形区。
  3. 设置“AVI Rate”(AVI的帧频率)。
  4. 如果需要手工决定开始、结束拷贝的时间,则设置“Copy Manually”框中的开始、结束热键。以后按下开始热键则开始拷贝,按下结束热键则结束拷贝。如果不按结束热键,则30秒后系统自动结束拷贝。
  5. 如果需要拷贝预定长度的动态图形,请设置“Copy Automatically”框中的开始热键,及拷贝时间长度。以后当按下开始热键则开始拷贝,拷贝到预定长度则自动结束。


密技曝光

一、WindowFromPoint陷井

在WinCam32中,有一个很基本的操作就是判断当前鼠标光标所在的窗口。Microsoft自己提供的抓图例子(源代码可在MSDN中找到)用的是WindowFromPoint函数。在MSDN中对该函数有如下描述:

The WindowFromPoint function does not retrieve a handle to a hidden or disabled window, even if the point is within the window. An application should use the ChildWindowFromPoint function for a nonrestrictive search.

而在MSDN中对ChildWindowFromPoint函数的描述是:

The ChildWindowFromPoint function determines which, if any, of the child windows belonging to a parent window contains the specified point.

Remarks

The system maintains an internal list, containing the handles of the child windows associated with a parent window. The order of the handles in the list depends on the Z order of the child windows. If more than one child window contains the specified point, the system returns a handle to the first window in the list that contains the point.

这实际上是一种深度优先的一般树遍历算法。对于用VB等基于控件的编程工具开发的界面,由于窗口之间的Parent-Child关系非常严格,因此这种算法一般不会出问题。但是对于VC等对Parent-Child关系要求不严格的开发工具开发的界面,则可能产生问题。

例如,如果已经定义了一个Frame,如Wincam32的Option对话框中的Option For Capturing AVI框,现在要在它里面再定义一个Frame,如Wincam32的Copy Manually框,对于VB来说,应该先定义地一个框,然后在它里面再放置第二个框,及包含在第一个框中的其它控件,它们的Parent Window均为第一个框(移动Parent Window时Child Window跟着动)。但对于VC则没有这个要求,第一个框和它里面的所有控件可以没有Parent-Child关系,这样如果第一个框的TAB Order小于它内部的某个控件(即Z order大于该控件),当鼠标光标移动到该控件上时,按WindowFromPoint和ChildWindowFromPoint函数的遍历顺序,根本不能识别出鼠标正落在控件上,而是识别为落在外框上。

著名的ACDSee软件的About对话框也包含这种情况,有兴趣的读者可以一试。

为了解决这个问题,在WinCam32中提出了一种新的识别方法,其准则说穿了只有一句:宁可错杀三千,决不放过一个。

由于这些方法都各有优缺点,因此在WinCam中两种方法都采用了,其中“纯鼠标操作拷贝静态图形”调用的是WindowFromPoint函数,“热键操作拷贝静态图形”及Option对话框中的Browse按钮用的是WinCam32自己的识别函数。谁有兴趣的话可以比较二者的差别。

二、非矩形窗口及图形的拷贝

目前随着GUI技术的发展,开始出现一些基于非矩形窗口(如一幅扫描进去的BMP,带透明色)的应用程序。在解决对GetWindowRgn函数的调用问题之前,WinCam还不能识别这些窗口的透明区域,仍然按这些窗口的原始矩形区域进行识别。

目前的WinCam32中还不支持对非矩形区域的拷贝,未来可预见的版本也不打算支持。如果真的有这项需要,建议您选择一个好一点的图像处理软件。

三、DIB vs. DDB

WinCam所处理的动态和静态图形均为Bitmap格式,而Bitmap又分为DIB和DDB两种,在MSDN中对它们的解释是:

device-independent bitmap (DIB)
An array of bits combined with several structures that specify the width and height of the bitmap image (in pixels), the color format of the device where the image was created, and the resolution of the device used to create that image. A DIB generally has its own color table, and can therefore be displayed on a variety of devices.
device-dependent bitmap (DDB)
An array of bits that can only be used with a particular display or printer.

DIB由于自带颜色表,理论上说在不同的设备上显示时均可按原来的颜色还原显示,或仿真显示,但是很明显颜色表需要消耗一定的存储空间,并且在每次显示时均要对颜色进行处理,因此速度较慢。DDB由于直接对颜色位平面进行记录,因此显示速度最快,但是在不同的设备上显示时不能保证颜色的还原。

一般来说,在剪贴板中存放的是DDB,在文件中存放的是DIB。AVI文件由于需要在不同的设备上播放,因此存放的是一系列DIB,每一张DIB就是一帧图像。

WinCam32直接从屏幕上获取的是DDB,在存为BMP和AVI文件时再调用相应的函数将DDB转换为DIB。在MSDN和一些BBS中均给出了将DDB转换为DIB的算法和代码,但是这些代码对256色的转换总是不能令人满意,在MFC Programmer's SourceBook网站的一篇文章中给出了如下解释:

It should be noted that on 256 color display, the colors of the DDB may not be written
correctly to the color table. This is because may display drivers use an internal 256
color palette for calls to GetDIBits. The only reliable work around that I know of for
this situation is to always request a 24-bit DIB to be created. This will always have
the correct color values generated.

但是Windows自带的“画图”程序在这方面解决得很好,因此如果有这方面的需要,可以先用WinCam捕捉图形,存入剪贴板(DDB格式),然后复制到“画图”程序,再选择“编辑->复制到”菜单,复制为磁盘文件。

附录 版本更新记录

Version 2.00
功能增强:除原有的Edit、RichEdit外,文字拷贝还可以拷贝SysListView32、SysHeader32、SysTreeView32、ComboBox、ListBox中的内容。
去掉所有DLL,采用更安全的方式实现文字拷贝、全局快捷键。

Version 1.14
错误修正:在“待机”后再恢复,屏幕右下角图标消失。

Version 1.13
在Option对话框中增加“Include cursor”项。如果此项被选中(缺省未选中),则拷贝的静态图形上会带光标,否则没有光标。

Version 1.12
1、截屏文件可以保存为PNG格式。
2、文件可以顺序编号,也可以反复覆盖同一个文件。