CheckBox がクリックされたら「メッセージを表示」して、ユーザーに「はい」・「いいえ」のいずれかを選択してもらう。
「はい」が選択された場合はプログラム自体を再起動。で、再起動後の FormCreate 時に当該 CheckBox の Checked プロパティをクリックされた(変更された)状態に設定。ただし、その際、メッセージは表示しない。
もし、「いいえ」が選択された場合は、CheckBox の Checked プロパティはチェック前の状態を維持、つまり、クリックを無効化する。もちろん、ここでもメッセージは出さずに、Checked プロパティのみ修正したい。
この動作を実現したくて、半日、ハマった。
【もくじ】
1.用意した手続きと関数
2.実行結果
3.お願いとお断り
1.用意した手続きと関数
なんとか、実現。完成したコードは以下の通り。
private
{ Private 宣言 }
//チェックボックスの状態をロード中に OnClick イベントがトリガーされるのを防止する
IsLoading: Boolean;
procedure SaveCheckCMS_State(CheckBox: TCheckBox); //Checked プロパティを保存
procedure LoadCheckCMS_State(CheckBox: TCheckBox); //Checked プロパティを読込
procedure ClearRestartFlag; //再起動フラグをクリア
function IsRestarting: Boolean;
procedure RestartApplication;
グローバル変数を一つ、手続きと関数を上のように準備。それから ini ファイルを使うので、System.IniFiles を uses に追加。
implementation
uses
System.IniFiles;
Shift+Ctrl+C でそれぞれの手続きや関数を次のように作成。
まず、SaveCheckCMS_State 手続き。CheckCMS が CheckBox の名前。Checked プロパティの状態を保存する。ちなみに CMS は、組み合わせ採点(Combined Scoring Method)の略。
procedure TForm1.SaveCheckCMS_State(CheckBox: TCheckBox);
var
IniFile: TIniFile;
begin
IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
try
IniFile.WriteBool('セクション', '組み合わせ採点', CheckCMS.Checked);
IniFile.WriteBool('セクション', 'IsRestarting', True); //再起動フラグを設定
finally
IniFile.Free;
end;
end;
次は LoadCheckCMS_State 手続き(保存した Checked プロパティの状態を読み込む)。
procedure TForm1.LoadCheckCMS_State(CheckBox: TCheckBox);
var
IniFile: TIniFile;
begin
IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
try
IsLoading := True; // イベントを無効にするためのフラグを設定
CheckCMS.Checked := IniFile.ReadBool('セクション', '組み合わせ採点', False);
finally
IsLoading := False; // フラグをリセット
IniFile.Free;
end;
end;
次は ClearRestartFlag 手続き( Checked プロパティの保存時に True に設定した再起動を知るフラグをクリアする)。
procedure TForm1.ClearRestartFlag;
var
IniFile: TIniFile;
begin
IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
try
IniFile.WriteBool('セクション', 'IsRestarting', False); //再起動フラグをクリア
finally
IniFile.Free;
end;
end;
次は IsRestarting 関数( FormCreate 時に呼び出し)。
function TForm1.IsRestarting: Boolean;
var
IniFile: TIniFile;
begin
IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
try
Result := IniFile.ReadBool('セクション', 'IsRestarting', False);
finally
IniFile.Free;
end;
end;
次は RestartApplication 手続き。これを呼び出すことでプログラム自体を再起動する。
procedure TForm1.RestartApplication;
var
FileName: string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
FileName := ParamStr(0);
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
ZeroMemory(@ProcessInfo, SizeOf(ProcessInfo));
if CreateProcess(PChar(FileName), nil, nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo) then
begin
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
Application.Terminate;
end;
以上のように手続き・関数を準備して、FormCreate 時の設定。
procedure TForm1.FormCreate(Sender: TObject);
begin
//チェックボックスの状態をロード中に OnClick イベントがトリガーされるのを防止する
IsLoading:=False;
LoadCheckCMS_State(CheckCMS); //Checked プロパティを復元
if IsRestarting then
ClearRestartFlag; //再起動フラグをクリア
end;
最後に、いちばん肝心な CheckCMSClick 手続き。実際は、ここからすべてが始まる。
procedure TForm1.CheckCMSClick(Sender: TObject);
var
strMsg: string;
begin
//再起動状態でなければ実行
if not IsLoading then
begin
SaveCheckCMS_State(CheckCMS); //Checked プロパティを保存
//最初はコレでいいかと思ったんだけれど・・・あまりにも乱暴な気が。
//strMsg:='設定はプログラムの再起動後に有効になります。'+#13#10+
// 'OKで再起動します。';
//Application.MessageBox(PChar(strMsg), PChar('情報'), MB_ICONINFORMATION);
//RestartApplication;
//操作の取り消しができるように修正
strMsg:='設定はプログラムの再起動後に有効になります。'+#13#10+
'再起動してよろしいですか?';
if Application.MessageBox(PChar(strMsg), PChar('情報'), MB_YESNO or MB_ICONINFORMATION) = mrYes then
begin
//[はい]が選ばれた時
RestartApplication;
end else begin
//[いいえ]が選ばれた時
//メッセージを表示せず、チェックボックスの状態のみ変更
if CheckCMS.Checked then
begin
CheckCMS.OnClick := nil; //OnClickイベントを一時的に無効にする
CheckCMS.Checked := False;
CheckCMS.OnClick := CheckCMSClick; //OnClickイベントを再度設定
end else begin
CheckCMS.OnClick := nil; //OnClickイベントを一時的に無効にする
CheckCMS.Checked := True;
CheckCMS.OnClick := CheckCMSClick; //OnClickイベントを再度設定
end;
end;
end;
end;
2.実行結果
(1)プログラムを起動。フォームが表示される。
(2)CheckBoxをクリックすると、メッセージが表示されるので、「はい」をクリックする。
(3)自分自身を再起動。CheckBox の Checked プロパティは終了時の True 状態で起動するが、上記のメッセージは表示されない。 これが実現したかったことのひとつめ。
(4)再度、CheckBox をクリック。Checked プロパティは False に変わり、CheckBox のチェックは外れた状態でメッセージが表示される。今度は「いいえ」をクリック。
(5)「いいえ」を選択したから再起動はしない。「再起動しない」から CheckBox の Checked プロパティは元の True であった状態を維持(= False から True へ修正)するが、メッセージは表示されない。これが実現したかったことのふたつめ。
3.お願いとお断り
このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容(プログラムを含む)利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。