MsgBox - Make unclickable OK Button and change to

2019-01-19 07:43发布

问题:

How to change OK button into a countdown timer like this...

  • 5,4,3,2,1,0 [MsgBox Closes automatically] don't display 0

  • Proceeds to setup procedure.

The button should not be clickable and faded. Like inactive window/button/box.

this one:

not this one:

I use the code code from this question: How to show a message box for a specified time?

回答1:

There's no built-in function with such functionality. Neither in Inno Setup, nor WinAPI.

You have to implement the dialog on your own and use the InnoCallback DLL to implement the count down.

[Files]
Source: InnoCallback.dll; Flags: dontcopy

[Code]

type
  TTimerProc = procedure(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);

function SetTimer(hWnd: LongWord; nIDEvent, uElapse: LongWord; 
  lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd: HWND; uIDEvent: LongWord): BOOL;
  external 'KillTimer@user32.dll stdcall';
function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord;
  external 'wrapcallback@files:innocallback.dll stdcall';

var
  CountdownButton: TNewButton;
  Countdown: Integer;

procedure UpdateCountDownButtonCaption;
begin
  CountdownButton.Caption := Format('%d sec', [Countdown]);
end;

procedure CountdownProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
  Dec(Countdown);
  if Countdown = 0 then
  begin
    CountdownButton.Enabled := True;
    TForm(CountdownButton.Parent).Close;
  end
    else
  begin
    UpdateCountDownButtonCaption;
  end;
end;

procedure CountdownMessageBoxCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  { Prevent the dialog from being close by the X button and Alt-F4 }
  CanClose := CountdownButton.Enabled;
end;

procedure CountdownMessageBox(Message: string; Seconds: Integer);
var
  Form: TSetupForm;
  MessageLabel: TLabel;
  CountdownCallback: LongWord;
  Timer: LongWord;
begin
  Form := CreateCustomForm;
  try
    Form.ClientWidth := ScaleX(256);
    Form.ClientHeight := ScaleY(96);
    Form.Caption := 'Information';
    Form.Position := poMainFormCenter;
    Form.OnCloseQuery := @CountdownMessageBoxCloseQuery;

    MessageLabel := TLabel.Create(Form);
    MessageLabel.Top := ScaleY(16);
    MessageLabel.Left := ScaleX(16);
    MessageLabel.AutoSize := True;
    MessageLabel.Caption := Message;
    MessageLabel.Parent := Form;

    if CountdownButton <> nil then
      RaiseException('Countdown in progress already');

    Countdown := Seconds;

    CountdownButton := TNewButton.Create(Form);
    CountdownButton.Parent := Form;
    CountdownButton.Width := ScaleX(88);
    CountdownButton.Height := ScaleY(26);
    CountdownButton.Left := Form.ClientWidth - CountdownButton.Width - ScaleX(18);
    CountdownButton.Top := Form.ClientHeight - CountdownButton.Height - ScaleX(11);
    UpdateCountDownButtonCaption;
    CountdownButton.Name := 'CountdownButton';
    CountdownButton.ModalResult := mrOk;
    CountdownButton.Default := True;
    CountdownButton.Enabled := False;

    CountdownCallback := WrapTimerProc(@CountdownProc, 4);
    Timer := SetTimer(0, 0, 1000, CountdownCallback);

    try
      Form.ShowModal();
    finally
      KillTimer(0, Timer);
    end;
  finally
    Form.Free();
    CountdownButton := nil;
  end;
end;  

Use it like:

CountdownMessageBox('Message here', 10);


Related questions:

  • How to show a message box for a specified time?
  • Inno Setup - How to close finished installer after a certain time?
  • Inno Setup - Automatically submitting uninstall prompts.


标签: inno-setup