转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
VB与Windows API 间的呼叫技巧         ★★★★

VB与Windows API 间的呼叫技巧

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1749 更新时间:2009/4/23 16:40:02
sp;    DIM  HLSTR5  AS  STRING(255)      HLSTR

    VB5中WIN32 API的呼叫请多多使用BSTR,因为使用HLSTR的结果是,VB还得做HLSTR
-> BSTR的转换来呼叫WIN API若有传回STRING而後再做BSTR->HLSTR的工作。然而使用
BSTR来工作时,若处理有传回值的STRING参数,则还要有额外的动作:

    1.先给定字串的初值,且字串的长度要够放传回值。
    2.传回後,去除传回值中多余的字元。

    或
例如:
-----------------------------------------------------------------------------
int GetWindowText(
    HWND        hWnd,           // handle of window or control with text
    LPTSTR      lpString,       // address of buffer for text
    int         nMaxCount       // maximum number of characters to copy
   );
   该 API 取得WINDOW  Title Bar的文字,而传回值是放入lpString的character个数。
VB的宣告如下:

Decl are Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
       (ByVal hwnd As Long,  _
        ByVal lpString As String,  _
        ByVal cch As Long)  As Long
范例一
*****************************************************************************
Dim CharCnt As Long
Dim lpString As String
Dim tmpstr As String
Dim NullPos As Long

Form1.Caption = "这是一个test"
lpString = String(255, 0)  ’设定初值
CharCnt = GetWindowText(Me.hwnd, lpString, 256)  ’CharCnt = 12
tmpstr = Left(lpString, CharCnt) ’如此做会有一些问题
Debug.Print Len(tmpstr)   ’得12
Label1.Caption = Left(lpString, CharCnt)
Debug.Print Len(Label1.Caption) ’得8
*****************************************************************************

    以范例一的例子来看,设定lpString= String(255,0)的目的,是设定255个字元的
空间给 lpString(加上最後的null一共256),CharCnt的值是12,明眼者可看到len("这
是一个test") 会是8,但CharCnt是12, 所以直接使用Left()函数来取得子字串会有问
题,这是UniCode与ANSI String间的关系,所以了,当您看到有些书的范例用这种方法
取子字串,是不太完善的,所以改用范例二的方式,比较正确。

范例二
*****************************************************************************
Form1.Caption = "这是一个test"
lpString = String(255, 0)  ’设定初值
CharCnt = GetWindowText(Me.hwnd, lpString, 256)  ’CharCnt = 12
NullPos = InStr(1, lpString, Chr(0), vbBinaryCompare)
tmpstr = Left(lpString, NullPos - 1)
lable1.Caption = tmpstr
*****************************************************************************
四、 Null 值的传递

    我们再回到求ProductId的问题,我们已知使用RegOpenKeyEx()来取得subkey的Han
dle值,紧接著便是用RegQueryValueEx()来取值。

-----------------------------------------------------------------------------
LONG RegQueryValueEx(
    HKEY     hKey,              // handle of key to query
    LPTSTR   lpszValueName,     // address of name of value to query
    LPDWORD  lpdwReserved,      // reserved
    LPDWORD  lpdwType,          // address of buffer for value type
    LPBYTE   lpbData,           // address of data buffer
    LPDWORD  lpcbData           // address of data buffer size
   );
VB的宣告(由API检视员中Copy下来者)
Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
    (ByVal hKey As Long, _
     ByVal lpValueName As String, _
     ByVal lpReserved As Long, _
    lpType As Long,  _
    lpData As Any, _
    lpcbData As Long) As Long
-----------------------------------------------------------------------------
    仔细看一下第三个参数,WIN API中是LPDWORD可是VB中麽会是用ByVal的方式传递
呢?原因在於 lpReserved一定要传Null进去,VB在呼叫时便在 这参数的位置上填0(见
范例三)。为何传Null就得这做?我们可以这麽想,我们 在程式中下指令,告诉VB要以
ByVal 的方式传0出去,而WIN API里,它可不管VB是ByVal或ByRef,API 认定我们传

来的就是它需要的,所以了,第三个参数在API中认定我们传进的是一个Address,而VB
传0进去,那代表API若去取得它的内容,便会取得Address 0 的内容,或许Window的
Null值便是指向Address 0呢!另一个作法比较直接,将VB宣告的第三个参数宣告由
ByVal lpReserved As Long改成 ByVal lpReserved as String而使用时固定传
vbNullString 进去也可以。这里在一个观念,那就是VB对Win API的宣告,纯粹是给VB
自己看的,在API中定义了一个指标的参数,Api检视员会将之宣告成ByRef的方式(字串
除外),但我们可随需要而更动它,一个原始应为ByRef的参数宣告,我们可以将之改为
ByVal的方式,只要我们能取得参数的位址,而将这型态为Long的位址以ByVal传出去,
Win API 端根本不知道VB端是用什麽方式传,反正只要我们传了一Long值进去,Win API
就会以这个Long值当作是Address来运作。

    问题还没有解决,RegQueryValueEx()的第四个参数lpType若为REG_SZ(= 1)那代表
lpData是Null Terminate的String,若为REG_DWORD ( = 4)那代表lpData是Long值,

是因为没有办法事先知道lpData的真正型态,所以VB就使用 ASAny的型态,它要VB放弃
型态的检查,传什麽值进去都可以,但是在这里有一些问题,如果lpType是REG_DWORD
那麽lpData以ByRef的方式没有问题,但是如果lpType 是REG_SZ,STRING是要以ByVal
的方式来宣告,所以会有冲突,而解决的方式就是改写API检视员Copy进来的宣告。

-----------------------------------------------------------------------------
Declare Function RegQueryLong Lib "advapi32.dll" Alias "RegQueryValueExA" _
     (ByVal hKey As Long, _
      ByVal lpValueName As String, _
      ByVal lpReserved As Long, _
      lpType As Long,  _
      lpData As Long, _
      lpcbData As Long) As Long

Declare Function RegQueryString Lib "advapi32.dll" Alias "RegQueryValueExA" _
     (ByVal hKey As Long, _
      ByVal lpValueName As String, _
      ByVal lpReserved As Long, _
      lpType As Long,  _
      Byval lpData As String, _
      lpcbData As Long) As Long
-----------------------------------------------------------------------------
    使用两个宣告来解决这个问题,依不同的lpType呼叫不同的函式,即lpType= REG_
DWORD时,呼叫RegQueryLong, lpType = REG_SZ时则为RegQueryString这也可以让我们
了解为何VB API的宣告为什麽要有Alias的存在。

范例三
*****************************************************************************
Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long)  _
        As Long
Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA"
  (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
   ByVal samDesired As Long, phkResult As Long) As Long
Declare Function RegQueryString Lib "advapi32.dll" Alias _
   "RegQueryValueExA" (ByVal hKey As Long,  _
   ByVal lpValueName As String, ByVal lpReserved As Long, _
   lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Const REG_EXPAND_SZ = 2
Const HKEY_CLASSES_ROOT = &H80000000
Const READ_CONTROL = &H20000
Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Const KEY_QUERY_VALUE = &H1
Const KEY_ENUMERATE_SUB_KEYS = &H8
Const KEY_NOTIFY = &H10
Const SYNCHRONIZE = &H100000
Const KEY_READ = ((STANDARD_RIGHTS_READ Or _
      KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or _
      KEY_NOTIFY) And (Not SYNCHRONIZE))

Dim key5 As String, ValueName as String, strBuff&nb

上一页  [1] [2] [3]  下一页


[VB.NET程序]Auto Complete combo Box(VB.NET Source Use API…  [VB.NET程序]在 VB 中使用 Unicode API
[VB.NET程序]API 更改系统菜单条目  [VB.NET程序]在VB中调用Windows API的注意事项
[VB.NET程序]vb调用winInet API接口post数据到指定的url  [VB.NET程序]如 何 用 API 播 放 CD
[VB.NET程序]VB5.0与Windows API 间的呼叫技巧  [VB.NET程序]在VB6中用WINDOWS API函数读写INI文件
[VB.NET程序]Visual Basic调用Windows API函数的应用举例  [VB.NET程序]VB + API 获取 IE 的 代理服务器 配制
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台