使用 nsDialogs 自定义现有的 NSIS MUI2 页面
Customizing an exsisting NSIS MUI2 page using nsDialogs
我想在 Finish Page 中包含自定义控件,具体取决于是否设置了 IfRebootFlag,但我不知道为什么其中一些控件已创建但未显示。
$hWnd 是每个添加的控件的一个数字!= 0,所以这意味着所有控件都已创建。控件的位置好像没问题。。。肯定不在左边图片的后面,因为左坐标高到可以让控件超出图片
我试了好几个小时都不知道是哪个问题
;--------------------------------
;Header Files
!include nsDialogs.nsh
!include LogicLib.nsh
!include MUI2.nsh
Name App
OutFile ctmFinishPage.exe
XPStyle on
;--------------------------------
;General
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
;--------------------------------
;Variables
Var hWndChkBoxRunApp
Var hWndChkBoxLinkApp
Var hWndHlineReboot
Var hWndLblReboot
Var hWndRadBtnRebootNow
Var hWndRadBtnRebootLater
Var ctlLeft
Var ctlTop
Var ctlWidht
Var ctlHeight
Var ctlText
;--------------------------------
;Pages
;install pages
!insertmacro MUI_PAGE_INSTFILES
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyFinishShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE MyFinishLeave
!insertmacro MUI_PAGE_FINISH
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
Section
SetRebootFlag true
SectionEnd
;--------------------------------
;Functions
Function MyFinishShow
;add custom Reboot section to Finish page (MUI_FINISHPAGE_NOREBOOTSUPPORT flag is required)
IfRebootFlag 0 noreboot
StrCpy $ctlLeft 120u
StrCpy $ctlWidht 61%
StrCpy [=10=] 50
StrCpy $ctlTop [=10=]u
StrCpy $R0 10
StrCpy $ctlHeight $R0u
StrCpy $ctlText "Create Desktop shortcut"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxLinkApp
SetCtlColors $hWndChkBoxLinkApp "" "ffffff"
${NSD_SetState} $hWndChkBoxLinkApp ${BST_CHECKED}
StrCpy 117
StrCpy $ctlTop u
StrCpy $R1 1
StrCpy $ctlHeight $R1u
StrCpy $ctlText ""
${NSD_CreateHLine} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndHlineReboot
IntOp $R1 $R1 + 4
IntOp + $R1
StrCpy $ctlTop u
StrCpy $R2 25
StrCpy $ctlHeight $R2u
StrCpy $ctlText "Your computer must be restarted in order to complete the installation of App. Do you want to reboot now?"
${NSD_CreateLabel} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndLblReboot
SetCtlColors $hWndLblReboot "" "ffffff"
IntOp $R2 $R2 + 8
IntOp + $R2
StrCpy $ctlTop u
StrCpy $R3 10
StrCpy $ctlHeight $R3u
StrCpy $ctlText "Reboot now"
${NSD_CreateRadioButton} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndRadBtnRebootNow
SetCtlColors $hWndRadBtnRebootNow "" "ffffff"
${NSD_SetState} $hWndRadBtnRebootNow ${BST_CHECKED}
IntOp $R3 $R3 + 9
IntOp + $R3
StrCpy $ctlTop u
StrCpy $R4 10
StrCpy $ctlHeight $R4u
StrCpy $ctlText "I want to manually reboot later"
${NSD_CreateRadioButton} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndRadBtnRebootLater
SetCtlColors $hWndRadBtnRebootLater "" "ffffff"
${NSD_SetState} $hWndRadBtnRebootLater ${BST_UNCHECKED}
${NSD_OnChange} $hWndChkBoxLinkApp ToggleChkBoxState
${NSD_OnChange} $hWndRadBtnRebootNow ToggleRadBtnState
${NSD_OnChange} $hWndRadBtnRebootLater ToggleRadBtnState
Goto end
noreboot:
StrCpy $ctlLeft 120u
StrCpy $ctlWidht 61%
StrCpy [=10=] 110
StrCpy $ctlTop [=10=]u
StrCpy $R0 10
StrCpy $ctlHeight $R0u
StrCpy $ctlText "Run App"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxRunApp
SetCtlColors $hWndChkBoxRunApp "" "ffffff"
${NSD_SetState} $hWndChkBoxRunApp ${BST_UNCHECKED}
IntOp $R0 $R0 + 9
IntOp [=10=] + $R0
StrCpy $ctlTop u
StrCpy $R1 10
StrCpy $ctlHeight $R1u
StrCpy $ctlText "Create Desktop"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxLinkApp
SetCtlColors $hWndChkBoxLinkApp "" "ffffff"
${NSD_SetState} $hWndChkBoxLinkApp ${BST_CHECKED}
${NSD_OnChange} $hWndChkBoxRunApp ToggleChkBoxState
${NSD_OnChange} $hWndChkBoxLinkApp ToggleChkBoxState
end:
FunctionEnd
Function MyFinishLeave
;reboot the PC if radio button for "Reboot Now" option is checked (MUI_FINISHPAGE_NOREBOOTSUPPORT flag needed)
IfRebootFlag 0 noreboot
${NSD_GetState} $hWndChkBoxLinkApp [=10=]
${If} [=10=] == ${BST_CHECKED}
Call CreateDesktopShortcut
${EndIf}
${NSD_GetState} $hWndRadBtnRebootNow [=10=]
${If} [=10=] == ${BST_CHECKED}
;Reboot
MessageBox MB_OK "Reboot..."
${EndIf}
Goto end
noreboot:
${NSD_GetState} $hWndChkBoxRunApp [=10=]
${If} [=10=] == ${BST_CHECKED}
Call LaunchAppFile
${EndIf}
${NSD_GetState} $hWndChkBoxLinkApp [=10=]
${If} [=10=] == ${BST_CHECKED}
Call CreateDesktopShortcut
${EndIf}
end:
FunctionEnd
Function ToggleChkBoxState
;manage Reboot radio buttons state. If one is checked, the other one is not checked and the other way around
Pop ; = $hWndChkBoxRunApp/LinkApp
${NSD_GetState} [=10=]
${If} [=10=] == ${BST_CHECKED}
${NSD_SetState} ${BST_UNCHECKED}
${Else}
${NSD_SetState} ${BST_CHECKED}
${EndIf}
FunctionEnd
Function ToggleRadBtnState
;manage Reboot radio buttons state. If one is checked, the other one is not checked and the other way around
Pop ; = $hWndRadBtnRebootNow/Later
${NSD_GetState} [=10=]
${If} [=10=] == ${BST_CHECKED}
${If} == $hWndRadBtnRebootNow
${NSD_SetState} $hWndRadBtnRebootLater ${BST_UNCHECKED}
${Else}
${NSD_SetState} $hWndRadBtnRebootNow ${BST_UNCHECKED}
${EndIf}
${Else}
${If} == $hWndRadBtnRebootNow
${NSD_SetState} $hWndRadBtnRebootLater ${BST_CHECKED}
${Else}
${NSD_SetState} $hWndRadBtnRebootNow ${BST_CHECKED}
${EndIf}
${EndIf}
FunctionEnd
Function LaunchAppFile
;create a file batch at runtime for launching an excel instance pointing to the App file name
MessageBox MB_OK "App launched at runtime..."
FunctionEnd
Function CreateDesktopShortcut
;create App shortcut on DESKTOP folder with custom icon
MessageBox MB_OK "Desktop Shortcut created..."
FunctionEnd
显示完成页面时没有收到错误消息
编辑:使用 User32::SetWindowPos API 函数解决以修改自定义控件 Z 顺序
!define HWND_TOP 0
!define SWP_NOSIZE 0x0001
!define SWP_NOMOVE 0x0002
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($hWndCtmCtl, ${HWND_TOP}, 0, 0, 0, 0, ${SWP_NOSIZE}|${SWP_NOMOVE})"
$mui.FinishPage.Text
带有 ${MUI_FINISHPAGE_TEXT}
文本的 MUI 静态控件显示在您的某些控件之上。
用
隐藏它
Function MyFinishShow
ShowWindow $mui.FinishPage.Text 0
...
或者,如果您想保留文本并在其下查看控件,则将其设置为透明。如果要保留文本以免它们重叠,则必须将复选框向下移动一点。
Function MyFinishShow
SetCtlColors $mui.FinishPage.Text "${MUI_TEXTCOLOR}" transparent
...
我想在 Finish Page 中包含自定义控件,具体取决于是否设置了 IfRebootFlag,但我不知道为什么其中一些控件已创建但未显示。
$hWnd 是每个添加的控件的一个数字!= 0,所以这意味着所有控件都已创建。控件的位置好像没问题。。。肯定不在左边图片的后面,因为左坐标高到可以让控件超出图片
我试了好几个小时都不知道是哪个问题
;--------------------------------
;Header Files
!include nsDialogs.nsh
!include LogicLib.nsh
!include MUI2.nsh
Name App
OutFile ctmFinishPage.exe
XPStyle on
;--------------------------------
;General
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
;--------------------------------
;Variables
Var hWndChkBoxRunApp
Var hWndChkBoxLinkApp
Var hWndHlineReboot
Var hWndLblReboot
Var hWndRadBtnRebootNow
Var hWndRadBtnRebootLater
Var ctlLeft
Var ctlTop
Var ctlWidht
Var ctlHeight
Var ctlText
;--------------------------------
;Pages
;install pages
!insertmacro MUI_PAGE_INSTFILES
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyFinishShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE MyFinishLeave
!insertmacro MUI_PAGE_FINISH
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
Section
SetRebootFlag true
SectionEnd
;--------------------------------
;Functions
Function MyFinishShow
;add custom Reboot section to Finish page (MUI_FINISHPAGE_NOREBOOTSUPPORT flag is required)
IfRebootFlag 0 noreboot
StrCpy $ctlLeft 120u
StrCpy $ctlWidht 61%
StrCpy [=10=] 50
StrCpy $ctlTop [=10=]u
StrCpy $R0 10
StrCpy $ctlHeight $R0u
StrCpy $ctlText "Create Desktop shortcut"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxLinkApp
SetCtlColors $hWndChkBoxLinkApp "" "ffffff"
${NSD_SetState} $hWndChkBoxLinkApp ${BST_CHECKED}
StrCpy 117
StrCpy $ctlTop u
StrCpy $R1 1
StrCpy $ctlHeight $R1u
StrCpy $ctlText ""
${NSD_CreateHLine} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndHlineReboot
IntOp $R1 $R1 + 4
IntOp + $R1
StrCpy $ctlTop u
StrCpy $R2 25
StrCpy $ctlHeight $R2u
StrCpy $ctlText "Your computer must be restarted in order to complete the installation of App. Do you want to reboot now?"
${NSD_CreateLabel} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndLblReboot
SetCtlColors $hWndLblReboot "" "ffffff"
IntOp $R2 $R2 + 8
IntOp + $R2
StrCpy $ctlTop u
StrCpy $R3 10
StrCpy $ctlHeight $R3u
StrCpy $ctlText "Reboot now"
${NSD_CreateRadioButton} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndRadBtnRebootNow
SetCtlColors $hWndRadBtnRebootNow "" "ffffff"
${NSD_SetState} $hWndRadBtnRebootNow ${BST_CHECKED}
IntOp $R3 $R3 + 9
IntOp + $R3
StrCpy $ctlTop u
StrCpy $R4 10
StrCpy $ctlHeight $R4u
StrCpy $ctlText "I want to manually reboot later"
${NSD_CreateRadioButton} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndRadBtnRebootLater
SetCtlColors $hWndRadBtnRebootLater "" "ffffff"
${NSD_SetState} $hWndRadBtnRebootLater ${BST_UNCHECKED}
${NSD_OnChange} $hWndChkBoxLinkApp ToggleChkBoxState
${NSD_OnChange} $hWndRadBtnRebootNow ToggleRadBtnState
${NSD_OnChange} $hWndRadBtnRebootLater ToggleRadBtnState
Goto end
noreboot:
StrCpy $ctlLeft 120u
StrCpy $ctlWidht 61%
StrCpy [=10=] 110
StrCpy $ctlTop [=10=]u
StrCpy $R0 10
StrCpy $ctlHeight $R0u
StrCpy $ctlText "Run App"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxRunApp
SetCtlColors $hWndChkBoxRunApp "" "ffffff"
${NSD_SetState} $hWndChkBoxRunApp ${BST_UNCHECKED}
IntOp $R0 $R0 + 9
IntOp [=10=] + $R0
StrCpy $ctlTop u
StrCpy $R1 10
StrCpy $ctlHeight $R1u
StrCpy $ctlText "Create Desktop"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxLinkApp
SetCtlColors $hWndChkBoxLinkApp "" "ffffff"
${NSD_SetState} $hWndChkBoxLinkApp ${BST_CHECKED}
${NSD_OnChange} $hWndChkBoxRunApp ToggleChkBoxState
${NSD_OnChange} $hWndChkBoxLinkApp ToggleChkBoxState
end:
FunctionEnd
Function MyFinishLeave
;reboot the PC if radio button for "Reboot Now" option is checked (MUI_FINISHPAGE_NOREBOOTSUPPORT flag needed)
IfRebootFlag 0 noreboot
${NSD_GetState} $hWndChkBoxLinkApp [=10=]
${If} [=10=] == ${BST_CHECKED}
Call CreateDesktopShortcut
${EndIf}
${NSD_GetState} $hWndRadBtnRebootNow [=10=]
${If} [=10=] == ${BST_CHECKED}
;Reboot
MessageBox MB_OK "Reboot..."
${EndIf}
Goto end
noreboot:
${NSD_GetState} $hWndChkBoxRunApp [=10=]
${If} [=10=] == ${BST_CHECKED}
Call LaunchAppFile
${EndIf}
${NSD_GetState} $hWndChkBoxLinkApp [=10=]
${If} [=10=] == ${BST_CHECKED}
Call CreateDesktopShortcut
${EndIf}
end:
FunctionEnd
Function ToggleChkBoxState
;manage Reboot radio buttons state. If one is checked, the other one is not checked and the other way around
Pop ; = $hWndChkBoxRunApp/LinkApp
${NSD_GetState} [=10=]
${If} [=10=] == ${BST_CHECKED}
${NSD_SetState} ${BST_UNCHECKED}
${Else}
${NSD_SetState} ${BST_CHECKED}
${EndIf}
FunctionEnd
Function ToggleRadBtnState
;manage Reboot radio buttons state. If one is checked, the other one is not checked and the other way around
Pop ; = $hWndRadBtnRebootNow/Later
${NSD_GetState} [=10=]
${If} [=10=] == ${BST_CHECKED}
${If} == $hWndRadBtnRebootNow
${NSD_SetState} $hWndRadBtnRebootLater ${BST_UNCHECKED}
${Else}
${NSD_SetState} $hWndRadBtnRebootNow ${BST_UNCHECKED}
${EndIf}
${Else}
${If} == $hWndRadBtnRebootNow
${NSD_SetState} $hWndRadBtnRebootLater ${BST_CHECKED}
${Else}
${NSD_SetState} $hWndRadBtnRebootNow ${BST_CHECKED}
${EndIf}
${EndIf}
FunctionEnd
Function LaunchAppFile
;create a file batch at runtime for launching an excel instance pointing to the App file name
MessageBox MB_OK "App launched at runtime..."
FunctionEnd
Function CreateDesktopShortcut
;create App shortcut on DESKTOP folder with custom icon
MessageBox MB_OK "Desktop Shortcut created..."
FunctionEnd
显示完成页面时没有收到错误消息
编辑:使用 User32::SetWindowPos API 函数解决以修改自定义控件 Z 顺序
!define HWND_TOP 0
!define SWP_NOSIZE 0x0001
!define SWP_NOMOVE 0x0002
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($hWndCtmCtl, ${HWND_TOP}, 0, 0, 0, 0, ${SWP_NOSIZE}|${SWP_NOMOVE})"
$mui.FinishPage.Text
带有 ${MUI_FINISHPAGE_TEXT}
文本的 MUI 静态控件显示在您的某些控件之上。
用
隐藏它Function MyFinishShow
ShowWindow $mui.FinishPage.Text 0
...
或者,如果您想保留文本并在其下查看控件,则将其设置为透明。如果要保留文本以免它们重叠,则必须将复选框向下移动一点。
Function MyFinishShow
SetCtlColors $mui.FinishPage.Text "${MUI_TEXTCOLOR}" transparent
...