Can't find IDOK (1) in the custom UI! How to add a custom OK Button in NSIS? - user-interface

Please Help ! In NSIS, I'm using
!define MUI_PAGE_CUSTOMFUNCTION_SHOW LicenseShow
then
Function LicenseShow
; New dialog for custom items
nsDialogs::Create 1018
Pop $0
; Accept button
${NSD_CreateButton} 373, 223, 50, 14 "Accept" ; Can't find IDOK (1) in the custom UI!
; Decline button
${NSD_CreateButton} 21, 223, 50, 14 "Decline"
; Picture
${NSD_CreateBitmap} 5 5 100% 100 "disclosure.bmp"
Pop $0
${NSD_SetImage} $0 $PLUGINSDIR\image.bmp $ImageHandle
; Disclaimer
nsDialogs::CreateControl /NOUNLOAD ${__NSD_Text_CLASS} ${DEFAULT_STYLES}|${WS_TABSTOP}|${ES_WANTRETURN}|${ES_MULTILINE} ${__NSD_Text_EXSTYLE} 5 220 660 115 ''
Pop $1
SendMessage $1 ${EM_SETREADONLY} 1 0
SetCtlColors $1 0x000000 0xFFFFFF
${NSD_SetText} $1 "The license text"
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
How do I tell that the Accept button has the IDOK on it ?
Please help.

You can set the id by calling System::Call 'user32::SetWindowLong(i $myhwnd,i -12,i $mynewid)' but what you really should be doing is setting up callback functions:
...
${NSD_CreateButton} ...
pop $0
${NSD_OnClick} $0 userclicked
...
Function userclicked
MessageBox mb_ok Hello
SendMessage $hwndparent ${WM_COMMAND} 1 0
FunctionEnd

Related

With in Graphical Installer & NSIS, the text of Label overlapped when I changed it dynamically

I created a custom page which contains a label and two buttons to control the label's contents.
I suppose to set the text of the label within callbacks of the buttons, as the following codes:
Function FuncShowNewFeature
; ...
; Add Controls
${NSD_CreateLabel} 0 13u 100% 12u "Show new features here"
Pop $lblContents
${GraphicalInstallerRedrawLabel} $lblContents
${NSD_CreateButton} 0 -13u 40u 13u "Prev"
Pop $btnPrev
${NSD_OnClick} $btnPrev PrevFeature ; callback
${NSD_CreateButton} -40u -13u 40u 13u "Next"
Pop $btnNext
${NSD_OnClick} $btnNext NextFeature ; callback
# Put this macro before EACH calling nsDialogs::Show to draw background properly
${GraphicalInstallerRedrawnsDialogsPage}
nsDialogs::Show
FunctionEnd
Function NextFeature
${NSD_SetText} $lblContents "To show the next tip of new-feature"
${GraphicalInstallerRedrawLabel} $lblContents ;I don't know whether this macro is necessary here
FunctionEnd
Function PrevFeature
${NSD_SetText} $lblContents "To show the previous tip of new-feature"
${GraphicalInstallerRedrawLabel} $lblContents ;I don't know whether this macro is necessary here
FunctionEnd
But the result shows something wrong, which the "new" text overlapped on the old ones, just like the label has not been refreshed/cleared before redrawing.
Did I miss any necessary calling in my process?
You are missing GraphicalInstaller::SubclassLabel /NOUNLOAD $variable_name
The correct code:
Function FuncShowNewFeature
; ...
; Add Controls
${NSD_CreateLabel} 0 13u 100% 12u "Show new features here"
Pop $lblContents
${GraphicalInstallerRedrawLabel} $lblContents
GraphicalInstaller::SubclassLabel /NOUNLOAD $lblContents # <<< ADDED HERE
${NSD_CreateButton} 0 -13u 40u 13u "Prev"
Pop $btnPrev
${NSD_OnClick} $btnPrev PrevFeature ; callback
${NSD_CreateButton} -40u -13u 40u 13u "Next"
Pop $btnNext
${NSD_OnClick} $btnNext NextFeature ; callback
# Put this macro before EACH calling nsDialogs::Show to draw background properly
${GraphicalInstallerRedrawnsDialogsPage}
nsDialogs::Show
FunctionEnd
Function NextFeature
${NSD_SetText} $lblContents "To show the next tip of new-feature"
FunctionEnd
Function PrevFeature
${NSD_SetText} $lblContents "To show the previous tip of new-feature"
FunctionEnd
GraphicalInstaller::Subclass[CONTROL] is part of
${GraphicalInstallerRedraw[CONTROL]} macro.
This works fine for [CONTROL] of type RadioButton or CheckBox, but it is missing in Label.
We will fix this in next release, sorry for this inconsistency.
One simple workaround is to just hide the label while you update its text:
!include nsDialogs.nsh
Page Custom gfxpage
Function onClick
Pop $0
System::Call 'kernel32::GetTickCount()i.r0' ; "Arbitrary" number
ShowWindow $2 0
${NSD_SetText} $2 "$0$0$0"
ShowWindow $2 1
FunctionEnd
Function .onInit
InitPluginsDir
File /oname=$PLUGINSDIR\image.bmp "${NSISDIR}\Contrib\Graphics\Header\nsis-r.bmp"
FunctionEnd
Function gfxpage
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 -13u 100% 12u "Click me"
Pop $1
${NSD_OnClick} $1 onClick
${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
Pop $2
SetCtlColors $2 000000 transparent
${NSD_CreateBitmap} 0 0 100% 12u ""
Pop $3
${NSD_SetBitmap} $3 $PLUGINSDIR\image.bmp $4
nsDialogs::Show
${NSD_FreeBitmap} $4
FunctionEnd

NSIS: Custom page on StateChanged

I have a some different license pages with check box on it. The Next button should be disabled if check box is unchecked. Is there an event that I can use if checkbox state changed? Here is my code of one of this
var Window
var labelDescription
var checkBoxIsUserAgree
Function CreateCustomLicense1
nsDialogs::Create 1018
Pop $Window
GetDlgItem $0 $HWNDPARENT
EnableWindow $0 0
${NSD_CreateLabel} 13u 22u 270u 96u "Description"
Pop $labelDescription
${NSD_CreateCheckBox} 10u 110u 100u 15u "I Agree"
$checkBoxIsUserAgree
FunctionEnd
Function ShowCustomLicence1
Call CreateCustomLicense1
nsDialogs::Show
Function
Function .oncheckBoxIsUserAgreeStateChanged ; what event I can use for track checkbox state changing
EnableWindow $0 1
FunctionEnd
The built-in NSIS license page supports a checkbox and can be used multiple times but if you insist on creating a custom page you just have to add a on* handler:
!include nsDialogs.nsh
Var checkBoxIsUserAgree
Function ShowCustomLicence1
nsDialogs::Create 1018
Pop $1
GetDlgItem $0 $HWNDPARENT 1
EnableWindow $0 0
${NSD_CreateLabel} 13u 22u 270u 90u "Description"
Pop $1
${NSD_CreateCheckBox} 10u 110u 100u 15u "I Agree"
Pop $checkBoxIsUserAgree
${NSD_OnClick} $checkBoxIsUserAgree oncheckBoxIsUserAgreeStateChanged1
nsDialogs::Show
FunctionEnd
Function oncheckBoxIsUserAgreeStateChanged1
Pop $1 ; Throw away parameter
${NSD_GetState} $checkBoxIsUserAgree $1
EnableWindow $0 $1
FunctionEnd
Page Custom ShowCustomLicence1
Page InstFiles

NSIS: How to change RichEdit background color

I'm using Nsis for install my project. I need to change richEdit background color. I try SetCtlColors method but it doesn't make any changes. Here is my code:
; handle variables
Var hCtl_FirstDialog
Var hCtl_FirstDialog_RichText1
Var hCtl_FirstDialog_Button1
; dialog create function
Function fnc_FirstDialog_Create
; === FirstDialog (type: Dialog) ===
nsDialogs::Create 1018
Pop $hCtl_FirstDialog
${If} $hCtl_FirstDialog == error
Abort
${EndIf}
!insertmacro MUI_HEADER_TEXT "Dialog title..." "Dialog subtitle..."
; === RichText1 (type: RichText) ===
nsDialogs::CreateControl /NOUNLOAD "RichEdit20A" ${WS_VISIBLE}|${WS_CHILD}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN} ${WS_EX_STATICEDGE} 12.51u 14.77u 261.32u 92.92u ""
Pop $hCtl_FirstDialog_RichText1
; RichText1 ControlCustomScript
nsRichEdit::Load $hCtl_FirstDialog_RichText1 D:\temp\NsisProject\EULA.rtf
SetCtlColors $hCtl_FirstDialog_RichText1 ccff00 ccff00
; === Button1 (type: Button) ===
${NSD_CreateButton} 225.11u 118.77u 49.37u 14.15u "Button1"
Pop $hCtl_FirstDialog_Button1
${NSD_OnClick} $hCtl_FirstDialog_Button1 FillText
FunctionEnd
; dialog show function
Function fnc_FirstDialog_Show
Call fnc_FirstDialog_Create
nsDialogs::Show
FunctionEnd
The richedit control does not support SetCtlColors, you must use its documented messages to set the text format:
!include nsDialogs.nsh
!include WinMessages.nsh
!define /ifndef /math EM_SETBKGNDCOLOR ${WM_USER} + 67
!define /ifndef /math EM_SETCHARFORMAT ${WM_USER} + 68
!define /ifndef /math EM_SETTEXTEX ${WM_USER} + 97
!define /ifndef ST_SELECTION 2
!define /ifndef CFM_COLOR 0x40000000
!define /ifndef SCF_DEFAULT 0x0000
!define /ifndef SCF_ALL 0x0004
Var hRichEd
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
nsDialogs::CreateControl /NOUNLOAD "RichEdit20A" ${WS_VISIBLE}|${WS_CHILD}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN} ${WS_EX_STATICEDGE} 12.51u 14.77u 261.32u 92.92u ""
Pop $hRichEd
SendMessage $hRichEd ${EM_SETBKGNDCOLOR} 0 0x00ffcc
!if 1 ; Set default
System::Call '*(i 60, i ${CFM_COLOR}, i0,i0,i0, i 0xcc00ff, i, &m32)p.r0' ; Note: 60 is the ANSI size
SendMessage $hRichEd ${EM_SETCHARFORMAT} ${SCF_ALL} $0
System::Free $0
${nsD_SetText} $hRichEd "Text goes here"
!else ; Import RTF
System::Call '*(i${ST_SELECTION},i0)p.r0'
SendMessage $hRichEd ${EM_SETTEXTEX} $0 "STR:{\rtf1\ansi\deff0{\colortbl;\red115\green0\blue25;}\cf1 Text goes here}" ; www.pindari.com/rtf1.html
System::Free $0
SendMessage $hRichEd ${EM_REPLACESEL} 0 "STR: and more text here"
!endif
nsDialogs::Show
FunctionEnd
Page Custom MyPageCreate

Cant understand why ${NSD_GetState} $Checkbox is not working

Can anyone explain to me, why ${NSD_GetState} $Checkbox is not working ?
I lost about 4 hours trying to find out what is wrong. I tried diffrent variants but in THIS script they are not working.
Actualy it is my first attempt to make a nsis installer, so I even dont know where should I look for mistake or I just dont understand the logic of this language.
From Russia with love :)
And sorry for my bad english
!define NAME "Simple LiveUSB installer"
!define FILENAME "USB"
!define VERSION "v0.1"
Name "${NAME} ${VERSION}"
OutFile "${FILENAME}.exe"
SetCompressor LZMA
ShowInstDetails hide
XPStyle on
!include MUI2.nsh
!include FileFunc.nsh
!include nsDialogs.nsh
;!include LogicLib.nsh
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\HEADER2.bmp"
!define MUI_HEADERIMAGE_BITMAP_NOSTRETCH
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\media-floppy.ico"
Page custom drivePage
Page custom Var123
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"
LangString DrivePage_Title ${LANG_RUSSIAN} "TEXT"
LangString DrivePage_Title2 ${LANG_RUSSIAN} "TEXT"
LangString DrivePage_Text ${LANG_RUSSIAN} "TEXT"
LangString DrivePage_Text2 ${LANG_RUSSIAN} "Format"
LangString DrivePage_Input ${LANG_RUSSIAN} "Choose"
Var Label
Var Label2
Var Checkbox
;Var Checkbox_State
Var DestDriveHW
Var DestDrive
# Functions #######################################
Function drivePage
!insertmacro MUI_HEADER_TEXT $(DrivePage_Title) $(DrivePage_Title2)
nsDialogs::Create 1018
${If} $DestDrive == ""
GetDlgItem $6 $HWNDPARENT 1
EnableWindow $6 0
${EndIf}
${NSD_CreateLabel} 0 0 100% 160 $(DrivePage_Text)
Pop $Label
${NSD_CreateLabel} 10 182 100% 15 $(DrivePage_Input)
Pop $Label2
${NSD_CreateDroplist} 10 200 13% 20 ""
Pop $DestDriveHw
${NSD_OnChange} $DestDriveHw db_select.onchange
${GetDrives} "FDD" driveListFiller
${If} $DestDrive != ""
${NSD_CB_SelectString} $DestDriveHw $DestDrive
${EndIf}
${NSD_CreateCheckbox} 80 203 100% 10u $(DrivePage_Text2)
Pop $Checkbox
${If} $Checkbox_State == ${BST_CHECKED}
${NSD_Check} $Checkbox_State
${EndIf}
nsDialogs::Show
FunctionEnd
Function db_select.onchange
Pop $DestDriveHw
${NSD_GetText} $DestDriveHw $0
StrCpy $DestDrive "$0"
GetDlgItem $6 $HWNDPARENT 1
EnableWindow $6 1
FunctionEnd
Function driveListFiller
SendMessage $DestDriveHw ${CB_ADDSTRING} 0 "STR:$9"
Push 1
FunctionEnd
Function Var123
Pop $Checkbox
MessageBox mb_ok "FIN Checkbox_State=$Checkbox_State Checkbox=$Checkbox"
${NSD_GetState} $Checkbox $0
${If} $0 <> 0
MessageBox mb_ok "Custom checkbox was checked... N=$0"
${EndIf}
${If} $0 == 0
MessageBox mb_ok "Custom checkbox ZERO... N=$0"
${EndIf}
Functionend
# Section #######################################
Section "" main
InitPluginsDir
File /oname=$PLUGINSDIR\syslinux.cfg "${NSISDIR}\plugins\syslinux.cfg"
File /oname=$PLUGINSDIR\syslinux.exe "${NSISDIR}\plugins\syslinux.exe"
File /oname=$PLUGINSDIR\nsExec.dll "${NSISDIR}\plugins\nsExec.dll"
StrCpy $R0 $DestDrive -1
;ExpandEnvStrings $0 %COMSPEC%
;nsExec::Exec '"$0" /c echo. | format $R0 /q /x /v:LiveUSB /fs:fat32'
nsExec::Exec '$PLUGINSDIR\syslinux.exe -maf -d boot\syslinux $R0'
;SendMessage $Checkbox ${BM_GETSTATE} 0 0 $0
;${If} $0 != 0
; MessageBox MB_OK checked!
;${EndIf}
;Pop $Checkbox
;MessageBox mb_ok "FIN Checkbox_State=$Checkbox_State Checkbox=$Checkbox"
;${NSD_GetState} $Checkbox $0
;${If} $0 <> 0
; MessageBox mb_ok "Custom checkbox was checked... N=$0"
;${EndIf}
CopyFiles $PLUGINSDIR\syslinux.cfg "$R0\syslinux.cfg"
SectionEnd
There is so much unrelated code in your example that it is a bit hard to understand what you really want to do.
If you want to retrieve the state of a checkbox on another page then you must save the state because the checkbox control is destroyed when you leave the page.
!include nsDialogs.nsh
Var hwndCheckbox
Var CheckboxState
Page Custom myPageWithCombobox myPageWithComboboxLeaveCallback
Page Custom myPageWithComboState
Function .onInit
StrCpy $CheckboxState ${BST_CHECKED} ; Set the initial state. This is optional but useful if you use $CheckboxState in a section when the installer is silent
FunctionEnd
Function myPageWithCombobox
nsDialogs::Create 1018
Pop $0
${NSD_CreateCheckbox} 80 203 100% 10u $(DrivePage_Text2)
Pop $hwndCheckbox
${NSD_SetState} $hwndCheckbox $CheckboxState ; Reuse the existing state so it is correct when the back button is used
nsDialogs::Show
FunctionEnd
Function myPageWithComboboxLeaveCallback
${NSD_GetState} $hwndCheckbox $CheckboxState ; Save the state so we can retrieve it on the next page
FunctionEnd
Function myPageWithComboState
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 160 CheckboxState=$CheckboxState
Pop $0
nsDialogs::Show
FunctionEnd

How to change custom page label text on the fly in nsis?

I have written a custom page where i want to change the label text on the fly .I tried following code but some how I could not bale to change the text .
Function Maintainance
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "The $CurrentVersion complete installation folder is available at the below link"
Pop $Label
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $1 $0 1006
SendMessage $1 ${WM_SETTEXT} 0 "STR:new value 111111"
nsDialogs::Show
FunctionEnd
Any pointer on this will be a help.
The custom page is not visible until you call nsDialogs::Show. Any dynamic action has to happen after that with a timer or in response to a user action:
Page Custom MyPageCreate
Page InstFiles
!include nsDialogs.nsh
var mylabel
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "Hello"
Pop $mylabel
${NSD_CreateButton} 0 50% 50% 12u "Change"
Pop $0
${NSD_OnClick} $0 ChangeIt
nsDialogs::Show
FunctionEnd
Function ChangeIt
System::Call kernel32::GetTickCount()i.r0
SendMessage $mylabel ${WM_SETTEXT} 0 "STR:World! $0"
FunctionEnd

Resources