Win95系統API函數大揭秘
發表于:2007-07-14來源:作者:點擊數:
標簽:
Win95以其嶄新精致的外觀、簡便快捷的操作方式,讓你盡享操作平臺之樂趣。同屬Microsoft公 司的Visual Basic不僅僅是一門計算機語言,還是一個集應用程序 開發 、 測試 、查錯功能于一體的功能 強大的集成式開發環境, 數百萬的 程序員 受益于此。 Visual Basi
Win95以其嶄新精致的外觀、簡便快捷的操作方式,讓你盡享操作平臺之樂趣。同屬Microsoft公
司的Visual Basic不僅僅是一門計算機語言,還是一個集應用程序
開發、
測試、查錯功能于一體的功能
強大的集成式開發環境, 數百萬的
程序員受益于此。
Visual Basic一個強大的特性是它具有調用駐留在動態連接庫(DLL)文件中的函數功能,其中包
括由
Windows提供和使用的所有函數。對幾百個函數以及DLL所包含的其它函數的存取將Visual Basic
的功能進行了大大的擴充,其功能遠遠超出其它語言,真有種“信手拈來”之神韻,畢竟Visual Basic
是Microsoft公司的“嫡系部隊”。 你可以在你的應用程序中利用
WINDOWS API提供的數百個API接口
函數進行擴充,加速應用程序的建立,減少程序開發的重復性(比爾.蓋茨找你打版權官司可不關我事!
——喔喔?。?br>
所謂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?。梗禈藴实摹按疟P格式化”窗口,以實現對磁盤相應
的操作功能。
窗體加入如下代碼:
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_SE
TDESKWALLPAPER = 20
Const SPIF_UPDATEINIFILE = &H1 'update Win.ini Const
ant
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)的方法,可以
獲得比實際可用內存更大的內存。知道內存如何分配后,就可以讀入內存值并操作大型數字文件??梢?br>
用豐富的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_SU
CCESS = 0&
Const ERROR_BADDB = 1009&
Const ERROR_BADKEY = 1010&
Const ERROR_C
ANTOPEN = 1011&
Const ERROR_CANTREAD = 1012&
Const ERROR_CANTWRITE = 1013&
Const ERROR_REGISTRY_RECOVERED = 1014&
Const ERROR_REGISTRY_COR
RUPT = 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儲存程序所需要的附加數據。
原文轉自:http://www.anti-gravitydesign.com