在 Inno Setup 中实现倒数N秒后激活按钮
作者:xin 日期:2006-08-06
timectrl.dll 为一个 6.5 KB 的按钮激活时间控制插件。

引用来自 Example1.iss,2009-1-19 12:35:12
点击这里下载脚本例子:
http://restools.hanzify.org/inno/timectrl/inno_timectrl.zip


; -- Example1.iss --
; restools
; http://restools.yeah.net
; 此插件同样可以使用在 NSIS 的安装程序中。
; 这只不过是演示一下没有什么是实现不了的,只是值不值得的问题,为了这么一个小功能而去编一个相对麻烦的插件,我觉得太过浪费时间了。
; 其实只要在 Windows 中,就可以外挂任何的东西,只不过看看究竟你的重心是在做安装程序,还是在做外挂。如果做一个外挂的插件比做这个安装程序还复杂,倒不如我自己编写安装程序的自由度还来得大。
; 时间仓促,所以编程可能会有点谬误,如有错误可以提出
[Setup]
AppName=我的程序
AppVerName=我的程序 版本 1.5
DefaultDirName={pf}\我的程序
DefaultGroupName=我的程序
UninstallDisplayIcon={app}\MyProg.exe
LicenseFile=license.txt
[Files]
Source: "MyProg.exe"; DestDir: "{app}"
Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme
Source: "timectrl.dll"; Flags: dontcopy
[Icons]
Name: "{group}\我的程序"; Filename: "{app}\MyProg.exe"
[code]
function starttimer(WizardFormHandle: HWND; ButtonHandle: HWND; ButtonCaption: PChar; RTime: UINT): BOOL; external 'starttimer@files:timectrl.dll stdcall';
//WizardFormHandle 向导窗口句柄
//ButtonHandle 下一步按钮句柄
//ButtonCaption 秒数倒数完毕后要在按钮上显示的文字
//RTime 剩余时间
function stoptimer(): BOOL; external 'stoptimer@files:timectrl.dll stdcall';
function IsWindowEnabled(hWnd: HWND): BOOL; external 'IsWindowEnabled@user32.dll stdcall';
procedure InitializeWizard();
begin
WizardForm.LICENSEACCEPTEDRADIO.Hide;
WizardForm.LICENSENOTACCEPTEDRADIO.Hide;
WizardForm.LICENSEACCEPTEDRADIO.Checked := True;
WizardForm.LICENSEMEMO.Height := 170;
with TLabel.Create(WizardForm) do
begin
Parent := WizardForm.LicensePage;
Top := 200;
Left := 2;
Caption := '如果你点击“我同意”进入下一页面,即表示你同意以上协议。';
end;
end;
procedure DeinitializeSetup();
begin
stoptimer();
end;
procedure CurPageChanged(CurPageID: Integer);
begin
//一定要别人先看协议20秒,即使返回欢迎页面,秒数倒数会停止,再进入协议秒数倒数继续
if CurPageID = wpLicense then
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',20)
else
if (CurPageID = wpWelcome) or (CurPageID = wpSelectDir) then
begin
stoptimer();
WizardForm.NEXTBUTTON.Caption := '下一步(&N) >';
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if (CurPageID = wpLicense) then
Result := IsWindowEnabled(WizardForm.NextButton.Handle)
else
Result := True;
end;
; restools
; http://restools.yeah.net
; 此插件同样可以使用在 NSIS 的安装程序中。
; 这只不过是演示一下没有什么是实现不了的,只是值不值得的问题,为了这么一个小功能而去编一个相对麻烦的插件,我觉得太过浪费时间了。
; 其实只要在 Windows 中,就可以外挂任何的东西,只不过看看究竟你的重心是在做安装程序,还是在做外挂。如果做一个外挂的插件比做这个安装程序还复杂,倒不如我自己编写安装程序的自由度还来得大。
; 时间仓促,所以编程可能会有点谬误,如有错误可以提出
[Setup]
AppName=我的程序
AppVerName=我的程序 版本 1.5
DefaultDirName={pf}\我的程序
DefaultGroupName=我的程序
UninstallDisplayIcon={app}\MyProg.exe
LicenseFile=license.txt
[Files]
Source: "MyProg.exe"; DestDir: "{app}"
Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme
Source: "timectrl.dll"; Flags: dontcopy
[Icons]
Name: "{group}\我的程序"; Filename: "{app}\MyProg.exe"
[code]
function starttimer(WizardFormHandle: HWND; ButtonHandle: HWND; ButtonCaption: PChar; RTime: UINT): BOOL; external 'starttimer@files:timectrl.dll stdcall';
//WizardFormHandle 向导窗口句柄
//ButtonHandle 下一步按钮句柄
//ButtonCaption 秒数倒数完毕后要在按钮上显示的文字
//RTime 剩余时间
function stoptimer(): BOOL; external 'stoptimer@files:timectrl.dll stdcall';
function IsWindowEnabled(hWnd: HWND): BOOL; external 'IsWindowEnabled@user32.dll stdcall';
procedure InitializeWizard();
begin
WizardForm.LICENSEACCEPTEDRADIO.Hide;
WizardForm.LICENSENOTACCEPTEDRADIO.Hide;
WizardForm.LICENSEACCEPTEDRADIO.Checked := True;
WizardForm.LICENSEMEMO.Height := 170;
with TLabel.Create(WizardForm) do
begin
Parent := WizardForm.LicensePage;
Top := 200;
Left := 2;
Caption := '如果你点击“我同意”进入下一页面,即表示你同意以上协议。';
end;
end;
procedure DeinitializeSetup();
begin
stoptimer();
end;
procedure CurPageChanged(CurPageID: Integer);
begin
//一定要别人先看协议20秒,即使返回欢迎页面,秒数倒数会停止,再进入协议秒数倒数继续
if CurPageID = wpLicense then
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',20)
else
if (CurPageID = wpWelcome) or (CurPageID = wpSelectDir) then
begin
stoptimer();
WizardForm.NEXTBUTTON.Caption := '下一步(&N) >';
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if (CurPageID = wpLicense) then
Result := IsWindowEnabled(WizardForm.NextButton.Handle)
else
Result := True;
end;
点击这里下载脚本例子:
http://restools.hanzify.org/inno/timectrl/inno_timectrl.zip
评论: 12 | 引用: 0 | 查看次数: 18097

我没发现有什么具体的错误,你如果像描述清楚,只能上比较完整的代码。
错了,重发
完整的代码就是使用你在上面公布的代码了,只是在相应位置上代码作修改而已:
if CurPageID = wpLicense then
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',20)
修改成如下既是:
if CurPageID = wpLicense then
begin
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',10);
stoptimer();;
end;

我没发现有什么具体的错误,你如果像描述清楚,只能上比较完整的代码。
完整的代码就是使用你在上面公布的代码了,只是在相应位置上代码作修改而已:
if CurPageID = wpLicense then
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',20)
修改成如下既是:
if CurPageID = wpLicense then
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',20)
begin
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',10);
stoptimer();;
end;
我没发现有什么具体的错误,你如果像描述清楚,只能上比较完整的代码。

报告一个发现的问题:
在倒数没有结束(starttimer)之前不小心调用了stoptimer的话,整个倒数完全混乱卡死.请xin有时间时修正下.
用如下测试代码:
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',10);
stoptimer();
在倒数没有结束(starttimer)之前不小心调用了stoptimer的话,整个倒数完全混乱卡死.请xin有时间时修正下.
用如下测试代码:
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',10);
stoptimer();
临时解决办法,在调用stoptimer之前先判断按钮是否可用。如下:
if IsWindowEnabled(WizardForm.NextButton.Handle); //为什么要是可用而不是不可用,不明白?
stoptimer();
彻底的解决方法要等大大更新了。
报告一个发现的问题:
在倒数没有结束(starttimer)之前不小心调用了stoptimer的话,整个倒数完全混乱卡死.请xin有时间时修正下.
用如下测试代码:
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',10);
stoptimer();
在倒数没有结束(starttimer)之前不小心调用了stoptimer的话,整个倒数完全混乱卡死.请xin有时间时修正下.
用如下测试代码:
starttimer(WizardForm.Handle,WizardForm.NEXTBUTTON.Handle,'我同意(&I)',10);
stoptimer();
修整添加部分。早就发现了,只是懒得改而已。
引用来自 Example1.iss,2009-1-19 12:35:12
[code]
function IsWindowEnabled(hWnd: HWND): BOOL; external 'IsWindowEnabled@user32.dll stdcall';
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if (CurPageID = wpLicense) then
Result := IsWindowEnabled(WizardForm.NextButton.Handle)
else
Result := True;
end;

[code]
function IsWindowEnabled(hWnd: HWND): BOOL; external 'IsWindowEnabled@user32.dll stdcall';
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if (CurPageID = wpLicense) then
Result := IsWindowEnabled(WizardForm.NextButton.Handle)
else
Result := True;
end;
有个巨大的BUG
在安装界面中一路按回车键下去,就可以跳过倒计时的限制.
哈哈哈.
解决之后麻烦发我邮箱一下:
jianzexing@163.com
在安装界面中一路按回车键下去,就可以跳过倒计时的限制.
哈哈哈.
解决之后麻烦发我邮箱一下:
jianzexing@163.com

好,站长知道怎么才能让INNO SETUP打包的安装程序,在被解包时出现这样
查看图片
查看图片
方法在网上就可以找到,你自己找找吧。
BTW: 就算这世界本来就乱的,也不应该由我来把它搞得更乱。
发表评论
但是上面说的都不是重点,重点是我不明白你为什么要这么做,正如编写代码不正确并不能归咎为代码语言的错。