Win95系統API函數大揭秘
Win95以其嶄新精緻的外觀、簡便快捷的操作方式,讓你盡享操作平台之樂趣。同屬Microsoft公
司的Visual Basic不僅僅是一門電腦語言,還是一個集應用程式開發、測試、查錯功能於一體的功能
強大的整合式開發環境, 數百萬的程式員受益於此。
Visual Basic一個強大的特性是它具有調用駐留在動態串連庫(DLL)檔案中的函數功能,其中包
括由Windows提供和使用的所有函數。對幾百個函數以及DLL所包含的其它函數的存取將Visual Basic
的功能進行了大大的擴充,其功能遠遠超出其它語言,真有種“信手拈來”之神韻,畢竟Visual Basic
是Microsoft公司的“嫡系部隊”。 你可以在你的應用程式中利用WINDOWS API提供的數百個API介面
函數進行擴充,加速應用程式的建立,減少程式開發的重複性(比爾.蓋茨找你打著作權官司可不關我事!
——喔喔!)
所謂API就是“應用程式介面”(Application Programing Interface),是一些用C語言編寫由作業系統
自身調用的函數。Windows API函數由許多“動態串連庫”或DLL組成。在32位Windows中,核心的Windows
API DLL有如下一些:
gdi32.dll--------圖形顯示介面的API
kernel32.dll-----處理低級任務(比如記憶體和任務管理)的API
user32.dll-------處理視窗和訊息(Visual Basic程式員能把其中一些當作事件訪問)的API
還不斷有新的API出現,處理新的作業系統擴充,比如E-MAIL、連網和新的外設。
由於Windows API函數不是Visual Basic內建函式,所以在使用它們之前必須顯式地加以聲明。要
想得到正確格式化的函式宣告,可以訪問WINAPI目錄下的檔案WIN32API.TXT。
本文只對Win95系統API函數加以說明並調用Win95內建功能。例如,我們可以直接調用標準化的“重
新啟動”、“磁碟格式化”、調用並更改標準“關於視窗”、查看“屬性”、 設定“牆紙”、 建立快速鍵、
確定記憶體、讀寫“註冊表”、在建立狀態列表徵圖等。
? 重新啟動
有些應用程式安裝完畢要求重新啟動一次,以使設定生效,可利用ExitWindowsEx函數實現。
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved
As Long) As Long
Private Sub Command1_Click()
ExitWindowsEx &H43, 0
End Sub
? 磁碟格式化
當滑鼠右鍵單擊“3.5磁碟片A”並選擇“格式化”時,則彈出標準的“磁碟格式化”視窗。我們
也可以在應用程式中利用函數輕鬆調用Windows 95標準的“磁碟格式化”視窗,以實現對磁碟相應
的操作功能。
表單加入如下代碼:
Private Sub Form_Click()
FormatFloppy
End Sub
加入代碼如下的模組:
Public Const WM_CLOSE = &H10
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal
lpWindowName As Any) As Long
Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal
lpBuffer As String, ByVal nSize As Long) As Long
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
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Type POINTAPI
X As Long
y As Long
End Type
Const SWP_NOSIZE = &H1
Const SWP_NOZORDER = &H4
Public Sub FormatFloppy()
Dim sBuffer As String, Windir As String, Procs As String, X
Dim lResult As Long
sBuffer = String$(255, 0)
lResult = GetWindowsDirectory(sBuffer, Len(sBuffer))
Windir = Trim(sBuffer)
Procs = Left(Windir, lResult) & "/rundll32.exe shell32.dll,SHFormatDrive"
Call CenterDialog("Format - 3? Floppy (A:)")
X = Shell(Procs, 1)
Call CenterDialog("Format - 3? Floppy (A:)")
k = LockWindowUpdate(0)
End Sub
Public Sub CenterDialog(WinText As String)
DoEvents
On Error Resume Next
Dim D3 As Long
D3 = LockWindowUpdate(GetDesktopWindow())
Dim wdth%
Dim hght%
Dim Scrwdth%
Dim Scrhght%
Dim lpDlgRect As RECT
Dim lpdskrect As RECT
Dim hTaskBar As Long
hTaskBar = FindWindow(0&, WinText)
Call GetWindowRect(hTaskBar, lpDlgRect)
wdth% = lpDlgRect.Right - lpDlgRect.Left
hght% = lpDlgRect.Bottom - lpDlgRect.Top
Call GetWindowRect(GetDesktopWindow(), lpdskrect)
Scrwdth% = lpdskrect.Right - lpdskrect.Left
Scrhght% = lpdskrect.Bottom - lpdskrect.Top
X% = (Scrwdth% - wdth%) / 2
y% = (Scrhght% - hght%) / 2
Call SetWindowPos(hTaskBar, 0, X%, y%, 0, 0, SWP_NOZORDER Or SWP_NOSIZE)
DoEvents
End Sub
? 調用“關於”視窗
在“協助”菜單選擇“關於XXX”會彈出標準“關於”視窗,利用ShellAbout函數不但可以調用
標準“關於”視窗,還可以隨意更改其中內容呢!
ShellAbout聲明如下:
HWnd設定視窗控制代碼,szApp設定視窗的“Caption”, szOtherStuff 在“著作權”和“使用權”
之間的空白處增加額外說明。
Private Declare Function ShellAbout Lib "shell32.dll" Alias "ShellAboutA" (ByVal hWnd As Long,
ByVal szApp As String, ByVal szOtherStuff As String, ByVal hIcon As Long) As Long
Private Sub Form_Load()
Call ShellAbout(hWnd, "何發武天使工作室!", "調用標準的關於視窗" & vbCrLf & "上帝與你同在!
阿彌陀佛!", 0)
End Sub
你還可以通過對註冊表資訊“動手術”來改變系統的“著作權資訊”運行REGEDIT,按照如下路徑:
HKEY_LOCAL_MACHINE →SOFTWARE → Microsoft→Windows→ CurrentVersion →Version,就會找到
你電腦中“關於”版本的通用設定,你可以把Version的內容改為你心儀的設定,如“何發武天使工
作室”、“ 何發武野狼工作室”等。
? 查看“屬性”
Win95中增加了一個全新的概念——“屬性”,每個對象都擁有自己的“屬性”,在“屬性”視窗裡
是關於對象的詳細描述, 並且不同的對象“屬性”視窗的說明是不同的。我們可以用ShellExecuteEX函
數直接調用“屬性”標準視窗。下述程式功能相當於當滑鼠右鍵單擊根目錄下的“autoexec.bat”並選
擇“屬性”時,則彈出標準的“屬性”視窗。
表單加入如下代碼:
Private Sub FORM_Click()
Dim r As Long
Dim FileName As String
FileName = "c:/autoexec.bat"
r = ShowProperties(FileName, Me.hwnd)
If r <= 32 Then MsgBox "Error"
End Sub
加入代碼如下的模組:
Option Explicit
Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type
Public Const SEE_MASK_INVOKEIDLIST = &HC
Public Const SEE_MASK_NOCLOSEPROCESS = &H40
Public Const SEE_MASK_FLAG_NO_UI = &H400
Declare Function ShellExecuteEX Lib "shell32.dll" Alias "ShellExecuteEx" _
(SEI As SHELLEXECUTEINFO) As Long
Public Function ShowProperties(FileName As String, OwnerhWnd As Long) As Long
Dim SEI As SHELLEXECUTEINFO
Dim r As Long
With SEI
.cbSize = Len(SEI)
.fMask = SEE_MASK_NOCLOSEPROCESS Or SEE_MASK_INVOKEIDLIST Or SEE_MASK_FLAG_NO_UI
.hwnd = OwnerhWnd
.lpVerb = "properties"
.lpFile = FileName
.lpParameters = vbNullChar
.lpDirectory = vbNullChar
.nShow = 0
.hInstApp = 0
.lpIDList = 0
End With
r = ShellExecuteEX(SEI)
ShowProperties = SEI.hInstApp
End Function
? 設定牆紙
牆紙是顯示在案頭的圖片或映像,是Win95的一個重要視窗。你可以通過改變列表中的檔案來選擇多
姿多採的牆紙。牆紙為Win95蒙上了一披美麗的面紗,我們可以利用SystemParametersInfo函數來揭開
它的“神秘面紗”並親手為她營造異樣的風采。
在表單中增加List1控制項,表單加入如下代碼:
Option Explicit
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA"
(ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long)
As Long
Const SPI_SETDESKWALLPAPER = 20
Const SPIF_UPDATEINIFILE = &H1 'update Win.ini Constant
Const SPIF_SENDWININICHANGE = &H2 'update Win.ini and tell everyone
Private Sub Form_Load()
Dim Temp As String
Temp = InputBox("Please Input A Directory", "Changer", "C:/WINDOWS/")
If Temp = "" Then End 'Cancel clicked
If Right$(Temp, 1) <> "/" Then Temp = Temp + "/"
List1.Tag = Temp
Temp = Temp + "*.bmp" 'Set the file filter (path + *.BMP)
Temp = Dir$(Temp)
Do While Temp$ <> ""
Temp = Dir$
If Temp = "" Then Exit Do
List1.AddItem Temp
Loop
List1.AddItem "(None)"
Show
List1.SetFocus
List1.ListIndex = 0
End Sub
Private Sub list1_dblclick()
Dim Temp As String
Dim BMPFile As String
Temp = Tag
If List1.Text = "(None)" Then
BMPFile = "(none)"
Else
BMPFile = Temp + (List1)
End If
SystemParametersInfo SPI_SETDESKWALLPAPER, 0, ByVal BMPFile, SPIF_UPDATEINIFILE
End Sub
Private Sub List1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then list1_dblclick
End Sub
馬上試試,當場把你的牆紙改變啦(不變不收錢)!爽吧!
? 建立快速鍵
Win95中捷徑提供了對常用程式和文檔的訪問捷徑,你可以為案頭或檔案夾中的任何程式、文檔
或印表機添加捷徑。VB5中利用fCreateShellLink函數可以為常用程式和文檔快速建立建立快速鍵。
fCreateShellLink的聲明為:
Private Declare Function fCreateShellLink Lib "STKIT432.DLL" (ByVal lpstrFolderName As String,
ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArgs As String)
As Long
LpstrFolderName設定捷徑的檔案夾名稱,lpstrLinkName設定捷徑的標題名稱,lpstrLinkPath
設定捷徑所指向的應用程式的目錄及檔案名稱。簡而言之,如下格式:
fCreateShellLink(Destinationpath, Shortcutname, SourcepathAppName, "")
如下代碼在“案頭”上為“d:/path/appname.exe”應用程式建立名為"Shortcut Title"的快捷方
式。
Private Declare Function fCreateShellLink Lib "STKIT432.DLL" (ByVal lpstrFolderName As String,
ByVal lpstrLinkName As String, ByVal lpstrLinkPath As String, ByVal lpstrLinkArgs As String)
As Long
Private Sub Form_Click()
lResult = fCreateShellLink("..../WINDOWS/DESKTOP", "Shortcut Title", "d:/path/appname.exe",
"")
End Sub
技巧:
如果想在“案頭”上建立捷徑,則建立目標目錄應該為“..../WINDOWS/DESKTOP”; 如果想在
“開始”菜單中建立捷徑,則建立目標目錄應該為“..../WINDOWS/Start Menu”; 如果想在“程
序”菜單中建立捷徑,則建立目標目錄應該為相應的“....C:/WINDOWS/Start Menu/Programs”中,
以此類推。
? 確定記憶體
我們經常要訪問Windows管理的記憶體。對應用程式效能影響最大的因素是可用的記憶體容量,訪問系
統記憶體在處理類似於位元影像檔案之類的大檔案時非常有用,因為程式通過分頁檔(Swap)的方法,可以
獲得比實際可用記憶體更大的記憶體。知道記憶體如何分配後,就可以讀入記憶體值並操作大型數字檔案。可以
用豐富的Win32 API函數確定Windows 的全域記憶體並操作資料檔案,這些對於確定程式能否正常工作非
常有用。
dwLength 資料結構的長度
dwMemoryLoad 記憶體使用量百分比
dwTotalPhys 實際記憶體總位元組數
dwAvailPhys 可用的實際記憶體位元組數
dwTotalPageFile 分頁檔案總位元組數
dwAvailPageFile 分頁檔案可用位元組數
dwTotalVirtual 虛擬記憶體的總位元組數
dwAvailVirtual 可用的虛擬記憶體位元組數
加入代碼如下的模組:
Type MEMORYSTATUS
dwLength As Long
dwMemoryLoad As Long
dwTotalPhys As Long
dwAvailPhys As Long
dwTotalPageFile As Long
dwAvailPageFile As Long
dwTotalVirtual As Long
dwAvailVirtual As Long
End Type
Declare Sub GlobalMemoryStatus Lib "kernel32" (lpBuffer As MEMORYSTATUS)
表單中加入如下代碼:
Private Sub Form_Click()
Dim m As MEMORYSTATUS
m.dwLength = Len(m)
GlobalMemoryStatus m
Print "資料結構的長度", m.dwLength
Print "記憶體使用量百分比", m.dwMemoryLoad
Print "實際記憶體總位元組數 ", m.dwTotalPhys
Print "可用的實際記憶體位元組數", m.dwAvailPhys
Print "分頁檔案總位元組數", m.dwTotalPageFile
Print "分頁檔案可用位元組數", m.dwAvailPageFile
Print "虛擬記憶體的總位元組數", m.dwTotalVirtual
Print "可用的虛擬記憶體位元組數", m.dwAvailVirtual
End Sub
? 讀寫註冊表
Win95及NT的註冊表資料庫(Registry)是系統中非常重要的組成部分,它設定了Win95及NT的參數,
包括使用者資訊、系統硬體設定和應用程式等資訊。註冊表系統代替了舊版Windows中的多個INI檔案。(警
告:如果你對註冊表不熟悉,不要隨意修改它。如果登錄機碼目出錯,會使機器崩潰,甚至破壞操作系
統本身。)
Win32 API中Reg函數處理對註冊表資料庫一般的讀寫過程如下:
1、使用RegOpenKey或RegCreateKey開啟或建立一個鍵;
2、如果上一步成功,使用RegQueryValue(或RegQueryValueEx)讀取子鍵的值,使用RegSetValue(或
RegvSetValueEx)設定子索引值,使用RegEnumKey獲得所有子鍵,使用RegDeleteKey刪除一個鍵;
3、完成操作後使用RegCloseKey關閉鍵。
下述應用程式示範了如何產生鍵、存放值並取得註冊表資料。在HKEY_LOCAL_MACHINE鍵下面產生三
個子鍵Test/Mastering vb5、 Windows Width、Windows Height,用於存放上次執行時的表單尺寸。
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As
Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As
Long, ByVal lpSubKey As String) As Long
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey
As Long, ByVal lpValueName As String) As Long
Private 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 ' Note that if you declare the lpData parameter as
String, you must pass it By Value.
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey
As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As
Any, ByVal cbData As Long) As Long ' Note that if you declare the lpData parameter as
String, you must pass it By Value.
Const ERROR_SUCCESS = 0&
Const ERROR_BADDB = 1009&
Const ERROR_BADKEY = 1010&
Const ERROR_CANTOPEN = 1011&
Const ERROR_CANTREAD = 1012&
Const ERROR_CANTWRITE = 1013&
Const ERROR_REGISTRY_RECOVERED = 1014&
Const ERROR_REGISTRY_CORRUPT = 1015&
Const ERROR_REGISTRY_IO_FAILED = 1016&
Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const regkey = "Test/Mastering vb5"
Private Sub Form_Load()
Dim retValue As Long
Dim result As Long
Dim keyValue As String
Dim keyId As Long
Dim subKey As String
Dim bufSize As Long
Label6.Caption = regkey
retValue = RegCreateKey(HKEY_LOCAL_MACHINE, regkey, keyId)
If retValue = 0 Then
subKey = "Windows Width"
retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, 0&, bufSize)
If bufSize < 2 Then
keyValue = Me.Width
retValue = RegSetValueEx(keyId, subKey, 0&, reg_sz, ByVal keyValue, Len(keyValue) + 1)
Else
keyValue = String(bufSize + 1, "")
retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, bykeyvalue, bufSize)
keyValue = Left$(keyValue, bufSize - 1)
Me.Width = keyValue
End If
Label4.Caption = subKey
Label5.Caption = Me.Width
subKey = "Widows Height"
retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, 0&, bufSize)
If bufSize < 2 Then
keyValue = Me.Height
retValue = RegSetValueEx(keyId, subKey, 0&, reg_sz, ByVal keyValue, Len(keyValue) + 1)
Else
keyValue = String(bufSize + 1, "")
retValue = RegQueryValueEx(keyId, subKey, 0&, reg_sz, ByVal keyValue, bufSize - 1)
Me.Height = keyValue
End If
Label8.Caption = subKey
Label7.Caption = Me.Height
End If
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim keyValue As String
Dim retValue As Long
Dim keyId As Long
retValue = RegCreateKey(HKEY_LOCAL_MACHINE, regkey, keyId)
keyValue = Me.Width
retValue = RegSetValueEx(keyId, "Windows Width", 0&, reg_sz, ByVal keyValue, Len(keyValue) +
1)
keyValue = Me.Height
retValue = RegSetValueEx(keyId, "Windows Height", 0&, reg_sz, ByVal keyValue, Len(keyValue)
+ 1)
End Sub
? 在“狀態區”中建立表徵圖
Win95中如“音量”、“日期”、“螢幕”等可以在Win95的狀態列(Tray)上建立快捷表徵圖。如果鼠
標停留在表徵圖上,會顯示出相應的工具提示(ToolTip),當使用者在表徵圖上單擊(或雙擊)滑鼠左鍵時,軟
件會實現相應的功能,單擊右鍵時會實現其簡捷的功能。
Tray也稱作SysTray、TrayIcon、NotifyIcon、Status Area等,它是Win95/NT的任務條上一個特殊區
域,許多軟體運行時在Tray中加入自己的表徵圖,這個地區的另一個特殊之處在於你可以從資源管理員內
拖檔案然後放在這個地區。正是由於這些特性,Tray編程在Win95/NT中有特殊的地位。
Tray編程比較特殊,主要包括三個主要方面:表徵圖、工具提示和訊息。它屬於Shell編程的一部分,
主要是利用Shell API中的Shell_NotifyIcon函數完成的。Shell_NotifyIcon函數是這樣聲明的:
Type NOTIFYICONDATA
cbSize As Long 結構所佔的位元組數
hwnd As Long 接受TRAY托盤表徵圖訊息的視窗控制代碼
uID As Long 由應用程式定義的表徵圖識別符
uFlags As Long 標誌
uCallbackMessage As Long 由應用程式定義的訊息
hIcon As Long TRAY表徵圖控制代碼
szTip As String * 64 工具提示字串
End Type
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long,
lpData As NOTIFYICONDATA) As Long
這個結構中的uFlags很重要,它有三種取值:NIF_ICON、NIF_MESSAGE和NIF_TIP,分別表示
hIcon、uCallbackMessage和szTip參數有效,用來修改表徵圖、訊息和工具提示。這三個取值可以同時使
用(三個參數相或),也可以單獨使用。為了實現對使用者滑鼠操作的響應,需要在程式中處理
uCallbackMessage所定義的訊息,該訊息的長參數lParam包含Win32所定義的滑鼠訊息,如果有多個圖
標,短參數wParam表示表徵圖識別符。
在vb光碟片中/TOOLS/UNSUPPRT/SYSTRAY目錄下有SYSTRAY的工程,經編譯後產生
SYSTRAY.OCX控制項。
現在我們應用SYSTRAY.OCX控制項進行Tray編程。
首先建立一個“工程”,依次:“工程”——“組件”(或者在“工具箱”上單擊滑鼠右鍵選擇“部
件”),再複選SYSTEM TRAY CONTROL CSYSTRAY,CSYSTRAY控制項即出現在“工具箱”中。
SYSTRAY.OCX控制項擁有MouseDblClick、MouseDown、MouseMove、MouseUp四個事件,響應先
後為MouseMove、MouseDown、MouseUp、MouseDblClick。下面編程很清楚地說明他們的回應時間次
序。
Private Sub cSysTray1_MouseDblClick(Button As Integer, Id As Long)
MsgBox "Hei!You have DblClick the mouse!"
End Sub
Private Sub cSysTray1_MouseDown(Button As Integer, Id As Long)
If Button = 2 Then
MsgBox "Hei!You have clicked me in right button!"
End If
End Sub
Private Sub cSysTray1_MouseMove(Id As Long)
MsgBox "Hello!I am here!"
End Sub
Private Sub cSysTray1_MouseUp(Button As Integer, Id As Long)
MsgBox "Hei!You clicked me just now!"
End Sub
Private Sub Form_Load()
cSysTray1.TrayTip = "Hello! I am the King of the world!"
cSysTray1.InTray = True
cSysTray1.TrayIcon = "c:/fittings/FACE.ico"
End Sub
SYSTRAY控制項還擁有InTray、Name、TrayIcon、TrayTip、Parent、Index、Object、Tag屬性。InTray
設定是否在Win95的狀態列Tray上建立一個快捷表徵圖;Name設定SYSTRAY控制項的名稱;TrayIcon設
置在Tray上所建立快捷表徵圖的外觀;TrayTip設定如果滑鼠停留在表徵圖上所顯示的工具提示(ToolTip)內
容;Tag儲存程式所需要的附加資料。