收藏 分享(赏)

C#调用windowsAPI入门.doc

上传人:hwpkd79526 文档编号:7221916 上传时间:2019-05-10 格式:DOC 页数:117 大小:1.46MB
下载 相关 举报
C#调用windowsAPI入门.doc_第1页
第1页 / 共117页
C#调用windowsAPI入门.doc_第2页
第2页 / 共117页
C#调用windowsAPI入门.doc_第3页
第3页 / 共117页
C#调用windowsAPI入门.doc_第4页
第4页 / 共117页
C#调用windowsAPI入门.doc_第5页
第5页 / 共117页
点击查看更多>>
资源描述

1、使用 C#调用 windows API 入门(一)一:入门,直接从 C# 调用 DLL 导出其实我们的议题应该叫做 C#如何直接调用非托管代码,通常有 2 种方法: 1 直接调用从 DLL 导出的函数。 2 调用 COM 对象上的接口方法我主要讨论从 dll 中导出函数,基本步骤如下:1使用 C# 关键字 static 和 extern 声明方法。 2将 DllImport 属性附加到该方法。DllImport 属性允许您指定包含该方法的 DLL 的名称。3如果需要,为方法的参数和返回值指定自定义封送处理信息,这将重写 .NET Framework 的默认封送处理。好,我们开始1首先我们查询

2、MSDN 找到 GetShortPathName 的定义The GetShortPathName function retrieves the short path form of the specified path.DWORD GetShortPathName(LPCTSTR lpszLongPath,LPTSTR lpszShortPath,DWORD cchBuffer);2查找对照表进行数据类型的转换(出处:http:/ )Data TypesWin32 Types Specification CLR Typechar, INT8, SBYTE, CHAR 8-bit signed

3、integerSystem.SByteshort, short int, INT16, SHORT16-bit signed integerSystem.Int16int, long, long int, INT32, LONG32, BOOL , INT 32-bit signed integerSystem.Int32_int64, INT64, LONGLONG64-bit signed integerSystem.Int64unsigned char, UINT8, UCHAR , BYTE8-bit unsigned integerSystem.Byteunsigned short,

4、 16-bit unsigned System.UInt16Win32 Types Specification CLR TypeUINT16, USHORT, WORD, ATOM, WCHAR , _wchar_tintegerunsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT32-bit unsigned integerSystem.UInt32unsigned _int64, UINT64, DWORDLONG, ULONGLONG64-bit unsigned integerSystem.UInt64

5、float, FLOAT Single-precision floating pointSystem.Singledouble, long double, DOUBLEDouble-precision floating pointSystem.Double In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type devoted to this meaning.3调用 GetShortPathName 这个 API,简单的写法

6、如下(编译通过的话),using System;using System.Runtime.InteropServices;public class MSSQL_ServerHandlerDllImport(“kernel32.dll“)public static extern int GetShortPathName(string path,StringBuilder shortPath,int shortPathLength)而我们之前的例子:using System;using System.Runtime.InteropServices;public class MSSQL_Server

7、HandlerDllImport(“kernel32.dll“, CharSet = CharSet.Auto)public static extern int GetShortPathName(MarshalAs(UnmanagedType.LPTStr) string path,MarshalAs(UnmanagedType.LPTStr) StringBuilder shortPath,int shortPathLength)对比可知,其中 DllImport ,static ,extern 基本上是必须有的,其他CharSet,MarshalAs ( )是可选项,在这里即使没有,程序也

8、是可以调用此 API 了。说明:1MSSQL_ServerHandler. GetShortPathName 方法用 static 和 extern 修饰符声明并且具有 DllImport 属性,该属性使用默认名称 GetShortPathName 通知编译器此实现来自 kernel32.dll。若要对 C# 方法使用不同的名称(如 getShort),则必须在 DllImport 属性中使用 EntryPoint 选项,如下所示:DllImport(“kernel32.dll“, EntryPoint=“getShort“)2 使用 MarshalAs(UnmanagedType.LPTSt

9、r)保证了在任何平台上都会得到 LPTStr,否则默认的方式会把从 C#中的字符串作为 BStr 传递。现在如果是仅含有简单参数和返回值的 WIN32 API,就都可以利用这种方法进行对照,简单的改写和调用了。二背后的原理 知其所以然,相关的知识1平台调用详原理平台调用依赖于元数据在运行时查找导出的函数并封送其参数。下图显示了这一过程。对非托管 DLL 函数的“ 平台调用 ”调用当“平台调用”调用非托管函数时,它将依次执行以下操作: 查找包含该函数的 DLL。 将该 DLL 加载到内存中。 查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据。 注意 只在第一次调用函数时,才会查找和加

10、载 DLL 并查找函数在内存中的地址。将控制权转移给非托管函数。 平台调用会向托管调用方引发由非托管函数生成的异常。2关于 Attribute(属性,注意蓝色字)属性可以放置在几乎所有声明中(但特定的属性可能限制它在其上有效的声明类型)。在语法上,属性的指定方法为:将括在方括号中的属性名置于其适用的实体声明之前。例如,具有 DllImport 属性的类将声明如下:DllImport public class MyDllimportClass . 有关更多信息,请参见 DllImportAttribute 类。许多属性都带参数,而这些参数可以是定位(未命名)参数也可以是命名参数。任何定位参数都必

11、须按特定顺序指定并且不能省略,而命名参数是可选的且可以按任意顺序指定。首先指定定位参数。例如,这三个属性是等效的:DllImport(“user32.dll“, SetLastError=false, ExactSpelling=false)DllImport(“user32.dll“, ExactSpelling=false, SetLastError=false)DllImport(“user32.dll“)第一个参数(DLL 名称)是定位参数并且总是第一个出现,其他参数为命名参数。在此例中,两个命名参数都默认为假,因此它们可以省略(有关默认参数值的信息,请参见各个属性的文档)。在一个声明

12、中可以放置多个属性,可分开放置,也可放在同一组括号中:bool AMethod(InOutref double x);bool AMethod(OutInref double x);bool AMethod(In,Outref double x);某些属性对于给定实体可以指定多次。此类可多次使用的属性的一个示例是 Conditional:Conditional(“DEBUG“), Conditional(“TEST1“) void TraceMethod() .注意 根据约定,所有属性名称都以单词“Attribute”结束,以便将它们与 .NET Framework 中的其他项区分。但是,在代

13、码中使用属性时不需要指定属性后缀。例如,DllImport 虽等效于 DllImportAttribute,但 DllImportAttribute 才是该属性在 .NET Framework 中的实际名称。3 MarshalAsAttribute 类指示如何在托管代码和非托管代码之间封送数据。可将该属性应用于参数、字段或返回值。该属性为可选属性,因为每个数据类型都有默认的封送处理行为。大多数情况下,该属性只是使用 UnmanagedType 枚举标识非托管数据的格式。例如,默认情况下,公共语言运行库将字符串参数作为 BStr 封送到 COM 方法,但是可以通过制定 MarshalAs 属性,

14、将字符串作为 LPStr、LPWStr、LPTStr 或 BStr 封送到非托管代码。某些 UnmanagedType 枚举成员需要附加信息。三:进阶,如何处理含有复杂的参数和返回值类型的 API 的调用(To Be Continue)暴强贴:从.NET 平台调用 Win32 API小序Win32 API 可以直接控制 Microsoft Windows 的核心,因为API( Application Programming Interface)本来就是微软留给我们直接控制 Windows 的接口。想玩儿吗?呵呵,太难了。C#使用非常简单,写程序就像打拱猪,Sorry -_-! ,搭积木一样简单

15、。想玩儿吗?呵呵,没办法直接控制 Windows 的核心。难道就没有两全其美的办法吗?当然不是!要不微软的产品早就没人买了。其实从 C#(或者说.NET 平台)调用 Win32 API 还是非常简单滴今天偶们大家就一起来研究研究。一. 基础知识Win32 API 是 C 语言(注意,不是 C+语言,尽管 C 语言是 C+语言的子集)函数集。C#语言与 C 语言是完全不同的(除了语法上比较像),所以,要想用 C#语言调用 C 语言的 Win32 API,要费上一番周折。首先我们就要准备一些基础知识。1. Win32 API 函数放在哪里?Win32 API 函数是 Windows 的核心,比如我

16、们看到的窗体、按钮、对话框什么的,都是依靠 Win32 函数“ 画”在屏幕上的,由于这些控件(有时也称组件)都用于用户与 Windows 进行交互,所以控制这些控件的 Win32 API函数称为“用户界面 ”函数( User Interface Win32 API),简称 UI 函数;还有一些函数,并不用于交互,比如管理当前系统正在运行的进程、硬件系统状态的监视等等这些函数只有一套,但是可以被所有的 Windows 程序调用(只要这个程序的权限足够高),简而言之,API 是为程序所共享的。为了达到所有程序能共享一套 API 的目的,Windows 采用了“动态链接库”的办法。之所以叫“动态链接

17、库 ”,是因为这样的函数库的调用方式是“随用随取” 而不是像静态链接库那样“用不用都要带上” 。这里不太好理解,不要紧,我们举个小例子。我们把 Windows 比做一个游乐场,而把在游乐场里玩儿的小孩比做一个一个程序。小孩在玩的过程中可能要喝水。我们有两个办法让小家伙们想喝水的时候就有水喝:1.给每个小家伙配一个水壶,小家伙们喝了的话就喝自己带的水;2.给游乐场配一个饮水机,谁渴了谁来喝。显然,第二个方法要好得多,这体现在三个地方。第一,带着水壶,小家伙身体不灵活、玩不爽(影响程序的速度),况且这只是带了一个水壶,要是再带上饭盒呢?还有轮滑、头盔、创可贴、纱布AK-47 My God,如果带全

18、了就赶上美国大兵了。所以游乐园里还是有个公用“仓库”要来的方便,让大家随用随取(动态链接)。第二,小家伙们带了那么多东西,占了游乐场很多地方,让游乐场拥挤不堪,别的小朋友就进不来了(程序体积大,影响程序和系统的性能)。第三,如果某件物品升级了,比如水壶从一升的改为二升的,那么每个小家伙就必须 go home 去换新的(重新编译程序,由编译器把新的静态库链接进程序主体里),而第二种情况里,只要游乐场把自己仓库里的水壶换个型号,那么所有小家伙就都在同一时间拥有了大容量的水壶。(悟空!我就一会儿不在,你怎么就乱丢东西?!打到小朋友多不好)悟空已经急了,我就不再叽叽歪歪了 呃Win32 API 函数是

19、放在Windows 系统的核心库文件中的,这些库在硬盘里的存储形式是 .dll 文件。我们常用到的 dll 文件是 user32.dll 和 kernel32.dll 两个文件,还有其它一些 dll 文件也非常重要,大家要在实践中多积累经验。我们知道 Win32 API 函数是放在 dll 文件中了,但新问题又来了我们怎么调用它们呢?这些 dll 文件是用 C 语言写的,源代码经 C 语言编译器编译之后,会以二进制可执行代码形式存放在这些 dll 文件中,就好像苹果被打碎机打成果酱后装在罐子里一样你再也分不清哪个是你 GF 给你的,哪个是你老妈给你的一样。为了能让程序使用这些函数,微软在发布每

20、个新的操作系统的时候,也会放出这个系统的 SDK,目前最新的是 Win2003 SP1 SDK,据说 Vista 的马上就要放出来,而且已经把 UI 的 API 从核心库中分离出去以提高系统的稳定性了。SDK 里有一些 C 语言的头文件(.h 文件),这些文件里描述了核心 dll 文件里都有哪些 Win32 API 函数,在写程序的时候,把这些.h 文件用#include“.“指令包含进你的程序里,你就可以使用这些Win32 API 了。至于程序是怎样链接的,超出了本文的范围也超出了本人的知识范围:D至此,如果你是 C 语言高手,已经可以使用 Windows SDK 去调教Windows 了!

21、不过,今天我们讨论的是 C#语言调用 Win32 API 的问题。我们现在已经知道 API 函数放在 dll 动态链接库文件里,也知道 C 语言怎么调用它们了,那么 C#语言怎么办呢?C# 语言是不能使用 C 语言的.h 文件的。C#语言也使用 dll 动态链接库,不过这些 dll 都是.NET 版本的,具有“自描述性”,也就是自己肚子里都有哪些函数都已经写在自己的 metadata 里了,不用再附加一个.h 文件来说明。现在,我们已经找到了问题的关键点:如何用 .NET 平台上的 C#语言来调用 Win32 平台上的 dll 文件。答案非常简单:使用DllImport 特性。二. 小试牛刀下

22、面,就让我们写一个小程序,试一试如何用 C#语言和 DllImport 特性来调用 Win32 API。using System;using System.Runtime.InteropServices;class ProgramDllImport(“User32.dll“)public static extern int MessageBox(int h, string m, string c, int type);static int Main()MessageBox(0, “Hello Win32 API“, “水之真谛“, 4);Console.ReadLine();return 0;

23、新建一个 C#的控制台程序,把 VS 自动生成的代码清空,把上面的代码Copy 过去就可以编译执行了。让我们剖析一下这个程序:1. 要使用 DllImport 这个特性(特性也是一种类),必须使用这一句 using System.Runtime.InteropServices;,导入“运行时 -交互服务”。喔 运行时的交互服务不就是 “动态链接”吗?感谢 Microsoft!2. 然后我们就可以制造一个 DllImport 类的实例,并把这个实例绑定在我们要使用的函数上了。“特性类” 这种类非常怪制造类实例的时候不使用MyClass mc = new MyClass();这种形式,而是使用特性

24、类(参数列表)这种形式;特性类不能独立存在,一定要用作修饰其它目标上(本例是修饰后面的一个函数),不同的特性可以用来修饰类、函数、变量等等;特性类实例在被编译的时候也不产生可执行代码,而是被放进 metadata 里以备检索。总之,你记住特性类很怪就是了,想了解更多就查查 MSDN,懒得查就先这么记不懂惯性定律不影响你学骑自行车。DllImport(“User32.dll“)是说我们要使用的 Win32 API 函数在 User32.dll 这个文件里。问题又来了:我怎么知道那么多 API 函数都在哪个 dll 文件里呢?这个你可以在 MSDN 里查到,位置是Root-Win32 and CO

25、M Development-Development Guides-Windows API-Windows API-Windows API Reference-Functions by Category。打开这页,你会看到有很多 API 的分类,API全在这里了。打开一个分类,比如 Dialog Box,在 Functions 段,你会看到很多具体的函数,其中就有上面用到的 MessageBox 函数,点击进入。你将打开 MessageBox 的详细解释和具体用法。它的名字、返回值、参数类型尽收眼底、一览无余!而且很练英文哦在这一页的底部,你可以看到一个小表格,里面有一项“Minimum DLL

26、 Version user32.dll”就是说这个函数在 user32.dll 里。3. 接下来就是我们的函数了。在 C#里调用 Win32 函数有这么几个要点。第一:名字要与 Win32 API 的完全一样。第二:函数除了要有相应的DllImport 类修饰外,还要声明成 public static extern 类型的。第三:也是最变态的一点,函数的返回值和参数类型要与 Win32 API 完全一致!这可难煞我们这群初学者Win32 的数据类型比较搞怪,比如什么 LPSTR、什么HINSTANCE 都是些虾米东东呢?给大家一个小参考,我的 Blog 里有Windows 数据类型探幽千回百转

27、你是谁? 系列拙文,可以查一下。另外在此,我从 MSDN 里摘出一张表来,是常用 Win32 数据类型与.NET 平台数据类型的对应表:Figure 2 Non-Pointer Data TypesWin32 Types Specification CLR Typechar, INT8, SBYTE, CHAR 8-bit signed integer System.SByteshort, short int, INT16, SHORT16-bit signed integer System.Int16int, long, long int, INT32, LONG32, BOOL, INT

28、32-bit signed integer System.Int32_int64, INT64, LONGLONG64-bit signed integer System.Int64Win32 Types Specification CLR Typeunsigned char, UINT8, UCHAR, BYTE8-bit unsigned integer System.Byteunsigned short, UINT16, USHORT, WORD, ATOM, WCHAR, _wchar_t16-bit unsigned integerSystem.UInt16unsigned, uns

29、igned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT32-bit unsigned integerSystem.UInt32unsigned _int64, UINT64, DWORDLONG, ULONGLONG64-bit unsigned integerSystem.UInt64float, FLOAT Single-precision floating pointSystem.Singledouble, long double, DOUBLEDouble-precision floating pointSystem.Double

30、In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type devoted to this meaning.有了这些东西,我们就能把一个 Win32 API 函数转成 C#函数了。还拿MessageBox 函数为例(看刚才给出的函数表),它的 Win32 原形如下:int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );函数名:Mess

31、ageBox 将保持不变。返回值:int 将保持不变(无论是 Win32 还是 C#,int 都是 32 位整数)参数表:H 开头意味着是 Handle,一般情况下 Handld 都是指针类型,Win32 平台的指针类型是用 32 位来存储的,所以在 C#里正好对应一个 int整型。不过,既然是指针,就没有什么正负之分,32 位都应该用来保存数值这样一来,用 uint(无符号 32 位整型)来对应 Win32 的 H 类型更合理。不过提醒大家一点,int 是受 C#和.NET CLR 双重支持的,而 uint 只受 C#支持而不受.NET CLR 支持,所以,本例还是老老实实地使用了 int

32、型。(肚子饿了再坚持坚持)至于 LPCTSTR 是 Long Pointer to Constant String 的缩写,说白了就是字符串。所以,用 C#里的 string 类型就对了。修饰符:要求有相应的 DllImport 和 public static extern经过上面一番折腾,Win32 的 MessageBox 函数就包装成 C#可以调用的函数了:DllImport(“User32.dll“)public static extern int MessageBox(int h, string m, string c, int type);好人做到底,我把四个参数的用处也说一下:第

33、一个:弹出的 MessageBox 的父窗口是谁。本例中没有,所以是 0,也就是“空指针”。第二个:MessageBox 的内容。本例中是“Hello Win32 API”。第三个:MessageBox 的标题。本例中用的是本人 Blog 的名字水之真谛请大家不要忘记。第四个:MessageBox 上的按钮是什么,如果是 0,那就只有一个OK,MessageBox 太短了,你将看不全“ 水之真谛”四个字,于是偶改成了4,这样就有两个按钮了。这些在 MSDN 的函数用法里都有。不过,我还是非常推荐您阅读一下本人的另一篇拙作一个 Win32 程序的进化 。至此,一个麻雀虽小、五毒俱全Sorry -

34、_-! 五脏俱全的 C#调用Win32 API 的程序就分析完了。原理并不难吧!应届生拿去蒙 HR 足够了!真正见功底的地方是你使用 MSDN、SDK 、.NET Framework 类库 VC/VC#的熟练程度。相信我MSDN+SDK+VC/C# 绝对足够把 Windows 收拾得服服帖帖了:D三. 真的有必要吗?嘿嘿嘿嘿 看我的表情,我在坏坏地笑哦!你们都上当啦!操作Windows 的底层不一定都要调用 Win32 API 滴 (哪儿来的砖头!)我想说的是:.NET Framework 是对 Win32 API 的良好封装,大部分 Win32 API 函数都已经封装在了.NET Frame

35、work 类库的各个类里了。如果说 Win32 API 函数是散落在地上的珍珠的话,那么.NET Framework 就是把这些珍珠按种类分放到了各个抽屉里让我想起我妈来了我的书放得满地满床的时候我总是能找到,她一收拾我就再也找不到了,郁闷。唉没办法,我们还是仔细把.NET Framework 类库好好翻翻吧,会有很多惊喜哦!最后,用一个例子结束我们的文章吧!例子是这样滴那是在很久很久以前,我给一个公司写程序用来控制用户登录,在登录之前,用户不能把鼠标移出登录窗体,因为要控制鼠标,所以我首先想起了调用 Win32 API 中与 Cursor 相关的函数来于是不管三七二十一、花了九牛二虎之力调用

36、了 Win32 API 中的 ClipCursor()这个函数,效果还不错。结果前两天翻 .NET Framework 类库的时候,发现System.Windows.Forms.Cursor 类的 Clip 属性就是专门做这个用的!差点没把鼻子气歪了请大家自己动手创建一个 C#的 Windows 程序,把下面的核心代码贴到主窗体的双击事件里,试一试。做这个例子的目的就是要告诉大家:1.对类库的了解程序直接决定了你编程的效率和质量用类库里的组件比我们“从轮子造起 ”要快得多、安全得多。 2.不到万不得已,不要去直接调Win32 API 函数那是不安全的。private void Form1_Do

37、ubleClick(object sender, EventArgs e)Rectangle r = new Rectangle(this.Left, this.Top, this.Width, this.Height);System.Windows.Forms.Cursor.Clip = r;最后,大家一定非常想知道,.NET Framework 都为我们封装好了哪些Win32 API,OK ,MSDN 里有一篇文章,专门列出了这些。文章的名字是Microsoft Win32 to Microsoft .NET Framework API Map请感兴趣的朋友自己阅读。四. 感恩新年快到了,

38、这篇文章也做为一份小小的礼物,一是博大家一乐,二是让我们永远铭记这幸福的时刻。送给对我有着知遇之恩的陆经理;送给刘莹 Lead 感谢在工作中给予的指导和支持;送给我的 Team 伙伴乐莲、王勇(Worksoft),没有你们的帮助,我是不可能开始工作的!送给我宿舍的兄弟张雄,没有你,我可能要睡在城铁站了。送给段玮和陈宁,感谢你们组织的活动和培训。送给陈曦、陈建、王勇、常勇、舜贤、挺挺、对面的女孩李芳,还有本组的 JJMM,还有小朱与你们共事是我最大的快乐!.NET Development (General) Technical Articleswindows 数据类型探幽千回百转你是谁?(1)

39、作者:未知windows data typeswindows 数据类型由微软 windows 操作系统所支持的各种数据类型是用来定义函数的返回值、函数和消息的参数以及结构体成员(因为 win32程序是用 c 语言来编写,所以没有“类” 这个概念)的。这些数据类型定义了上述元素的尺码(在内存中的,也就是占用内存的字节数)和含义。笔者以前一直不太注意这些东西,结果在程序设计时可谓步履维艰。不同类型的常/变量,在程序用扮演的角色相去甚远,了解这些类型,对剖析程序的工作原理是非常有用的。今天又是周末,我把这些类型列出来,然后把它们的“原形”也找出来是不是很像“照妖镜” 呀。下面这张表里包括这些类型:字

40、符类型(character),整数类型(integer ),逻辑值类型(布尔型,海峡那边的兄弟们喜欢叫“布林型” ,boolean),指针类型(pointer),句柄型( handle)。其中,字符类型、整数类型和逻辑值(布尔)类型是c 语言编译器通用的,也就是与标准 c 语言一样。大多数指针类型都是以 p(pointer )或者 lp(long pointer)前缀开头。 “句柄”是指被装载进内存的一个资源(本质而言就是指一定范围内的唯一编号)。下面这张表是我结合 msdn 里的资料制作的,因为自己也是初学,做的还比较粗糙,请大家多多指正 :)windows 数据类型本质类型字节数定义过程(

41、来历)含义 atomunsigned short2unsigned shortwordatom 在 atom 表中,一键(16位整数)一值(一个 string)为一个 atom。bool int*intbool 逻辑变量,布尔值 (取值为 true 或 false)booleanunsigned char1unsigned charbyteboolean 逻辑变量,布尔值 (取值为 true 或 false)byteunsigned char1unsigned charbyte 字节型,8 位。callback_stdcall 调用_stdcallcallback 回调函数的调用约定 char

42、char1charchar8 位 windows 字符(ansi)colorrefunsigned long4unsigned longdwordcolorref 红,绿,蓝(rgb )值 constconst 关键字 constconst 常量 critical_sectionrtl_critical_section 结构体?rtl_critical_section(结构)critical_sectioncritical-section 对象 dwordunsigned long4unsigned longdword32 位无符号整数dword_ptrunsigned long4unsign

43、ed longulong_ptrdword_ptr (另有其它路径)略(用处挺大,不过太长了)dword32unsigned int*unsigned intdword3232 位无符号整数 dword64unsigned _int648unsigned _int64dword6464 位无符号整数floatfloat4floatfloat 浮点数变量 haccelhaccel_结构体指针 由 declare_handle(name)宏定义的指向 haccel_结构体的指针快捷键列表的句柄 handlevoid *(一个地址) void *handle 对象的句柄 hbitmaphbitmap

44、_结构体指针 由 declare_handle(name)宏定义的指向 hbitmap_结构体的指针位图的句柄 hbrushhbrush_结构体指针 由 declare_handle(name)宏定义画刷的句柄hconvhconv_结构体指针 由 declare_handle(name)宏定义动态数据交换(dde)会话的句柄 hconvlisthconvlist_结构体指针 由 declare_handle(name)宏定义 动态数据交换(dde)会话列表的句柄 hcursorhicon_结构体指针 hicon_ *hiconhcursor 光标的句柄 hdchdc_结构体指针 由 decla

45、re_handle(name)宏定义设备上下文(dc)的句柄 hddedatahddedata_结构体指针 由declare_handle(name)宏定义 动态数据交换数据的句柄 hdeskhdesk_结构体指针 由 declare_handle(name)宏定义桌面(desktop)的句柄 hdrophdrop_结构体指针 由 declare_handle(name)宏定义handle to an internal drop structure.hdwpvoid *(一个地址) void *handlehdwphandle to a deferred window position str

46、ucture.henhmetafilehenhmetafile_结构体指针 由declare_handle(name)宏定义 增强图元文件的句柄 hfileint*inthfile 由 openfile(而不是 createfile)打开的文件的句柄.hfonthfont_结构体指针 由 declare_handle(name)宏定义字体的句柄 hgdiobjvoid near * void near *hgdiobjgdi 对象的句柄hglobalvoid *(一个地址) void *handlehglobal 全局内存块的句柄 hhookhhook_结构体指针 由 declare_hand

47、le(name)宏定义句子(hook)的句柄 hiconhicon_结构体指针 由 declare_handle(name)宏定义图标的句柄 himagelist_imagelist 结构体指针 _imagelist *himagelist 图片列表的句柄 himchimc_结构体指针 由 declare_handle(name)宏定义输入上下文的句柄hinstancehinstance_结构体指针 由 declare_handle(name)宏定义实例的句柄 hkeyhkey_结构体指针 由 declare_handle(name)宏定义(另有一条路径,一样)注册表键的句柄 hklhkl_结

48、构体指针 由 declare_handle(name)宏定义输入点标识符hlocalvoid *(一个地址) void *handlehlocal 本地内存块的句柄 hmenuhmenu_结构体指针 由 declare_handle(name)宏定义菜单的句柄 hmetafilehmetafile_结构体指针 由 declare_handle(name)宏定义图元文件的句柄 hmodulehinstance_结构体指针 hinstance_*hinstancehmodule 模块的句柄。值由模块的位置来决定。hmonitorhmonitor_结构体指针 由declare_handle(name)宏定义 显示器的句柄 hpalettehpalette_结构体指针 由 declare_handle(name)宏定义调色板的句柄hpenhpen_结构体指针 由 declare_handle(name)宏定义 画(线)笔的句柄 hrgnhrgn_结构体指针 由 declare_handle(name)宏定义区域的句柄 hrsrchrsrc_结构体指针 由 declare_handle(name)宏定义资源的句柄 hszhsz_结构体指针 由de

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报