0
votes

I want to create a checkbox in NSIS at the end of the installation process, when checked, it will lead the user to a custom page that has a bunch of radioboxes that lead the user to another custom page (depending on the choice) and so on.

I know how to create a custom page using nsDialogs, but I can't figure out the logic behind multiple optional custom pages. Any help is appreciated.

Alternatively, is there a way to create multiple checkbox/radiobox groups that are disabled by default (except the first one) and only activated when the user selects a box in a group before it?

1
Where is the checkbox "at the end of the installation process"? - Anders
I meant a checkbox in a custom page - soundlarp
But your idea (to do it in a section) is cool so thanks for that. - soundlarp

1 Answers

0
votes

Pages are skipped by calling Abort in the page Pre-callback. Then all you have to do is keep track of which page you want to show and which you want to skip:

!include nsDialogs.nsh
!include LogicLib.nsh

Section "Do custom page thing" SID_DOCUSTOMPAGES
SectionEnd

Page Components
Page InstFiles
Page Custom Cust1Pre Cust2Next
Page Custom CustAPre
Page Custom CustBPre

Var WantedPage

Function Cust1Pre
${IfNot} ${SectionIsSelected} ${SID_DOCUSTOMPAGES}
    StrCpy $WantedPage ""
    Abort
${EndIf}
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 0 30u 100% 10u "Page A"
Pop $1
${NSD_Check} $1
${NSD_CreateRadioButton} 0 40u 100% 10u "Page B"
Pop $2
nsDialogs::Show
FunctionEnd

Function Cust2Next
${NSD_GetState} $1 $0
${If} $0 <> ${BST_UNCHECKED}
    StrCpy $WantedPage A
${Else}
    StrCpy $WantedPage B
${EndIf}
FunctionEnd

Function CustAPre
${IfNotThen} $WantedPage == A ${|} Abort ${|}
GetDlgItem $0 $hWndParent 1
SendMessage $0 ${WM_SETTEXT} "" "STR:$(^CloseBtn)" ; Change button text since page B is skipped and we are now the last page
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page A"
Pop $0
nsDialogs::Show
FunctionEnd

Function CustBPre
${IfNotThen} $WantedPage == B ${|} Abort ${|}
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page B"
Pop $0
nsDialogs::Show
FunctionEnd

You can get rid of the WM_SETTEXT workaround by having a single page that is "A" or "B":

!include nsDialogs.nsh
!include LogicLib.nsh

Section "Do custom page thing" SID_DOCUSTOMPAGES
SectionEnd

Page Components
Page InstFiles
Page Custom Cust1Pre Cust2Next
Page Custom CustAOrBPre

Var WantedPage

Function Cust1Pre
${IfNot} ${SectionIsSelected} ${SID_DOCUSTOMPAGES}
    StrCpy $WantedPage ""
    Abort
${EndIf}
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 0 30u 100% 10u "Page A"
Pop $1
${NSD_Check} $1
${NSD_CreateRadioButton} 0 40u 100% 10u "Page B"
Pop $2
nsDialogs::Show
FunctionEnd

Function Cust2Next
${NSD_GetState} $1 $0
${If} $0 <> ${BST_UNCHECKED}
    StrCpy $WantedPage A
${Else}
    StrCpy $WantedPage B
${EndIf}
FunctionEnd

Function CustAPre
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page A"
Pop $0
nsDialogs::Show
FunctionEnd

Function CustBPre
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 30u 100% 10u "Page B"
Pop $0
nsDialogs::Show
FunctionEnd

Function CustAOrBPre
${If} $WantedPage == A
    Call CustAPre
${Else}
    Call CustBPre
${EndIf}
FunctionEnd

Having just a single page with disabled options is of course better:

!include nsDialogs.nsh
!include LogicLib.nsh

Page InstFiles
Page Custom CustPre

Function CustPre
nsDialogs::Create 1018
Pop $0

${NSD_CreateCheckBox} 10 30u 100% 10u "Enable other stuff"
Pop $0
${NSD_OnClick} $0 OnCheckChange

${NSD_CreateRadioButton} 10 50u 100% 10u "Foo"
Pop $1
${NSD_AddStyle} $1 ${WS_GROUP}
${NSD_Check} $1
${NSD_CreateRadioButton} 10 70u 100% 10u "Bar"
Pop $2
${NSD_RemoveStyle} $2 ${WS_TABSTOP}

Push $0
Call OnCheckChange ; Enforce state
nsDialogs::Show
FunctionEnd

!macro SetRadiosEnabled state
EnableWindow $1 ${state}
EnableWindow $2 ${state}
!macroend
Function OnCheckChange
Pop $0
${NSD_GetState} $0 $0
${If} $0 <> ${BST_UNCHECKED}
    !insertmacro SetRadiosEnabled 1
${Else}
    !insertmacro SetRadiosEnabled 0
${EndIf}
FunctionEnd