VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
楼主: liusai

[原创] VB API初级入门(新手必看。注意:不是广告)

  [复制链接]
 楼主| 发表于 2007-2-27 22:17:26 | 显示全部楼层
还是多谢大家支持,下一篇文章正在编辑中,希望大家能够从中学到更多知识。。。。:)
回复 支持 反对

使用道具 举报

发表于 2007-2-27 23:51:18 | 显示全部楼层
强烈要求置顶。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-2-27 23:52:39 | 显示全部楼层
接上面第四节“如何慢慢提升自己的API功力?”

    提升自己的API功力?如何提升?怎么个提升法?这一点有待讨论,不过目前咱们需要做的是多多接触一下API,这样长久以后你就自然会对API产生一种亲切感,慢慢的你会觉得自己用API写程序是多么正常的一件事情。呵呵这个亲切感我喜欢!

    1,试着自己从小程序开始写起。

    写小程序?对!在你写小程序时应该拣你最感兴趣的程序写,否则有可能你写到一半以后会觉得自己这个程序写得毫无价值,简直是在浪费时间,最后到头来还是功亏一篑。这里我拿什么当题材呢?我在这里也想了很久,最后还是决定选择一个注销Windows程序来做题材(其实这是我当初学API最想实现的功能)。

    注销Windows也就是退出Windows(重启,关机等都一样,不都是退出的意思吗?),根据表面意思在API浏览器中输入Exit(退出)Windows,看看有没有这个API?这里提醒一下,你在查找这个API的时候还会看到ExitWindowsEX这个API,其实这两个API实现的功能一样,前者是用在16位操作系统上,只不过在Win32位操作系统上一般都使用ExitWindowsEX。所以这里就使用后者。API见以下:

  
  Private Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long

    看看里面的两个参数,ByVal uFlags As Long?这里我们需要传入一个整形数字,可是应该传入什么数字呢?这里说下,API中的参数可以传入不同的值,不同的值从而导致产生不同的结果。分析API中参数应该传递哪些值其实是有技巧的,以后大家只要是看到参数字符中包函Flags字符的话那就说明该参数可以被传入一个或多个标志,并且大部分都是传入API常数(什么是API常数就不用我说了吧)。说白话点,就是我们可以传入多个API常量,并且可以在API浏览器中找到,当然,不一定所有的API常数都可以在API浏览器中找到,不过大部分都可以。

  
    在API浏览器查API常量时我前面就教过大家技巧,现在该是我们实践的时候了,分析如下:

  
  Exit   :头一个大写字符 E
  Windows:头一个大写字符 W
  Ex     :头一个大写字符 E
  组合   :EWE_
  

    好了,现在在API浏览器的中常数中找找,咦?发现好像没有以EWE开头的常数??只发现以EWX开头的?现在先别着急,咱们回过头来再分析下,咱们是失败在最后一步Ex上,这里我不得不否决我前面教过大家的技巧,但是又不能完全否决,出现这种情况时就需要大家灵活运用API常数的分析法,可以看到EWX最后一个X是以Ex的X作结尾的,以这种方法做API常数开头的不止这一个,所以这里我特意留了一个陷阱,希望给大家带来一些经验将来能够灵活运用。现在我把关机uFlags所能用到的相关常数发上来,如下:

  
  Private Const EWX_FORCE = 4
  Private Const EWX_LOGOFF = 0
  Private Const EWX_REBOOT = 2
  Private Const EWX_SHUTDOWN = 1

    怎么样?看得懂吧?英语稍微好一点基本上没问题。不过这里我还是要解释一番,照顾新手嘛!

  
    EWX_FORCE 前面的 EWX_ 我就不说了,关键是看 _ 符号后面的,Force 单词翻译:强制,强迫。人工在翻译一下(我英文不好,翻译错了请别见怪,呵呵 ^_^ ),意思是说:强制执行ExitWindowsEx API关机函数。不知道这样解释你能不能明白。那到底这个常数有什么用呢?这里我们先回忆一下以前关机的时候,当Windows无法关闭某些窗口的时候就停止继续关机了,最后还得把无法关闭的窗口手动关闭方可,现在,如果我们使用这个常数进行关机,那Windows不管你窗口能不能关闭,直接强制关闭。希望你懂了。
  
  EWX_LOGOFF 这个嘛,貌似组合单词,不可直接翻译,那样就不是那个意思了。Logout Off,是这样写吗?注销的意思。
  
  EWX_REBOOT 不浪费时间了,直接说明意思:重新启动。
  
  EWX_SHUTDOWN 关机。

   
    至于第二个ByVal dwReserved As Long,为保留整形,一般为0即可。至于为什么为0,大家可以到网上下载一些专门讲解API函数的电子书看看,里面有大部分API函数的详细讲解。或者下载VS.MSDN看看,在MSDN中说Windows 2000/95/98/Me中此参数忽略,XP中是指定关机消息说明。

  
    最后看看这个API为Function声明,说明该函数有返回值,返回值为Long,MSDN中说:如果执行成功,则返回非零,否则为零。

  
    现在上面已经把这个关机API和相关参数常量都给你分析透了,你可别告诉我你还不知道怎么写?好了,这里我们做一个定时注销程序,呵呵,虽然很简单,不过很多时候用得上哦!在Form窗口上添加Timer控件,Interval 设置为1000,Enabled 设置为 True。好了,代码如下:

  
  Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
  Private Const EWX_LOGOFF = 0
  Private Sub Timer1_Timer()
      Static i As Integer
   
      i = i + 1
   
      Me.Caption = i '这一步纯粹是想看看当前已经执行到几秒了?可不要
   
      If i = 10 Then '秒数判断,可以根据自己的需要进行运算
          ExitWindowsEx EWX_LOGOFF, 0
      End If
  End Sub

  
    其实我都有点不想分析了,不过为了照顾大众,不得不说下,Static i As Integer 静态变量(问:啥叫静态变量?答:我晕!),i = i + 1是每执行Timer一次i就加1,Timer的interval设置为1000,1000为一秒,2000为二秒。。。。后面一个If i = 10 Then是判断当i=10以后,也就是10秒,就执行注销,这个时候你可别忘了保存好你的其它没有保存的文件哦,如果没保存资料丢失的话偶不承担任何法律责任的。其实这里我们可以自己做一个,如可以写成这样:ExitWindowsEx EWX_LOGOFF Or EWX_FORCE, 0,其中用了Or运算,整体的意思是强制Windows注销。这样理解就够了,只要能让你明白。

  
    现在我又要说一下了,不说不行的!就是在API中使用 Or 运算,关于Or运算符VB书中都有详细解释的,别告诉我你没看?没看马上去看!上面EWX_LOGOFF Or EWX_FORCE 的使用是把 注销 和 强制 进行Or位运算,对两个数值执行按位析取,这里涉及到二进制运算,说多了你可能不明白(如果你还是想追根到底的想知道到底是怎么一回事的话,我也没办法,给个网址你慢慢看http://book.csdn.net/bookfiles/110/1001103366.shtml),我就说简单点的吧,以后如果你想组合两个API常数的功能,一般都是用 Or 进行运行的。如上面写的。

  
    好了,保存其它文件,然后F5运行之,看着Form标题的数字慢慢添加,当为10时,Windows开始注销。。。

  
    小提示:在使用EWX_SHUTDOWN的时候你可能会感觉没有作用,主要是NT系统的安全性提高,需要用其它API进行提升自己的权限才可以。关于如何提升应用程序权限请百度一下。

  
    2,先从一些最简单的API开始

  
    无疑自己试着写程序是最好的提升方法,学完一些知识以后自己试着写写,这样能让你理解的更快更好,好了不说废话了,接着往下看。

  
    最简单的API,呵呵,哪些最简单呢?这个我也说不好,这样吧,咱们就从Get(获取)开始,那Get什么呢?Window(窗口),还是从窗口下手吧,这样更接近我们日常的编程,谁叫这是一个Windows操作系统呢?先列几个常用的API:

  
  GetWindow、GetWindowDC、GetWindowLong、GetWindowRect、GetWindowRgn、GetWindowsDirectory、GetWindowText、GetWindowThreadProcessId
  

    还有很多,我就先列举几个简单点的,咱们就从这几个中间随便抽几个来讲讲吧。

  
    先从GetWindowText下手,大家就表面的意思进行理解下,Get(获取)Window(窗口)Text(文本),Very Good!这个API以前不错的,可以获取密码框中的密码,呵呵,说到这里,我估计有些人开始兴奋起来了!那好,Follow Me!

  
    新建一个Form窗口,然后添加一个CommandButton,Caption设置为:显示密码。接着添加两个TextBox,Text1属性设置:PasswordChar=*;Text=123456789,Text2的属性基本上没有什么需要设置的,只需要把Text属性为空就可以了,它主要是用来帮助咱们显示出密码的。好了,在Form1代码框中填入以下代码:

  
  Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
  Private Sub Command1_Click()
      Dim sBuffer As String
   
      sBuffer = Space(255)
      GetWindowText Text1.hwnd, sBuffer, 255
   
      Text2.Text = sBuffer
  End Sub

  
    OK,F5运行,点击Command1,怎么样?Text1中的密码字符显示在Text2中了吧?你可以再更改下Text1中的密码,然后再点击Command1试试。也许你觉得会多此一举,为何不Text2.Text=Text1.Text这样?如果真的这样的话看似简单,那你就学不到API了。

  
    又到了开始分析的时候了,打起精神来,先看第一句:Dim sBuffer As String,不用说,声明一个字符串变量呗!接着看第二句:sBuffer = Space(255) 那这一句呢?有些人可能不知道了,没事,我会仔细讲的。Space是VB内置的字符串处理函数,VB中的帮助文件中有说明:
  
  
  开始{
  
  本示例使用 Space 函数来生成一个字符串,字符串的内容为空格,长度为指定的长度。
  Dim MyString
  ' 返回 10 个空格的字符串。
  MyString = Space(10)
  ' 将 10 个空格插入两个字符串中间。
  MyString = "Hello" & Space(10) & "World"
  
  }结束

评分

参与人数 2威望 +21 人气 +1 收起 理由
jzy123456 + 1 + 1 精品文章
410023425 + 20 支持

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-2-27 23:54:26 | 显示全部楼层
很显然,我这一句是要分配255个空格字符串内存,为啥要用分配?这都是为后面所要用到打定的基础。接着往下:

  
    GetWindowText Text1.hwnd, sBuffer, 255 这一步是关键,通过它来获取咱们想要的窗口文本,看第一个参数,我前面讲过hwnd一般都是需要传入句柄的,这时咱们传入了Text1.hwnd(Text1控件的句柄),第二个参数,lpSting为字符串变量,所以这里咱们传入sBuffer字符串变量。最后一个cch为Long整形,所以理应传入数字,这里我们传入了255。现在又有人想问了,为什么需要这么传入值?貌似和以前的传入不一样?确实!一刚开始你可能搞不懂,这时候我先讲讲大概的意思,我们用GetWindowText来获取窗口中的文本,当获取成功以后,理所当然会返回窗口中的字符串,但是当我们用这个API进行获取时,必须需要一个缓冲来保存我们所获取的字符串,你如果不信去试试把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
  
  
  
  
  
  好了,大家先凑合着看吧,下次更精彩,每天吸收一点有助力身体健康哈!!!^_^

评分

参与人数 1威望 +1 人气 +1 收起 理由
jzy123456 + 1 + 1 精品文章

查看全部评分

回复 支持 反对

使用道具 举报

发表于 2007-2-28 01:48:50 | 显示全部楼层
第二章有一处不懂, 就是OR的运算
其中:
  Private Const EWX_FORCE = 4
  Private Const EWX_LOGOFF = 0

如果将logoff和force结合使用,如:ExitWindowsEx EWX_LOGOFF Or EWX_FORCE, 0
那么这个数值等于0是如何得来的?具体该如何计算。
回复 支持 反对

使用道具 举报

发表于 2007-2-28 09:22:34 | 显示全部楼层
自己写的?水平好高啊!
回复 支持 反对

使用道具 举报

发表于 2007-2-28 09:51:01 | 显示全部楼层
看完了```自认为比昨天又强了一些``嘎嘎``3Q
回复 支持 反对

使用道具 举报

发表于 2007-2-28 10:51:22 | 显示全部楼层
HOHO,上帝又出新的一集啦,学习学习。。。
回复 支持 反对

使用道具 举报

发表于 2007-2-28 11:31:46 | 显示全部楼层
上帝下凡................
回复 支持 反对

使用道具 举报

发表于 2007-2-28 11:34:03 | 显示全部楼层
原帖由 踏雪冬思 于 2007-2-28 01:48 发表
第二章有一处不懂, 就是OR的运算
其中:
  Private Const EWX_FORCE = 4
  Private Const EWX_LOGOFF = 0

如果将logoff和force结合使用,如:ExitWindowsEx EWX_LOGOFF Or EWX_FORCE, 0
那么这个数值等 ...


你没发现吗?那几个参数全是偶数...所以位运算之后系统还能分辨...
这个数值不等于0,0前面有个逗号的,说明是第二个参数...
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2021-3-5 17:44

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表