计经集注--VBSpine专栏

世事洞明皆学问,人情练达即文章

QQ群讲义2--VB的API与SDK简介

这次的主要内容是关于SDK的概念介绍和VBAPI的基本使用方法,因为大家会不时遇到一些不是数据库,也不一定是简单的图形或网络相关的功能要求,比如不用控件播放MP3,设置窗口总在最前,对注册表的指定位置进行读写(Word中近期文件记录就是采用此策略),这些功能有好多都是通过API来实现的

说到API,就要不能不说C语言的历史和SDK的概念。

以前就有不少同学问我初学程序,从什么语言开始,我的回答几乎千篇一律:C语言+VB,原因很简单,C语言是上天入地无所不能,在目前几乎所有的操作系统上都有它的踪迹,而且,好多深入学习计算机有关知识的文章都是采用C语言的描述方式的;而VB是非常快速建立Windows程序的一种方式,能够在一定程度上抵消初学C语言那种困乏的感觉。

第一篇:C

在这里,先介绍一下C语言与标准C语言。

C是大约三十多年前Dennis Ritchie这位老前辈在B语言的基础上改进出来的一种语言,特点是精练简洁,可以进行硬件操作,其实最初的设计目的就是为了方便在Unix上的工作,在C语言出现不久Ken ThompsonDennis Ritchie两位大叔把Unix系统的大部分用C语言重写,由于当年Unix的广泛使用,C语言开始占领了程序设计领域的大半疆土。

1978年,Brian KernighanDennis Ritchie(简称K & R)这两位出版了一本经典的著作《The C Programming Language》,此书是后来随着历史的变迁出现的各种C语言实现版本的基础,80年代末,美国国家标准化协会(简称ANSI)面对当时出现的各种C语言编译器上诸多细节有差异的现象,制订了对C语言一些细节和一些配套类库的规定,这些规定推荐给后来的编译器设计厂商去遵守,以方便开发人员的使用,这个就称为C语言的ANSI标准。

ANSI C的标准是很简练的。现在,咱们会见到很多关于语言的标准,比如C++Java的标准,这些标准都是规定了一些函数的写法细节和好多类库的组织方式。比如,现在几乎所有的C语言编译器都有stdio.h都以main函数为主函数,最新的C标准规定main函数必须写成int main的方式。

但标准毕竟不是法律,只是推荐遵守,所以在VC2005中,就出现了tmain这样的怪胎。

好,语言的标准有了,实现就是留给各大厂商各显其能的机会了,于是,有了Turbo CTurbo C++Borland C++Visual C++等种种实现的方式,诸如TCVCBCVC#这些其实就是集成了编辑功能的编译工具,当然,每个工具都配有自己的独门绝活-实现某些功能的类库,比如BC中的OWL,这套函数库提供了在Windows3.1条件下写图形程序的至尊武器,VCMFC更是在用CC++语言写Windows图形式程序方面大显神威。

从此以后,见到类似VCVC++BC之类名词的,自己上网查找去,再敢在群内胡搅蛮缠者,牌无赦。

第二篇:SDK

目前Windows程序设计的设计主要有三种方式,原始的SDK方式,MFC方式,使用VBDelphi等在较高层次上封装了API(但仍可调用)的工具来编写的方式。本次讲座涉及到的是SDK方式和第三种。

What is SDK ??SDK is Software Development Kit,一般来说,SDK就是由软件厂商为了方便别人在他们的产品上二次开发而提供的用来编译程序的一组工具,一些函数库,往往还带着一些示例文档,JavaSDK称为JDKWindows程序设计的SDK带在VC中,从VC6.0开始,安装了VC,也就安装了WindowsSDK

Windows系统上,SDK的表现方式就是诸多的APIApplication Program Interface)。APIWindows SDK中的定义方式是C语言的格式,众多API为编写和系统相关的程序提供了途径,所以毫无疑问,要直接看MSDNAPI的原型,C语言的功底是必不可少的。

当然,安装VC后所自动安装的SDK主要是为用C语言通过VC这个工具进行Windows程序设计提供了基础,实际上,如果安装了Delphi,则Delphi就可以通过它自定义的方式调用WindowsAPI,安装了VB也是一样,也就是说,API是早已客观存在的,安装这些SDK只是为调用它提供了方便。

API的物理存在形式就是dll文件,这个文件当中通过类的方式对函数进行了封装,留下了调用的接口。根据功能与dll文件,API函数被分成了几大类:

Kernel32.dll文件中封装的函数:通常是和内存处理、文件的I/O和进程管理,多线程等功能有关。

User32.dll文件中封装的函数:通常是处理窗口相关的。

Gdi32.dll文件中封装的函数:通常和图形类的程序设计有关。

除了这几个之外,还有很多的dll,大部分通过文件名就足以猜出其中函数主要是用来实现哪些方面功能的,当然,现有的诸多API手册也往往对API进行了分类

第三篇:VB的实例

实际上,VB的好多操作都是有相应的API来操作的,VB这个工具是把很多API经过处理之后,用一种特殊的方式展现了出来,隐藏了很多的工作细节,比如,消息循环,在VB中被加工成了事件,这个低一层的内容,下次说。

一般使用API的步骤,是通过对API分类的了解,或上网查到文章,或在群里问到某位弟兄推荐你用某个函数,然后就开始查找目标。

比如,现在我要实现一个VB的窗口总在最前,经过上网查找,得知要使用SetWindowsPos函数,于是,先新建一个VB的标准exe工程。

注:由于API函数的使用往往涉及到系统,在Windows98机器上本人有多次蓝屏花屏黑白屏经历,在Windows2000下也死机多次,故为了安全起见,运行前,一定要保存工程文件,并用Option Explicit强制VB变量声明。

然后,先打开VB工具中的API浏览器,搜索到有关的函数名称之后,复制到VB的环境中,这个APIVB中的调用声明如下:

Public Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

这个就是这个函数在VB中使用的声明方式,有时,某些参数类型有特殊,还要看一下函数的原型,这里顺便给大家看一眼这个函数的原型(C语言的方式):

BOOL SetWindowPos

(

    HWND hWnd,       // handle of window

    HWND hWndInsertAfter,      // placement-order handle

    int X,      // horizontal position

    int Y,       // vertical position

    int cx,     // width

    int cy,     // height

    UINT uFlags // window-positioning flags

   );

解释一下上边那段声明:Public和一般的函数使用声明没什么区别,加上Declare说明函数作用域的,SetWindowsPos是这个函数的名称,Lib “user32”说明这个函数的存在位置是系统目录中下的user32.dll文件中,Alias是别名的标志,和后边引号中的内容共同定义了这个函数的另外一个名称,大多数情况下这个功能没用,大家抄下来就好,最后的As Long就是说明这个函数是返回一个长整型数,括号中那一串是函数的参数,ByVal表示都是采用按值进行传递的方式(这个和C语言中函数的方式是一致的),然后挨个看参数的说明。

关于参数的说明可以在网上有人整理出来的API手册中查找,当然最强大的当属MSDN,我这里用的是一个小型的VB API手册上,查到说明如下:

Hwnd

Long,欲定位的窗口

hWndInsertAfter

Long,窗口句柄。在窗口列表中,窗口hwnd会置于这个窗口句柄的后面。也可能选用下述值之一:

——————————————————————————————————————

HWND_BOTTOM

将窗口置于窗口列表底部

HWND_TOP

将窗口置于Z序列的顶部;Z序列代表在分级结构中,窗口针对一个给定级别的窗口显示的顺序

HWND_TOPMOST

将窗口置于列表顶部,并位于任何最顶部窗口的前面

HWND_NOTOPMOST

将窗口置于列表顶部,并位于任何最顶部窗口的后面

X

——————————————————————————————————————

Long,窗口新的x坐标。如hwnd是一个子窗口,则x用父窗口的客户区坐标表示

Y

Long,窗口新的y坐标。如hwnd是一个子窗口,则y用父窗口的客户区坐标表示

Cx

Long,指定新的窗口宽度

Cy

Long,指定新的窗口高度

wFlags

Long,包含了旗标的一个整数

——————————————————————————————————————

SWP_DRAWFRAME

围绕窗口画一个框

SWP_HIDEWINDOW

隐藏窗口

SWP_NOACTIVATE

不激活窗口

SWP_NOMOVE

保持当前位置(xy设定将被忽略)

SWP_NOREDRAW

窗口不自动重画

SWP_NOSIZE

保持当前大小(cxcy会被忽略)

SWP_NOZORDER

保持窗口在列表的当前位置(hWndInsertAfter将被忽略)

SWP_SHOWWINDOW

显示窗口

SWP_FRAMECHANGED

强迫一条WM_NCCALCSIZE消息进入窗口,即使窗口的大小没有改变

       

实际上,这些常数都可以指定为具体某个数值,意义是一样的,这种方式就是为了使用方便。观察这一串参数说明,可以看出,大部分的参数实际上就是需要我们在几个常数间作出选择,真正需要给出的只有第一个参数hwnd,这个参数的类型是Long,解释为窗口句柄。

好,新的概念出现了,窗口句柄是什么呢?于是,我翻出了传说中的Charles Petzold大叔的那本《Windows程序设计》,看到了这样的一段解释:

A handle is simply a number (usually 32 bits in size) that refers to an object. The handles in Windows are similar to file handles used in conventional C or MS-DOS programming. A program almost always obtains a handle by calling a Windows function. The program uses the handle in other Windows functions to refer to the object. The actual value of the handle is unimportant to your program, but the Windows module that gives your program the handle knows how to use it to reference the object.

翻译:句柄是一个(通常为32位的)整数,它代表一个对象。Windows中的句柄类似传统C或者MS-DOS程序设计中使用的文件句柄。程序几乎总是通过调用Windows函数取得句柄。程序在其它Windows函数中使用这个句柄,以使用它代表的对象。代号的实际值对程序来说是无关紧要的。但是,向您的程序提供代号的Windows模块知道如何利用它来使用相对应的对象。

这一大串其实要说明的问题很简单,就是:句柄是程序用来对窗口进行操作和处理的途径,那么大家会问,说了这么多,我如何调用某个窗口的句柄?

答案很简单,窗体的hwnd属性。

好,句柄的问题解决,再回来看看那几个参数,有的关于xy之类的可以手工指定,还剩下几个有名无值的,怎么办?

解决方法是再次打开API的文本浏览器,其中提供了常量搜索,对这些常量的具体值一番查找,可以得到如下的常量列表:

Public Const SWP_HIDEWINDOW&H80

Public Const SWP_NOACTIVE&H10

Public Const SWP_NOCOPYBITS&H100

Public Const SWP_NOMOVE&H2

Public Const SWP_NOOWNERZORDER&H200

Public Const SWP_NOREDRAW&H8

Public Const SWP_NOREPOSITIONSWP_NOOWNERZORDER

Public Const SWP_NOSIZE&H1

Public Const SWP_NOZORDER&H4

Public Const SWP_SHOWWINDOW&H40

Public Const HWND_BOTTOM1

Public Const HWND_BROADCAST1

Public Const HWND_DESKTOP0

Public Const HWND_NOTOPMOST=-2

Public Const HWND_TOPMOST=-1

Public Const HWND_TOP0

Public Const FLAGSSWP_NOMOVE Or SWP_NOSIZE

好了,这些常量的声明贴到通用的声明部分就可以,像一般的常量声明那样。

注:有时,常量前边的PublicPrivateGlobal有特殊规定,根据错误的提示改一下就好。

其实,这些常量当中真正使用到的往往只是很少的几个,全列出来,给大家一个感性认识。

有了这一番折腾,咱们向目标终于迈近了很大的一步,下一步就开始准备使用这个函数来实现咱们的目的:

VB的工程中,如果想通过一个按钮来实现窗口的总在前面,就在窗口上加一个按钮,然后在按钮的事件中写下:

Dim lngTop as Long

lngTopSetWindowsPos(me.hwnd,HWND_TOPMOST,0,0,1000,1000,FLAGS)

OK,大功告成。

第四篇:几个问题的说明

经过上边的一个过程,我想大多数人应该明白了API的基本使用过程,这里再说一些在API的使用中常见的一些问题:

1,  操作系统相关问题:

API这个东西是用来实现和系统相关的功能的,那它自然就和系统的版本密切相关,在MSDN中,经常会看到对某个函数的版本要求的说明,比如刚才那个SetWindowsPos函数,在MSDN中,有个Function Information

Minimum DLL Version

user32.dll

Header

Declared in Winuser.h, include Windows.h

Import library

User32.lib

Minimum operating systems

Windows 95, Windows NT 3.1

Unicode

Implemented as Unicode version

这段信息非常明确的说明,这个函数只能用于Windows32位的环境上,要求的操作系统支持是95NT3.1及以上。

这种的其实好办,最愁人的是那些到了新版操作系统中失效的函数,也就是说,这个数到了新的操作系统中可能失效。这就有个API函数的进化问题。

一般来说,API的进化大概有三个方向:死亡,转世和分身。

死亡:就是说,某个功能出于某些原因在新的系统中干脆取消了,找不到替代的函数,也没有其它不用API实现的方式,对于一个API函数来说,毫无疑问,这是最悲哀的结局。

转世:这是操作系统发生变化时,某些进行非常底层操作的函数最常见的结局。在转世大军中,我们遇到了Hmemcpy这位兄弟,喜好破解的朋友应该看着非常眼熟,这个函数的主要功能就是复制内存数据,在新的系统中,它已经成功的换上了memcpy这个马甲,马甲换了,功能不变。

分身:这个是最令人头疼的一种结局,也就是在新的系统中,原来某个函数不幸身亡,然后魂归几处,就像幻想三国志中的三龙宝器-青龙剑,玉龙玺,赤龙珠,这种情况下,一般都需要在新的系统中通过几个API函数的组合来实现原先对应的功能,这种情况往往是为了安全性的提高,但是,这种方式往往会给咱们程序设计者带来很大的痛苦。

最典型的当属SystemParametersInfo这个函数,在Windows9598下,这个函数威力甚大,是实现屏蔽任务管理器的利器,但不幸到了Windows2000XP下,实现相应功能用这个函数却完全无效,直到今天,我们还会在好多论坛上见到询问如何屏蔽任务管理器,然后有人又放出了这个函数,然后这个人被后来的以板砖拍之……

实际上,屏蔽任务管理器的实现方式已经化身为AdjustTokenPrivilegesLookupPrivilegeValueOpenProcessToken一系列函数,使用十分复杂,过几天,等我把以前作的那个杀掉任务管理器的程序找出来,运行成功之后发共享。

2,关于Shell_NotifyIcon函数

这个函数的功能是用来实现系统托盘的关键,但是相信很多人在使用的时候都遭遇了找不到函数入口点的错误,而相关的提问曾经在各大论坛上成为大家争论的焦点,其实,问题很简单,就是VBAPI文本浏览器在这个函数上存在一个Bug多了一个空格 :)而尤其可恶的是。好多其它的API手册中往往还不提供这个函数的说明。以后谁使用这个函数,如果发现找不到函数入口点的错误,先仔细看看这个函数前后是否多了或少了空格,处理之,应该可以解决的。

3,  关于API中某些特殊的类型

实际上,使用API函数进行Windows程序设计首选的是C语言,在VB中,还要对API进行一番复杂的声明,在VC中,#include <windows.h> 即可解决大部分的API声明,而且问题不止于此,还有诸多数据类型的问题存在。

首先,在MSDN中,可以看到一些VB中不存在的类型,这些类型基本都有替代的方案,不过,针对具体问题的不同,并不能保证100%有效:

lpVoidVB中通常写成Any类型

NullVB中通常写成ByVal 0&vbNullString

Void,通常是无返回值的函数,在VB中改为Sub

 
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭