win32 api接口函数Word文档下载推荐.docx
《win32 api接口函数Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《win32 api接口函数Word文档下载推荐.docx(94页珍藏版)》请在冰点文库上搜索。
这是因为缺乏这些知识你的脑子里根本行不成一种总体的设计构思。
二、API文本游览器。
很多API函数都是很长很长的。
想看什么样子吗?
如下就是作为例子的APIDdeClientTransaction函数∶
DeclareFunctionDdeClientTransactionLib"
user32"
(pDataAsByte,ByValcbDataAsLong,ByValhConvAsLong,ByValhszItemAsLong,ByValwFmtAsLong,ByValwTypeAsLong,ByValdwTimeoutAsLong,pdwResultAsLong)AsLong
哇!
这么长?
如果你从来没有接触过API,我想你肯定被吓住了。
你也许考虑,该不该继续学下去。
不过不要担心,幸运的是Microsoft的设计家们为我们提供了有用的工具,这便是API
文本查看器。
通过API文本查看器,我们可以方便地查找程序所需要的函数声明、结构类型和常数,然后将它复制到剪贴板,最后再粘贴到VB程序的代码段中。
在大多数情况下,只要我们确定了程序所需要的函数、结构和常数这三个方面后,就可以通过对API文本游览器的以上操作将他们加入到程序段中,从而程序中可以使用这些函数了。
这些是学习API最基本的常识问题,它远远占不到API的庞大的体系内容。
今后我们把精力浪费(这绝不是浪费)在哪里呢?
那就是∶
什么时候使用什么函数,什么时候使用什么结构类型,什么时候使用什么常数。
三、API函数声明。
让我们回想一下。
在VB中,如何声明函数呢?
我想,如果你正在看此文,那么你绝对能够回答得出这个问题。
以下便是你应该很熟悉的函数声明∶
FunctionSetFocus(ByValhwndAsLong)AsLong
即,这行代码定义了名为SetFocus的函数,此函数具有一个Long型数据类型的参数,并按值传递(ByVal),函数执行后将返回一个Long型数据。
API函数的声明也很类似,如,API中的SetFocus函数是这样写的∶
DeclareFunctionSetFocusLib"
Alias"
SetFocus"
(ByValhwndAsLong)AsLong
有点复杂了一些。
是的,是复杂了点。
但我可以告诉你,除了这些多出来的部分,其他部分还是和你以前学到的东西是一样的。
函数在程序中的调用也是一样。
如:
DimdlAsLong
dl&
=SetFoucs(form1.Hwnd)
但,一点是清楚的。
它不象你自己写的程序那样能够看到里面的运行机理,也不像VB
自带的函数那样,能够从VB的联机帮助中查到其用法。
唯一的方法就是去学、查VB以外的资料。
Declare语句用于在模块级别中声明对动态链接库(DLL)中外部过程的引用。
对此,你只要记住任何API函数声明都必须写这个语句就可以了。
Iib指明包含所声明过程或函数的动态链接库或代码资源。
也就是说,它说明的是,函数或过程从何而来的问题。
如在上例中,SetFocusLib"
说明函数SetFocus来自user32.dll文件。
主要的dll动态连接库文件有∶
user32.dllWindows管理。
生成和管理应用程序的用户接口。
GDI32.dll图形设备接口。
产生Windows设备的图形输出
Kernel32.dll系统服务。
访问操作系统的计算机资源。
注意,当DLL文件不在Windows或System文件夹中的时候,必须在函数中说明其出处(
路径)。
如,SetFocusLib"
c:
\Mydll\user32"
函数声明中的Alias是可选的。
表示将被调用的过程在动态链接库(DLL)中还有另外的名称(别名)。
如,Alias"
,说明SetFocus函数在User32.dll中的另外一个名称是,
SetFocus。
怎么两个名都一样呢?
当然,也可以是不同的。
在很多情况下,Alias说明的函数名,即别名最后一个字符经常是字符A,如SetWindowsText函数的另一个名称是
SetWindowsTextA,表示为Alias"
SetWindowsTextA"
。
这个A只不过是设计家们的习惯的命名约定,表示函数属于ANSI版本。
那么,别名究竟有什么用途呢?
从理论上讲,别名提供了用另一个名子调用API的函数方法。
如果你指明了别名,那么尽管我们按Declare语句后面的函数来调用该函数,但在函数的实际调用上是以别名作为首要选择的。
如,以下两个函数(Function,ABCD)声明都是有效的,他们调用的是同一个SetFocus函数∶
"
DeclareABCDSetFocusLib"
需要注意的是,选用Alias的时候,应注意别名的大小写;
如果不选用Alias时的时候,函数名必须注意大小写,而且不能改动。
当然,在很多情况下,由于函数声明是直接从API
文本游览器中拷贝过来的,所以这种错误的发生机会是很少的,但您有必要知道这一点。
最后提醒你一句,API声明(包括结构、常数)必须放在窗体或模块的"
通用(GeneralDeclarations)段。
(杭州元帅注:
在窗体里的API声明必须PrivateDeclareFunction......)
四、数据类型与"
类型安全"
API函数中使用的数据类型基本上和VB中的一样。
但作为WIN32的API函数中,不存在Integer
数据类型。
另外一点是在API函数中看不到Boolean数据类型。
Variant数据类型在API函数中是以Any的形式出现,如DataAsAny。
尽管其含义是允许任意参数类型作为一个该API函数的参数传递,但这样做存在一定的缺点。
其原因是,这将会使得对目标参数的所有类型检查都会被关闭。
这自然会给各种类型的参数调用带来了产生错误的机会。
为了强制执行严格的类型检查,并避免上面提到的问题,一个办法是在函数里使用上面提到到Alias技术。
如对API函数GetDIBits可进行另外一种声明方法。
如下∶
GetDIBits函数的原型∶
PublicDeclareFunctionGetDIBitsLib"
gdi32"
GetDIBits"
(ByValaHDCAsLong,ByValhBitmapAsLong,ByValnStartScanAsLong,ByValnNumScansAsLong,lpBitsAsAny,lpBIAsBITMAPINFO,ByValwUsageAsLong)AsLong
GetDIBits函数的改型∶
PublicDeclareFunctionGetDIBitsLongLib"
(ByValaHDCAsLong,ByValhBitmapAsLong,ByValnStartScanAsLong,ByValnNumScansAsLong,lpBitsAsLong,lpBIAsBITMAPINFO,ByValwUsageAsLong)AsLong
通过本课程前面所学到的知识,我们已经可以得知原型GetDIBits函数也好,改型GetDIBitsLong函数也好,实际将调用的都是Alias所指定的GetDIBits原函数。
但你应当看到,两者的区别在于,我们在改型的函数中强制指定lpBits参数为Long形。
这样就会使得函数调用中发生的错误机率减少到了最小。
这种方法叫做"
安全类型"
声明。
API函数中经常看到的数据类型有∶Long,String,Byte,Any....(也就这些吧。
)
五、常数
对于API常数来讲,没有什么太特别的学问。
请看VB中的以下代码∶
Msg=MsgBox("
您好"
vbOKCancel)
我们知道,vbOKCancel这个常数的值等于1。
对上面的代码我们完全可以这样写,而不会影响代码的功能∶
1)
但你大概不太愿意选择后一种,因为这会使得看懂代码费劲起来。
这种方法也被API采取了。
只是API常数必须在事情之前做好初始化声明VB本身是看不懂的。
其内容仍然来自与API
文本游览器。
具体形式如下等等∶
PublicConstABM_ACTIVATE=&
H6
PublicConstRIGHT_CTRL_PRESSED=&
H4
PublicConstRPC_E_SERVER_DIED=&
H80010007
PrivateConstRPC_S_CALL_FAILED_DNE=1727&
在常数的初始化中,有些程序使用Global,如GlobalConstABM_ACTIVATE=&
H6,但我认为Public完全可以代替它。
过去我也用过Global,但现在不大用了。
一会儿用这个,一会儿用那个,各程序之间不能保持一致性了,起码看起来别扭。
六、结构
结构是C和C++语言中的说法。
在VB中一般称为自定义数据类型。
想必很多朋友都已经认识它。
在API领域里,我更喜欢把它叫做结构,因为API各种结构类型根本不是我定义(
自定义)的。
在VB中,API结构同样由TYPE.......ENDTYPE语句来定义。
如,在API中,点(Point)结构的定义方法如下:
PublicTypePOINTAPI
XAsLong
'
点在X坐标(横坐标)上的坐标值
YAsLong
点在Y坐标(纵坐标)上的坐标值
EndType
又如,API中矩形(Rect)结构的定义如下∶
PublicTypeRECT
LeftAsLong
矩形左上角的X坐标
TopAsLong
矩形左上角的Y坐标
RightAsLong
矩形右下角的X坐标
BottomAsLong
矩形右下角的Y坐标
这些内容同样可以从API文本游览器中拷贝过来。
这些结构中的变量名可随意改动,而不会影响结构本身。
也就是说,这些成员变量都是虚拟的。
如,POINTAPI结构可改为如下∶
MyXAsLong
MyYAsLong
不过,一般来讲,是没有这种必要的。
结构本身是一种数据类型,因此,使用时必须声明具体变量为该结构型,才能在程序中真正使用到该结构。
结构的声明方法和其他数据的声明方法一样,如,以下语句把变MyPoint声明为POINTAPI结构类型∶
MyPointAsPOINTAPI
引用结构中的成员变量也十分简单,在结构名后面加上一个"
."
然后紧接着写要引用的成员变量即可。
这很象VB中的引用一个对象的某个属性。
如,假如我们把上面已经声明的MyPoint结构中的X变量的值赋给变量Temp&
则代码如下∶
Temp&
=MyPoint.X
&
nbs
p;
但,特别注意的是,你千万不要认为上例中的MyPoint是一个值。
它不是值,而是地址(
指针)。
值和地址是完全不同的概念。
结构要求按引用传递给WINDOWS函数,即所有API
函数中,结构都是按ByRef传递的(在Declare语句中ByRef是默认型)。
对于结构的传递,你不要试图采用ByVal,你将一无所获。
由于结构名实际上就是指向这个结构的指针(这个结构的首地址),所以,你也就传送特定的结构名就可以了(参见小结,我用红色字体来突出了这种传递方式)。
由于结构传送的是指针,所以函数将直接对结构进行读写操作。
这种特性很适合于把函数执行的结果装载在结构之中。
七、小结
以下的程序是为了总结本课中学到的内容而给出的。
启动VB,新建一个项目,添加一个命令按钮,并把下面的代码拷贝到代码段中,运行它。
PrivateDeclareFunctionGetCursorPosLib"
(lpPointAsPOINTAPI)AsLong
PrivateTypePOINTAPI
定义点(Point)结构
SubPrintCursorPos()
DimdlASLong
DimMyPointAsPOINTAPI
=GetCursorPos(MyPoint)
调用函数,获取屏幕鼠标坐标
Debug.Print"
X="
&
Str(MyPoint.X)&
and
Y="
Str(MyPoint.Y)
EndSub
PrivateSubCommand1_Click()
PrintCursorPos
输出结果为(每次运行都可能得到不同的结果,这得由函数调用时鼠标指针在屏幕中所处的位置而决定)∶
X=240
Y=151
程序中,GetCursorPos函数用来获取鼠标指针在屏幕上的位置。
以上例子中,你可以发现,以参数传递的MyPpint结构的内容在函数调用后发生了实质性变化。
这是由于结构是按ByRef传递的原因。
第二课∶句柄、矩形和画点函数
一、句柄
今天开始,我向大家讲有关API的是实质性内容。
我们就从"
句柄"
开始。
只要你来到了API的世界,经常碰到的问题之一就是句柄。
那么究竟什么是句柄呢?
如果你从来都没有听说过"
这个词,可能首先觉得句柄当中有很多内容。
其实不然,所谓句柄实际上是一个数据,是一个Long(整长型)的数据。
在API中,它经常是以一个参数的形式传递给各种API函数。
PublicDeclareFunctionGetWindow&
Lib"
(ByValhwndAsLong,ByValwCmdAsLong)
其中,hwnd就是句柄。
在VB里,句柄是一种属性,您打开VB中的对象游览器看一看form
窗体或者PictureBox控件等究竟有没有hwnd属性。
是有的。
VB中的解释是这样的∶
MicrosoftWindows运行环境,通过给应用程序中的每个窗体和控件分配一个句柄(或hWnd)来标识它们。
hWnd属性用于WindowsAPI调用。
许多Windows运行环境函数需要活动窗口的hWnd作为参数。
如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。
我们知道,所谓指针是一种内存地址。
应用程序启动后,组成这个程序的各对象是住留在内的。
如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。
但是,如果您真的这样认为,那么您就大错特错了。
我们知道,Windows是一个以虚拟内存为基础的操作系统。
在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。
对象被移动意味着它的地址变化了。
如果地址总是如此变化,我们该到哪里去找该对象呢?
为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。
Windows
内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。
这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。
这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。
句柄地址(稳定)→记载着对象在内存中的地址────→对象在内存中的地址(不稳定)→
实际对象
但是,必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。
假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。
在VB中获得一个对象的句柄十分简单,如要获取form1窗体的句柄,就可以这样写∶
form1.Hwnd
对象的句柄还可以通过API函数来获得,如∶
GetActiveWindow返回位于最顶部的具有输入焦点的窗口句柄
GetFocus获得当前线程里补获鼠标输入的窗口句柄
GetForegroundWindow从位于前台的线程里返回活动窗口的句柄
GetCursor取得当前指针的句柄
GetDesktopWindow获取整个桌面的句柄
GetWindow获得一个窗口的句柄,该窗口与某源窗口有特定的关系
《以上函数说明均可在WinAPI.hlp文件中找到。
》
本教程提供了演示例程──play1.vbp,正是为了说明这些函数的具体用法的。
程序运行后,用鼠标做一些任何你想做的事情,并观察各项目数据的变化。
通过本程序,注意观察以下几点∶
1,线程内与线程外。
(VB不支持多线程)。
其他应用程序对此程序来说都是线程外。
2,在windows95操作系统下,各个窗体(包括一些控件,如文本框,图片框等,
MICROSORT对它们均统称为窗体)拥有各自的鼠标指针。
这和win16下各应用程序使用同样一个指针是截然不同的。
3,每次从新启动,各窗体的句柄都有所变化。
Text5的装载和卸载过程中,句柄始终是在变化着的。
这说明了上面提的影院售门票中存在的现象是真实的。
获得对象句柄的函数还有很多,以后碰到它们时再介绍给大家。
二、驾驶句柄
只要弄清了什么是句柄,尤其是窗口句柄,那么操纵一个对象就变得自如一多了。
比如,可以通过GetWindowTextAPI函数,我们可以轻松地获得某特定窗口的标题。
GetWindowText在VB中的声明如下:
PrivateDeclareFunctionGetWindowText&
GetWindowTextA"
(ByValhwndAsLong,ByVallpStringAsString,ByValcchAsLong)
于是,我们可以通过以下一段代码来获得form1的窗口标题。
(新建一个项目,添加一个命令按钮,把以下的代码拷贝过去,还有上面的函数声明。
你就可以运行了)
DimformCaptionAsString
formCaption=Space(128)
=GetWindowText(form1.hwnd,formCaption,128)
PrintformCaption
注∶其中128是指字符串变量formCaption的长度(又称缓冲区大小)
这有必要吗?
为了获得form1窗体的标题,何必写这么多代码呢?
难道这就是API。
是的,的确在VB中用Printform1.Caption一行代码就可以抵挡住以上代码了。
但是,假如我们启动我们设计的应用程序后,想要在用鼠标点一下别的应用程序的时候,让我们的应用程序显示出那个窗体的标题,那又该怎么办呢?
比方说,我们另外启动的是MicorsoftWord,
用鼠标点击Word时让程序显示出"
您选择了MicrosoftWord"
字样。
显然只靠VB是办不到的,还得靠API这老手。
当然,您已经具备了这种能力,可以办到这件事情。
让我们一起来。
关键的问题是如何获得Word程序的句柄。
首先要认清的是,对VB的应用程序来说,Word
是属于