NsDialogs FAQ: Difference between revisions
No edit summary |
|||
Line 502: | Line 502: | ||
</highlight-nsis> | </highlight-nsis> | ||
== How to | == How to let controls receive Hotkey (alt+letter) combinations == | ||
Only controls that have labels can be assigned a hotkey, simply by including an ampersand in its title. E.g. | Only controls that have labels can be assigned a hotkey, simply by including an ampersand in its title. E.g. | ||
[code] | [code] |
Revision as of 02:30, 3 March 2009
How to Enable/Disable a control
Use the standard NSIS EnableWindow command.
NSDialogs lets you pop the hwnd of a control created via ${NSD_Create*}. EnableWindow takes a hwnd as one of its parameters. With this, you can easily enable/disable a control.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd var button Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateCheckbox} 0 0 50% 6% "Enable button below" Pop $hwnd ${NSD_OnClick} $hwnd EnDisableButton ${NSD_CreateButton} 25% 25% 50% 50% "Hello World" Pop $button EnableWindow $button 0 # start out disabled nsDialogs::Show FunctionEnd Function EnDisableButton Pop $hwnd ${NSD_GetState} $hwnd $0 ${If} $0 == 1 EnableWindow $button 1 ${Else} EnableWindow $button 0 ${EndIf} FunctionEnd Section "" SectionEnd
How to Show/Hide a control
Use the standard NSIS ShowWindow command.
NSDialogs lets you pop the hwnd of a control created via ${NSD_Create*}. ShowWindow takes a hwnd as one of its parameters. With this, you can easily show/hide a control.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd var button Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateCheckbox} 0 0 50% 6% "Show button below" Pop $hwnd ${NSD_OnClick} $hwnd EnDisableButton ${NSD_CreateButton} 25% 25% 50% 50% "Hello World" Pop $button ShowWindow $button ${SW_HIDE} # start out hidden nsDialogs::Show FunctionEnd Function EnDisableButton Pop $hwnd ${NSD_GetState} $hwnd $0 ${If} $0 == 1 ShowWindow $button ${SW_SHOW} ${Else} ShowWindow $button ${SW_HIDE} ${EndIf} FunctionEnd Section "" SectionEnd
How to create a multi-line edit (text) control
Although multi-line is a Style of a control, for Edit (Text) controls it is one of few styles that cannot be set once the control has already been created - so you can't use ${NSD_AddStyle}.
Instead, you will have to create the control manually:
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateText} 0 0 100% 40% "This is NOT a$\r$\nmulti-line$\r$\nedit control" Pop $hwnd nsDialogs::CreateControl EDIT \ "${__NSD_Text_STYLE}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN}" \ "${__NSD_Text_EXSTYLE}" \ 0 50% 100% 40% \ "This IS a$\r$\nmulti-line$\r$\nedit control" Pop $hwnd nsDialogs::Show FunctionEnd Section "" SectionEnd
Or, much cleaner, using the NsDialogs_CreateTextMultiline header:
!include "nsDialogs.nsh" !include "nsDialogs_createTextMultiline.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateText} 0 0 100% 40% "This is NOT a$\r$\nmulti-line$\r$\nedit control" Pop $hwnd ${NSD_CreateTextMultiline} 0 50% 100% 40% "This IS a$\r$\nmulti-line$\r$\nedit control" Pop $hwnd nsDialogs::Show FunctionEnd Section "" SectionEnd
How to create a Text Password control
See the nsDialogs documentation - a Password control is one of the controls supported by default; ${NSD_CreatePassword}
How to set the character used by a Text Password control
By default a Text Password control will use an asterisk (*****) character to mask the text. You can change this character using SendMessage with the EM_SETPASSWORDCHAR flag.
The password character is identified by its ASCII or UNICODE index; keep in mind that the font you use for your installer may not support the character you wish to use.
NOTE If you set the password character to 0 (zero), the text will not be masked! You can use this to toggle between the text being visible and masked. See also the How to hide/show passwords in a Text Password control entry.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreatePassword} 0 0 50% 8% "This is a password field" Pop $hwnd SendMessage $hwnd ${EM_SETPASSWORDCHAR} 149 0 # 149 = fat dot nsDialogs::Show FunctionEnd Section "" SectionEnd
How to hide/show passwords in a Text Password control
By using SendMessage with the EM_SETPASSWORDCHAR flag, specifying the character as 0 (zero), you can make a password visible, and invisible again by specifying a non-zero character.
See also the How to set the character used by a Text Password control entry.
NOTE The Password control has to be forcibly redrawn after changing the mask character. This is done by hiding and then showing the control using ShowWindow.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd var passwordControl Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateCheckbox} 0 0 25% 8% "Show password" Pop $hwnd ${NSD_OnClick} $hwnd ShowPassword ${NSD_CreatePassword} 0 10% 50% 8% "This is a password field" Pop $passwordControl nsDialogs::Show FunctionEnd Function ShowPassword Pop $hwnd ${NSD_GetState} $hwnd $0 ShowWindow $passwordControl ${SW_HIDE} ${If} $0 == 1 SendMessage $passwordControl ${EM_SETPASSWORDCHAR} 0 0 ${Else} SendMessage $passwordControl ${EM_SETPASSWORDCHAR} 42 0 ${EndIf} ShowWindow $passwordControl ${SW_SHOW} FunctionEnd Section "" SectionEnd
How to create a Numbers-only Text control
See the nsDialogs documentation - a Numbers-only control is one of the controls supported by default; ${NSD_CreateNumber}
How to create a Read-only Text control
The read-only state of a Text control can be set using SendMessage with the EM_SETREADONLY flag.
Note that a read-only Edit (Text) control is not the same as a disabled Text control. A disabled Text control will display its text grayed out, a read-only Text control remains black on a light grey background. In addition, a disabled multi-line Text control cannot be scrolled. A read-only multi-line Text control, on the other hand, can be scrolled.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd var textControl Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateCheckBox} 0 0 50% 6% "Set text field below read-only" Pop $hwnd ${NSD_OnClick} $hwnd SetReadonly ${NSD_CreateText} 0 12% 100% 8% "Hello World" Pop $textControl nsDialogs::Show FunctionEnd Function SetReadonly Pop $hwnd ${NSD_GetState} $hwnd $0 SendMessage $textControl ${EM_SETREADONLY} $0 0 FunctionEnd Section "" SectionEnd
How to create two groups of RadioButtons
Use ${NSD_AddStyle} to add the WS_GROUP style to the first radiobutton of each group. In Windows' UI handling, all radiobuttons are considered to be part of the same group if no group starter is defined.
Therefore, to have two radiobutton groups of two radiobuttons each, you must specify a group starter for each, otherwise the third and fourth radiobuttons will be considered part of the first group.
Setting a group starter is easy using ${NSD_AddStyle}, use:
${NSD_AddStyle} $hwnd ${WS_GROUP} # WS_GROUP is defined in winmessages.nsh </higlight-nsis> example: <highlight-nsis> !include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateRadioButton} 0 0 40% 6% "Group 1, Radio 1" Pop $hwnd ${NSD_AddStyle} $hwnd ${WS_GROUP} ${NSD_CreateRadioButton} 0 12% 40% 6% "Group 1, Radio 2" Pop $hwnd ${NSD_CreateRadioButton} 50% 0 40% 6% "Group 2, Radio 1" Pop $hwnd ${NSD_AddStyle} $hwnd ${WS_GROUP} ${NSD_CreateRadioButton} 50% 12% 40% 6% "Group 2, Radio 2" Pop $hwnd nsDialogs::Show FunctionEnd Section "" SectionEnd
How to easily handle radiobutton selections
Often you do not want to specify separate OnClick functions for each radiobutton...
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateRadioButton} 0 0 40% 6% "Group 1, Radio 1" Pop $hwnd ${NSD_AddStyle} $hwnd ${WS_GROUP} ${NSD_OnClick} $hwnd Group1Radio1Click ${NSD_CreateRadioButton} 0 12% 40% 6% "Group 1, Radio 2" Pop $hwnd ${NSD_OnClick} $hwnd Group1Radio2Click nsDialogs::Show FunctionEnd Function Group1Radio1Click Pop $hwnd MessageBox MB_OK "onClick:Group1Radio1" FunctionEnd Function Group1Radio2Click Pop $hwnd MessageBox MB_OK "onClick:Group1Radio2" FunctionEnd Section "" SectionEnd
But the only obvious alternative seems to be to place each in a different variable and comparing the hwnd on the stack when the callback function is called to that variable.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd var Group1Radio1 var Group1Radio2 Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateRadioButton} 0 0 40% 6% "Group 1, Radio 1" Pop $Group1Radio1 ${NSD_AddStyle} $Group1Radio1 ${WS_GROUP} ${NSD_OnClick} $Group1Radio1 RadioClick ${NSD_CreateRadioButton} 0 12% 40% 6% "Group 1, Radio 2" Pop $Group1Radio2 ${NSD_OnClick} $Group1Radio2 RadioClick nsDialogs::Show FunctionEnd Function RadioClick Pop $hwnd ${If} $hwnd == $Group1Radio1 MessageBox MB_OK "onClick:Group1Radio1" ${ElseIf} $hwnd == $Group1Radio2 MessageBox MB_OK "onClick:Group1Radio2" ${EndIf} FunctionEnd Section "" SectionEnd
However, you can eliminate both by making use of the getUserData and setUserData commands of nsDialogs. Using these *UserData commands, you can store data in a control and easily retrieve this later.
To simplify the use of these commands, we'll be using the header from NsDialogs UserData.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre var dialog var hwnd Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateRadioButton} 0 0 40% 6% "Group 1, Radio 1" Pop $hwnd ${NSD_AddStyle} $hwnd ${WS_GROUP} ${NSD_SetUserData} $hwnd "Group1Radio1" ${NSD_OnClick} $hwnd RadioClick ${NSD_CreateRadioButton} 0 12% 40% 6% "Group 1, Radio 2" Pop $hwnd ${NSD_SetUserData} $hwnd "Group1Radio2" ${NSD_OnClick} $hwnd RadioClick nsDialogs::Show FunctionEnd Function RadioClick Pop $hwnd ${NSD_GetUserData} $hwnd $0 ${If} $0 == "Group1Radio1" MessageBox MB_OK "onClick:Group1Radio1" ${ElseIf} $0 == "Group1Radio2" MessageBox MB_OK "onClick:Group1Radio2" ${EndIf} FunctionEnd Section "" SectionEnd
Using this method, you can easily set a variable to an internal string stored on the radiobutton control without any If-ElseIf-EndIf or Case selections in the OnClick event function at all.
!include "nsDialogs.nsh" !include "winmessages.nsh" !include "logiclib.nsh" OutFile "test.exe" Page Custom pre post var dialog var hwnd var minor Function pre nsDialogs::Create 1018 Pop $dialog ${NSD_CreateRadioButton} 0 0 40% 6% "I am 14 years of age or older" Pop $hwnd ${NSD_AddStyle} $hwnd ${WS_GROUP} ${NSD_SetUserData} $hwnd "false" ${NSD_OnClick} $hwnd RadioClick ${NSD_CreateRadioButton} 0 12% 40% 6% "I am younger than 14 of age" Pop $hwnd ${NSD_SetUserData} $hwnd "true" ${NSD_OnClick} $hwnd RadioClick nsDialogs::Show FunctionEnd Function RadioClick Pop $hwnd ${NSD_GetUserData} $hwnd $minor FunctionEnd Function post ${If} $minor == "" MessageBox MB_OK "Please specify your age group" Abort ${ElseIf} $minor == true MessageBox MB_OK "installation will continue with content appropriate for your age" ${Else} MessageBox MB_OK "installation will continue normally" ${EndIf} FunctionEnd Section "" SectionEnd
How to let controls receive Hotkey (alt+letter) combinations
Only controls that have labels can be assigned a hotkey, simply by including an ampersand in its title. E.g. [code] ${NSDCreateCheckbox} 3% 3% 20% 8% "The hot&key here is alt+k" [/code]
However, when the page is first navigated to in NSIS, the NSIS dialog is what has focus, rather than the inner nsDialogs dialog. So set focus before nsDialogs shows: [code] nsDialogs::Create 1018 Pop $dialog ; assuming you have a 'dialog' variable!
- further code here
SendMessage $dialog ${WM_SETFOCUS} $HWNDPARENT 0 nsDialogs::Show [/code] The NSIS dialog will still handle e.g. alt+N for the Next button as the hotkey event simply 'bubbles up' to the parent window if window with current focus does not react to it. ( Hint: That means you shouldn't set any hotkeys for the B(ack) or N(ext) letters! )
Using these methods, you can easily create an installer that can be navigated entirely and easily by keyboard-only.