Component Page Description-Box Scrollbar - nsis

I´m searching for a Solution to implement a Scrollbar to the Descriptionbox on the MUI2 Component page. Because i got a large text to fill in.
To make the UI bigger is the last option what i want to use.
I tried to implement the UMUI, with the option MUIEx to use the big description option, but with no effect.

There is no native support for this but putting a edit box there and hacking the change notification a bit seems to work OK:
OutFile Test.exe
RequestExecutionLevel user
!define MUI_CUSTOMFUNCTION_ONMOUSEOVERSECTION myOnMouseOver
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_PRE myCompPagePre
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Var LastText
Var ScrollWindow
!include LogicLib.nsh
!define /IfNDef SB_VERT 1
Function myCompPagePre
StrCpy $ScrollWindow ""
FunctionEnd
Function myOnMouseOver
${If} $ScrollWindow P= 0
System::Call 'USER32::GetWindowRect(p$mui.ComponentsPage.DescriptionText,#r0)' ; NSIS v3+
System::Call 'USER32::GetParent(p$mui.ComponentsPage.DescriptionText)p.s'
System::Call '*$0(i.r1,i.r2,i.r3,i.r4)'
IntOp $3 $3 - $1
IntOp $4 $4 - $2
System::Call 'USER32::MapWindowPoints(p0, pss, pr0, i1)'
System::Call '*$0(i.r1,i.r2)'
System::Call 'USER32::CreateWindowEx(i0, t"EDIT", p0, i ${WS_VISIBLE}|${WS_CHILD}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_READONLY}, i r1, i r2, i r3, i r4, ps, p0, p0, p0)p.s'
Pop $ScrollWindow
ShowWindow $mui.ComponentsPage.DescriptionText 0
SendMessage $mui.ComponentsPage.DescriptionText ${WM_GETFONT} 0 0 $0
SendMessage $ScrollWindow ${WM_SETFONT} $0 1
${EndIf}
${NSD_GetText} $mui.ComponentsPage.DescriptionText $0
System::Call 'USER32::IsWindowEnabled(p$mui.ComponentsPage.DescriptionText)i.r1'
${If} $1 <> 0 ; No hover text?
StrCpy $LastText $0
${EndIf}
${NSD_SetText} $ScrollWindow $LastText
System::Call 'USER32::ShowScrollBar(p $ScrollWindow, i ${SB_VERT}, i 1)'
System::Call 'USER32::GetScrollRange(p $ScrollWindow, i ${SB_VERT}, *i.r0, *i.r1)'
${If} $0 = $1
System::Call 'USER32::ShowScrollBar(p $ScrollWindow, i ${SB_VERT}, i 0)'
${EndIf}
FunctionEnd
Section SecA SID_A
SectionEnd
Section SecB SID_B
SectionEnd
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SID_A} "aaa a a aa a "
!define longstr "Very looooooo o o o o o oo o o o o o ooo o o ng stri i i i i i in ng"
!insertmacro MUI_DESCRIPTION_TEXT ${SID_B} "bbb b b b b b b b b b b b ${longstr} ${longstr} ${longstr} ${longstr} ${longstr} END"
!insertmacro MUI_FUNCTION_DESCRIPTION_END

Related

Select section by variable

!include "MUI2.nsh"
!include "FileFunc.nsh"
!include "LogicLib.nsh"
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
ShowInstDetails show
RequestExecutionLevel admin
;---------------------------------------------------------------------------
Name "Test"
Outfile "Test.exe"
;---------------------------------------------------------------------------
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
;---------------------------------------------------------------------------
!insertmacro MUI_LANGUAGE "English"
;---------------------------------------------------------------------------
LangString DESC_sec1 ${LANG_ENGLISH} "sec1 files"
Section /o "sec1" sec1
SectionEnd
LangString DESC_sec2 ${LANG_ENGLISH} "sec2 files"
Section /o "sec2" sec2
SectionEnd
LangString DESC_sec3 ${LANG_ENGLISH} "sec3 files"
Section /o "sec3" sec3
SectionEnd
Var test
Function .OnInit
StrCpy $test "sec2"
!insertmacro SelectSection $test
FunctionEnd
How to select section at runtime by section name?
In eample always selected 1st section (think its a bug)
But if i rewrite like this
!insertmacro SelectSection ${sec2}
All works fine...
Is there way to select section by name from variable?
some long text some long text some long text some long text
some long text some long text some long text some long text
Sections are accessed by their ID which is a number set at compile time:
Section "Foo"
SectionEnd
Section "Bar" SID_BAR
SectionEnd
Section "Baz"
SectionEnd
Page Components
Page InstFiles
!include Sections.nsh
Function .onInit
!insertmacro UnselectSection ${SID_BAR}
FunctionEnd
If you want to use the display name then you have to manually enumerate the sections:
Section "Foo"
SectionEnd
Section "Bar"
SectionEnd
Section "Baz"
SectionEnd
Page Components
Page InstFiles
!macro GetSectionIdFromName name outvar
Push "${name}"
Call GetSectionIdFromName
Pop ${outvar} ; ID of section, "" if not found
!macroend
Function GetSectionIdFromName
Exch $1 ; Name
Push $2
Push $3
StrCpy $2 -1
ClearErrors
loop:
IntOp $2 $2 + 1
SectionGetText $2 $3
IfErrors fail
StrCmp $3 $1 "" loop
StrCpy $1 $2
Goto done
fail:
StrCpy $1 ""
done:
Pop $3
Pop $2
Exch $1
FunctionEnd
!include Sections.nsh
!include LogicLib.nsh
Function .onInit
StrCpy $1 "Bar" ; The name we are looking for
!insertmacro GetSectionIdFromName $1 $0
${If} $0 != ""
!insertmacro UnselectSection $0
${EndIf}
FunctionEnd

How to move NSD_OnBack function from the section in NSIS

I'm writing an NSIS script, in this using some sections to execute EXE files. on depending output, I need to go back from the section to other custom pages but here nsis is moving to another section even though keeping of NSD_OnBack function or just calling the particular function
I have tried below 2 methods.
${NSD_OnBack} "callbackfunction"
call callbackfunction
//Section started
Section "validation" VALIDATION
DetailPrint "Executing Validation"
File "Folder_name\Validation.exe"
nsExec::Exec '"$INSTDIR\Validation.exe" $arg1 $arg2 $arg3'
IfFileExists "$INSTDIR\Output.txt" pass fail
pass:
FileOpen $chk "$INSTDIR\Output.txt" r
FileRead $chk $1
MessageBox MB_OK|MB_ICONSTOP "Validation_Output : in 1 $1"
Push $1
Push "true"
Call StrContains
Pop $3
${If} $3 == "true"
call someotherfunction
${ELSE}
goto fail
${ENDIF}
FileClose $chk
Delete $chk
fail:
MessageBox MB_OK|MB_ICONSTOP "fail"
//Here this call is not working
${NSD_OnBack} "callbackfunction"
SectionEnd
Function callbackfunction
GetDlgItem $0 $HWNDPARENT 2
${IF} $portalname == "centralised"
${IF} $username == ""
call CentralisedPage
${ENDIF}
${ELSE}
${IF} $username == ""
call SetCustom
${ENDIF}
${ENDIF}
Functionend
I am expecting to move other page based on EXE results.
${NSD_OnBack} is a callback for nsDialogs custom pages and it is invoked when the user presses the back button on that page, it is not relevant here.
Ideally you should collect all information before you get to the InstFiles page but if you can't do that then I would recommend that you just show a custom page after the InstFiles page if required.
If you absolutely need to execute sections multiple times you can use more than one InstFiles page:
!include LogicLib.nsh
!include WinMessages.nsh
!include nsDialogs.nsh
!include Sections.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_PRE Init1stStage
!insertmacro MUI_PAGE_INSTFILES
Page Custom MyCustomPageCreate
!define MUI_PAGE_CUSTOMFUNCTION_PRE Init2ndStage
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Var Needs2ndStage
Section "1st stage" SID_1
DetailPrint "1st stage"
MessageBox mb_yesno "Needs 2nd stage?" IDNO nope
StrCpy $Needs2ndStage 1
nope:
SectionEnd
Section "-2nd stage" SID_2
DetailPrint "2nd stage"
SectionEnd
Function Init1stStage
!insertmacro UnselectSection ${SID_2}
FunctionEnd
Function Init2ndStage
!insertmacro UnselectSection ${SID_1}
${IfThen} $Needs2ndStage = 0 ${|} Abort ${|}
FunctionEnd
Function MyCustomPageCreate
${IfThen} $Needs2ndStage = 0 ${|} Abort ${|}
!insertmacro SelectSection ${SID_2}
GetDlgItem $0 $hWndParent 1
SendMessage $0 ${WM_SETTEXT} "" "STR:C&ontinue"
GetDlgItem $0 $hWndParent 3
ShowWindow $0 0 ; Hide back
GetDlgItem $0 $hWndParent 2
EnableWindow $0 0 ; Disable cancel
!insertmacro MUI_HEADER_TEXT "Blah" "Blah blah blah"
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "Enter blah blah before you can enter the 2nd stage"
Pop $0
nsDialogs::Show
FunctionEnd

When I am clicking on "Finish" button or close button at the top right corner of the custom page, page is not closing using NSIS

I am facing a weird problem, I have added a new custom page (MyAbruptPage). When clicking on "Finish" button or close button at the top right corner of this custom page, page is not closing.
Scenario:
When Installing the software, if something went wrong and installation hasn't done properly it shows a MessageBox from INSTFILES page. Upon click on "OK" on the message box It is navigating to the "Abrupt" page. In the Abrupt Page it is showing "Finish" button, but when clicked on "Finish" the page is not closing instead it is showing a pop-up message (Are you sure you want to close?). Even when i clicked on close button in the top right corner also i am getting the same pop-up message. I don't want that message and the dialog should be closed when clicked on "Finish" button.
Observations:
I am thinking that the problem is due to the sequence of the pages. Because here i have used two custom pages (MyInfoPage, And MyAbruptPage).
If I replace the first page (MyInfoPage) with MyAbruptPage. Then I am not seeing any issue when clicking on "Finish" button in the Abrupt Page.
Below is my code snippet showing pages and its sequence:
Page Custom MyInfoPage ; First Custom page
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!insertmacro MUI_PAGE_LICENSE
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage ; Second Custom Page
!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; Below is my code for the Abrupt page
Function AbruptShow
StrCpy $IsOnAbruptPage 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function AbruptLeave
StrCpy $IsOnAbruptPage 0
FunctionEnd
Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0 ; Hide Next button
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ; Hide Back button
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "$(AbruptTitle)"
Pop $AbruptPageTitle
;SetCtlColors $InterruptPageTitle "" "${MUI_BGCOLOR}"
CreateFont $AbruptPageFont "$(^Font)" "12" "700"
SendMessage $AbruptPageTitle ${WM_SETFONT} $AbruptPageFont 0
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "$(AbruptText)"
Pop $AbruptPageText
Pop $0
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
Below is the section and from here Message box is popping up and navigating to the Abrupt screen:
;!insertmacro MUI_LANGUAGE "English"
Section MySection
SetOutPath $INSTDIR
MessageBox MB_OK|MB_ICONEXCLAMATION "Installation hasn't done properly" IDOK
Call AbruptLeave
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
SectionEnd
;Below is the code for the custompage "MyInfoPage"
Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0 ; Hide Next button
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "$(InterruptTitle)"
Pop $InterruptPageTitle
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "$(InterruptText)"
Pop $InterruptPageText
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
Function WelShow
StrCpy $PageId 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ; Hide Back button
FunctionEnd
Function onAbort
${If} $PageId <> 0
${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to close?" IDYES `
SendMessage $HWNDPARENT 0x408 -$PageId ""
${EndIf}
Abort
${EndIf}
FunctionEnd
I have tried by changing the sequence of the pages and every time I am observing different behaviors in both the custom pages. Please help me how to resolve this issue? And the correct way to implement this functionality.
Thank you in advance...
Below is the complete code and it is compiling:
Var PageId
Var PrintBtn
Var Image
Var ImageHandle
Var MyInfoPageTitle
Var MyInfoPageFont
var MyInfoPageText
var IsOnAbruptPage
Var AbruptPageTitle
Var AbruptPageFont
var AbruptPageText
!define MUI_CUSTOMFUNCTION_ABORT onAbort
!include "MUI2.nsh"
!include x64.nsh
Name "MyApp"
OutFile "MyApp.exe"
InstallDir "$PROGRAMFILES32\MyApp"
InstallDirRegKey HKLM "Software\MyApp" "Install_Dir"
RequestExecutionLevel admin
!include LogicLib.nsh
;--------------------------------
Page Custom MyInfoPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!define MUI_TEXT_WELCOME_INFO_TITLE $(welcometitle)
!define MUI_TEXT_WELCOME_INFO_TEXT $(welcometext)
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!define MUI_LICENSEPAGE_CHECKBOX ""
!define MUI_INNERTEXT_LICENSE_BOTTOM ""
!define MUI_INNERTEXT_LICENSE_TOP ""
!define MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX ""
!define MUI_TEXT_LICENSE_TITLE $(licensetitle)
!define MUI_TEXT_LICENSE_SUBTITLE $(licensesubtitle)
!define MUI_LICENSEPAGE_CHECKBOX_TEXT $(licensecheckboxtext)
!insertmacro MUI_PAGE_LICENSE "C:\Program Files (x86)\NSIS\Docs\Modern UI 2\license.txt"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!define MUI_DIRECTORYPAGE_TEXT_TOP $(mydirtoptext)
!define MUI_TEXT_DIRECTORY_TITLE $(mydirtitle)
!define MUI_TEXT_DIRECTORY_SUBTITLE $(mydirsubtitle)
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
!insertmacro MUI_PAGE_INSTFILES
!define MUI_TEXT_FINISH_INFO_TITLE $(Finishpagetitle)
!define MUI_TEXT_FINISH_INFO_TEXT $(Finishpagesubtitle)
!define MUI_FINISHPAGE_RUN ""
!define MUI_FINISHPAGE_RUN_TEXT $(FinishonlineReg)
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_INSTFILES
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
Function .onInit
InitPluginsDir
FunctionEnd
Function MyDirectoryShowCallback
StrCpy $PageId 3
GetDlgItem $0 $hwndparent 1 ;
SendMessage $0 ${WM_SETTEXT} 0 `STR:$(^NextBtn)`
FunctionEnd
Function MyLicenseShowCallback
StrCpy $PageId 2
GetDlgItem $0 $hwndparent 2
System::Call *(i,i,i,i)p.r1
System::Call 'USER32::GetWindowRect(pr0,pr1)'
System::Call *$1(i.r2,i.r3,i.r4,i.r5)
IntOp $5 $5 - $3 ;height
IntOp $4 $4 - $2 ;width
System::Call 'USER32::ScreenToClient(p$hwndparent,pr1)'
System::Call *$1(i.r2,i.r3)
System::Free $1
IntOp $2 $4 / 5
System::Call 'USER32::CreateWindowEx(i 0,t "Button",t "Print",i ${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},i r2,i r3,i r4,i r5,p $hwndparent,p 0x666,p 0,p 0)p.r0'
StrCpy $PrintBtn $0
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
ButtonEvent::AddEventHandler 0x666 $0
FunctionEnd
Function WelShow
StrCpy $PageId 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
!define MUI_WELCOMEPAGE_TITLE_HEIGHT 38
!define /math MUI_WELCOMEPAGE_TEXT_TOP 17 + ${MUI_WELCOMEPAGE_TITLE_HEIGHT}
${NSD_CreateLabel} 120u 10u 195u 28u "Setup Wizard was interrupted"
Pop $MyInfoPageTitle
CreateFont $MyInfoPageFont "$(^Font)" "12" "700"
SendMessage $MyInfoPageTitle ${WM_SETFONT} $MyInfoPageFont 0
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "Setup Wizard was interrupted"
Pop $MyInfoPageText
Pop $0
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
Function onAbort
${If} $PageId <> 0
${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to CANCEL" IDYES `
SendMessage $HWNDPARENT 0x408 -$PageId ""
${EndIf}
Abort
${EndIf}
FunctionEnd
Function AbruptShow
StrCpy $IsOnAbruptPage 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function AbruptLeave
StrCpy $IsOnAbruptPage 0
FunctionEnd
Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "Setup Wizard ended prematurely"
Pop $AbruptPageTitle
CreateFont $AbruptPageFont "$(^Font)" "12" "700"
SendMessage $AbruptPageTitle ${WM_SETFONT} $AbruptPageFont 0
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "Setup Wizard ended prematurely"
Pop $AbruptPageText
Pop $0
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
SectionIn RO
SetOutPath $INSTDIR
MessageBox MB_OK|MB_ICONEXCLAMATION "There is an installation failure. Aborting the installation process" IDOK
Call AbruptLeave
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
SectionEnd
Section "Uninstall"
SectionEnd
The MessageBox you see is coming from your own code in your onAbort function!
The fact that you are doing
!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
shows that you have don't understand how custom pages work.
To make your special abort page quit without further action you simple have to do nothing in your onAbort function when you are on that page:
Var PageId
var IsOnAbruptPage
!define MUI_CUSTOMFUNCTION_ABORT onAbort
!include "MUI2.nsh"
!include LogicLib.nsh
Name "MyApp"
#OutFile "MyApp.exe"
InstallDir "$temp\MyApp"
#RequestExecutionLevel admin
OutFile Test.exe
RequestExecutionLevel user
;--------------------------------
Page Custom MyInfoPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
Function MyDirectoryShowCallback
StrCpy $PageId 3
GetDlgItem $0 $hwndparent 1 ;
SendMessage $0 ${WM_SETTEXT} 0 `STR:$(^NextBtn)`
FunctionEnd
Function MyLicenseShowCallback
StrCpy $PageId 2
FunctionEnd
Function WelShow
StrCpy $PageId 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u 28u "Setup Wizard was interrupted"
Pop $0
nsDialogs::Show
FunctionEnd
Function onAbort
${If} $IsOnAbruptPage <> 0 ; If on aborted page
Return ; allow simple exit
${EndIf}
${If} $PageId <> 0
${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to CANCEL" IDYES `
SendMessage $HWNDPARENT 0x408 -$PageId ""
${EndIf}
Abort
${EndIf}
FunctionEnd
Function GoToAbruptPage
StrCpy $IsOnAbruptPage 1
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
FunctionEnd
Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u 20u "Setup Wizard ended prematurely"
Pop $0
${NSD_CreateLabel} 120u 120u 195u 20u "Setup Wizard ended prematurely"
Pop $0
nsDialogs::Show
FunctionEnd
;--------------------------------
Section "$(^Name) (required)"
SectionIn RO
SetOutPath $INSTDIR
MessageBox MB_OK|MB_ICONEXCLAMATION "There is an installation failure. Aborting the installation process" IDOK
Call GoToAbruptPage
SectionEnd

How to set the checkbox by default checked in the windows installer Finish page using NSIS

I wanted to set the checkbox as checked by default in the windows installer Finish page using NSIS. For that I used the below code snipped. But it is not even displaying the checkbox in the Finish page. Please help me on this.
Var Checkbox
Var CheckState ; Stored globally so we remember the choice if the user presses the back button and goes back to our page
!define CheckHeight 28
!macro CreateNativeControl hParent cls style exstyle x y w h text ; Note: Only supports pixel coordinates
System::Call 'USER32::CreateWindowEx(i ${exstyle}, t "${cls}", ts, i ${style}, i ${x}, i ${y}, i ${w}, i ${h}, p ${hParent}, i0, i0, i0)p.s' "${text}"
!macroend
!define MUI_PAGE_CUSTOMFUNCTION_SHOW FinishShow
!insertmacro MUI_PAGE_FINISH
Function FinishShow
System::Call *(i,i,i,i)p.r0 ; NSIS 2.51+
System::Call 'USER32::GetWindowRect(p$mui.FinishPage.Text, pr0)'
System::Call 'USER32::MapWindowPoints(i0,p$mui.FinishPage,p$0,i2)'
System::Call '*$0(i.r2,i.r3,i.r4,i.r5)'
System::Free $0
IntOp $5 $5 - ${CheckHeight}
System::Call 'USER32::SetWindowPos(i$mui.FinishPage.Text,i,i,i,i$4,i$5,i0x6)'
; Create and initialize the checkbox
IntOp $5 $3 + $5 ; y = TextTop + TextHeight
!insertmacro CreateNativeControl $mui.FinishPage ${__NSD_CheckBox_CLASS} "${__NSD_CheckBox_STYLE}" "${__NSD_CheckBox_EXSTYLE}" 0 $5 300 ${CheckHeight} "CheckboxTest"
Pop $Checkbox
SendMessage $mui.FinishPage ${WM_GETFONT} 0 0 $0
SendMessage $Checkbox ${WM_SETFONT} $0 1
System::Call 'USER32::SetWindowPos(i$Checkbox,i0,i,i,i,i,i0x33)'
${IfThen} $CheckState == "" ${|} StrCpy $CheckState 1 ${|}
${NSD_SetState} $Checkbox $CheckState
FunctionEnd
The finish page has built-in support for two optional check-boxes:
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN ""
!define MUI_FINISHPAGE_RUN_TEXT "Run Foo"
!define MUI_FINISHPAGE_RUN_FUNCTION MyRunFoo
;define MUI_FINISHPAGE_RUN_NOTCHECKED
!define MUI_FINISHPAGE_SHOWREADME "$InstDir\Bar.exe"
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Run Bar"
;define MUI_FINISHPAGE_SHOWREADME_FUNCTION
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function MyRunFoo
; Exec '"$InstDir\Foo.exe"'
FunctionEnd
Section
SectionEnd
Your example code is also missing a important call to !insertmacro MUI_LANGUAGE.
The function specified by MUI_FINISHPAGE_RUN_FUNCTION is only executed if the checkbox is checked. This is normal expected behavior.
If you want to do custom handling you can do it in the leave page:
!include nsDialogs.nsh
!include LogicLib.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN ""
!define MUI_FINISHPAGE_RUN_TEXT "Blah blah"
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE FinishLeave
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function FinishLeave
${NSD_GetState} $mui.FinishPage.Run $0 ; or $mui.FinishPage.ShowReadme
${If} $0 <> 0
MessageBox mb_ok "Checkbox checked"
${Else}
MessageBox mb_ok "Checkbox not checked"
${EndIf}
FunctionEnd

NSIS script + Skip button alignment issue

I am trying NSIS script to add "SKIP" button.
I have tested below code and it works well but when I actually integrate with the main code which is having a screen of option "back" "Next" and "Cancel" button. this skip button is not visible at all, it is in extreme right of cancel button and hardly visible.
How can move this "Skip" button towards left side.
Name BtnTest
Outfile test.exe
Installdir "$temp"
RequestExecutionLevel user
BrandingText " " ;Button covers this text
!include nsDialogs.nsh ;For WS_*
!define MUI_CUSTOMFUNCTION_GUIINIT SKIP
Function SKIP
; You are supposed to use ChangeUI (or MUI_UI) and a modified ui file to add new buttons but this example adds the button at run-time...
GetDlgItem $0 $hwndparent 2 ; Find cancel button
System::Call *(i,i,i,i)i.r1
System::Call 'USER32::GetWindowRect(ir0,ir1)'
System::Call *$1(i.r2,i.r3,i.r4,i.r5)
IntOp $5 $5 - $3 ;height
IntOp $4 $4 - $2 ;width
System::Call 'USER32::ScreenToClient(i$hwndparent,ir1)'
System::Call *$1(i.r2,i.r3)
System::Free $1
IntOp $2 $2 + $4 ;x
IntOp $2 $2 + 8 ;x+padding
System::Call 'USER32::CreateWindowEx(i0,t "Button",t "Click Me",i${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},ir2,ir3,ir4,ir5,i $hwndparent,i 0x666,i0,i0)i.r0'
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
GetFunctionAddress $0 onmybtnclick
ButtonEvent::AddEventHandler 0x666 $0
FunctionEnd
Function onmybtnclick
MessageBox mb_ok "You clicked me!"
FunctionEnd
Page Directory
Page Instfiles
Section
SectionEnd
And also this button appears on all screen How can I display only in one screen.
Change $2 and $3 before the call to CreateWindowEx to change the button position. You can save the handle to the button in another variable after CreateWindowEx but I just used the Id in this example (0x666).
Name BtnTest
Outfile test.exe
Installdir "$temp"
RequestExecutionLevel user
BrandingText " " ;Button covers this text
!include nsDialogs.nsh ;For WS_*
!define MUI_CUSTOMFUNCTION_GUIINIT SKIP
/**/ !include MUI2.nsh #*/
!ifndef MUI_INCLUDED
Function .onGuiInit
Call SKIP
FunctionEnd
!endif
Function SKIP
; You are supposed to use ChangeUI (or MUI_UI) and a modified ui file to add new buttons but this example adds the button at run-time...
GetDlgItem $0 $hwndparent 2 ; Find cancel button
System::Call *(i,i,i,i)i.r1
System::Call 'USER32::GetWindowRect(ir0,ir1)'
System::Call *$1(i.r2,i.r3,i.r4,i.r5)
IntOp $5 $5 - $3 ;height
IntOp $4 $4 - $2 ;width
System::Call 'USER32::ScreenToClient(i$hwndparent,ir1)'
System::Call *$1(i.r2,i.r3)
System::Free $1
!ifdef MUI_INCLUDED
StrCpy $2 15 ; Whatever you feel looks good
!else
IntOp $2 $2 + $4 ;x
IntOp $2 $2 + 8 ;x+padding
!endif
System::Call 'USER32::CreateWindowEx(i0,t "Button",t "Click Me",i${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},ir2,ir3,ir4,ir5,i $hwndparent,i 0x666,i0,i0)i.r0'
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
GetFunctionAddress $0 onmybtnclick
ButtonEvent::AddEventHandler 0x666 $0
FunctionEnd
Function onmybtnclick
MessageBox mb_ok "You clicked me!"
FunctionEnd
Function HideIt
GetDlgItem $0 $hwndparent 0x666
ShowWindow $0 0
FunctionEnd
Function ShowIt
GetDlgItem $0 $hwndparent 0x666
ShowWindow $0 1
FunctionEnd
!ifdef MUI_INCLUDED
!define MUI_PAGE_CUSTOMFUNCTION_SHOW HideIt
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_SHOW ShowIt
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_SHOW HideIt
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
!else
Page Components "" HideIt
Page Components "" ShowIt
Page Components "" HideIt
Page Instfiles
!endif
Section
SectionEnd

Resources