NSIS 之 NsDialogs 常见问题解答

如何启用/禁用控件

使用标准 NSIS EnableWindow 命令。

NSDialogs 允许您弹出通过 ${NSD_Create*} 创建的控件的 hwnd (句柄)。EnableWindow 将 hwnd 作为其参数之一。通过它,您可以轻松启用/禁用控件。

 

  !include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd
var button

Function pre
  nsDialogs::Create 1018
  Pop $dialog
  ${NSD_CreateCheckbox} 0 0 50% 6% "Enable button below"
    Pop $hwnd
    ${NSD_OnClick} $hwnd EnDisableButton

  ${NSD_CreateButton} 25% 25% 50% 50% "Hello World"
    Pop $button
    EnableWindow $button 0 # start out disabled

  nsDialogs::Show
FunctionEnd

Function
EnDisableButton
  Pop $hwnd
  ${NSD_GetState} $hwnd $0
  ${If} $0 == 1
    EnableWindow $button 1
  ${Else}
    EnableWindow $button 0
  ${EndIf}
FunctionEnd

Section
""
SectionEnd

如何显示/隐藏控件

使用标准 NSIS ShowWindow 命令。

NSDialogs 允许您弹出通过 ${NSD_Create*} 创建的控件的 hwnd (句柄)。ShowWindow将 hwnd 作为其参数之一。通过它,您可以轻松显示/隐藏控件。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd
var button

Function pre
  nsDialogs::Create 1018
    Pop $dialog
  ${NSD_CreateCheckbox} 0 0 50% 6% "Show button below"
    Pop $hwnd
    ${NSD_OnClick} $hwnd EnDisableButton

  ${NSD_CreateButton} 25% 25% 50% 50% "Hello World"
    Pop $button
    ShowWindow $button ${SW_HIDE} # start out hidden

  nsDialogs::Show
FunctionEnd

Function
EnDisableButton
  Pop $hwnd
  ${NSD_GetState} $hwnd $0
  ${If} $0 == 1
    ShowWindow $button ${SW_SHOW}
  ${Else}
    ShowWindow $button ${SW_HIDE}
  ${EndIf}
FunctionEnd

Section
""
SectionEnd

 如何创建一个文本居中的标签

文本居中 - 无论控件的大小如何,文本始终居中显示,这通常对于展示目的非常有用。使标签的文本居中对齐很简单,使用 ${NSD_AddStyle} 命令添加 ${SS_CENTER} 样式即可。

!include "nsDialogs.nsh"

OutFile "$%temp%\temp.exe"

var dialog
var hwnd
var null

Page custom Test

Function Test
    
nsDialogs::Create 1018
        
Pop $dialog

    ${NSD_CreateLabel}
0 0 100% 20% "This line will be centered.$\nAnd so will this line."
        
Pop $hwnd
        ${NSD_AddStyle} $hwnd ${SS_CENTER}

    
nsDialogs::Show
FunctionEnd

Section
SectionEnd

如何创建多行编辑(文本)控件 

 虽然多行是控件的一个样式,但对于编辑(文本)控件来说,它是少数几种样式之一,无法在控件创建后设置,因此无法使用 ${NSD_AddStyle}。

相反,您需要手动创建控件:

 

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

Function pre
  nsDialogs::Create 1018
    Pop $dialog
  ${NSD_CreateText} 0 0 100% 40% "This is NOT a$\r$\nmulti-line$\r$\nedit control"
    Pop $hwnd

  nsDialogs::CreateControl EDIT \
    "${__NSD_Text_STYLE}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN}" \
    "${__NSD_Text_EXSTYLE}" \
    0 50% 100% 40% \
    "This IS a$\r$\nmulti-line$\r$\nedit control"
    Pop $hwnd

  nsDialogs::Show
FunctionEnd

Section
""
SectionEnd

 

或者,更简洁的方法是使用  NsDialogs_CreateTextMultiline  头文件:

 

!include "nsDialogs.nsh"
!include "nsDialogs_createTextMultiline.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

Function pre
  nsDialogs::Create 1018
    Pop $dialog
  ${NSD_CreateText} 0 0 100% 40% "This is NOT a$\r$\nmulti-line$\r$\nedit control"
    Pop $hwnd

  ${NSD_CreateTextMultiline} 0 50% 100% 40% "This IS a$\r$\nmulti-line$\r$\nedit control"
    Pop $hwnd

  nsDialogs::Show
FunctionEnd

Section
""
SectionEnd

如何创建文本密码控件

请参阅 nsDialogs 文档 - 密码控件是默认支持的控件之一;${NSD_CreatePassword}

如何设置文本密码控件使用的字符

默认情况下,文本密码控件将使用星号(****)作为密码字符来掩盖文本(当'XPStyle off'时),或者使用圆点(••••)(当'XPStyle on'时)。您可以使用带有 EM_SETPASSWORDCHAR 标志的 SendMessage 来更改此字符。

密码字符由其 ASCII 或 UNICODE 码索引标识;请注意,您在安装程序中使用的字体可能不支持您希望使用的字符。

注意:如果将密码字符设置为 0(零),文本将不会被掩盖!您可以利用这一点在文本密码控件中切换文本的可见和掩盖状态。另请参阅如何在文本密码控制中隐藏/显示密码的条目。

!include "nsDialogs.nsh"

!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

Function pre
  nsDialogs::Create 1018
    Pop $dialog
  ${NSD_CreatePassword} 0 0 50% 8% "This is a password field"
      Pop $hwnd
      SendMessage $hwnd ${EM_SETPASSWORDCHAR} 149 0
                
# 在 ASCII 或 Unicode 编码中,149 指的是中等大小的圆点
  nsDialogs::Show
FunctionEnd

Section
""
SectionEnd

 如何在文本密码控件中隐藏/显示密码

通过使用带有 EM_SETPASSWORDCHAR 标志的 SendMessage 设置,通过将字符指定为 0(零),您可以让密码可见,而通过指定非零字符使密码再次不可见。

注意:更改掩码字符后,必须强制重绘密码控件。通常是通过隐藏然后使用 ShowWindow 显示控件来完成。

!include "nsDialogs.nsh"

!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd
var passwordControl

Function pre
  nsDialogs::Create 1018
    Pop $dialog

  ${NSD_CreateCheckbox} 0 0 25% 8% "Show password"
    Pop $hwnd
    ${NSD_OnClick} $hwnd ShowPassword

  ${NSD_CreatePassword} 0 10% 50% 8% "This is a password field"
      Pop $passwordControl

  nsDialogs::Show
FunctionEnd

Function
ShowPassword
  Pop $hwnd
  ${NSD_GetState} $hwnd $0
  ShowWindow $passwordControl ${SW_HIDE}
  ${If} $0 == 1
    SendMessage $passwordControl ${EM_SETPASSWORDCHAR} 0 0
  ${Else}
    SendMessage $passwordControl ${EM_SETPASSWORDCHAR} 42 0
  ${EndIf}
  ShowWindow $passwordControl ${SW_SHOW}
FunctionEnd

Section
""
SectionEnd

注意:在启用 'XPStyle on' 的情况下,如果要重置ANSI构建中看到的“粗点”字符,不能使用标准的SendMessage(底层使用 SendMessageA),因为它是一个 Unicode 字符。可以使用 System 插件调用 SendMessageW 函数:

 /* 9679是粗点字符 */

System::Call "user32::SendMessageW(i $hwnd, i ${EM_SETPASSWORDCHAR}, i 9679, i 0)"

如何创建仅数字的文本控件 

请参阅 nsDialogs 文档 - 仅限数字的控件是默认支持的控件之一;${NSD_CreateNumber}

如何创建只读文本控件 

文本控件的只读状态可以使用带有 EM_SETREADONLY 标志的 SendMessage 来设置。

请注意,只读的编辑(文本)控件与禁用的文本控件不同。禁用的文本控件将其文本显示为灰色,而只读的文本控件则保持黑色,并显示在浅灰色背景上。此外,禁用的多行文本控件无法滚动。而只读的多行文本控件则可以滚动。

 !include "nsDialogs.nsh"

!include "winmessages.nsh"

!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd
var textControl

Function pre
  nsDialogs::Create 1018
    Pop $dialog
  ${NSD_CreateCheckBox} 0 0 50% 6% "Set text field below read-only"
      Pop $hwnd
      ${NSD_OnClick} $hwnd SetReadonly
  ${NSD_CreateText} 0 12% 100% 8% "Hello World"
    Pop $textControl

  nsDialogs::Show
FunctionEnd

Function
SetReadonly
  Pop $hwnd
  ${NSD_GetState} $hwnd $0
  SendMessage $textControl ${EM_SETREADONLY} $0 0
FunctionEnd

Section
""
SectionEnd

单选按钮 (Radio buttons)

单选按钮基本用法 

 

!include nsDialogs.nsh
Page Custom MyPageCreate MyPageLeave

Var StationChoice

Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateFirstRadioButton}
0 0 40% 6% "NPR"
Pop $1
SendMessage $1 ${BM_CLICK} "" "" ; Must select a default
${NSD_CreateAdditionalRadioButton} 0 12% 40% 6% "BBC"
Pop $2
${IfThen} $StationChoice
== "BBC" ${|} SendMessage $2 ${BM_CLICK} "" "" ${|}
nsDialogs::Show
FunctionEnd

Function
MyPageLeave
${NSD_GetChecked} $1 $3
${If} $3
<> ${BST_UNCHECKED}
  StrCpy $StationChoice "NPR"
${Else}
  StrCpy $StationChoice "BBC"
${EndIf}
FunctionEnd

Section
DetailPrint
"Turning the dial to $StationChoice"
SectionEnd

根据单选按钮的变化更新页面 

 !include nsDialogs.nsh

Page Custom MyPageCreate

Function MyPageCreate
nsDialogs::Create 1018
Pop $0

; 组1
${NSD_CreateFirstRadioButton} 0 0 50% 12u "NPR"
Pop $1
${NSD_OnClick} $1
onStationChanged
${NSD_CreateAdditionalRadioButton} 0 14u 50% 12u "BBC"
Pop $2
${NSD_OnClick} $2
onStationChanged
${NSD_CreateLabel} 0 30u 80% 12u ""
Pop $3
SendMessage $1 ${BM_CLICK} "" "" ; 必须选择一个默认选项

; 组2
${NSD_CreateFirstRadioButton} 0 50u 50% 12u "FM"
Pop $0 ; 仅用于演示,稍后不需要句柄
${NSD_CreateAdditionalRadioButton} 0 64u 50% 12u "AM"
Pop $0 ; 仅用于演示,稍后不需要句柄
SendMessage $0 ${BM_CLICK} "" "" ; 必须选择一个默认选项

nsDialogs::Show
FunctionEnd

Function
onStationChanged
Pop $0
${NSD_GetChecked} $1 $0
${If} $0
<> ${BST_UNCHECKED}
    ${NSD_SetText} $3
"America, f*(# yeah!" ;
${Else}
    ${NSD_SetText} $3
"保持冷静,继续前行" ; Keep Calm and Carry On
${EndIf}
FunctionEnd

如何创建两组 RadioButton 

使用 ${NSD_AddStyle} 向每组的第一个单选按钮添加 WS_GROUP 样式。在 Windows 的 UI 处理中,如果没有定义组启动器,所有单选按钮都被视为同一组的一部分。

因此,要创建两个各有两个单选按钮的组,必须为每组指定一个组启动器,否则第三和第四个单选按钮将被视为第一组的一部分。

使用 ${NSD_AddStyle} 设置组启动器很简单,使用以下代码:

${NSD_AddStyle} $hwnd ${WS_GROUP}  # WS_GROUP 定义在 winmessages.nsh 中

示例:

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

Function pre
    
nsDialogs::Create 1018
        
Pop $dialog
    ${NSD_CreateRadioButton}
0 0 40% 6% "组 1,单选按钮 1"
        
Pop $hwnd
        ${NSD_AddStyle} $hwnd ${WS_GROUP}
    ${NSD_CreateRadioButton}
0 12% 40% 6% "组 1,单选按钮 2"
        
Pop $hwnd

    ${NSD_CreateRadioButton}
50% 0 40% 6% "组 2,单选按钮 1"
        
Pop $hwnd
        ${NSD_AddStyle} $hwnd ${WS_GROUP}
    ${NSD_CreateRadioButton}
50% 12% 40% 6% "组 2,单选按钮 2"
        
Pop $hwnd

    
nsDialogs::Show
FunctionEnd

Section
""
SectionEnd

如何轻松处理单选按钮的选择 

通常,你不希望为每个单选按钮指定单独的 OnClick 函数... 

 

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

Function pre
  nsDialogs::Create 1018
    Pop $dialog
  ${NSD_CreateRadioButton} 0 0 40% 6% "Group 1, Radio 1"
    Pop $hwnd
    ${NSD_AddStyle} $hwnd ${WS_GROUP}
    ${NSD_OnClick} $hwnd Group1Radio1Click
  ${NSD_CreateRadioButton} 0 12% 40% 6% "Group 1, Radio 2"
    Pop $hwnd
    ${NSD_OnClick} $hwnd Group1Radio2Click

  nsDialogs::Show
FunctionEnd

Function
Group1Radio1Click
  Pop $hwnd
  MessageBox MB_OK "onClick:Group1Radio1"
FunctionEnd
Function
Group1Radio2Click
  Pop $hwnd
  MessageBox MB_OK "onClick:Group1Radio2"
FunctionEnd

Section
""
SectionEnd

但是唯一明显的替代方法似乎是将每个单选按钮放在不同的变量中,并在回调函数调用时将堆栈上的 hwnd 与该变量进行比较。

 

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

var Group1Radio1
var Group1Radio2

Function pre
    
nsDialogs::Create 1018
        
Pop $dialog
    ${NSD_CreateRadioButton}
0 0 40% 6% "组 1, 单选 1"
        
Pop $Group1Radio1
        ${NSD_AddStyle} $Group1Radio1 ${WS_GROUP}
        ${NSD_OnClick} $Group1Radio1
RadioClick
    
${NSD_CreateRadioButton} 0 12% 40% 6% "组 1, 单选 2"
        
Pop $Group1Radio2
        ${NSD_OnClick} $Group1Radio2
RadioClick

    
nsDialogs::Show
FunctionEnd

Function
RadioClick
    
Pop $hwnd
    ${If} $hwnd
== $Group1Radio1
        
MessageBox MB_OK "点击:组 1 单选 1"
    
${ElseIf} $hwnd == $Group1Radio2
        
MessageBox MB_OK "点击:组 1 单选 2"
    
${EndIf}
FunctionEnd

Section
""
SectionEnd

然而,你可以通过使用 nsDialogs 的 getUserData 和 setUserData 命令来消除这种情况。使用这些 *UserData 命令,你可以将数据存储在控件中,并在以后轻松检索这些数据。

为了简化这些命令的使用,我们将使用 NsDialogs UserData 的头文件。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre

var dialog
var hwnd

Function pre
    
nsDialogs::Create 1018
        
Pop $dialog
    ${NSD_CreateRadioButton}
0 0 40% 6% "组 1, 单选 1"
        
Pop $hwnd
        ${NSD_AddStyle} $hwnd ${WS_GROUP}
        ${NSD_SetUserData} $hwnd
"Group1Radio1"
        
${NSD_OnClick} $hwnd RadioClick
    
${NSD_CreateRadioButton} 0 12% 40% 6% "组 1, 单选 2"
        
Pop $hwnd
        ${NSD_SetUserData} $hwnd
"Group1Radio2"
        
${NSD_OnClick} $hwnd RadioClick

    
nsDialogs::Show
FunctionEnd

Function
RadioClick
    
Pop $hwnd
    ${NSD_GetUserData} $hwnd $0
    ${If} $0
== "Group1Radio1"
        
MessageBox MB_OK "点击:组 1 单选 1"
    
${ElseIf} $0 == "Group1Radio2"
        
MessageBox MB_OK "点击:组 1 单选 2"
    
${EndIf}
FunctionEnd

Section ""
SectionEnd

使用这种方法,你可以轻松地将变量设置为存储在单选按钮控件上的内部字符串,而不需要在 OnClick 事件函数中使用任何 If-ElseIf-EndIf 或 Case 选择。

 

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"

Page Custom pre post

var dialog
var hwnd
var minor

Function pre
    
nsDialogs::Create 1018
        
Pop $dialog

    ${NSD_CreateRadioButton}
0 0 40% 6% "我已年满 14 岁"
        
Pop $hwnd
        ${NSD_AddStyle} $hwnd ${WS_GROUP}
        ${NSD_SetUserData} $hwnd
"false"
        
${NSD_OnClick} $hwnd RadioClick
    
${NSD_CreateRadioButton} 0 12% 40% 6% "我未满 14 岁"
        
Pop $hwnd
        ${NSD_SetUserData} $hwnd
"true"
        
${NSD_OnClick} $hwnd RadioClick

    
nsDialogs::Show
FunctionEnd

Function
RadioClick
    
Pop $hwnd
    ${NSD_GetUserData} $hwnd $minor
FunctionEnd

Function
post
    
${If} $minor == ""
        
MessageBox MB_OK "请选择你的年龄组"
        
Abort
    
${ElseIf} $minor == true
        
MessageBox MB_OK "安装将继续进行,内容适合你的年龄"
    
${Else}
        
MessageBox MB_OK "安装将正常进行"
    
${EndIf}
FunctionEnd

Section
""
SectionEnd

进度条

如何控制进度条控件(使用绝对值) 您可以使用 sendMessage 和进度条控件的消息来控制进度条。这些消息几乎都在 NSIS 附带的 WinMessages.nsh 头文件中定义,因此请务必包含此头文件。

至少有一个例外,它非常有用,因为它可以减少代码量并使您的源代码更容易阅读,那就是 PBM_SETRANGE32。PBM_SETRANGE32 允许您只用两个数字设置起始和结束范围,而不必像 PBM_SETRANGE 那样使用 WinDef.nsh 中的 ${MakeLong}

为了更新进度条的值,您需要使用 nsDialogs 计时器来调用处理实际处理的函数。此计时器仅调用一次。

下面是一个简单的示例,该示例创建了一个范围从 0(零)到 100 的进度条,用于典型的百分比增加,并将进度设置为 25%、50%、75% 和 100%,使用 Sleep 命令来模拟处理发生的情况——通常这可能是其他 NSIS 调用或在主安装之前调用外部应用程序/安装程序等。

!include "WinMessages.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"

OutFile "test.exe"

Section
SectionEnd

Var
dialog
Var hwnd
Var null


Page Custom page.custom
Function page.custom
    
nsDialogs::Create 1018
    
Pop $dialog

    ${NSD_CreateProgressBar}
0 0 100% 10% "Test"
        
Pop $hwnd

     ${NSD_CreateTimer}
NSD_Timer.Callback 10

    
nsDialogs::Show
FunctionEnd

Function
NSD_Timer.Callback
    
${NSD_KillTimer} NSD_Timer.Callback
    
SendMessage $hwnd ${PBM_SETRANGE32} 0 100

    
SendMessage $hwnd ${PBM_SETPOS} 25 0
    
Sleep 2000
    
SendMessage $hwnd ${PBM_SETPOS} 50 0
    
Sleep 2000
    
SendMessage $hwnd ${PBM_SETPOS} 75 0
    
Sleep 2000
    
SendMessage $hwnd ${PBM_SETPOS} 100 0
FunctionEnd

!insertmacro MUI_LANGUAGE "English"

如何控制进度条控件(使用步进值) 

上一个示例的一个缺点是,您必须始终跟踪百分比,而这些百分比可能并不重要,只要用户知道有进度即可。一个例子是,在复制/粘贴代码块时,跟踪百分比可能会变得棘手。您可能会突然发现自己的进度条从 0% 到 50%,然后回到 25%,再上升到 75%。

解决这个问题的一个相当简单的方法是使用步进进度条。这种方法允许您定义一个步进增量值,并简单地调用步进函数来逐步增加进度条的值。以下是使用这种方法的示例,其功能与前面的示例相同。请注意,我们将范围设置为函数中预期的步数。

 

!include "WinMessages.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"

OutFile "test.exe"

Section
SectionEnd

Var
dialog
Var hwnd
Var null

Page Custom page.custom
Function page.custom
    
nsDialogs::Create 1018
    
Pop $dialog

  ${NSD_CreateProgressBar} 0 0 100% 10% "测试"
    Pop $hwnd

     ${NSD_CreateTimer}
NSD_Timer.Callback 10

    
nsDialogs::Show
FunctionEnd

Function
NSD_Timer.Callback
    
${NSD_KillTimer} NSD_Timer.Callback
    
SendMessage $hwnd ${PBM_SETRANGE32} 0 4
    
SendMessage $hwnd ${PBM_SETSTEP} 1 0

    
SendMessage $hwnd ${PBM_STEPIT} 0 0
    
Sleep 2000
    
SendMessage $hwnd ${PBM_STEPIT} 0 0
    
Sleep 2000
    
SendMessage $hwnd ${PBM_STEPIT} 0 0
    
Sleep 2000
    
SendMessage $hwnd ${PBM_STEPIT} 0 0

    
SendMessage $hwnd ${PBM_SETPOS} 4 0
FunctionEnd

!insertmacro MUI_LANGUAGE "English"

请注意,在最后,我们仍然将进度设置为 100%。这是因为您的函数中可能有一些条件步骤。如果您忘记步进进度条,那么进度值将不会达到 100%。这是一个经常报告的用户界面问题,用户抱怨即使过程完成了,进度条仍然停留在少于 100% 的位置。

但是,请注意不要使用比在 PBM_SETRANGE32 调用中指定的步数更多的步骤,因为之后的任何步骤都会显示为 100%,而没有任何明显的进展。

如何创建一个跑马灯(无限循环)进度条控件 

有时您可能不知道进度 - 例如,您正在执行一个可能需要一些时间的任务,但无法确定任务进行到哪一步。在这种情况下,您可能希望使用一个所谓的跑马灯进度条,它只是从左到右无限循环。

有一个需要注意的事项:除非您使用带有 XP 样式的界面(另见 XPStyle),否则您不能使用跑马灯进度条。

除此之外,通过使用 ${NSD_AddStyle} 向进度条添加 PBS_MARQUEE 样式。

以下是一个这样的示例:

!include "WinMessages.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"

OutFile "test.exe"

Section
SectionEnd

Var
dialog
Var hwnd
Var null

!define PBS_MARQUEE 0x08

Page Custom page.custom
Function page.custom
    
nsDialogs::Create 1018
    
Pop $dialog

    ${NSD_CreateProgressBar}
0 0 100% 10% "测试"
        
Pop $hwnd
        ${NSD_AddStyle} $hwnd ${PBS_MARQUEE}

    ${NSD_CreateTimer}
NSD_Timer.Callback 10
    
nsDialogs::Show
FunctionEnd

Function
NSD_Timer.Callback
    
${NSD_KillTimer} NSD_Timer.Callback ; 关闭定时器
    
SendMessage $hwnd ${PBM_SETMARQUEE} 1 50 ; start=1|stop=0 间隔(ms)=+N
    
_again:
    
MessageBox MB_YESNO "停止跑马灯?" IDNO _again
        
SendMessage $hwnd ${PBM_SETMARQUEE} 0 0

FunctionEnd

!insertmacro MUI_LANGUAGE "English"

请注意,跑马灯进度条总是从左到右运行 - 您不能将其设置为其他任何位置。 

如何让控件接收快捷键(alt+字母)组合 

只有带标签的控件可以分配快捷键,只需在其标题中包含一个 & 符号。例如: 

${NSD_CreateCheckbox} 3% 3% 20% 8% "The hot&key here is alt+k"

但是,当在 NSIS 中首次导航到页面时,NSIS 对话框是获得焦点的,而不是内部的 nsDialogs 对话框。因此,在告诉 nsDialogs 显示之前,请先将焦点设置到 nsDialogs 对话框:

nsDialogs::Create 1018
Pop $dialog ; 假设您有一个 'dialog' 变量!
; 后续代码在这里
SendMessage $dialog ${WM_SETFOCUS} $HWNDPARENT 0
nsDialogs::Show

NSIS 对话框仍然会处理例如 alt+N 用于下一步按钮,因为如果当前焦点的窗口没有对快捷键事件作出反应,这些事件会简单地“冒泡”到父窗口。(提示:这意味着您不应该为 B(ack) 或 N(ext) 字母设置任何快捷键!)

使用这些方法,您可以轻松创建一个可以完全通过键盘操作的安装程序。

posted on 2024-07-20 12:01  水晶石  阅读(186)  评论(0编辑  收藏  举报