例子:控制NSIS进度条控件

优质
小牛编辑
173浏览
2023-12-01
引用脚本的内容:

!include nsDialogs.nsh
Name "ProgressBar"
OutFile "ProgressBar Test.EXE"
LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf"
;新建一个自定义页面
Page custom nsDialogsShow

;为使用的控件句柄分配个变量。
Var PROGBAR
Var WINDOW
Var Button1
Var Button2
Var Button3
Var Button4
Var Button5
Var Button6

Function nsDialogsShow
;创建一个NSD窗口,几个按钮,一个ProgressBar
nsDialogs::Create 1018
Pop $WINDOW

${NSD_CreateButton} 0u 25u 80u 14u "进度条+10%"
Pop $Button1
${NSD_OnClick} $Button1 Button1_OnClick

${NSD_CreateButton} 110u 25u 80u 14u "进度条-10%"
Pop $Button2
${NSD_OnClick} $Button2 Button2_OnClick

${NSD_CreateButton} 0u 45u 80u 14u "进度条置0"
Pop $Button3
${NSD_OnClick} $Button3 Button3_OnClick

${NSD_CreateButton} 110u 45u 80u 14u "进度条平滑+50%"
Pop $Button4
${NSD_OnClick} $Button4 Button4_OnClick

${NSD_CreateButton} 0u 65u 80u 14u "使用Timer控制进度"
Pop $Button5
${NSD_OnClick} $Button5 Button5_OnClick

${NSD_CreateButton} 110u 65u 80u 14u "Timer+执行任务"
Pop $Button6
${NSD_OnClick} $Button6 Button6_OnClick

;创建一个ProgressBar
${NSD_CreateProgressBar} 0u 100u 100% 12u ""
Pop $PROGBAR

nsDialogs::Show
FunctionEnd

Function Button1_OnClick
;进度条+10%
SendMessage $PROGBAR ${PBM_DELTAPOS} 10 0
FunctionEnd

Function Button2_OnClick
;进度条-10%
SendMessage $PROGBAR ${PBM_DELTAPOS} -10 0
FunctionEnd

Function Button3_OnClick
;进度条置0
SendMessage $PROGBAR ${PBM_SETPOS} 0 0
FunctionEnd

Function Button4_OnClick
;进度条平滑+50%
;用$R9作计数器,每次循环$R9减一。直到$R9=0停止,下文所示循环50次
StrCpy $R9 50                               ;50次循环
Loop:                                       ;开始循环
SendMessage $PROGBAR ${PBM_DELTAPOS} 1 0    ;将进度条+1%
Sleep 20                                    ;暂停10ms,便于观看
IntOp $R9 $R9 - 1                           ;$R9减一
StrCmp $R9 0 +2                             ;如果$R9=0跳出循环
Goto Loop                                   ;否则继续循环
FunctionEnd

Function Button5_OnClick
;使用Timer控制进度,优点是不影响其他控件工作。
MessageBox MB_ICONINFORMATION|MB_OK '注意,Timer运行时你仍然可以按其他按钮如+10%,-10%等控制进度条。'
;创建Timer控件并在Timer执行任务
${NSD_CreateTimer} OnTimer 100
FunctionEnd


Function OnTimer
;获取当前进度
SendMessage $PROGBAR ${PBM_GETPOS} 0 0 $1
;如果进度到100%,结束计算;否则跳到GoOn继续。
IntCmp $1 100 +1 GoOn +1
${NSD_KillTimer} OnTimer        ;停止Timer计算
MessageBox MB_OK '计算已满,结束计算。'
GoOn:
;进度条+3%
SendMessage $PROGBAR ${PBM_DELTAPOS} 3 0
FunctionEnd


Function Button6_OnClick
;执行普通操作控制进度,并且使用Timer辅助平滑进度条。

;作用:
;假设下面的MessageBox等待期间等效于在执行file,regdll命令
;但file,regdll不够多,如下面例子,一般情况下,只有三次断开(break)(如三个MessageBox的间隙)
;可以移动$PROGBAR,就会造成PROGBAR出现严重的跳跃
;但是如果配合Timer的话,可以使安装进度条在空闲时间动一下,就不至于被误认为死机了。
;当然这个只是初步的平滑,制造更多的break去加插设置进度条语句,才能更真实的反应安装进度。


;先进度条置0
SendMessage $PROGBAR ${PBM_SETPOS} 0 0
;创建Timer控件并在Timer执行任务
${NSD_CreateTimer} OnTimer2 200

MessageBox MB_OK '假设按下按钮时候安装执行完了50%'
;假设这里预算已经运行了一半,获取现在的进度GETPOS,如果Timer算出的进度>50%就不干预了,如果不够50%,补到50%
SendMessage $PROGBAR ${PBM_GETPOS} 0 0 $1
IntCmp $1 50 +1 +1 +2
SendMessage $PROGBAR ${PBM_SETPOS} 50 0
;假设这里预算已经运行了70%,获取现在的进度GETPOS,如果Timer算出的进度>70%就不干预了,如果不够70%,补到70%
MessageBox MB_OK '假设按下按钮时候安装执行完了70%'
SendMessage $PROGBAR ${PBM_GETPOS} 0 0 $1
IntCmp $1 70 +1 +1 +2
SendMessage $PROGBAR ${PBM_SETPOS} 70 0
;同上,继续补全
MessageBox MB_OK '假设按下按钮时候安装执行完了100%'
SendMessage $PROGBAR ${PBM_GETPOS} 0 0 $1
IntCmp $1 100 +1 +1 +2
SendMessage $PROGBAR ${PBM_SETPOS} 100 0
FunctionEnd

Function OnTimer2
SendMessage $PROGBAR ${PBM_GETPOS} 0 0 $1
IntCmp $1 100 +1 GoOn2 +1
${NSD_KillTimer} OnTimer2
MessageBox MB_OK '计算已满,结束计算。'
GoOn2:
SendMessage $PROGBAR ${PBM_DELTAPOS} 1 0
FunctionEnd

Section
SectionEnd

小结:
上面最后一个例子只是表面上平滑了进度条,真正有效的使进度条真实反映安装进度方法有:
将原来安装包含大量文件的文件夹
File /r C:\a\*
分拆为
File C:\a\1.exe
SendMessage $PROGBAR ${PBM_SETPOS} 3 0 ;假设安装完成3%
File C:\a\2.exe
SendMessage $PROGBAR ${PBM_SETPOS} 5 0 ;假设安装完成5%
File C:\a\3.exe
SendMessage $PROGBAR ${PBM_SETPOS} 10 0 ;假设安装完成10%
.....
这样的散句,才能有效反映真实的安装进度。