「ステップ28 「メモリ監視ツールを作る②(設定をレジストリに保存)」」の編集履歴(バックアップ)一覧はこちら

ステップ28 「メモリ監視ツールを作る②(設定をレジストリに保存)」」(2010/08/07 (土) 21:51:23) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

前回と同じ修正が必要。 またこのサンプルを実行するとレギストリに永遠に値が残るのでこれは重大な問題だと癒える。
前回と同じ修正が必要。 またこのサンプルを実行するとレギストリに永遠に値が残るのでこれは重大な問題だと癒える。 前回に引き続き、メモリ監視ツールに、オプション項目を付け足してみます。 今回作成するプログラムのサンプルファイルを置いておきますので、参考にしたい方はどうぞ☆ SystemWatcher2.zip(プロジェクトに必要なファイルがすべて入っています) オプション項目って何をするの? ・更新間隔の設定 ・最前面表示のオン/オフ 今回は、上記の2点と、それら設定項目のレジストリへの保存を試みます。 レジストリ操作 ① RegOpenKeyEx関数でレジストリキーをオープン ② RegQueryValueEx関数で値を読み込む / RegSetValueEx関数で値をセットする ③ RegCloseKey関数でレジストリキーを閉じる 各関数のパラメータの詳細は、ヘルプファイルでご確認下さい。 作り方☆ 前回のステップ27で作成したプロジェクトに手を加えていきます。 まず、MainWndのRAD画面を開き、下記のように、チェックボタン1つ、通常ボタン1つを挿入します。 次に、OptionButtonが押された時に表示するオプションダイアログを作ります。ProjectViewのMaterialタブ内のWindowフォルダを右クリックし、ウィンドウを挿入します。 OptionDlgにコントロールを挿入し、下の図のような構成に仕上げます。 MainWndのイベントコーディング ※太字は、前回からの変更点を表します。 ' ---------------------------------------------------------------------------- ' イベント プロシージャ ' ---------------------------------------------------------------------------- ' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。 ' ウィンドウ ハンドル: hMainWnd ' メモ - 以下の領域を、変数、構造体、定数、関数を宣言するための、 ' グローバル領域として利用することができます。 ' ----------------------------------ここから---------------------------------- Dim RenewalTiming As Long '更新間隔 ' ----------------------------------ここまで---------------------------------- ↑MainWnd.sbpの先頭部分には変更点はありません。RenewalTiming=500という行はあってもなくても構いません。 Sub MainWnd_Destroy() 'タイマーを終了する KillTimer(hMainWnd,0) '------------------------------ ' レジストリに設定値を書き込む '------------------------------ Dim hKey As HKEY Dim IsTopMost As Long '「常に手前に表示する」ボタンにチェックが入っているかどうかを調べる If SendMessage(GetDlgItem(hMainWnd,Check_TopMost),BM_GETCHECK,0,0) Then IsTopMost=1 Else IsTopMost=0 End If 'レジストリをオープン(サブキーが存在しなときは作成する) RegCreateKeyEx(HKEY_CURRENT_USER,"Software\SystemWatcher",0,NULL, _ REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,ByVal 0,hKey,0) '値 "IsTopMost" に変数 IsTopMost の内容をセットする RegSetValueEx(hKey,"IsTopMost",0,REG_DWORD,VarPtr(IsTopMost),Len(IsTopMost)) '値 "RenewalTiming" に変数 RenewalTiming の内容をセットする RegSetValueEx(hKey,"RenewalTiming",0,REG_DWORD,VarPtr(RenewalTiming),Len(RenewalTiming)) 'レジストリ ハンドルを閉じる RegCloseKey(hKey) SystemWatcher_DestroyObjects() PostQuitMessage(0) End Sub ↑Destroyイベントでは、設定内容のレジストリへの書き込みを行います。 Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT) Dim buf As String Dim BufSize As Long Dim hProgBar As Long '-------------------------------- ' レジストリから設定値を読み取る '-------------------------------- Dim hKey As HKEY Dim IsTopMost As Long 'レジストリをオープン If RegOpenKeyEx(HKEY_CURRENT_USER,"Software\SystemWatcher", 0,KEY_ALL_ACCESS,hKey)=ERROR_SUCCESS Then '値 "IsTopMost" の内容を変数 IsTopMost にコピーする '※読み込みが失敗したときは自動的にIsTopMostの内容は0になる BufSize=Len(IsTopMost) RegQueryValueEx(hKey,"IsTopMost",0,0,VarPtr(IsTopMost),VarPtr(BufSize)) '値 "RenewalTiming" の内容を変数 RenewalTiming にコピーする BufSize=Len(RenewalTiming) If RegQueryValueEx(hKey,"RenewalTiming",0,0, VarPtr(RenewalTiming),VarPtr(BufSize))<>ERROR_SUCCESS Then '読み込みが失敗したときは、デフォルト値の500にセットする RenewalTiming=500 End If 'レジストリを閉じる RegCloseKey(hKey) Else 'レジストリキーが存在しないときはデフォルト値をセットする IsTopMost=0 RenewalTiming=500 End If If IsTopMost Then 'IsTopMostの内容が0以外のときは、最前面ウィンドウにする SendDlgItemMessage(hMainWnd,Check_TopMost,BM_SETCHECK,BST_CHECKED,0) SetWindowPos(hMainWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE Or SWP_NOSIZE) End If '-------------------------- ' 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イベントでは、レジストリの読み込みを行います。 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イベントに変更点はありません。 Sub MainWnd_Check_TopMost_Click() If SendMessage(GetDlgItem(hMainWnd,Check_TopMost),BM_GETCHECK,0,0) Then '最前面ウィンドウに設定する SetWindowPos(hMainWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE Or SWP_NOSIZE) Else '最前面ウィンドウを解除する SetWindowPos(hMainWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE Or SWP_NOSIZE) End If End Sub ↑「常に手前に表示する」ボタンがクリックされたときのイベントです。SetWindowPos関数を使って、最前面ウィンドウのオン/オフを行っています。 Sub MainWnd_OptionButton_Click() Dim ret As Long 'オプション ダイアログ ボックスを表示する ret=DialogBox(hMainWnd,"OptionDlg") 'キャンセルボタンが押された時は抜け出す If ret=-1 Then Exit Sub '更新タイミングを変更 RenewalTiming=ret 'タイマーを再始動させる KillTimer(hMainWnd,0) SetTimer(hMainWnd,0,RenewalTiming,0) End Sub ↑「オプション」ボタンがクリックされたときのイベントです。DialogBox関数でOptionDlgを表示し、更新間隔の取得、設定を行います。 ここから下はOptionDlg.sbp内のコーディングになります。OptionDlgに関するイベントコーディングを行っていきます。 ' ---------------------------------------------------------------------------- ' イベント プロシージャ ' ---------------------------------------------------------------------------- ' このファイルには、ウィンドウ [OptionDlg] に関するイベントをコーディングします。 ' ウィンドウ ハンドル: hOptionDlg ' メモ - 以下の領域を、変数、構造体、定数、関数を宣言するための、 ' グローバル領域として利用することができます。 ' ----------------------------------ここから---------------------------------- Sub SetDlgCenter(ByVal hOwner As Long, ByVal hDlg As Long) Dim OwnerRect As RECT, DlgRect As RECT Dim x As Long, y As Long GetWindowRect(hOwner,OwnerRect) 'メイン ウィンドウの座標を取得 GetWindowRect(hDlg,DlgRect) 'ダイアログボックスの座標を取得 '新しい座標を計算 x=((OwnerRect.right-OwnerRect.left)-(DlgRect.right-DlgRect.left))/2 + OwnerRect.left y=((OwnerRect.bottom-OwnerRect.top)-(DlgRect.bottom-DlgRect.top))/2 + OwnerRect.top '位置を変更 SetWindowPos(hDlg,NULL,x,y,0,0,SWP_NOSIZE) End Sub ' ----------------------------------ここまで---------------------------------- ↑OptionDlg.sbpの先頭部分のコーディングです。SetDlgCenter関数には、指定したウィンドウを中央に配置する機能を持たせます。 Sub OptionDlg_Create(ByRef CreateStruct As CREATESTRUCT) 'ダイアログボックスを中央に表示する SetDlgCenter(hMainWnd,hOptionDlg) 'ラジオボタンの初期選択 Select Case RenewalTiming Case 100 SendMessage(GetDlgItem(hOptionDlg,RadioButton1),BM_SETCHECK,BST_CHECKED,0) Case 500 SendMessage(GetDlgItem(hOptionDlg,RadioButton2),BM_SETCHECK,BST_CHECKED,0) Case Else SendMessage(GetDlgItem(hOptionDlg,RadioButton3),BM_SETCHECK,BST_CHECKED,0) End Select End Sub ↑OptionDlgのCreateイベントです。RenewalTiming変数の内容を元に、ラジオボタンの初期化を行います。 Sub OptionDlg_OkButton_Click() Dim ret As Long '選択されているラジオボタンを調べる If SendMessage(GetDlgItem(hOptionDlg,RadioButton1),BM_GETCHECK,0,0) Then ret=100 ElseIf SendMessage(GetDlgItem(hOptionDlg,RadioButton2),BM_GETCHECK,0,0) Then ret=500 Else ret=1000 End If '戻り値に変数retの内容をセットする EndDialog(hOptionDlg,ret) End Sub ↑OptionDlgのOKボタンがクリックされたときのイベントです。選択されているラジオボタンを調べ、DialogBox関数の戻り値を設定します。この戻り値が、後に更新間隔を示すことになります。 Sub OptionDlg_CancelButton_Click() 'キャンセルが押された時は、戻り値に-1をセットする EndDialog(hOptionDlg,-1) End Sub ↑OptionDlgのキャンセルボタンがクリックされたときのイベントです。 これで作業は完了です。更新間隔の設定が正常に行われているかどうか、レジストリへの書き込み、読み込みが正常かどうかをチェックしてみましょう。

表示オプション

横に並べて表示:
変化行の前後のみ表示: