VB-API初级入门 (3)

VB-API初级入门 (3)2009-09-12 10:48:27  www.hackbase.com  来源:CSDN博客
  一、API是什么?  这个我本来不想说的,不过也许你知道其它人不知道,这里为了照顾一下新手,不得不说些废话,请大家谅解。  Win32 API即为Microsoft 32位平台的应用程序编程接口(Application Pr ...
信去试试把sBuffer = Space(255)去掉,后面的255其实就是告诉这个API我们缓冲字符串的大小,这里再告诉大家一个技巧,以后只要是看见包函有cch字符时,大部分都是输入相关类型的大小。

  再附加一点,就里我说过,hwnd是用来传句柄的,你也可以传入其它窗口句柄,只要其它窗口有文本,都是可以通过这个API获取的。还有Text2.Text = sBuffer其实是可以先把sBuffer处理一下再传给Text2.Text的,关于字符串处理这里不讲。

  好了,分析结束,来个小提示:在Windows操作系统中,任何有句柄的东东都可被看作为一个窗口。另外你可能会去试试QQ的密码框,^_^ 这里我要告诉你一下,无法成功,为什么无法成功呢?这是一个技术问题目前不提!

  接着再来试试GetWindowsDirectory,大家看表面意思吧!Get(获取)Windows(就是Windows目录)Directory(目录),也就是获取咱们那个系统目录,如:C:\Windows。可能我的Windows目录中在C盘,而其它人的可能在D盘、E盘也说不定,所以有的时候软件需要这个API进行获取操作系统具体的Windows目录。

  好了,还是新建一个标准EXE,添加一个CommandButton,属性Caption=显示Windows目录,OK,写入以下代码:

  Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long

  Private Sub Command1_Click()

  Dim sBuffer As String

  sBuffer = Space(255)

  GetWindowsDirectory sBuffer, 255

  MsgBox "Windows目录在: " & sBuffer

  End Sub

  分析!第一个Dim sBuffer As String字符串变量,sBuffer = Space(255)缓冲字符串,GetWindowsDirectory sBuffer, 255这个和上面所讲的一样,最后一个参数nSize为Long整形,所以传入数值,那传入什么数值呢?Size???当然是缓冲字符串大小了,以后遇到这个nSize一般也是传入相关类型的大小的。MsgBox "Windows目录在: " & sBuffer,是用MsgBox消息框显示出Windows目录的位置。

  OK,恭喜你,你又会使用了一个API,还要继续吗?(问:当然还要啦!答:最后一次哦!)

  GetWindowThreadProcessId,这次玩玩窗口进程,我估计有些人只要看见与进程有关的东东也会变得兴奋,呵呵!好了,先看看这个API是什么样的?如下:

  Private Declare Function GetWindowThreadProcessId Lib "user32" Alias "GetWindowThreadProcessId" (ByVal hwnd As Long, lpdwProcessId As Long) As Long

  看表面意思:Get(获取)Window(窗口)Thread(线程)Process(程序)Id(ID),组合:获取当前线程的窗口进程ID。至于进程ID要着有什么用,自己以后深入32编程就知道了。

  看看参数,ByVal hwnd As Long,哈哈,熟悉吧,一个hWnd句柄。lpdwProcessId As Long这个就是咱们需要的进程ID,老规矩,新建标准EXE,添加一个CommandButton,属性:Caption=获取窗口进程ID。代码如下:

  Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long

  Private Sub Command1_Click()

  Dim PID As Long

  GetWindowThreadProcessId Me.hwnd, PID

  MsgBox "窗口进程的ID是:" & PID

  End Sub

  我已经习惯了给大家分析了。首先看看第一个参数,ByVal hwnd As Long,又是句柄来的(问:废话!答:教会了你也别这样啊),lpdwProcessId As Long,这个就要注意了,看看这个参数的传递方式,是以ByRef进行传递的(问:呵呵,不懂什么意思?答:不懂?转回去看过程函数这章),也就是说ByRef是以地址进行传递的,过程中可以改变传递的参数值。明白了吗?还不明白的话回去乖乖看书吧!现在明白了传递方式,也就是说我们声明的PID是用来获取窗口进程ID的,厉害啊。

  F5,运行之,点击Command1,PID出来了吧?没出来我马上从十楼跳下去。

  温馨小提示^_^:hWnd可以传入其它窗口句柄,同样可以获取其它窗口进程ID。

  接下来我们再来看看Set(设置),Set什么呢?当然还是Window(窗口)容易些,先列出几个常用的API:

  SetWindowLong、SetWindowPos、SetWindowRgn、SetWindowText

  接上面的。

  首先咱们先看SetWindowText,咱们在上面讲过GetWindowText这个API,GetWindowText是用来获取窗口文本的,而这个正好相反。现在可以看看表面意思Set(设置)Window(窗口)Text(文本),好了这样理解就够了,我们已经知道这个API是设置窗口文本的,接着咱们就到API浏览器中找找这个API,如下:

  Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

  接着咱们看里面所需要传递的参数,一共有两,第一个ByVal hwnd As Long我就不用说了,传入句柄呗,第二个ByVal lpString As String,其中声明的lpString是字符串变量,可想而知,这里需要传入字符串,好了,开始实践。新建一个标准EXE,然后添加一个TextBox控件,然后再添加一个CommandButton,写入以下代码:

  Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

  Private Sub Command1_Click()

  SetWindowText Text1.hwnd, "这是咱们设置的文本"

  End Sub

  呵呵,这个看似比前面的更简单,不过我还是要罗嗦一下,首先把Text1的句柄传入第一个参数,这样API知道咱们需要操作哪个窗口,第二个是一个字符串变量,所以这里就是我们需要传入的文本。好了,F5运行,点击Command1,OK。

  再看SetWindowPos,可以说这个API可以看成设置窗口位置,但是最终的实现效果取决于咱们传递的参数,好了,在API浏览器中找到这个API,如下:

  Private 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

  呵!好家伙,这个API看起来有些复杂啊?不过别担心,有我在嘛,我会帮你好好分析的,这里还请大家别光我一个人分析,必须把自己融入进来,咱们一起分析这样不更有趣?好了,废话少说,先看第一个参数:

  ByVal hwnd As Long  这里我就不讲了,传入窗口句柄

  ByVal hWndInsertAfter As Long 好了,看看这个!hwndInstrAfter,可以看到里面包函有hwnd字符,这时你可能会说我前面不是已经说过嘛,只要看见包函有hwnd字符的都应该传入句柄嘛?呵呵,没错,你很聪明,记得我说的话呢!在这里夸一下你,别骄傲啊!现在咱们好好分析一下这个地方应该传入哪些参数!打开MSDN,不好意思是英文,这里我就把翻译过来的说明放上来,如下:

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

  HWND_BOTTOM    将窗口置于窗口列表底部

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

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

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

  可以看到这个地方有四个参数供我们选择,一般我们会使用第三个API常数和第四个API常数,这几个API常数都可以在API浏览器中找到,至于具体实现什么功能我相信大家都知道吧,后面有写呢!

  再看看后面的几个 x,y,cx,cy 分别为Long变量,我上面讲过,SetWindowPos可以看成设置窗口位置嘛,所以这里理所当然是传入相关的坐标值,如果忽略则为0,自己可以试下。

  ByVal wFlags As Long,这个参数,我又说过,看看字符Flags,呵呵,熟悉吧,所以这里咱们需要传入相关的标识常数,利用咱们以前学过的常数分析法进行分析,Set(S)Window(W)Pos(P)=SWP_ ,可以看到相关的常数了吧?这里我把相关常数的说明发上来大家看下,如下:

  SWP_DRAWFRAME    围绕窗口画一个框

  SWP_HIDEWINDOW  隐藏窗口

  SWP_NOACTIVATE  不激活窗口

  SWP_NOMOVE      保持当前位置(x和y设定将被忽略)

  SWP_NOREDRAW    窗口不自动重画

  SWP_NOSIZE      保持当前大小(cx和cy会被忽略)

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

  SWP_SHOWWINDOW  显示窗口

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

  所以我说过,一个这样的API他具体实现的功能取决于你所传递的参数。假设这里咱们需要实现一个窗口永远置前的功能,首先新建一个标准EXE,输入以下代码:

  Private Declare Function SetWindowPos Lib "user32" (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

  Private Const HWND_TOPMOST = -1

  Private Const SWP_NOMOVE = &H2

  Private Const SWP_NOSIZE = &H1

  Private Sub Form_Load()

  SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE

  End Sub

  现在咱们开始分析,第一个参数传入句柄,第二个我上面讲过,实现什么功能传入什么参数,这里咱们是实现的窗口永久置前的功能,所以传入HWND_TOPMOST常数,现在看看其实坐标,如果你不想改变窗口的具体位置的话,这里可不设为0,再看看后面的wFlags,我传入了两个常数,这两个常数的相关说明请大家看看上面就知道,主要是不改变窗口位置和不改变窗口大小的前提下把窗口置前,其它常数如果大家有兴趣可以自己试试。

  最后一个,看看SetWindowRgn,这里我要解释一番,这个API所实现的功能呢就是改变窗口外观,也就是咱们所说的异形窗口等,通过这个API咱们可以把窗口改变成任何形状,在API浏览器找到这个API,如下:

  Private Declare Function SetWindowRgn Lib "user32" Alias "SetWindowRgn" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

  好了,第一个参数,句柄。第二个参数,Long变量,这里需要传入什么咱们下面会讲到。第三个,Boolean变量,可以说明这里需要传入布尔值,Redraw为重画的意思,所以如果我们用这个API改变窗口形状,这里需要为True,表示重画窗口。

  现在新建一个标准EXE,然后把Form的ScaleMode设置成3-Pixel,我们知道Windows是以像素为单位的,所以使用这个API进行设置的时候是以像素为单位进行处理窗口外观。然后把BorderStyle设置为0-None,这样看得更明显。好了,写入以下代码:

  Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

  Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long

  Private Sub Form_Load()

  Dim hRgn As Long

  hRgn = CreateRoundRectRgn(0, 0, Me.ScaleWidth, Me.ScaleHeight, 10, 10)

  SetWindowRgn Me.hWnd, hRgn, True

  End Sub

  我不得不说一下这里我又用了一个API,主要是因为使用SetWindowRgn


本篇文章来源于 黑客基地-全球最大的中文黑客站 原文链接:http://www.hackbase.com/tech/2009-09-12/55967_3.html

posted @ 2009-09-16 15:57  雨城  阅读(337)  评论(0编辑  收藏  举报