フォームの状態と位置・起動時刻・終了時刻を保存するには(INIファイル編)

ウィンドウの状態と位置・起動時刻・終了時刻を保存してみます。
キーワードは「INIファイル()関数」です。
INIファイルは別名「初期化ファイル」とも呼びます。
Windows3.1の時代まで、多くのプログラムは設定内容やプログラム終了時のフォームの位置などを
記憶するためにINIファイルを使っていました。

Windows95以降はレジストリが導入されて、それらの情報をレジストリに書き込むことが多くなったため
最近のプログラムではINIファイルを使うものはWindows3.1の頃に比べ少なくなりましたが、
操作性(テキストファイルと同じなので簡単に扱える)やバックアップやリカバリーの手軽さなどから
現在でもINIファイルを採用しているプログラムは数多くあります。

今回はそのINIファイルにフォームの位置・状態・起動時刻・終了時刻を記録しています。
プログラムの流れは大まかに次の通りです。
[起動時]
    @現在のフォームの状態をGetWindowPlacement()関数で取得する
    AINIファイルを読み込む。もしINIファイル内に必要な値がなければ
      @のデータを使う。
    BINIファイルから取得した情報を元にフォームの位置やサイズを
      SetWindowPlacement()関数で設定する。

[終了時]
    @現在のフォームの状態をGetWindowPlacement()関数で取得する
    AINIファイルに必要な値を書き込む
あとはこれにいくつかの処理を付けただけです。

実行中の様子

このプログラムを実行するとWindowsフォルダに
左のようなファイルが作成され、下のような内
容が記録される
[WindowPlacement]
flags=0
showCmd=1
ptMinPosition.X=-1
ptMinPosition.Y=-1
ptMaxPosition.X=-1
ptMaxPosition.Y=-1
rcNormalPosition.Left=132
rcNormalPosition.Top=174
rcNormalPosition.Right=523
rcNormalPosition.Bottom=383
[Time]
StartTime=01:35:29
EndTime=01:39:52
Dim ThisTime As INFO, BeforeTime As INFO

Private Sub Form_Load()
    Dim temp As String
    
    ThisTime.StartTime = Format(Now, "hh:mm:ss")            '起動時間の記録
    Call ReadBeforeStatus(BeforeTime)                       '前回の記録の取得
    
    BeforeTime.lpwndpl.length = Len(BeforeTime.lpwndpl)     '構造体のバイト数
    Call GetWindowPlacement(Me.hWnd, BeforeTime.lpwndpl)    'ファイルがないときは現在の状態を使う
    Call SetWindowPlacement(Me.hWnd, BeforeTime.lpwndpl)    '前回のウィンドウの状態に設定
    Me.Label4(0).Caption = BeforeTime.lpwndpl.rcNormalPosition.Left
    Me.Label4(1).Caption = BeforeTime.lpwndpl.rcNormalPosition.Top
    
    temp = ""
    Select Case BeforeTime.lpwndpl.showCmd
        Case SW_HIDE: temp = "非表示"
        Case SW_MINIMIZE: temp = "アイコン化状態"
        Case SW_RESTORE, SW_SHOWNORMAL: temp = "アクティブ状態"
        Case SW_SHOW: temp = "アクティブ状態"
        Case SW_SHOWMAXIMIZED: temp = "アクティブ & 最大化状態"
        Case SW_SHOWMINIMIZED: temp = "アクティブ & 最小化状態"
        Case SW_SHOWMINNOACTIVE: temp = "最小化状態"
        Case SW_NOACTIVATE: temp = "非アクティブ状態"
    End Select
    Me.Label4(2).Caption = temp                             '前回のウィンドウの状態
    
    Me.Label4(3).Caption = BeforeTime.StartTime             '前回起動時間
    Me.Label4(4).Caption = BeforeTime.EndTime               '前回終了時間
    Me.Label4(5).Caption = ThisTime.StartTime               '今回起動時間
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) ThisTime.EndTime = Format(Now, "hh:mm:ss") '終了時間の記録 Call SaveStatus(ThisTime) '今回の情報の記録 End Sub
Private Sub Form_Unload(Cancel As Integer) ThisTime.EndTime = Format(Now, "hh:mm:ss") '終了時間の記録 Call SaveStatus(ThisTime) '今回の情報の記録 End Sub
Private Sub ReadBeforeStatus(param As INFO) '前回の情報をINIファイルから読み込む Dim temp As String, rc As Long 'INIファイルからウィンドウに関する情報だけを取得 With param.lpwndpl .flags = GetPrivateProfileInt("WindowPlacement", "flags", .flags, _ "WinAPI_Archive_Sample_12.ini") .showCmd = GetPrivateProfileInt("WindowPlacement", "showCmd", _ .showCmd, "WinAPI_Archive_Sample_12.ini") .ptMinPosition.x = GetPrivateProfileInt("WindowPlacement", "ptMinPosition.X", _ .ptMinPosition.x, "WinAPI_Archive_Sample_12.ini") .ptMinPosition.y = GetPrivateProfileInt("WindowPlacement", "ptMinPosition.Y", _ .ptMinPosition.y, "WinAPI_Archive_Sample_12.ini") .ptMaxPosition.x = GetPrivateProfileInt("WindowPlacement", "ptMaxPosition.X", _ .ptMaxPosition.x, "WinAPI_Archive_Sample_12.ini") .ptMaxPosition.y = GetPrivateProfileInt("WindowPlacement", "ptMaxPosition.Y", _ .ptMaxPosition.y, "WinAPI_Archive_Sample_12.ini") .rcNormalPosition.Left = GetPrivateProfileInt("WindowPlacement","rcNormalPosition.Left", _ .rcNormalPosition.Left, "WinAPI_Archive_Sample_12.ini") .rcNormalPosition.Top = GetPrivateProfileInt("WindowPlacement","rcNormalPosition.Top", _ .rcNormalPosition.Top, "WinAPI_Archive_Sample_12.ini") .rcNormalPosition.Right = GetPrivateProfileInt("WindowPlacement","rcNormalPosition.Right", _ .rcNormalPosition.Right, "WinAPI_Archive_Sample_12.ini") .rcNormalPosition.Bottom = GetPrivateProfileInt("WindowPlacement","rcNormalPosition.Bottom", _ .rcNormalPosition.Bottom, "WinAPI_Archive_Sample_12.ini") End With 'INIファイルから前回の時間に関する情報を取得する With param temp = String(260, Chr(0)) rc = GetPrivateProfileString("Time", "StartTime", vbNullString, temp, Len(temp), _ "WinAPI_Archive_Sample_12.ini") .StartTime = Mid(temp, 1, rc) temp = String(260, Chr(0)) rc = GetPrivateProfileString("Time", "EndTime", vbNullString, temp, Len(temp), _ "WinAPI_Archive_Sample_12.ini") .EndTime = Mid(temp, 1, rc) End With End Sub
Private Sub SaveStatus(param As INFO) '今回の情報をINIファイルに書き込む Dim temp As String param.lpwndpl.length = Len(lpwndpl) '構造体のサイズ Call GetWindowPlacement(Me.hWnd, param.lpwndpl) 'ウィンドウに関する情報の取得 'INIファイルにウィンドウに関する情報だけを記録 With param.lpwndpl temp = "flags=" & .flags & vbNullChar temp = temp & "showCmd=" & .showCmd & vbNullChar temp = temp & "ptMinPosition.X=" & .ptMinPosition.x & vbNullChar temp = temp & "ptMinPosition.Y=" & .ptMinPosition.y & vbNullChar temp = temp & "ptMaxPosition.X=" & .ptMaxPosition.x & vbNullChar temp = temp & "ptMaxPosition.Y=" & .ptMaxPosition.y & vbNullChar temp = temp & "rcNormalPosition.Left=" & .rcNormalPosition.Left & vbNullChar temp = temp & "rcNormalPosition.Top=" & .rcNormalPosition.Top & vbNullChar temp = temp & "rcNormalPosition.Right=" & .rcNormalPosition.Right & vbNullChar temp = temp & "rcNormalPosition.Bottom=" & .rcNormalPosition.Bottom & vbNullChar & vbNullChar Call WritePrivateProfileSection("WindowPlacement", temp, "WinAPI_Archive_Sample_12.ini") End With 'INIファイルに時間に関する情報を記録 With param temp = "StartTime=" & .StartTime & vbNullChar temp = temp & "EndTime=" & .EndTime & vbNullChar & vbNullChar Call WritePrivateProfileSection("Time", temp, "WinAPI_Archive_Sample_12.ini") End With End Sub
ダウンロード