如何使用C# *** 作WinAPI

如何使用C# *** 作WinAPI,第1张

在C#里调用Windows API通常使用DllImport特性来导入动态链接库(.dll),然后使用extern 关键字对函数进行修饰声明。就像这样:

[DllImport("kernel32")]

private static extern long Foo(parameters-list)

视窗 *** 作系统应用程序接口(Windows API),有非正式的简称法为WinAPI,是微软对于Windows *** 作系统中可用的内核应用程序编程接口的称法。它设计为由C/C++程序调用,而且它也是应用软件与Windows系统最直接的交互方式。而大多数驱动程序所需要的对Windows系统的更底层次访问接口,由所用版本的Windows的Native API来提供接口。 Windows有一个软件开发包(SDK, software development kit)提供相应的文档和工具,以使程序员开发使用Windows API的软件和利用Windows技术。 历史 Windows API总会为程序员提供大量的构建不同Windows的底层结构,这有助于为Windows程序员开发应用程序提供大量的灵活性和功能。但是,它同样使Windows applications要负责处理大量底层且有时是繁琐的与图形用户界面(GUI)相关的 *** 作。 Charles Petzold, 许多有关Windows API的畅销书的作者曾经说过:[1]“The original hello-world program in the Windows 1.0 SDK was a bit of a scandal. HELLO.C was about 150 lines long, and the HELLO.RC resource script had another 20 or so more lines. (...) Veteran C programmers often curled up in horror or laughter when encountering the Windows hello-world program.” —Charles Petzold, Programming Microsoft Windows with C# 常用的例子程序Hello world程序,通常是用来演示一个系统上最简单的程序(即打印一行"Hello World")。 这些年来,Windows *** 作系统已经今非昔比,而Windows API也随之改变和成长并反映出这种变化。Windows API的 Windows 1.0 版本只提供不到450个函数调用(Subroutine),而现在的版本提供了上千个。然而,整体而言,Windows接口保持了相当好的一致性,古老的Windows 1.0程序对习惯于现在版本Windows API的程序员也并不陌生。[2] Microsoft特别强调维持软件的向后兼容性。为了实现此一目标,有时微软甚至不惜支持使用了非官方乃至(编程上)非法的API的软件。Raymond Chen,一位致力于Windows API的Windows开发者,曾提及他:[3]“could probably write for months solely about bad things apps do and what we had to do to get them to work again (often in spite of themselves). Which is why I get particularly furious when people accuse Microsoft of maliciously breaking applications during OS upgrades. If any application failed to run on Windows 95, I took it as a personal failure.” —Raymond Chen, What about BOZOSLIVEHERE and TABTHETEXTOUTFORWIMPS?Windows API分类Windows API所提供的功能可以归为七类:[4] 基础服务(Base Services)[5],提供对Windows系统可用的基础资源的访问接口。比如象:文件系统(file system)、外部设备(device)、, 进程(process)、线程(thread)以及访问注册表(Windows registry)和错误处理机制(error handling)。这些功能接口位于,16位Windows下的kernel.exe、krnl286.exe或krnl386.exe系统文件中;以及32位Windows下的 kernel32.dll和advapi32.dll中。 图形设备接口(GDI)[6],提供功能为:输出图形内容到显示器、打印机以及其他外部输出设备。它位于16位Windows下的gdi.exe;以及32位Windows下的gdi32.dll。 图形化用户界面(GUI)[7],提供的功能有创建和管理屏幕和大多数基本控件(control),比如按钮和滚动条。接收鼠标和键盘输入,以及其他与GUI有关的功能。这些调用接口位于:16位Windows下的user.exe, 以及32位Windows下的user32.dll。从Windows XP版本之后, 基本控件和通用对话框控件(Common Control Library)的调用接口放在comctl32.dll中。 通用对话框链接库(Common Dialog Box Library)[8],为应用程序提供标准对话框,比如打开/保存文件对话框、颜色对画框和字体对话框等等。这个链接库位于:16位Windows下的commdlg.dll中,以及32位Windows下comdlg32.dll中。它被归类为User Interface API之下。 通用控件链接库(Common Control Library)[9],为应用程序提供接口来访问 *** 作系统提供的一些高级控件。比如像:状态栏(status bar)、进度条(progress bars)、工具栏(toolbar)和标签(tab)。这个链接库位于:16位Windows下的commctrl.dll中,以及32位Windows下comctl32.dll中。. 它被归类为User Interface API之下。

WinMain()函数等价于控制台程序中的main()函数。

该函数是执行开始的地方,也是为程序其余部分执行基本初始化工作的地方。

为了允许Windows传递数据,WinMain()函数有4个形参和一个int类型的返回值,其原型如下:

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow

)

在返回类型说明符int的后面,有一个函数说明符WINAPI。WINAPI是一个Windows定义的宏,将使系统以特定于Windows

API函数的某种特殊方式处理函数名和实参。这种方式与C++通常处理函数的方式不同。具体的细节是不重要的——这只不过是Windows所要求的方式而

已,因此只需要将WINAPI宏名称放在由Windows调用的函数名前面即可。

如果确实想要了解调用约定,就查看随Visual

C++提供的文档,文档中有对调用约定的描述。WINAPI定义为__stdcall,将此修饰符置于函数名之前表明使用的是标准Windows调用约

定。这要求参数以相反的顺序被推入栈,被调用函数结束时清除栈。本章稍后将看到的CALLBACK修饰符也定义为__stdcall,因此与WINAPI

是等价的。标准C++调用约定由__cdecl修饰符指定。

Windows传递给WinMain()函数的4个参数包含着重要的数据:

hInstance属于HINSTANCE类型,是指向某个实例的句柄——

这里的实例是正在运行的程序。句柄是标识某种对象(这里是应用程序的实例)的整数值。句柄的实际整数值是多少并不重要。在任何给定时刻都可能有好几个程序

在Windows下执行,这就使相同应用程序可能有若干副本同时在活动,而这种情形需要识别出来。因此,hInstance句柄标识某个特定的副本。如果

启动某个程序的多个副本,则每个副本都有自己独特的hInstance值。正如我们很快就将看到的那样,句柄还用来标识各种其他事物。

hPrevInstance是从16位版本的Windows *** 作系统继承下来的,我们可以放心地对它置之不理。在当前版本的Windows中,该参数始终为空。

lpCmdLine是指向某个字符串的指针,该字符串包含启动程序的命令行字符。该指针允许挑出可能在命令行中出现的任何参数值。LPSTR类型是

另一种Windows类型,用来指定32位(long)的字符串指针,或者当以64位模式编译时,则用来指定64位的字符串指针。WinMain()的另

一个版本接收LPWSTR,用于使用Unicode。

nCmdShow决定着被创建窗口的外观。窗口可以正常显示,也可以最小化显示;例如,程序的快捷方式可能指定该程序在启动时应该最小化显示。该参

数可以是一组固定值之一,这些值是由像SW_SHOWNORMAL和SW_SHOWMINNOACTIVE这样的一些符号常量定义的。此类定义窗口显示方

式的常量还有9个,它们都以SW_开始。通常不需要检查nCmdShow的值,而是直接将其传递给负责显示应用程序窗口的Windows API函数。

程序中的WinMain()函数需要做以下4件事情:

告诉Windows该程序需要的窗口种类

创建程序窗口

初始化程序窗口

检索属于该程序的Windows消息


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12104763.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存