避免使用 Win32 API 假如您是一位 Microsoft Visual Basic® 6.0 開發人員,您就無法避免調用 Win32 API。開發人員有太多的任務需要完成,而 Visual Basic 卻不能提供任何實現方法。例如,在 Visual Basic 6.0 中,您很難完成以下任務:
確定文件版本信息 在注冊表的任何位置進行讀取和寫入操作。 確定用戶的特定文件夾,例如 Microsoft Windows® 收藏夾或個人文件夾。 檢索所有可用驅動器的列表。 查找用戶的登錄名或計算機名。 檢索所有打開窗口的列表。 假如僅使用 Visual Basic 6.0 中提供的工具,您不可能解決上述任何問題。對于每個問題,開發人員都需要使用 Windows API。許多開發人員使用 Windows API 已經找到了完成這些(以及許多其他)任務的方法。
Windows API 存在什么問題? 為什么不繼續在 .NET 環境中使用 Windows API 呢?假如使用 .NET 平臺調用服務(稱為“P/Invoke”),您當然可以這樣做。從 Visual Basic 開發人員的角度來說,調用 Windows API 并不比使用他們所熟悉的 Declare 語句困難。不過,在 .NET 環境中使用 Windows API 存在一些比較嚴重的缺陷,您可能需要考慮采取任何可行的措施來避免這些問題。例如:
.NET 公共語言運行時不會受平臺影響。當您使用 Windows API 調用時,您將代碼綁定到編寫代碼的特定平臺上(即,相對于其他操作系統的某個特定 Windows 版本或 Windows 本身)。必要時,您需要將代碼轉換到另一個平臺上,而這樣做就需要修改使用 API 調用的每行代碼。 從 .NET 中調用 Windows API(或 DLL 中的任何非托管代碼)不像在 Visual Basic 6.0 中那樣簡單。例如,對結構的工作方式的限制使得很難將結構傳遞給 API 調用。此外,由于數據類型的更改以及更嚴格的類型轉換,Visual Basic 6.0 的 API 聲明也需要進行更改。 根據語言的不同,使用 Windows API(以及通常情況下使用的外部代碼)的技巧也不盡相同。假如您打算在多 .NET 語言環境中工作,則需要把握各種語言的不同技巧。 調用 Windows API 的代碼要求調用這些代碼的用戶具有執行此操作的權限。這將影響應用程序的安全保護方案,您需要對此要求提前做出安排。 這個問題很簡單:盡管您可以在 Visual Basic .NET 應用程序中繼續使用 Windows API,但通常情況下,您應當盡可能尋找由 .NET 框架提供的替代品。雖然 .NET 框架的目的并不是要阻止您直接使用 Windows 的功能,但框架的確提供了大量的類,可以幫助您放棄對 Windows API 調用的依靠。
假如能夠給出一個完整列表,列出 Win32 API 調用以及在 .NET 框架中完成相同任務的相應方法(假如有),可能會很方便,不過本文不涉及此任務。在本文中,您將了解到一些由 .NET 框架提供的特定且非常有用的類,它們可以解決您的問題。在每個示例中,本文所討論的類都可以用來替代一個或多個 Win32 API 調用,而在 Microsoft Visual Basic 6.0 中,您必須調用一個或多個 Win32 API 才能完成相同的任務。
使用注冊表 假如您與大多數 Visual Basic 6.0 開發人員一樣,您會發現 Microsoft Visual Basic for applications (VBA) 中內置的 SaveSetting、GetSetting、GetAllSettings 和 DeleteSetting 方法有點兒用處,但卻很可能被它們的局限性弄得精疲力盡。所有這些方法都只能在注冊表的 HKEY_CURRENT_USER/Software/VB 和 VBA PRogram Settings 下的項中使用。假如您要在注冊表的其他地方讀取或寫入注冊表項或注冊表值,則必須使用復雜的 API 調用,或依靠別人的代碼來處理此問題。
.NET 框架在 Microsoft.Win32 名稱空間中提供了一對功能強大的類(Registry 和 RegistryKey),從而簡化了注冊表的使用,即不再需要 API 調用!
作為演示,請在示例項目的主窗體上單擊 Work with the Registry(使用注冊表)按鈕。此窗體提供了 SOFTWARE/Microsoft/Windows/CurrentVersion/Run 項的 HKEY_LOCAL_MACHINE 配置單元中所有注冊表值的列表。您可以右鍵單擊列表中的任何項,然后選擇插入新項,或者編輯或刪除選定項,如圖 1 所示。
提示:示例窗體也已經過設計,在列表框中按下 Enter 鍵時,可以編輯當前選定的項。按下 Delete 鍵可以刪除選定項,按下 Insert 鍵可以添加一個新值。這些項對應于列表框的上下文菜單中的項。
圖 1:使用 Registry 和 RegistryKey 類輕松檢索和修改 Windows 注冊表中的信息
.NET 框架提供了兩個非常有用的類,使您可以輕松使用 Windows 注冊表。第一個類是 Registry,它提供的字段與標準 Registry 配置單元的各字段相對應:
' 打開注冊表項,然后使用 ' 該項的值加載列表框。 reg = reg.OpenSubKey(conRegKey) astrValues = reg.GetValueNames() For Each strValue In astrValues rd.Value = strValue.ToString rd.Data = reg.GetValue(strValue) lstItems.Items.Add(rd) Next lstItems.EndUpdate() End Sub
要編輯示例窗體中的值或添加新值,需要運行以下代碼:
Private Sub AddOrEdit( _ ByVal rd As RegData, _ ByVal Mode As frmAddValue.accessMode) Dim reg As RegistryKey = Registry.LocalMachine Dim frm As New frmAddValue(Mode)
frm.KeyName = rd.Value frm.KeyData = rd.Data
If frm.ShowDialog() = DialogResult.OK Then If frm.KeyName <> String.Empty Then reg = reg.OpenSubKey(conRegKey, True) reg.SetValue(frm.KeyName, frm.KeyData) ListLoad() End If End If End Sub
要刪除項值,示例窗體將調用以下代碼: Private Sub DeleteKey(ByVal rd As RegData) Dim strText As String Dim reg As RegistryKey = Registry.LocalMachine
If lstItems.SelectedIndex = -1 Then Exit Sub End If
' 刪除選定的項。 strText = String.Format( _ "Are you sure you want to delete ""{0}""?", _ rd.Value)
If MessageBox.Show(strText, _ "Delete Registry Value", _ MessageBoxButtons.YesNo, _ MessageBoxIcon.Question) = DialogResult.Yes Then ' 打開項,答應寫入。 reg = reg.OpenSubKey(conRegKey, True) reg.DeleteValue(rd.Value) ' 重新加載列表框。 ListLoad() End If End Sub
此代碼將打開項并請求對其執行寫入操作,然后將調用 DeleteValue 方法刪除選定的值。
有了示例窗體提供的信息和 .NET 框架附帶的文檔,便可以輕松地完成與注冊表相關的任何任務,而不必使用 Windows API。這是一個簡單的對象模型,但它提供的功能比 Visual Basic 6.0 開發人員先前所擁有的功能更強大。