Search code examples
installationnsis

Is it possible to add a confirmation popup to a license page before moving to the next page with NSIS?


The behavior I am hoping to achieve is as follows:

  • EULA is displayed (!insertmacro MUI_PAGE_LICENSE "${license}")
  • Once the user scrolls to the bottom of the EULA the continue button will enable
  • Upon pressing the continue button a popup will appear with three options and a checkbox:

Buttons:

  1. Read EULA - this will close the pop up to allow the user to continue reading
  2. Disagree - this aborts the installer
  3. Agree - this moves on to the next page

Checkbox - Enables/disables the agree button

The issues I am having is that my popup is showing after moving on from the license page when I want it to be a part of the license page and not move on until the accept button is pressed.

I currently have the popup logic almost working using DlgHost, I have added comments to the areas where I am having issues:

!include MUI2.nsh
!include 'LogicLib.nsh'
!include nsDialogs.nsh
!include DlgHost.nsh


Function CloseApp
Pop $0
DlgHost::Close
Quit
FunctionEnd

Function Accept
Pop $0
;todo move to next page(First issue)
FunctionEnd

Function ReturnToEULA
Pop $0
DlgHost::Close
FunctionEnd

var AGREE_BUTTON
var CHECKBOX

Function EnDisableButton
    Pop $CHECKBOX
    ${NSD_GetState} $CHECKBOX $0
    ${If} $0 == 1
        EnableWindow $AGREE_BUTTON 1
    ${Else}
        EnableWindow $AGREE_BUTTON 0
    ${EndIf}
FunctionEnd

Function MyDlgBoxCallback
${Select} $0
${Case} ${DLGHOST_DLGBOXMSG_INITDLG}
    nsDialogs::Create 1018
    Pop $1
    DlgHost::SetClient $1
    #x pos, y pos, width, height 
    ${NSD_CreateLabel} 5% 5% 87% 35u "Label 1 text."
    Pop $1
    
    ${NSD_CreateLabel} 5% 25% 87% 30u "Label 2 text."
        CreateFont $0 "$(^Font)" "8" "700"; size 8 weight 700 makes it bold 
        SendMessage $1 ${WM_SETFONT} $0 0
        Pop $1
    
    ${NSD_CreateCheckbox} 5% 55% 87% 30u "&Check box label."
        Pop $CHECKBOX
        CreateFont $0 "$(^Font)" "8" "700"; size 8 weight 700 makes it bold 
        SendMessage $CHECKBOX ${WM_SETFONT} $0 0
        ${NSD_OnClick} $CHECKBOX EnDisableButton

    
    ${NSD_CreateButton} 230u 84% 50u 15u "&Disagree"
        Pop $1
        ${NSD_OnClick} $1 CloseApp

    ${NSD_CreateButton} 290u 84% 50u 15u "&Agree"    
        Pop $AGREE_BUTTON
        EnableWindow $AGREE_BUTTON 0
        ${NSD_OnClick} $AGREE_BUTTON Accept
    
    ${NSD_CreateButton} 5% 84% 70u 15u "&Read EULA"
        Pop $1
        ${NSD_OnClick} $1 ReturnToEULA

${Case} ${DLGHOST_DLGBOXMSG_SHOWDLG}
    nsDialogs::Show
${EndSelect}
FunctionEnd

Function ShowConfirmationPopup
GetFunctionAddress $0 MyDlgBoxCallback
DlgHost::DlgBox "* $0 p 550 250 Confirm Terms and Conditions"
FunctionEnd

!define MUI_LICENSEPAGE_BUTTON "Continue"
!insertmacro MUI_PAGE_LICENSE "${license}"

Page instfiles ;Here is the second issue
Section "ShowPopup"
Call ShowConfirmationPopup
SectionEnd

!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES

I think I need to perhaps replace the call back for the license page continue button with my popup code as a macro but I am unsure where that is handled. I am using Modern UI 2 and it appears to be in License.nsh but I am new to NSIS and unable to follow the logic.


Solution

  • NSIS already provides a radio or checkbox mode that should be close enough to what you are after:

    !include "MUI2.nsh"
    !define MUI_LICENSEPAGE_RADIOBUTTONS
    !insertmacro MUI_PAGE_LICENSE "${__FILE__}"
    !insertmacro MUI_PAGE_INSTFILES
    !insertmacro MUI_LANGUAGE English
    

    You need to use the license page leave callback if you want to stay on that page depending on some condition:

    Unicode False
    !include DlgHost.nsh
    !include MUI2.nsh
    !define MUI_PAGE_CUSTOMFUNCTION_LEAVE LeaveLicensePage
    !insertmacro MUI_PAGE_LICENSE "${__FILE__}"
    !insertmacro MUI_PAGE_INSTFILES
    !insertmacro MUI_LANGUAGE English
    
    Function CloseApp
    Pop $0
    DlgHost::Close
    Quit
    FunctionEnd
    
    Function Accept
    Pop $0
    DlgHost::Close
    FunctionEnd
    
    Function ReturnToEULA
    Pop $0
    DlgHost::Close
    StrCpy $9 1 ; We can't Abort here, check this flag later
    FunctionEnd
    
    var AGREE_BUTTON
    var CHECKBOX
    
    Function EnDisableButton
        Pop $CHECKBOX
        ${NSD_GetState} $CHECKBOX $0
        ${If} $0 == 1
            EnableWindow $AGREE_BUTTON 1
        ${Else}
            EnableWindow $AGREE_BUTTON 0
        ${EndIf}
    FunctionEnd
    
    Function MyDlgBoxCallback
    ${Select} $0
    ${Case} ${DLGHOST_DLGBOXMSG_INITDLG}
        nsDialogs::Create 1018
        Pop $1
        DlgHost::SetClient $1
        #x pos, y pos, width, height 
        ${NSD_CreateLabel} 5% 5% 87% 35u "Label 1 text."
        Pop $1
        
        ${NSD_CreateLabel} 5% 25% 87% 30u "Label 2 text."
            CreateFont $0 "$(^Font)" "8" "700"; size 8 weight 700 makes it bold 
            SendMessage $1 ${WM_SETFONT} $0 0
            Pop $1
        
        ${NSD_CreateCheckbox} 5% 55% 87% 30u "&Check box label."
            Pop $CHECKBOX
            CreateFont $0 "$(^Font)" "8" "700"; size 8 weight 700 makes it bold 
            SendMessage $CHECKBOX ${WM_SETFONT} $0 0
            ${NSD_OnClick} $CHECKBOX EnDisableButton
    
        
        ${NSD_CreateButton} 230u 84% 50u 15u "&Disagree"
            Pop $1
            ${NSD_OnClick} $1 CloseApp
    
        ${NSD_CreateButton} 290u 84% 50u 15u "&Agree"    
            Pop $AGREE_BUTTON
            EnableWindow $AGREE_BUTTON 0
            ${NSD_OnClick} $AGREE_BUTTON Accept
        
        ${NSD_CreateButton} 5% 84% 70u 15u "&Read EULA"
            Pop $1
            ${NSD_OnClick} $1 ReturnToEULA
    
        StrCpy $9 ""
    
    ${Case} ${DLGHOST_DLGBOXMSG_SHOWDLG}
        nsDialogs::Show
    ${EndSelect}
    FunctionEnd
    
    Function LeaveLicensePage
    GetFunctionAddress $0 MyDlgBoxCallback
    DlgHost::DlgBox "* $0 p 550 250 Confirm Terms and Conditions"
    ${If} $9 = 1
      Abort ; Stay on license page
    ${EndIf}
    FunctionEnd
    

    To really annoy your users, use the ScrollLicense plug-in to force them to scroll.