dotNET C# Programmer’s Guide to the Win32 API (Win32 API 声明C#版)

dotNET C# Programmer’s Guide to the Win32 API (Win32 API 声明 C# 版 )

小气的神 2001.09.07

噢,对不起我用了这个标题,事实上如果我能做到 10% ,我就很高兴了。因为我的桌上正放着一本 Dan Appleman 的书,它曾伴随我许多年,也许你也有一本: 1215 页,蓝色书皮,机械工业出版社。英文名叫:《 Dan Appleman’s Visual Basic 5.0 Programmer’s Guide to the Win32 API 》。而我除了借用这个类似的名字之外,只是做了一下整理工作,不过这是一个不小的工作量 (haha)

我把 KERNEL32.DLL 、 USER32.DLL 、 GDI32.DLL 、 ADVAPI32.DLL 、 SHELL32.DLL 、 SPOOLSS.DLL 、 WINMM.DLL 的函数和声明整理了一下,改用 C# 的语法重新改写了一遍,整理出一个 C# 版本。这样针对 dotNET 的 Platform Invocation Services(PInVoke), 你就可以直接使用这些 Win32 的 API 函数了。目前 MS 没有公布整个的 Win32API 有多少可以在 dotNET 中使用,有多少不行。有些功能在 dotNET 中没有对应的实现,那么目前你可能还需要使用 Win32 的 API 函数。

结构和枚举声明放在一起, Kernel32.dll 、 User32.Dll 、 GDI32.dll 分别放在 3 个 cs 文件中;剩下的 Advapi32.dll 、 Shell32.dll 、 Spoolss.dll 、 Winmm.dll 四个 DLL 的函数放在一个 cs 文件中,整个的 namespace 起名叫 Win32API. 大致的构架应该象下面这样:

namespace Win32API {

using System;

using System.Runtime.InteropServices;

先是所有的结构和枚举声明

class Kernel32 {….}

class User32 {….}

class GDI32 {….}

class Advapi32 {….}

class Shell32 {….}

class Spoolss {….}

class Winmm {….}

}

对应的生成下面的 C# 文件 :

Structs.NET.cs

Kernel32.NET.cs

User32.NET.cs

GDI32.NET.cs

OtherFnc.NET.cs

然后编译它们,这样就可以使用它们了,我没有计算 5 个文件包括的所有的准确个数,不过应该有百个结构和枚举,上千个函数声明吧。完成这些之后,现在最常用的 MessageBox 我可以这样使用了:

using System ;

using Win32API;

public class TestWin32API

{

public static void Main ()

{

int iRet ;

iRet = User32.MessageBox( 0, "Hello C# Win32 API" , "My Pinvoke", 0 ) ;

}

}

就在测试这个例子时发生了一件有趣的事,因为刚开始我的 cs 文件都没有加 NET 的标识这样很自然的就有了 Kernel32.cs 、 User32.cs 等等, MessageBox 是 User32.DLL 中的,而我编译的 User32.cs 默认生成的也叫 User32.DLL, 当我执行这个测试程序时终于发生错误,我一直以为自己的声明有问题,然后我用 FrameworkSDK 中的例子也还是出错,直到我在其它的目录中运行正常时,我才发现原来自己的 DLL 名和系统的 DLL 名完全一样。然后就改成上面的那样,不过很奇怪 csc /t:exe /r:User32.dll TestWin32API.cs 的编译指令居然没有错误提示,真是可恶。提醒你不要也象我一样。

恶梦也许还在后面,我还不知道真正的 cs 声明中又有多少个错误,反正用到的时候再调试吧。因为太多了所以不可能全都测试,也不敢一个个的测试,只希望自己这些整理能起到抛砖引玉的作用,如果以后你有新的版本,不要忘了 Mail 一份给我。

附带的 Zip 包中有所有 cs 的源码,我在 Framework SDK Beta2 下都编译通过。

Windows 2000 ADV Server SP2 EN

Visual C# Compiler Version 7.00.9254

CLR version v1.0.2914

你可以根据你的情况进行编译(要先编译 Structs.NET.cs ,因为其它的都要 /r:Structs.NET.DLL )或者使用二进制的 DLL 。 dotnet 的编译技术很好, 5 个 DLL 加起来才 100 多 K 。

下面是一下源码的节选:


// Write by ccBoy

// Date: 2001.09.07

// csc /t:library /r:System.dll Structs.NET.cs

// csc /t:library /r:Structs.NET.dll Kernel32.NET.cs

// Emeditor 3.14

** namespace Win32API { **


** using System; **

** using System.Runtime.InteropServices; **


** [StructLayout (LayoutKind.Sequential)] **

** public class ABC { **

** public int abcA; **

** public int abcB; **

** public int abcC; **

** } **


** [StructLayout (LayoutKind.Sequential)] **

** public class ABCFLOAT { **

** public float abcfA; **

** public float abcfB; **

** public float abcfC; **

** } **


** public Class Kernel32 { **


** [DllImport("KERNEL32.DLL") ] **

** public static extern int GlobalHandle (int pMem); **


** [DllImport("KERNEL32.DLL") ] **

** public static extern int GlobalLock (int hMem); **


** [DllImport("KERNEL32.DLL") ] **

** public static extern void GlobalMemoryStatus (MEMORYSTATUS lpBuffer); **


** [DllImport("KERNEL32.DLL") ] **

** public static extern int GlobalReAlloc (int hMem, int dwBytes, int uFlags); **


** [DllImport("KERNEL32.DLL") ] **

** public static extern int GlobalSize (int hMem); **


** [DllImport("KERNEL32.DLL") ] **

** public static extern bool GlobalUnWire (int hMem); **

** } **


** public class User32 { **


** [DllImport("USER32.DLL") ] **

** public static extern bool MessageBeep (int uType); **


** [DllImport("USER32.DLL") ] **

** public static extern int MessageBoxEx (int hWnd, String lpText, String lpCaption, int uType, short wLanguageId); **


** [DllImport("USER32.DLL") ] **

** public static extern int MessageBoxIndirect (MSGBOXPARAMS anonymous0); **


** [DllImport("USER32") ] **

** public static extern int MessageBox (int hWnd, String lpText, String lpCaption, int uType); **

** } **


** pubic class Winmm { **


** [DllImport("WINMM.DLL") ] **

** public static extern int SendDriverMessage (int hDriver, int message, int lParam1, int lParam2); **


** [DllImport("WINMM.DLL") ] **

** public static extern int auxGetDevCaps (int uDeviceID, AUXCAPS pac, int cbac); **


** [DllImport("WINMM.DLL") ] **

** public static extern int auxGetNumDevs (); **


** [DllImport("WINMM.DLL") ] **

** public static extern int auxGetVolume (int uDeviceID, int[] pdwVolume); **


** [DllImport("WINMM.DLL") ] **

** public static extern int auxOutMessage (int uDeviceID, int uMsg, int dw1, int dw2); **


** [DllImport("WINMM.DLL") ] **

** public static extern int auxSetVolume (int uDeviceID, int dwVolume); **

** } **

** .,. ..,. ..,.. ..,..,.. ,. ..,. ..,.. ..,..,.. ** ** 太多太多 hahaha.. **

** } **

Published At
Categories with Web编程
Tagged with
comments powered by Disqus