首款WindowsPhone 7 PC端实时截图工具诞生攻坚实录(一)

这是首款WindowsPhone 7 PC端实时截图工具,能够实时显示Windows Phone真机中的界面!

安装包下载:https://files.cnblogs.com/rupeng/ScrnMonitor20110620.zip
安装方法:

1、首先把手机连接到电脑上,并且启动Zune,将电脑和手机设置为Connected状态。
2、ItcastWPDevPC20110620.zip 是PC端程序,启动ItcastWPDev.exe,设置监听端口后点击【Start】启动监听。
3、WP7ScreenMonitorAgent.xap是手机端程序。安装后启动“ScreenMonitor”,设置服务器IP和端口后点击【Start】启动手机端监听即可。如果要退出程序进入Tile主页面或者进入别的程序,那么需要按Home键,也就是Windows徽标键来回到Tile主页面,不要按后退键退出程序,否则监听进程会退出。

下面开始正题,这么多年没熬过夜了,这次我连续四天熬夜到3点多终于搞出来了这款工具,遂写下战斗日记。PS:不要熬夜,真的伤身体。
一、有需求才能有产品——“学生说:要有是实时截图工具!所以就有了截图工具。”
虽然说通过模拟器基本能够让学生理解Windows Phone手机,不过如果能让学生看到真机那感觉还是不一样的。如何把Windows Phone真机的屏幕展示给讲台下的学生看就成了必须解决的问题,曾经想着用电脑摄像头照手机的屏幕,但是反光问题很难解决,而且手在操作触摸屏的时候就会遮挡屏幕,因此需要一款通过程序来截取真机屏幕显示到PC上的工具。

二、解决后台截屏问题——稳扎稳打
“不要重复造轮子”,我先到网上搜索是否有了类似的工具,网上的资料都是关于截取程序截图的,我想要一个也能截取手机中其他的程序界面的工具。最终找到一款牛人fiinix开发的“CSharp DllImport”,这个工具中提供了后台截屏的功能,开启程序以后进入到要截屏的界面按下拍照键就可以将当前界面的截图保存到MediaLibrary中,就是它了!


不要小看这款工具,熟悉Windows Phone的开发人员看到它绝对有“它打开了通向Windows Phone未知领域的大门”,为什么这么说呢?首先看“后台”功能,众所周知,在Mango之前WP7是不支持多任务的,因此一旦离开程序进入别的程序,那么当前的程序就会被结束掉了。“CSharp DllImport”使用的是网上流传的《修改注册表让WP7支持多任务》的方法来避免离开程序比较程序被结束的问题。“CSharp DllImport”中启动一个无限循环的后台线程,不断检测手机的按键状态,如果用户按下了拍照键,则会自动进行系统截屏。问题又来了,Windows Phone中只能对本程序的界面进行截图,是没有提供全屏截屏的功能,对Windows Mobile、Windows CE的朋友可能会说“那调用GDI来截图不就行了吗?”,不幸的是,Windows Phone中不支持PInvoke机制的,也就是无法编写调用GDI等win32 dll中的函数的代码,更不能调用自己用C/C++写的dll。

“Windows Phone中不支持PInvoke机制”这句话只是给你我这等菜鸟听的,牛人从来不相信。有牛人发现了《在Windows Phone中调用win32 dll的方法》,原理就是微软的Microsoft.Phone.InteropServices.dll中的ComBridge类提供了RegisterComDll方法用来注册一个Com组件到WP7系统中,这样将Native代码写成一个Com组件,然后通过RegisterComDll注册到系统中即可。神奇的大门打开了!!!

Windows Phone底层仍然是Windows CE,可以把Windows Phone看成Windows CE上运行的一个大软件,就像当年的Windows 3.1是DOS上运行的一个软件一样,因此我们就可以用支持Windows CE开发的平台开发出Com组件,可以调用任何的Windows CE的SDK,然后放到Windows Phone中去执行。


使用ComBridge调用VC编写的Dll的几个关键点,这块开发要涉及到Com组件的开发以及Interop的知识,这块知识不是这篇文章能覆盖的,因此如果您不熟悉Com这个.Net的老祖宗,那么可以不用看,也不影响你对于整体架构的理解。
1)在VC中创建一个Com项目。注意如果要运行在HTC等Arm CPU的真机上时,需要构建ARM平台的二进制代码,如果要在Windows Phone7模拟器上运行的时候则需要构建为X86的平台,因为XDE是X86的CPU。
把Com组件生成的dll每次修改Com组件并且编译通过后都要拷到WindowsPhone项目中。为方便调试,建议将Com项目的输出路径指向Windows Phone项目,这样避免了把生成的dll拷来拷去的麻烦。

2)添加WMAppManifest.xml 到Windows Phone项目根目录下内容为:
<?xml version="1.0" encoding="utf-8" ?>
<Interop>
</Interop>

3)修改Windows Phone项目的WMAppManifest.xml文件,在Capabilities节点下增加
<Capability Name="ID_CAP_INTEROPSERVICES" />
也就是给程序INTEROP的能力。

4)在使用组件之前(比如程序启动的时候、类的Static初始化中)调用RegisterComDll方法用来注册Com组件
例子:ComBridge.RegisterComDll("Network.dll", new Guid("0111B877-9EE5-45ba-800E-CF324B5552C7"));
Network.dll 为Com组件的dll文件名,"0111B877-9EE5-45ba-800E-CF324B5552C7"为组件实现类的Guid。

5)在Windows Phone中声明对应的实现类和接口,使用ComImport标记类和接口,例如:
    [ComImport, Guid("0111B877-9EE5-45ba-800E-CF324B5552C7"),
    ClassInterface(ClassInterfaceType.None)]
    internal class NetworkClass
    {
    }
   
    [ComImport, Guid("25CC9D0F-CA11-4DED-8019-BC7C20CEE5D3"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface INetSockets
    {
        [PreserveSig]
        int HttpPost(string remoteServer, int remotePort, string path, IntPtr buffer, int len);
    }
    然后INetSockets socks = new NetworkClass() as INetSockets;就可以拿到组件的实例然后调用Com组件中的方法了!
   
   
    “CSharp DllImport”中使用的是CreateCompatibleDC、BitBlt等GDI方法来进行屏幕截取的,没什么特别的,不再详述。
    现在已经有很多基于这个机制的WP7程序了,比如注册表编辑器RegistryEditor、TouchXPlorer、Yaaf.Wp7.AdvancedExplorer等。
    注意使用这种方法调用Native代码是无法通过Marketplace审核的,所以这样的工具只能在越狱的机器上直接部署Xap的方式安装。
    现在Windows Phone还没有系统级别的中文输入法,我猜测也许可以将Windows CE上的中文输入法通过这样的方法移植到Windows Phone上,这样可以解决Mango之前大家用不了输入法的问题,有高人如果想做这项好事,我非常非常以及非常愿意提供帮助。

posted @ 2011-06-20 23:40  杨中科  阅读(5217)  评论(25编辑  收藏  举报