一個小巧精致的CPU監視器
我們在運行一些系統占用率比較高的程序時,為了避免出現資源不足而運行失敗或者速度非常慢的情況,應該首先確定當前的CPU使用情況。我們一般是使用“系統工具”中的“資源狀況”工具,它雖然比較全面和易用,但是自身卻又消耗了較多資源,而且它的那些附屬的功能都是我們所不需要的,因此,我們可以考慮自己編程實現對CPU資源狀況的監視。筆者經過一番探索,開發了一個小巧精致的CPU監視器,它不僅界面友好,而且占用資源極少,確實可以取代windows的“資源狀況”程序。
(一)編程原理;
CPU的資源占用狀況被記載在注冊表的項目HKEY_DYN_DATAPerfStatsStatData分支“KERNELCPUUsage"中,通過周期性的讀取該鍵的鍵值,并且將參數傳遞到我們自己制作的監視器界面中,使之相應的變化,這就可以即時反映出CPU的使用狀況了。本文程序中的關鍵是相關鍵值的讀取和反映輸出到監視器上。
(二)編程實踐;
(1)設計程序界面;
為了達到較小CPU占有率,必須將應用程序設計的既能夠全面反映問題,又能夠盡量的小。首先建立一個標準exe工程,將窗體命名為frmmain,borderstyle屬性為3-fixed,caption屬性為空白,添加一個frame控件“frame1”,caption屬性為空白,添加picturebox控件,前景色為綠色,背景色為淺紅色,添加一個定時器控件“timer”,interval設置為100,enabled為true,其他的屬性采用系統的默認值即可,調整窗體和控件到適當位置和適當大小,效果如圖2所示即可。
雙擊窗體frmmain,寫入以下代碼:
(一)編程原理;
CPU的資源占用狀況被記載在注冊表的項目HKEY_DYN_DATAPerfStatsStatData分支“KERNELCPUUsage"中,通過周期性的讀取該鍵的鍵值,并且將參數傳遞到我們自己制作的監視器界面中,使之相應的變化,這就可以即時反映出CPU的使用狀況了。本文程序中的關鍵是相關鍵值的讀取和反映輸出到監視器上。
(二)編程實踐;
(1)設計程序界面;
為了達到較小CPU占有率,必須將應用程序設計的既能夠全面反映問題,又能夠盡量的小。首先建立一個標準exe工程,將窗體命名為frmmain,borderstyle屬性為3-fixed,caption屬性為空白,添加一個frame控件“frame1”,caption屬性為空白,添加picturebox控件,前景色為綠色,背景色為淺紅色,添加一個定時器控件“timer”,interval設置為100,enabled為true,其他的屬性采用系統的默認值即可,調整窗體和控件到適當位置和適當大小,效果如圖2所示即可。
雙擊窗體frmmain,寫入以下代碼:
| Option Explicit Private Const LP-HT-CAPTION = 2 Private Const WM-NCLBUTTONDOWN = &HA1 Private Declare Function ReleaseCapture Lib “user32" () As Long Private Declare Function SendMessage Lib “user32" Alias“SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private CPU As New CPUUsage Private Avg As Long Private Sum As Long Private Index As Long Private Sub Form_Load() Me.Caption = App.Title ‘初始化應用程序標題欄 CPU.InitCPUUsage End Sub Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) ‘程序結束前關閉定時器和釋放內存 Timer.Enabled = False Set CPU = Nothing Cancel = 0 End Sub Private Sub Frame1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ‘用左鍵可以拖動程序 Call Form_MouseDown(Button, Shift, X, Y) End Sub Private Sub pctPrg_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ‘右鍵單擊退出程序 If Button = 2 Then Unload Me End End If Call Form_MouseDown(Button, Shift, X, Y) End Sub Private Sub Timer_Timer() ‘利用定時器周期性的讀取資源狀況 Dim tmp As Long tmp = CPU.GetCPUUsage Me.Caption = App.Title & FormatPercent(tmp / 100) ‘ ‘在標題欄用百分比數字形式反映占用率 Sum = Sum + tmp Index = Index + 1 Avg = Int(Sum / Index) pctPrg.Cls pctPrg.Line (0, 0)-(tmp, 18), , BF pctPrg.Line (Avg, 0)-(Avg, 18), &HFF pctPrg.Line (Avg + 1, 0)-(Avg + 1, 18), &HFF ‘用圖式形式反映占用率 End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ‘使程序可以被拖動 Dim rc As Long rc = ReleaseCapture rc = SendMessage(hwnd, WM-NCLBUTTONDOWN, LP_HT-CAPTION, ByVal 0&) End Sub (2)編寫讀取注冊表中CPU使用狀況的類模塊; 添加一個類模塊,命名為“CPUusage”,寫入以下代碼: Option Explicit 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 Private Declare Function RegOpenKey Lib“advapi32.dll" Alias “RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long Private Declare Function RegCloseKey Lib“advapi32.dll" (ByVal hKey As Long) As Long Private Const REG_DWORD = 4 Private Const HKEY_DYN_DATA = &H80000006 Public Sub InitCPUUsage() Dim Data As Long, Typ As Long, Size As Long Dim hKey As Long, hRet As Long hRet = RegOpenKey(HKEY-DYN-DATA, “PerfStatsStartStat", hKey) hRet = Reg QueryValueEx(hKey, “KERNELCPUUsage", 0, REG-DWORD, Data, 4) hRet = RegCloseKey(hKey) End Sub Public Function GetCPUUsage() As Long On Error GoTo eee ‘如果注冊表錯誤的話轉到eee: Dim Data As Long, Typ As Long, Size As Long Dim hKey As Long Dim hRet As Long hRet = RegOpenKey(HKEY-DYN-DATA,“PerfStatsStatData", hKey) ‘打開主鍵 hRet = RegQueryValueEx(hKey, “KERNELCPUUsage", 0&, REG_DWORD, Data, 4) ‘讀取參數 GetCPUUsage = Data hRet = RegCloseKey(hKey) Exit Function eee: |