介绍
这篇文章将示范:
- 怎样使用P/Invoke 访问非托管代码。
- 怎样使用Spy++将Windows消息载入日志,获取参数wParam,lParam的值。
- 怎样用C#实现FindWindow( )方法和SendMessage( )方法。
- 怎样和Windows Media Player互操作。
关于Win32 APIs
MSDN对Windows API的定义是这样的:
Windows API(Application Programming Interface 应用程序接口)由函数,消息,数据结构,数据类型和对它们的描述组成,可以使用这些创建在Windows环境下运行的应用程序。API 中使用最多的部分是通过Windows(操作系统)调用API函数的代码,包括: 对Windows函数的必要的声明,用户自定义的类型(作为数据结构传递给Windows函数),还有常量的声明(作为传递给那些函数或者它们的返回值)。
简单的说,Windows APIs就是嵌入微软Windows操作系统的动态链接库。因为这些库中包含了数以千计的有用的函数,因此如果在我们的代码中使用Window APIs,将大大减少开发的时间和复杂度。但这样做也有不利之处:Window APIs没有使用托管代码,而且有许多不同于Visual Studio.NET中的数据类型。.NET框架已经为我们将一部分重要的Win32 APIs包装为托管代码,而剩下的那些则需要我们在平台调用服务(Platform Invocation Service,一下称为P/Invoke)中编写托管代码来调用了。
关于平台调用服务(Platform Invocation Services,P/Invoke)
P/Invoke是这样一种机制:通过它,托管代码可以调用DLL中实现的那些非托管函数。
当调用非托管函数时,P/Invoke必须知道动态链接库的名字和它所包含的函数(或者序号)。DllImport属性用来指定DLL的位置(包含某些外部方法的实现的DLL),而该属性的参数用来详细说明一些细节,比如EntryPoint和CharSet。获得更多关于DllImport属性的信息,请参考MSDN中的DllImportAttribute类。
表1:Win32 API中常用的DLL
DLL | 描述 |
Kernel32.dll | 包含一些关于内存管理和资源处理的底层函数 |
GDI32.dll | 包含设备输出的一些图形设备接口,比如管理绘图和字体的一些接口 |
User32.dll | 包含Windows处理消息、计时、菜单、通信的函数 |
使用C# 调用Windows API的步骤
- 导入System.Runtime.InteropServices 名称空间
- 用DllImport定义函数
- 增加编码调用Win32 API
我们将通过下面的Win32类来说明怎样实现和User32.dll中的API函数有关系的FindWindow( )、SendMessage( )。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
Windows Media Player 的交互操作概念:
需要:
- Microsoft Visual Studio .NET
- Microsoft Spy++
- Windows Media Player
- 打开Spy++。
- 打开Windows Media Player,拖动窗口使Media Player 和Spy++同时可见。
- 确保Windows Media Player 没有使用“自动隐藏菜单栏”属性。
- 在工作区中选择窗口“Windows Media Player”后按下Log Messages 按钮,或者按快捷键“Ctrl+M”。
接下来,在“Message Options”对话框中切换到Messages标签页,清除所有选中的消息,在显示消息的列表框中向下滚动,选中“WM_COMMAND”,然后单击OK确定。
接下来,在Windows Media Player的菜单“Play”下选择“Stop”命令,或者按快捷键“Ctrl+S”(确保Player先前处于播放状态),Spy++ 将会记录WM_COMMAND消息。
Spy++的查看消息窗口将如下图所示。请注意,第一列显示了窗口的句柄,第二列显示了这条消息的编码,而剩下的部分则显示了消息的参数和返回值。
在这条消息上单击右键选择“属性”,就可以查看该消息的附加信息,比如wParam和lParam的十六进制值。
对于Windows Media Player中“Play”命令的消息,也可以通过重复以上步骤得到:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
使用P/Invoke和Spy++,很容易扩展包括其他一些操作的功能,比如切换、重复、调整音量等,但作为示例,我们只实现 播放/暂停 和 停止。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
结束语
我写这篇文章只是兴趣所在,尽管这不是什么新颖的想法,但我还是希望有人能发现它的用处。开始,我打算深入的研究Windows Media Player,通过FindWindowEx( )函数和ATL:SysListView32中的“Current Playlist”,在远程机器上使用WMI接口操作本机Windows Media Player的播放列表。如果谁有好的意见或者独特的想法,请联系我。
作者简介
Alexander Kent![]() | Biography in progress ;o)
|