How to create NSD_Text dynamically depending from a NSD_CheckBox? - nsis

I want to create a Textinput for the User dynamically depending from the State of a Checkbox above it.
I tried something like this:
...
Function nsDialogsPage
nsDialogs::Create 1018
${NSD_CreateCheckBox} 20u 55u 50% 20u "Download with Proxy"
Pop $testBox
${NSD_OnClick} $testBox button_click
nsDialogs::Show
FunctionEnd
Function button_click
${NSD_GetState} $testBox $6
${If} $6 == 1
${NSD_CreateText} 20u 75u 80% 25p "Enter your Proxy ..."
${Else}
;Remove the Text, Set it invisible or do something like this ...
${EndIf}
FunctionEnd
Function nsDialogsPageLeave
;does something with the input
FunctionEnd
I didn't find anything on http://nsis.sourceforge.net/Docs/nsDialogs/Readme.html and
I dont know how to remove the Box or make it invisible for the User or something like this, that he can't enter anything when the CheckBox is unchecked.

Take a look at EnableWindow
${NSD_CreateText} 20u 75u 80% 25p "Enter your Proxy ..."
Pop $myText
#disable control
EnableWindow $myText 0
#enable control
EnableWindow $myText 1
#hide control
ShowWindow $myText 0
#show control
ShowWindow $myText 1

Related

Clear text field value on click the checkbox nsis

I have TextField that is editable.
But when the user click on the Checkbox, i need to disabled the TextField and as well as to clear the value of textfield. I disabled the field but not able to clear the TextField value. So please let me know how to do this.
Note : Clear value means if the TextField have any value then it is should be blank onClick the checkbox.
Code :
${NSD_CreateText} 50u 67u 200u 12u ""
Pop $txtUsername
${NSD_SetText} $txtUsername $Text_txtUsername
${NSD_CreatePassword} 50u 80u 200u 12u ""
Pop $pwdPassword
${NSD_SetText} $pwdPassword $Text_pwdPassword
${NSD_CreateCheckbox} 0 96u 100% 12u "&Use Windows Login (Domain account must have 'log on as a service' right.)"
Pop $chkCheckbox
${NSD_OnClick} $chkCheckbox EnDisableWindowsLoginButton
Function EnDisableWindowsLoginButton
Pop $chkCheckbox
${NSD_GetState} $chkCheckbox $sqlLogin
${If} $sqlLogin == 1
EnableWindow $txtUsername 0
EnableWindow $pwdPassword 0
${Else}
EnableWindow $txtUsername 1
EnableWindow $pwdPassword 1
${EndIf}
FunctionEnd
You can set the value of a textbox with NSD_SetText. Indeed, it looks like you're already using it to initialize those fields. Try something like this:
Function EnDisableWindowsLoginButton
Pop $chkCheckbox
${NSD_GetState} $chkCheckbox $sqlLogin
${If} $sqlLogin == 1
${NSD_SetText} $txtUsername ""
${NSD_SetText} $pwdPassword ""
EnableWindow $txtUsername 0
EnableWindow $pwdPassword 0
${Else}
EnableWindow $txtUsername 1
EnableWindow $pwdPassword 1
${EndIf}
FunctionEnd
If you don't want to loose the values entered by the user, you can StrCpy them to some temp variables and restore them if/when user unchecks the checkbox.

NSIS onblur or onfocus event equivalent

I need to be able to fill out a second text box based on content from another (first) text box, and I need to do it when the first text box loses focus (or when the second text box gains focus).
I am not able to do what I need to do using OnChange because it is triggered after every keypress, but the value of the first text box needs to be evaluated only after the user finishes inputting.
How would I do this? There are no OnBlur or OnFocus event handlers, and the existing ones OnChange, OnClick, OnBack, OnNotify can't seem to do the job.
I don't think nsDialogs can handle this, you probably have to use the WndSubclass plug-in:
Page Custom MyPage
Page InstFiles
!include LogicLib.nsh
!include nsDialogs.nsh
!include WinMessages.nsh
!include WndSubclass.nsh
Var EditName
Var EditNick
Var NickSubProc
Function MyPage
nsDialogs::Create 1018
Pop $0
${NSD_CreateText} 7% 0 77% 12u "Joe Sixpack"
Pop $EditName
${NSD_CreateText} 7% 14u 77% 12u ""
Pop $EditNick
${WndSubclass_Subclass} $EditNick NickSubProc $NickSubProc $NickSubProc
nsDialogs::Show
FunctionEnd
Function NickSubProc
${If} $2 = ${WM_SETFOCUS}
${If} $3 = $EditName ; $EditName lost focus?
${OrIf} $3 = 0 ; or no previous focus?
${NSD_GetText} $EditName $4
${If} $4 != ""
${NSD_SetText} $EditNick "Foo $4 Bar"
SendMessage $EditNick ${EM_SETSEL} 0 -1
${EndIf}
${EndIf}
${EndIf}
FunctionEnd
Section
SectionEnd

Label or text box

So this is what I have for password set up. I would like to know how I make it so that the page has a lable or text box on it that Askes you to enter a password. As of rigth now it is blank. any ideas
!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
Page Custom pre leave
var dialog
var hwnd
Function leave
${NSD_GetText} $hwnd $0
${If} $0 != "Password"
MessageBox MB_OK "Please enter a valid Security Code"
Abort
${EndIf}
FunctionEnd
Function pre
nsDialogs::Create 1018
Pop $dialog
${NSD_CreatePassword} 0 0 50% 8% ""
Pop $hwnd
SendMessage $hwnd ${EM_SETPASSWORDCHAR} 149 0 # 149 = medium dot
nsDialogs::show
FunctionEnd
...
${NSD_CreateLabel} 0 2d 70d 16d "Password:"
Pop $0
${NSD_CreatePassword} 70d 0 50% 20d ""
Pop $hwnd
...

Radio button with Immeditate action using NSIS?

I have created customize page with two radio button for repair and remove.If the user select the repair button it goes for repair fun.but again come to old page that is repair and remove page.so the user selects both option.My requirement is user selects only one option and do corresponding actions only.No need to give the option to select both the buttons.
Function nsDialogpage
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateRadioButton} 0 5u 100% 10u "Repair"
Pop $Repair
${NSD_AddStyle} $Repair ${WS_GROUP}
${NSD_OnClick} $Repair Repair
${NSD_CreateRadioButton} 0 25u 100% 56u "Remove"
Pop $Remove
${NSD_OnClick} $Remove Remove
nsDialogs::Show
FunctionEnd
Function Repair
-- Do repair function.
FunctionEnd
Function Remove
ExecWait "$INSTDIR\uninstall.exe"
Quit
FunctionEnd
also if remove fun have remove the installer and quit the installation.
uninstaller has been done successfully.but installer again go main page after that user click any button then only quit from installation steps.
1.User select any one option and leave this repair and remove page.
2.If user click remove option remove the installer and immediately quit the process.
Quit does not quit right away when used in a page action callback, it will quit when the page changes. Performing some action when a radio button is clicked is not normal Windows behavior (Try pressing TAB) so I added a normal example aswell.
!include nsDialogs.nsh
Page Custom RepairOrRemovePageInsane_Create
Page Custom RepairOrRemovePageNormal_Create RepairOrRemovePageNormal_Leave
Page InstFiles
Function Remove
ExecWait '"cmd" /C echo This is a dummy uninstall command...&pause' ; Call real uninstaller here
FunctionEnd
Function Repair
# Do repair....
FunctionEnd
Function RepairOrRemovePageInsane_Create
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 0 5u 100% 10u "Repair"
Pop $0
SendMessage $HWNDPARENT ${WM_NEXTDLGCTL} $0 1
${NSD_OnClick} $0 RepairInsane
${NSD_CreateRadioButton} 0 25u 100% 56u "Remove"
Pop $0
${NSD_OnClick} $0 RemoveInsane
GetDlgItem $0 $hwndparent 1 ; Get Next button handle and
EnableWindow $0 0 ; ...disable it because it does not make sense with this insane radio button handling
nsDialogs::Show
FunctionEnd
Function RemoveInsane
Call Remove
SendMessage $HWNDPARENT ${WM_CLOSE} 0 0
FunctionEnd
Function RepairInsane
Call Repair
SendMessage $HWNDPARENT 0x408 1 0 ; Go to next page
FunctionEnd
Function RepairOrRemovePageNormal_Create
nsDialogs::Create 1018
Pop $1
${NSD_CreateRadioButton} 0 5u 100% 10u "Repair"
Pop $1
${NSD_CreateRadioButton} 0 25u 100% 56u "Remove"
Pop $2
SendMessage $1 ${BM_CLICK} 0 0 ; Select one of them by default
nsDialogs::Show
FunctionEnd
Function RepairOrRemovePageNormal_Leave
${NSD_GetState} $1 $0
${If} $0 <> 0
Call Repair
${Else}
Call Remove
Quit
${EndIf}
FunctionEnd

Retain data on custom pages when back button is pressed

Incase of custom pages in NSIS script is there any way to retain the data entered by user when back button is pressed (when the installer is running)?
There are a couple of ways to do this. Either way you need to store your data in globals.
1) Use a "Leave" function.
Page custom EnterCustom LeaveCustom
; Create two variables for each value/widget pair
Var Text
Var TextWidget
Var Check
Var CheckWidget
Function EnterCustom
nsDialogs::Create 1018
Pop $0
${NSD_CreateText} 0 0 80u 12u $Text
Pop $TextWidget
${NSD_CreateCheckBox} 0 26u 80u 12u "Check this box"
Pop $CheckWidget
${NSD_SetState} $CheckWidget $Check
nsDialogs::Show
FunctionEnd
Function LeaveCustom
${NSD_GetText} $TextWidget $Text
${NSD_GetState} $CheckWidget $Check
FunctionEnd
The only problem with this method is that LeaveCustom only gets called if you hit the next button. So if you edit the fields then click the Back button your changes are lost. The changes are however saved if you go forward then come back.
2) Use the OnChange callback.
This is a little more complicated but solves the problem with the previous method.
Page custom EnterCustom
Var Initialized
; Create two variables for each value/widget pair
Var Text
Var TextWidget
Var Check
Var CheckWidget
Function EnterCustom
nsDialogs::Create 1018
Pop $0
${If} $Initialized != "True"
; Set defaults for all your values here
StrCpy $Text "Initial Value"
StrCpy $Check ${BST_UNCHECKED}
StrCpy $Initialized "True"
${EndIf}
; Create and configure all of your widgets
${NSD_CreateText} 0 0 80u 12u $Text
Pop $TextWidget
${NSD_OnChange} $TextWidget OnTextChange
${NSD_CreateCheckBox} 0 26u 80u 12u "Check this box"
Pop $CheckWidget
${NSD_SetState} $CheckWidget $Check
${NSD_OnClick} $CheckWidget OnCheckClick
nsDialogs::Show
FunctionEnd
; Create a callback function for each Widget
Function OnTextChange
Pop $0 ; Widget handle is on stack
${NSD_GetText} $TextWidget $Text
FunctionEnd
Function OnCheckClick
Pop $0 ; Widget handle is on stack
${NSD_GetState} $CheckWidget $Check
FunctionEnd
Some widgets, e.g. RadioButtons and CheckBoxes, use the OnClick function instead. Also the ComboBox does not work well with this method. However, a DropList, which does not seem to be documented, can usually replace it and works fine.
Radio buttons are also a little tricky because only the click callback for the selected button is called. I solved this by updating all of the radio button values in each radio button click callback.
Messy/tedious but it works.
I know it's an old question, but I've landed here from my googling.
You can use NSD_OnBack (or call nsDialogs::OnBack directly) to set OnBack callback.
Here is the code snipet:
Function portsSelectionPage
nsDialogs::Create 1018
Pop $0
${NSD_CreateNumber} 70u 0 40u 12u $TomcatPort
Pop $TomcatPortHWND
${NSD_CreateNumber} 70u 14u 40u 12u $PostgresPort
Pop $PostgresPortHWND
nsDialogs::Show
${NSD_OnBack} "portsSelectionPageLeave"
FunctionEnd
Function portsSelectionPageLeave
${NSD_GetText} $TomcatPortHWND $TomcatPort
${NSD_GetText} $PostgresPortHWND $PostgresPort
FunctionEnd
You can store data in a global variable, or in a .ini in $pluginsdir
!include nsDialogs.nsh
!include LogicLib.nsh
Name nsDialogs
OutFile nsDialogs.exe
XPStyle on
Var Dialog
Var Label
Var Text
Var Text_State
Var Checkbox
Var Checkbox_State
Page custom nsDialogsPage nsDialogsPageLeave
Page license
Page instfiles
Function .onInit
StrCpy $Text_State "Type something here..."
FunctionEnd
Function nsDialogsPage
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
Pop $Label
${NSD_CreateText} 0 13u 100% 12u $Text_State
Pop $Text
${NSD_CreateCheckbox} 0 30u 100% 10u "&Something"
Pop $Checkbox
${If} $Checkbox_State == ${BST_CHECKED}
${NSD_Check} $Checkbox
${EndIf}
# alternative for the above ${If}:
#${NSD_SetState} $Checkbox_State
nsDialogs::Show
FunctionEnd
Function nsDialogsPageLeave
${NSD_GetText} $Text $Text_State
${NSD_GetState} $Checkbox $Checkbox_State
FunctionEnd
Section
DetailPrint "hello world"
SectionEnd
more information http://nsis.sourceforge.net/Docs/nsDialogs/Readme.html#step-memory

Resources