メッセージボックスで、「10秒後に終了しますか?」と出したい。

解決


ぺろ  2008-11-29 07:33:03  No: 32749  IP: [192.*.*.*]

MessageDlgでも、何でもいいのですが、

「60秒後にアプリを終了させます。いいですか?
  はい  /  いいえ」

秒数の部分は、時間によってカウントしたいのですが・・・、調べ方が悪いのか、メッセージボックス関係では、うまく検索出来ません。
’はい’なら即終了、’いいえ’ならカウント中止で。

やはり、難しいでしょうか?
もしくは、的はずれな調べ方でしょうか?

もしかしたら、あれってMessageDlgとかではなく、Form2をメッセージボックスっぽくしているのかなー?と、思ったり。
それなら、出来るかなー?と思うんですが、セオリーの方法はありますか?

編集    削除
New Monkey  2008-11-29 13:41:43  No: 32750  IP: [192.*.*.*]

カウントを表示するのがタイトルバーでもいいなら、強引な方法ですが別スレッドを作ってそこから更新してやればできます。
スレッドの作成はここが参考になります。
http://www.wwlnk.com/boheme/delphi/techdoc/dad0010.html
※私自身このへん詳しくないのでとんでもないことをしている可能性があります。フォローお願いします。

==========
Unit1
==========
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit2;

type
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private 宣言 }
    MyThread: TMyThread;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  MyThread := TMyThread.Create(False);
  if MessageDlg('終了しますか?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then Action := caNone;
end;

end.
==========
Unit2
==========
unit Unit2;

interface

uses
  Classes;

type
  TMyThread = class(TThread)
  private
    { Private 宣言 }
    hDlg: THandle;
    cnt: integer;
    procedure CountDown;
    procedure CloseDlg;
  protected
    procedure Execute; override;
  end;

implementation

uses
  SysUtils, Windows, Messages, Unit1;

procedure TMyThread.Execute;
var
  i: integer;
begin
  Sleep(1000);
  hDlg := FindWindow(PChar('TMessageForm'), PChar('確認'));
  for i:=10 downto 1 do begin
    cnt := i;
    Synchronize(CountDown);
    Sleep(1000);
  end;
  Synchronize(CloseDlg);
end;

procedure TMyThread.CountDown;
begin
  SendMessage(hDlg, WM_SETTEXT, 0, integer(PChar(IntToStr(cnt))));
end;

procedure TMyThread.CloseDlg;
begin
  SendMessage(hDlg, WM_CLOSE, 0, 0);
end;

end.

編集    削除
KHE00221  2008-11-29 17:48:37  No: 32751  IP: [192.*.*.*]

>もしかしたら、あれってMessageDlgとかではなく、Form2をメッセージボックスっぽくしているのかなー?と、思ったり。
>それなら、出来るかなー?と思うんですが、セオリーの方法はありますか?

MessageDlg 自体 TMessageForm というフォームです。

var
  Form8: TForm8;
  MessageForm: TForm;
  Message: TLabel;
  Count: Integer;

implementation

{$R *.dfm}

procedure TForm8.Button1Click(Sender: TObject);
var
    I: Integer;
begin

    Count := 10;

    //フォーム作成
    MessageForm := CreateMessageDialog(IntToStr(Count)+'秒後に終了します', mtInformation, [mbOk,mbCancel]);

    //ラベルの検索
    Message := nil;
    for I:=0 to MessageForm.ComponentCount -1 do
    begin
      if MessageForm.Components[I] is TLabel then Message := TLabel(MessageForm.Components[I]);
    end;

    Timer1.Interval := 1000;
    Timer1.Enabled := True;

    //フォーム表示
    MessageForm.Show;

    Self.Enabled := False;

    while MessageForm.ModalResult = mrNone do
    begin
      Application.ProcessMessages;
    end;

    Timer1.Enabled := False;

    Self.Enabled := True;

    if MessageForm.ModalResult = mrOk then
    begin
      MessageForm.Free;
      Close;
    end
    else
    begin
      MessageForm.Free;
    end;

end;

procedure TForm8.Timer1Timer(Sender: TObject);
begin
    Dec(Count);
    if Count = 0 then MessageForm.ModalResult := mrOk;
    if Assigned(Message) = True then
    begin
      Message.Caption := IntToStr(Count) + '秒後に終了します';
    end;
end;

編集    削除
ぺろ  2008-11-30 16:59:20  No: 32752  IP: [192.*.*.*]

すっきりした回答ありがとうございました。
MessageDlgというフォームも、いじれる可能性も考えなかったわけではないですが、もっとAPIとか使って、複雑かな?と思っていました。
こんなにもすっきりするものなんですね。

こういう初心者には、あまり意識しなくてもいい部分が分からないのは、やはりまだDelphiは素人なのだと感じました。
アプリ側でButtonを作るプログラムを、勉強し始めた所なので、これからも長く見守って頂ければ幸いです。

本当にありがとうございました。

編集    削除