Win32プログラミング講座 〜 Step27. メモリ監視ツールを作る@ 〜




ActiveBasic3.0のサンプルアプリとして作られたメモリ監視ツール「System Watcher」の自作に挑戦してみましょう。

今回作成するプログラムのサンプルファイルを置いておきますので、参考にしたい方はどうぞ☆
SystemWatcher.zip(プロジェクトに必要なファイルがすべて入っています)


具体的に、どんな機能がついてるの?

・OS名、OSバージョン、サービスパック等の情報
・物理メモリの使用状況(リアルタイム表示)
・仮想メモリの使用状況(リアルタイム表示)

おおまかに、上記の3点の機能を作っていきます。リアルタイム表示とは、指定した時間間隔ごとに常に最新の情報を取得&表示していく手法のことです。Timerイベントを利用し、リアルタイム表示に対応させます。


OS情報の取得方法

OSの名前やバージョンは、GetVersionEx関数で取得することができます。この関数のパラメータの、OSVERSIONINFO構造体にOS情報が格納されます。OSVERSIONINFO構造体の内容は、下記の通りです。

Type OSVERSIONINFO
    dwOSVersionInfoSize As Long   '構造体のサイズ(事前に指定して下さい)
    dwMajorVersion As Long        'マイナーバージョン番号が格納されます
    dwMinorVersion As Long        'メジャーバージョン番号が格納されます
    dwBuildNumber As Long         'ビルド番号が格納されます
    dwPlatformId As Long          'プラットフォームの識別 ID が格納されます
    szCSDVersion[127] As Byte     'サービスパックなどの関連情報が、文字列で格納されます
End Type
OSプラットフォームの識別ID
dwPlatformId
メジャーバージョン
dwMajorVersion
マイナーバージョン
dwMinorVersion
Windows 95VER_PLATFORM_WIN32_WINDOWS40
Windows 98410
Windows Me490
Windows NT4.0VER_PLATFORM_WIN32_NT40
Windows 200050
Windows XP51
Windows .NET Server51



メモリ使用状況の取得方法

物理メモリ、仮想メモリの使用状況を取得するときは、GlobalMemoryStatus関数を使います。この関数のパラメータの、MEMORYSTATUS構造体に情報が格納されます。MEMORYSTATUS構造体の内容は、下記の通りです。

Type MEMORYSTATUS
    dwLength As Long          '構造体のサイズ(事前に指定して下さい)
    dwMemoryLoad As Long      'メモリの使用状況がパーセンテージで格納されます(0 〜 100)
    dwTotalPhys As Long       '物理メモリの容量がバイト単位で格納されます
    dwAvailPhys As Long       '物理メモリの空き容量がバイト単位で格納されます
    dwTotalPageFile As Long   'ページ ファイル(仮想メモリ)の容量がバイト単位で格納されます
    dwAvailPageFile As Long   'ページ ファイル(仮想メモリ)の空き容量がバイト単位で格納されます
    dwTotalVirtual As Long    'ユーザーが使用できるアドレス空間の容量がバイト単位で格納されます
    dwAvailVirtual As Long    'ユーザーが使用できるアドレス空間の空き容量がバイト単位で格納されます
End Type


作り方☆

ノーマルウィンドウベースのプロジェクトを新規作成します。この際に、プロジェクトオプションの「コモンコントロールを使用する」にチェックを入れておいて下さい。

MainWndのRAD画面を開き、以下のようにコントロールを配置していきます。ゴチャゴチャしていますが、根気良く、進めましょう。MainWndのウィンドウ プロパティ内では、「最大化ボタン」「最小化ボタン」のチェックを外しておいて下さい。プログレスバーのプロパティで、「スムーズ」にチェックを入れておいて下さい。

イベントコーディングの前に、MainWnd.sbpの先頭部分に以下のコードを入れておきます。

' ----------------------------------------------------------------------------
'  イベント プロシージャ
' ----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd

' メモ - 以下の領域を、変数、構造体、定数、関数を宣言するための、
'        グローバル領域として利用することができます。
' ----------------------------------ここから----------------------------------

Dim RenewalTiming As Long    '更新間隔
RenewalTiming=500            'ミリ秒

' ----------------------------------ここまで----------------------------------

↑RenewalTiming変数には、メモリ状況の更新間隔をミリ秒単位で格納しておきます。

イベントコーディング

Sub MainWnd_Destroy()

    'タイマーを終了する
    KillTimer(hMainWnd,0)

    SystemWatcher_DestroyObjects()
    PostQuitMessage(0)
End Sub

↑Destroyイベントでは、タイマーを終了するためのKillTimer関数の呼び出しを行います。

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
    Dim buf As String
    Dim hProgBar As Long

    '--------------------------
    ' OSのバージョン情報を取得
    '--------------------------
    Dim OsVerInfo As OSVERSIONINFO
    Dim BuildNum As Long
    OsVerInfo.dwOSVersionInfoSize=Len(OsVerInfo)
    GetVersionEx(OsVerInfo)

    If OsVerInfo.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS Then
        'Windows 9x系OS(メジャーバージョンは常に4)
        Select Case OsVerInfo.dwMinorVersion
            Case 0
                buf="Windows 95"
            Case 10
                buf="Windows 98"
            Case 90
                buf="Windows Me"
        End Select
        BuildNum=LOWORD(OsVerInfo.dwBuildNumber)
    ElseIf OsVerInfo.dwPlatformId=VER_PLATFORM_WIN32_NT Then
        'Windows NT系OS
        If OsVerInfo.dwMajorVersion=4 Then
            buf="Windows NT"
        ElseIf OsVerInfo.dwMajorVersion=5 Then
            If OsVerInfo.dwMinorVersion=0 Then
                buf="Windows 2000"
            ElseIf OsVerInfo.dwMinorVersion=1 Then
                buf="Windows XP"
            End If
        End If
        BuildNum=OsVerInfo.dwBuildNumber
    End If

    'OS情報をウィンドウに表示する
    SetWindowText(GetDlgItem(hMainWnd,Static_OSName),buf)
    SetWindowText(GetDlgItem(hMainWnd,Static_OSBuildNum),Str$(BuildNum))
    SetWindowText(GetDlgItem(hMainWnd,Static_OSNote),OsVerInfo.szCSDVersion)


    '------------------
    ' メモリ情報を取得
    '------------------
    Dim MemStatus As MEMORYSTATUS
    Dim rate_Physical As Long, rate_Virtual As Long
    MemStatus.dwLength=Len(MemStatus)
    GlobalMemoryStatus(MemStatus)

    '物理メモリに関する情報を表示する
    rate_Physical=MemStatus.dwMemoryLoad
    SetWindowText(GetDlgItem(hMainWnd,Static_RatePhysical),Str$(rate_Physical)+"%")
    SetWindowText(GetDlgItem(hMainWnd,Static_TotalPhysical),Str$(Int(MemStatus.dwTotalPhys/1024))+"KB")
    SetWindowText(GetDlgItem(hMainWnd,Static_UsedPhysical),_
                         Str$(Int((MemStatus.dwTotalPhys-MemStatus.dwAvailPhys)/1024))+"KB")

    '仮想メモリに関する情報を表示する
    rate_Virtual= _
Int(CDbl(MemStatus.dwTotalPageFile-MemStatus.dwAvailPageFile)/CDbl(MemStatus.dwTotalPageFile)*100)
    SetWindowText(GetDlgItem(hMainWnd,Static_RateVirtual),Str$(rate_Virtual)+"%")
    SetWindowText(GetDlgItem(hMainWnd,Static_TotalVirtual),Str$(Int(MemStatus.dwTotalPageFile/1024))+"KB")
    SetWindowText(GetDlgItem(hMainWnd,Static_UsedVirtual),_
                         Str$(Int((MemStatus.dwTotalPageFile-MemStatus.dwAvailPageFile)/1024))+"KB")

    '物理メモリ使用率のプログレスバーの初期設定
    SendMessage(GetDlgItem(hMainWnd,ProgressBar_Physical),PBM_SETRANGE,0,MAKELONG(0,100))
    SendMessage(GetDlgItem(hMainWnd,ProgressBar_Physical),PBM_SETPOS,rate_Physical,0)

    '仮想メモリ使用率のプログレスバーの初期設定
    SendMessage(GetDlgItem(hMainWnd,ProgressBar_Virtual),PBM_SETRANGE,0,MAKELONG(0,100))
    SendMessage(GetDlgItem(hMainWnd,ProgressBar_Virtual),PBM_SETPOS,rate_Virtual,0)


    'メモリ使用率のタイマーを設定(RenewalTiming秒間隔)
    SetTimer(hMainWnd,0,RenewalTiming,0)
End Sub

↑Create関数では、OS情報の表示と、物理メモリ/仮想メモリ表示の初期設定を行っています。プログレスバーについては、ステップ10で解説あります。

Sub MainWnd_Timer(ByVal TimerID As Long)
    Dim MemStatus As MEMORYSTATUS
    Dim rate_Physical As Long, rate_Virtual As Long


    '------------------
    ' メモリ情報を取得
    '------------------

    MemStatus.dwLength=Len(MemStatus)
    GlobalMemoryStatus(MemStatus)

    '物理メモリに関する情報を更新する
    rate_Physical=MemStatus.dwMemoryLoad
    SetWindowText(GetDlgItem(hMainWnd,Static_RatePhysical),Str$(rate_Physical)+"%")
    SetWindowText(GetDlgItem(hMainWnd,Static_UsedPhysical),_
                        Str$(Int((MemStatus.dwTotalPhys-MemStatus.dwAvailPhys)/1024))+"KB")

    '仮想メモリに関する情報を更新する
    rate_Virtual= _
Int(CDbl(MemStatus.dwTotalPageFile-MemStatus.dwAvailPageFile)/CDbl(MemStatus.dwTotalPageFile)*100)
    SetWindowText(GetDlgItem(hMainWnd,Static_RateVirtual),Str$(rate_Virtual)+"%")
    SetWindowText(GetDlgItem(hMainWnd,Static_UsedVirtual), _
                        Str$(Int((MemStatus.dwTotalPageFile-MemStatus.dwAvailPageFile)/1024))+"KB")

    'プログレスバーの位置を設定
    SendMessage(GetDlgItem(hMainWnd,ProgressBar_Physical),PBM_SETPOS,rate_Physical,0)
    SendMessage(GetDlgItem(hMainWnd,ProgressBar_Virtual),PBM_SETPOS,rate_Virtual,0)
End Sub

↑Timerイベントでは、物理メモリ/仮想メモリの表示内容の更新を行います。

これですべての作業は完了です。コンパイル&実行を行い、メモリ監視が正常に行われているか、確認してみましょう。SystemWatherを立ち上げた後、適当にアプリケーションの起動、終了を繰り返すと、メモリの変化を見ることができますよ☆

前へ戻る - 次へ進む
トップへ戻る


©2005 Discoversoft