VB 版 (精华区)

发信人: bloom (├┝┞┟┠┢┣), 信区: VB
标  题: VB API教程(王国荣版)(一)(转载)
发信站: 哈工大紫丁香 (2000年09月07日18:42:47 星期四), 转信

【 以下文字转载自 cnTemp 讨论区 】
【 原文由 bloom 所发表 】
发信人: Love1976 (狄飞惊), 信区: VisualBasic       
发信站: BBS 水木清华站 (Thu Apr  6 04:19:53 2000)

我认为这部教程写得非常好,以例子为中心,上手很快。现在已经编成书出版了,
就是邮电的那个旗标系列中的一本。

发信人: coolknight (酷骑士~找工作中), 信区: VB
标  题: VB 與 Windows API 講座(一) /王國榮
发信站: 武汉白云黄鹤站 (Tue Nov  9 20:02:31 1999), 站内信件

VB 與 Windows API 講座(一) /王國榮
------------------------------------------------------------------------
----
----
進入 Windows API 的熱身運動
------------------------------------------------------------------------
----
----
「VB 沒有提供這樣的功能, 必須呼叫 Windows API」, 有時候筆者會這樣回答
讀者的
問題, 雖然這麼回答有點偷懶, 或者說不負責任, 但這的確是事實, VB 所提
供的敘
述、函數、物件…雖然也不在少數, 但是都十分標準, 或者說規矩, 想變點花
樣,
通常是行不通的, 這是筆者決定開始撰寫本文的主要原因。
 
------------------------------------------------------------------------
----
----
Windows API 是大家的
------------------------------------------------------------------------
----
----
 
感覺上 VB 程式要呼叫 Windows API 是一件比較困難的事情, 或者說比較麻煩的
事情
, 但別忘了 Windows API 是大家的, 凡是在 Windows 工作環境底下執行的應用
程式
, 但別忘了 Windows API 是大家的, 凡是在 Windows 工作環境底下執行的應用
程式
, 都有權利呼叫 Windows API。
 
Windows 這個多工作業系統除了協調應用程式的執行、分配記憶體、管理系統資源
…之
外, 她同時也是一個很大的服務中心, 呼叫這個服務中心的各種服務(每一種服
務就是
一個函數), 可以幫應用程式達到開啟視窗、描繪圖形、使用周邊設備…等目的,
 由於
這些函數服務的對象是應用程式(Application), 所以便稱之為 Application 
Program
ming Interface, 簡稱 API 函數。
 
但 Windows API 與 C 語言最親近
------------------------------------------------------------------------
----
----
 
雖然說呼叫 Windows API(以下簡稱 API 或 API 函數) 是每一個應用程式的權利
, 但
不可否認的 API 卻與 C 語言最親近, 因為 API 函數在參數的傳遞上就是以 C 
語言為

標準。
 
但這並不表示 VB 程式不能呼叫含有參數的 API 函數, 如果傳遞的參數是單純的
資料
型別, 例如「整數」, 則 VB 與 C 語言還是相通的, 如果是特殊的資料型別(
包含「
字串」), 則必須遵循一定的規範, 否則不是無法得到正確的結果, 就是因為違
反規
定而被踢出系統。如何正確地傳遞各種資料型別的參數, 是 VB 程式呼叫 API 很
重要
的課題, 當然也是本系列講座的重點。
 
 
------------------------------------------------------------------------
----
----
物件 vs. handle
------------------------------------------------------------------------
----
----
 
除了參數傳遞方式有所不同之外, 要以 VB 程式呼叫 API, 還要具備 Windows 
程式設
計的 handle 觀念。VB 的程式設計模式是以物件為核心, 但 Windows 的程式設
計模式
卻是以 handle 為核心, 以下筆者先舉個簡單的例子來說明, 假設有一 VB 的表
單 F
orm1, 若要改變此一表單的標題, 則使用的方法是設定表單物件的 Caption 屬
性,
敘述如下:
 
Form1.Caption = "新的標題"
 
若以 API 來執行相同的工作, 則敘述如下:
 
ret = SetWindowText( Form1.hwnd, "新的標題" )
 
其中 Form1.hwnd (hwnd 是 handle of window 的縮寫)代表的是 Form1 這個表單
「視
窗」的 handle 。以下是呼叫此一 API 函數的完整程式:
Private Declare Function SetWindowText Lib _
"user32" Alias "SetWindowTextA" _
"user32" Alias "SetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String) As Long
Private Sub Command1_Click()
ret = SetWindowText(Me.hwnd, "新的標題")
End Sub
 
由於筆者接下來的解說會繼續使用此一函數, 請將以上程式輸入於表單的程式視
窗中,
 並且在表單上佈置一個 Command1 命令鈕。(如果懶得輸入, 可進入筆者網站下
載)
 
handle 是什麼?
------------------------------------------------------------------------
----
----
 
handle 是什麼?讓我們來檢查看看, 首先在 SetWindowText 之後增加以下敘述

 
Print TypeName(Form1.hwnd)
Print Form1.hwnd
 
結果 TypeName 印出 Long, 這表示 handle 的資料型別是 Long, 而接下來的 
Form1
.hwnd 則印出一個整數值。
 
handle 只是一個整數值嗎?一個整數值能夠做什麼呢?
 
 
真實世界的 handle
------------------------------------------------------------------------
----
----
 
handel 就字義來說, 是器具的「把手」, 以鍋子為例, 把手的用途是方便我們
取用
鍋子裡的食物, 它本身雖然沒什麼用, 卻可以幫我們取得有用的食物, 再舉個
例子,
 車子的門把也叫做 handle, 雖然門把好像也沒什麼大用處, 但透過門把打開車
門,
 可以讓我們使用整部車子, 也許有人會捧著鍋子吃東西, 或者打破車窗進入車
子,
但使用鍋把取用食物及使用門把打開車門還是最方便的事情。
 
handle 者, 存取 Windows 資源之識別碼
------------------------------------------------------------------------
----
----
 
在 Windows 的世界裡, 充滿著各種不同的系統資源, 例如視窗、功能表、圖片
、記憶
體、程式、程序…等, 都算是系統資源, 而 Windows 是這些資源的總管理者,
 為了
能夠管理這些資源, Windows 必須給每一資源一個唯一的識別碼, 此一識別碼便
稱為
 handle。
 
Windows 世界的 handle 與真實世界的把手在觀念上很類似, 由於每一個 handle
 都是
一個唯一的識別碼, 因此當程式要求 Windows 提供存取資源的服務時, 須出具
此一識
別碼, 如此 Windows 便可以找到此一識別碼所對應的資源, 然後進行存取的工
作,
別碼, 如此 Windows 便可以找到此一識別碼所對應的資源, 然後進行存取的工
作,
所以 handle 雖然只是一個整數值, 但它就像是鍋子的把手可用來取用鍋子的食
物一樣
, 此一數值則可用來取用 Windows 的系統資源。
 
handle 最重要的特性是同一時間不會有兩個資源的 handle 值是相同的, 在前面
的 S
etWindowText API 函數中, 程式傳入 Form1 表單視窗的 handel, 所以 
Windows 便
能夠根據此一唯一的 handle 值, 取得該 handle 所對應的視窗資源, 進而將把
標題
設定給這個視窗。
 
從 handle 到物件
------------------------------------------------------------------------
----
----
 
對很多 VB 的物件而言, 都含有 handle 性質的屬性, 如圖-1, 當我們使用這
類物件
時, 除了可以利用該物件的屬性及方法來操作物件外, 也可以利用其中 
handle 性質
的屬性來呼叫 API, 直接啟動 Windows 所提供的服務, 以前面的 
SetWindowText(Fo
rm1.hwnd, "新的標題") 為例, hwnd 便是附屬於 Form1 的 handle 性質屬性。

 
圖-1 含有 handle 的物件
 
簡單地說, VB 所提供的物件並沒有把 Windows 的 handle 程式設計模式丟到一
邊,
而是將 handle 封裝起來, 使之成為物件的一個屬性。
 
 
註:雖然說 Windows 的程式設計是以 handle 為核心, 但仍然有不少 API 函數
是與
handle 無關的, 例如字串的複製, 這類 API 函數通常不會使用到 Windows 所
配置的
系統資源, 所以不需要使用 handle。
 
------------------------------------------------------------------------
----
----
使用 Windows API 的難處
------------------------------------------------------------------------
----
----
 
當我們要開始使用 API 時, 必須知道三件事情:
 
(1) 要呼叫哪一個 API 函數。
(2) 如何宣告 API 函數。
(3) 如何傳遞參數。
 
要呼叫哪一個 API 函數
------------------------------------------------------------------------
----
----
 
這是以上三件事情當中最困難的一件, 主要的原因是 Windows 的 API 實在太多
了,
大約有 1500 個, 這還不包含 OLE、ODBC…等特殊的 API, 此外, 如果我們把
 API
大約有 1500 個, 這還不包含 OLE、ODBC…等特殊的 API, 此外, 如果我們把
 API
按不同性質加以分類, 則使用每一類 API 函數所應具備的背景知識亦各有不同,
 以系
統註冊區相關的 API 函數為例, 就必須先瞭解 Windows 如何安排系統註冊區,
 以及
存取系統註冊區的方式。
 
不過也不必被 1500++ 個函數給打退堂鼓了, 因為不是所有的程式設計都要仰賴
 API,
 當我們面對一個問題時, 首先還是尋求 VB 的解決方案, 如果 VB 實在無法解
決,
才考慮使用 API, 當然, 筆者接下來的講座也不是 API 函數一個一個往下介紹
, 而
會先過濾掉那些可用 VB 完成的 API。
 
如何宣告 API 函數
------------------------------------------------------------------------
----
----
 
在 VB 程式中, 若要使用 VB 內建的敘述或函數, 不必事先宣告直接呼叫即可,
 若要
使用 API 函數, 則必須在先把 API 函數的出處、函數名稱、參數、傳回值…等
宣告在
表單的 "一般" 區塊或是一般模組(.bas 檔案)中, 感覺上也是一件挺麻煩的工作
, 但
由於 VB 提供有輔助程式, 所以相對於另外兩件事情, 反倒是最輕鬆的。
 
如何傳遞參數
------------------------------------------------------------------------
----
----
 
 
由於 API 採用了 C 語言的參數傳遞方式, 而 C 語言的參數傳遞又與 VB 有著不
小的
差異, 以致不少呼叫 API 所造成的錯誤都發生在參數傳遞時, 所以本期我們將
會有不
少的篇幅放在如何傳遞參數上面。
 
------------------------------------------------------------------------
----
----
如何宣告 Windows API
------------------------------------------------------------------------
----
----
 
API 函數的宣告並不困難, 因為我們可以請 VB 的「API 檢視員」來幫忙, 以下
是使
用「API 檢視員」的方法:
 
1. 首先選取 VB 功能表的「增益集/增益功能管理員」, 然後在「增益功能管理
員」交
談窗中核取「VB API Viewer」, 按下「確定」鈕後, VB 的「增益集」功能表欄
底下
就會出現「API 檢視員」, 選取此一命令, 即可啟動「API 檢視員」。
 
2. 第一次執行 API 檢視員時, 須利用功能表的「檔案/載入文字檔」載入 VB 
Winapi
 目錄底下的 Win32api.txt, 接著在「可選項的項目」底下即會列出所有的 
API 函數
, 若我們雙按其中的函數, 則該函數的宣告即會出現在「選取的項目」底下, 
此時再
按下「複製」鈕, 可將選取的函數宣告複製到剪貼簿, 過程如圖-2, 接著回到
 VB 的
程式視窗, 再選取功能表的「編輯/複製」, 即可將函數的宣告從剪貼簿中複製
過來。
程式視窗, 再選取功能表的「編輯/複製」, 即可將函數的宣告從剪貼簿中複製
過來。

 
圖-2 利用「API 檢視員」將 API 的宣告複製到剪貼簿
 
接下來請注意 API 宣告式複製到 VB 程式的位置, 此時您有兩種選擇:(1) 先利
用 V
B 功能表的「專案/新增模組」新增一個一般模組(.bas 檔), 然後將 API 宣告式
複製
到此一模組的程式視窗中, (2) 將 API 宣告式複製到表單程式視窗的 "(一般
)" 區塊
底下, 但複製過來之後, 必須在 Declare 前面加上 Private 保留字。
 
將 API 宣告式放在一般模組與表單模組的差異是:放在一般模組的 API 函數, 
可供同
一專案的所有程式使用, 若放在表單模組, 則只有宣告 API 函數的表單可以使
用。
 
提昇載入 API 宣告式的速度
------------------------------------------------------------------------
----
----
 
如果您經常使用 API 檢視員, 就會發現載入 Win32api.txt 是蠻花時間的, API
 檢視
員允許我們將此一檔案轉換成 mdb 格式的資料庫, 此時所使用的命令是功能表的
「轉
換文字檔為資料庫」, 轉換之後, Win32api.txt 的所在目錄會增加 Win32api.
mdb 資
料庫檔案, 將來我們便可以利用功能表的「檔案/載入資料庫檔案」來載入此一資
料庫
檔案, 則載入的速度確實提昇不少。
 
 
不過 API 檢視員實在有點「阿達」, 因為載入 Win32api.txt 的 API 檢視員具
有「搜
尋」API 的功能, 但如果載入的是 Win32api.mdb 資料庫檔案, 則「搜尋」的功
能反
而不見了。筆者實在很不滿, 所以決定撰寫一個改良版的 API 檢視員, 也取您
閱讀本
文時, 也經完成了, 請隨時注意筆者的網站。
 
------------------------------------------------------------------------
----
----
如何傳遞參數
------------------------------------------------------------------------
----
----
 
在 API 函數所定義的參數型別中, 大致上可分成「數值」、「自訂型別」、「字
串」
(String)、及「Any」四種資料型別, 以下讓筆者按照這四種資料型別來說明 
VB 程式
與 API 的參數傳遞方式:
 
數值的傳遞
------------------------------------------------------------------------
----
----
 
數值型別在 API 的參數定義中可能有兩種形式:「參數名 As 數值型別」及「
ByVal 參
數名 As 數值型別」, 所代表的意義分別是數值的「傳址」及「傳值」呼叫, 與
 VB
的習慣完全相同, 以 GetFileSize(讀取檔案的長度) API 為例, 其宣告式如下

的習慣完全相同, 以 GetFileSize(讀取檔案的長度) API 為例, 其宣告式如下

 
Declare Function GetFileSize Lib "kernel32" Alias "GetFileSize" (ByVal 
hFile
 As Long, lpFileSizeHigh As Long) As Long
 
而呼叫的例子如下:
 
Dim hFile As Long, lenFile As Long
hFile = OpenFile(…) ' OpenFile 也是 API 函數
ret = GetFileSize ( hFile, lenFile ) ' lenFile 將傳回檔案長度
 
其中 hFile 參數為 Long 型別的「傳值」呼叫, lenFile 參數則是 Long 型別的
「傳
址」呼叫, 若呼叫成功, 則 GetFileSize 會將檔案的長度設定給 lenFile。
 
自訂型別的參數傳遞
------------------------------------------------------------------------
----
----
 
對 C 語言而言, 自訂型別的參數只能以位址來傳遞, 因此在 API 函數中, 並
沒有「
ByVal 參數名 As 自訂型別」的參數宣告, 至於「參數名 As 自訂型別」的傳址
呼叫,
 則與 VB 的習慣完全相同, 以 GetCursorPos(讀取滑鼠的位置) 為例, 其宣告
式如下

 
 
Type POINTAPI ' POINTAPI 為一自定型別
x As Long
y As Long
End Type
Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint
 As
POINTAPI) As Long
 
而呼叫的例子則是:
 
Dim p As POINTAPI
ret = GetCursorPos ( p )
Print p.x, p.y ' p 傳回滑鼠的位置
 
如果 API 函數的參數中含有自訂型別, 則除了 API 函數的宣告式之外, API 所
使用
的自訂型別(例如 GetCursorPos 的 POINTAPI)也必須放到 VB 程式中, 此時 API
 檢視
員的操作方法如下:
 
1. 選取「API 類型」底下的「型態(Types)」, 接著「可選用的項目」底下所列
示的不
再是 API 函數的宣告式, 而是 API 函數的自訂型別。
 
2. 接下來是選取並且複製自訂型別的定義到剪貼簿中, 然後再從剪貼簿複製到 
VB 程
式中。
式中。
 
字串的傳遞
------------------------------------------------------------------------
----
----
 
在 API 函數中, 字串參數的宣告只有「ByVal 參數名 As String」一種形式(沒
有「參
數名 As String」形式), 按照 VB 習慣, 這是「傳值」呼叫, 但實際上, API
 對於
所有字串參數的處理, 卻一概以「傳址」視之, 所以當我們傳遞字串到 API 函
數時,
 心理上應有的準備是「這個字串的內容可能會被 API 改變掉」, 以 
GetWindowText(
讀取視窗的標題) API 為例, 其宣告式如下:
 
Private Declare Function GetWindowText Lib "user32" Alias 
"GetWindowTextA" (
ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As 
Long
 
表面上 lpString 參數為傳值呼叫, 但執行以下的呼叫式之後, S 的內容卻會改
變(將
等於 Form1 視窗的標題):
 
Dim S As String
S = "某字串................................."
ret = GetWindowText(Form1.hwnd, S, Len(S) )
 
當然不是所有字串參數的內容都會被改變, 以下面的 SetWindowText 呼叫式為例
, A
當然不是所有字串參數的內容都會被改變, 以下面的 SetWindowText 呼叫式為例
, A
PI 就只會讀取字串 S 的內容, 而不會改變它:
Dim S As String
S = "某字串................................."
ret = SetWindowText(Form1.hwnd, S)
 
在呼叫含有字串參數的 API 函數以前, 我們必須先弄清楚 API 函數的本質, 確
定 A
PI 函數對於傳入的參數是否會進行寫入的動作, 因為兩者在 VB 程式端應預先準
備的
工作並不相同。稍後筆者會進一步說明。
 
Any 型別的參數傳遞
------------------------------------------------------------------------
----
----
 
所謂 Any 型別的參數, 指的是 VB 程式可以傳入數值、字串、或自訂型別…等資
料的
參數, 至於可以傳入哪一種資料, 則與個別 API 函數有關係。Any 型別可說是
 API
的參數類型中最為邪惡的一種, 因為如果傳入的參數不正確, 輕則結果錯誤, 
重則出
現「這個程式執行的作業無效, 即將關閉」, 表示程式當掉了!
 
有哪些 API 函數含有 Any 型別的參數呢?還好不多, 而且使用過一兩個之後,
 就能
夠掌握參數傳遞的原則, 未來本講座所介紹的 API 函數若屬於此一性質, 也會
特別說
明。
 
 
------------------------------------------------------------------------
----
----
VB 字串 vs. API 字串
------------------------------------------------------------------------
----
----
 
其實以上所介紹幾種的參數類型中, 最大宗還是「字串」的傳遞, 而且對初學者
來說
, 也是最容易犯錯的。
 
VB 的字串
------------------------------------------------------------------------
----
----
 
VB 字串可分成「非固定長度」及「固定長度」兩種, 如下:
 
Dim S1 As String ' 非固定長度字串
Dim S2 As String*80 ' 固定長度字串
 
兩者的差別除了長度是否可變之外, 非固定長度字串會在字串的最尾端補上 
Chr(0) 字
元, 以 "VB5" 字串為例, 在記憶體內部其實含有 "VB5"+Chr(0) 共 4 個字元,
 至於
固定長度的字串則會先用「空白」字元補滿整個字串, 然後才補上 Chr(0) 字元
, 以
下面的 S2 字串為例:
下面的 S2 字串為例:
 
Dim S2 As String * 80
S2 = "VB5"
 
在 S2 的記憶體中所包含的字元則有 "VB5"+77個空白字元+Chr(0)。
 
雖然 VB 會在字串的尾端補上 Chr(0) 字元, 但這個字元並不會計入字串的長度
中,
以 "VB5" 為例, 雖然記憶體內部是 "VB5" + Chr(0), 但長度依然等於 3。其實
在 V
B 的字串中, 除了補上 Chr(0) 字元之外, 還會在字串的前面預留 4 個字元來
記錄著
字串的長度, 結構如圖-3:
 
圖-3 VB 字串的結構
 
當我們呼叫 Len() 函數時, VB 不是計算 Chr(0) 的位置來求取字串的長度, 而
是直
接取出記錄於字串中的長度。
 
API 的字串
------------------------------------------------------------------------
----
----
 
相對於 VB 的字串, API 的字串並不會記錄「字串的長度」, 而它計算字串長度
的方
法是判斷 Chr(0) 字元, 其結構如圖-4:
法是判斷 Chr(0) 字元, 其結構如圖-4:
 

圖-4 API 字串的結構
雖然 VB 的字串與 API 的字串結構不同, 但是當我們傳遞 VB 的字串到 API 時
, VB
 只會傳入圖-3「字串的內容+Chr(0)」的部分, 如此才可以配合 API 的字串結構

 
解決字串的不一致性問題
------------------------------------------------------------------------
----
----
 
儘管 VB 已經把傳入 API 的字串弄得跟 API 的字串結構一樣, 但還是可能有問
題,
直接來看例子, 請比較以下兩個呼叫 SetWindowText 的例子:
 
ret = SetWindowText(Form1.hwnd, "某字串")
Dim S As String * 80
S = "某字串"
ret = SetWindowText(Form1.hwnd, S)
 
第一個 SetWindowText 呼叫式是直接傳入「字串常數」, 結果沒有問題, 但傳
入「固
定長度」字串 S 的第二個 SetWindowText 呼叫式卻有點小問題, 因為「S = "某
字串
"」其實表示「S = "某字串"+77個空白字元+Chr(0)」, 所以它比 "某字串" 要多
出 7
7 個空白字元, 如果希望 S 只傳入 "某字串"+Chr(0), 則程式修正的方法如下

 
 
S = "某字串" + Chr(0)
ret = SetWindowText(Form1.hwnd, S)
 
接下來讓我們再來檢視會改變字串內容的 API 函數, 例如:
 
Dim S As String * 80
ret = GetWindowText(Form1.hwnd, S, 80 )
 
以上的 GetWindowText 函數會把 Form1 視窗的標題填入 S 字串中, 然後傳回來
。(註
:以上的參數三表示參數二的長度, 目的是告訴 GetWindowText 參數二的長度只
有 8
0 個字元, 如此一來, 即使 Form1 的標題超過 80 個字元, GetWindowText 也
不會
把資料寫出 80 個字元的範圍, 如此可避免破壞其他資料)
 
以上的呼叫式有沒有問題呢?讓我們假設 Form1 的標題是 "Form1", 然後來檢視
執行
的結果, 由於 API 以 Chr(0) 為字串的結束字元, 因此當 GetWindowText 將 
"Form
1" 指定給 S 字串時, 實際的動作等於「S = "Form1" + Ch(0)」, 結果使得 
S 變成
「"Form1"+Ch(0)+74個空白字元+Chr(0)」, 這樣的結果雖然不算錯, 但請注意
 S 字
串中所記錄的長度仍然等於 80, 如圖-5(a), 而實際上我們期望的結果應該如圖
-5(b
)。
 
圖-5 字串的結果不是我們期望的
 
 
為了讓 S 能夠得到我們期望的圖-5(b), 呼叫 GetWindowText 之後, 應該將 
S 第一
個 Chr(0) 之前的字串指定給另一個非固定長度字串, 如下:
 
Dim S As String * 80
Dim Sx As String
ret = GetWindowText(Form1.hwnd, S, 80 )
Sx = Left( S, InStr(S, Chr(0)) - 1 )
 
則 Sx 就剛好等於 "Form1"。
 
GetWindowText 是直接把 Chr(0) 補在字串參數中, 藉以告訴呼叫端傳回字串的
長度,
 有些函數則會把字串的長度當成參數傳回來, 以 RegQueryValue 為例:
 
Declare Function RegQueryValue Lib "advapi32.dll" Alias "RegQueryValueA"
 (By
Val hKey As Long, ByVal lpSubKey As String, ByVal lpValue As String, 
lpcbVal
ue As Long) As Long
 
參數三 lpValue 是傳入的字串, 參數四則是傳回的字串長度, 若呼叫此類函數
, 則
呼叫之後可利用 Left 函數設定正確的傳回字串, 如下:
 
Dim L As Long
ret = RegQueryValue(hKey, KeyName, S, L)
ret = RegQueryValue(hKey, KeyName, S, L)
Sx = Left( S, L )
 
傳遞的字串常見的錯誤
 
其實我們可以把 API 的字串參數分成「唯讀」及「可寫入」兩種, 以 
SetWindowText
 為例, API 會讀取字串參數, 然後將參數內容設定給視窗的標題, 所以字串參
數是
唯讀的, 以 GetWindowText 為例, API 會讀取視窗的標題, 然後設定給字串參
數,
 所以字串參數是可寫入的, 在使用上, 可寫入的參數比較容犯以下兩種錯誤:

 
(1)
Dim S ' 未將 S 宣告成「字串」型別

S = Space(80)
ret = GetWindowText(Form1.hwnd, S, 80 )
 
(2)
Dim S As String ' S 為一空字串
ret = GetWindowText(Form1.hwnd, S, 80 )
 
◇ 錯誤(1):沒有把 S 宣告成「字串」, 這將使得 S 無法正確地轉換成 API 的
字串
, 所以呼叫 API 函數之後, 仍然無法得到正確的結果。
◇ 錯誤(2):傳入 API 函數的字串 S, 沒有足夠的空間容納 API 函數所寫入的
字串,
 此時 API 函數將會破壞 S 之後的資料, 而此一破壞資料的行為極可能讓程式當
掉。
 此時 API 函數將會破壞 S 之後的資料, 而此一破壞資料的行為極可能讓程式當
掉。


 
------------------------------------------------------------------------
----
----
準備工作
------------------------------------------------------------------------
----
----
 
本期所介紹的內容只能算是 Windows API 的初步, 但也許這是您第一次接觸 
Windows
 API, 所以筆者並沒有打算一開始就給您滿漢大餐, 如果您有意繼續跟著筆者進
入 W
indows API 的世界, 建議您先熟悉 API 檢視員的使用, 然後試著寫程式檢測本
期所
介紹過的 API 函數, 在檢測的過程中, 一定會遭遇不少挫折, 但這是正常的現
象,
 當然, 如果您想比對筆者所寫的呼叫範例, 可進入網站下載, 下一期起筆者將
會開
始介紹 Windows API 中比較實用的函數。
 

--
" The Matrix is everywhere, it's all around us, here even in this room.
 You
 can see it out your window, or  on your television. You feel it when 
you
 go to work, or go to church or pay your taxes. It is the world that has
 been
 pulled over your eyes to blind you from the truth... Unfortunately, 
no one
can be told what the Matrix is. You have to see it for yourself."
------------------------------------------------------------------------
----
                                                                   
Morphe

※ 来源:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 202.114.3.124]

--
我并不是在等待奇迹,因为我知道没有奇迹的。
有的,也只是爱情、意志和勇气。
是这些东西的重叠后,而成为奇迹的。
所以,我从未曾想过放弃。

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: blo0m.bbs@smth.org]
--
※ 转载:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: 202.118.247.254]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:209.947毫秒