使用 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
...