Components Page Leave Function: Always says a Component is checked - installation

On my MUI Components Page I call a function when the users attempts to leave that page. In that function I am trying to see that there is atleast 1 component checked. If there isn't then I show a MessageBox and abort(stop from continuing to the next page).
My Problem: My function always says a component is checked even when it isn't. What am I doing wrong?
For some reason the program always thinks the 1st component is checked/selected when it is not?
!include nsdialogs.nsh
!include MUI2.nsh
!define MUI_PAGE_CUSTOMFUNCTION_SHOW compshow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE compleave
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_LANGUAGE "English"
OutFile "test.exe"
Function compshow
FunctionEnd
Function compleave
!insertmacro SectionFlagIsSet ${section1} ${SF_SELECTED} +1 +2
MessageBox MB_OK "Component Selected"
MessageBox MB_OK "Component NOT Selected"
FunctionEnd
Section "Dummy1"
SectionEnd
Section "Dummy2"
SectionEnd

Your problem is with relative jumps. You should use some labels instead because macros may contain many commands, not just one.
Also, think that the execution will continue after the first jump. Dont forget to skip the other branch of the test.
The modified compleave callback works as you intended :
Function compleave
!insertmacro SectionFlagIsSet ${section1} ${SF_SELECTED} selected not_selected
selected:
MessageBox MB_OK "Component Selected"
goto end
not_selected:
MessageBox MB_OK "Component NOT Selected"
end:
FunctionEnd

Related

VBScript, cant end my project

this is the last part of my script
MsgBox("text")
vbOK
WScript.Quit
End If
x=MsgBox("text",1,"text")
vbOK
If vbOK Then
do
Loop
vbCancel
If vbCancel Then
WScript.Quit
MsgBox("text")
but somehow it wont work. i use vbsedit, but when i press start it tell me to add 'end',so i do but then it tell me to add'if'. after ive done that it tells me to add 'end' again, and so it goes on.
how can i fix it?
im new to VBS and spent 5h trying to find a solution.
When in doubt, read the documentation:
Displays a message in a dialog box, waits for the user to click a button, and returns a value indicating which button the user clicked.
MsgBox(prompt[, buttons][, title][, helpfile, context])
Arguments
[...]
buttons
Numeric expression that is the sum of values specifying the number and type of buttons to display, the icon style to use, the identity of the default button, and the modality of the message box. See Settings section for values. If omitted, the default value for buttons is 0.
As you can see the button layout of VBScript message boxes is controlled via the second parameter, and the function's return value indicates which button was pressed by the user.
If for instance you want to present a user with a yes/no choice you could do something like this:
choice = MsgBox("question", vbYesNo, "title")
Select Case choice
Case vbYes : MsgBox "User pressed 'Yes'."
Case vbNo : MsgBox "User pressed 'No'."
Case Else : MsgBox "Something unexpected happened.", , "Error"
End If

Clickable banner/ header image in Setup program

I need to make an Windows installer either with NSIS or InnoSetup. The customer wants an image to be displayed in the installer dialogues/ wizard pages and the image needs to be clickable, e.g. open a browser window when clicked.
Is this possible? If yes, is it also possible to use animated gifs?
To make the welcome page's left image clickable, you can use the following:
[Code]
procedure OnBannerClick(Sender: TObject);
var
ErrorCode: Integer;
begin
ShellExec('', 'http://www.stackoverflow.com', '', '', SW_SHOW, ewNoWait,
ErrorCode);
end;
procedure InitializeWizard;
begin
WizardForm.WizardBitmapImage.Cursor := crHand;
WizardForm.WizardBitmapImage.OnClick := #OnBannerClick;
end;
....and the same thing for NSIS:
!include MUI2.nsh
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MakeClickableWizardImage
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_INSTFILES
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MakeClickableWizardImage
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function OnWizardClick
ExecShell "" "http://example.com"
FunctionEnd
Function MakeClickableWizardImage
StrCpy $0 $mui.WelcomePage.Image
${If} $mui.FinishPage.Image <> 0
StrCpy $0 $mui.FinishPage.Image
${EndIf}
${NSD_OnClick} $0 OnWizardClick
FunctionEnd
If you want to implement a gif image, you can use this extension:
GifCTRL 2.1
It's Chinese but the example Inno script shows everything you need.

MUI pages order in NSIS

How to change order of pages depending on some clauses? For example, there are 2 radiobuttons on custom page - 'repair programm' and 'uninstall programm'. When I select 'repair programm' next should show 5 pages and when I select another radiobutton should be 2 pages.
And is it possible use in uninstaller install pages and vice versa?
MUI_UNPAGE_CONFIRM does not really make sense in a installer, other than that you can use all page types in both the installer and uninstaller.
To skip a page you must call Abort in the pre callback function for that page. You can also jump directly to a specific page.
!include MUI2.nsh
!include LogicLib.nsh
Var pagemode
Function selectpagemode
MessageBox MB_YESNO "Mode A?" IDNO nope
StrCpy $pagemode "A"
Return
nope:
StrCpy $pagemode "B"
FunctionEnd
Function onlymodeA
${IfThen} $pagemode != "A" ${|} Abort ${|}
FunctionEnd
Function onlymodeB
${IfThen} $pagemode == "A" ${|} Abort ${|}
FunctionEnd
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE selectpagemode
!insertmacro MUI_PAGE_WELCOME
;Mode A
!define MUI_PAGE_CUSTOMFUNCTION_PRE onlymodeA
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
!define MUI_PAGE_CUSTOMFUNCTION_PRE onlymodeA
!insertmacro MUI_PAGE_COMPONENTS
;Mode B
!define MUI_PAGE_CUSTOMFUNCTION_PRE onlymodeB
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_PRE onlymodeB
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English

Call Function When Someone Selects a Component on the Component MUI Page

I am trying to add some custom functionality to the MUI2 Components Page.
When the user selects a Component(Checkbox) I want to call my custom function. If the 1st component has bee selected then I want to check/select the 2nd component also.
My code below attempts to code this functionality but I am getting compile errors:
Error in macro __NSD_OnControlEvent on macroline 8
!include nsdialogs.nsh
!include MUI2.nsh
!define MUI_PAGE_CUSTOMFUNCTION_SHOW compshow
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
OutFile "test.exe"
Function OnCustomisationComponentClick
#SendMessage 1032 ${TVM_SETITEM} 0 $someTVItem
MessageBox MB_OK "abc"
FunctionEnd
Function compshow
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $0 $0 1032 # 1032 is the Treeview that holds the components
!insertmacro __NSD_OnControlEvent ${TVM_SELECTITEM} $0 OnCustomisationComponentClick
FunctionEnd
Section "Dummy"
SectionEnd
NSDialogs macros only work on NSDialog pages, the component page is a native NSIS page.
You must use the .onSelChange callback function to handle changes (Use the helper macros in sections.nsh)

Clearing the State of Fields in InstallOptions pages

I'm working on an NSIS installer. One of the requirements is to allow the user to input some information multiple times for multiple different entries (essentially, it allows them to enter server information for as many servers as they'd like). I'm currently recycling the pages by going to this page after my advanced options page:
Function RedirectPage
${If} $addtCheck <> 0 ; Was the checkbox checked?
StrCpy $startedXml 1 ; make this "true"
SendMessage $HWNDPARENT 0x408 -1 "" ; If so, go back
${Else}
Abort
${EndIf}
FunctionEnd
addtCheck checks to see if the checkbox is ticked that recycles the page. If so this function causes the previous page to be displayed again. The problem is that the fields contain the information that the user just entered. Now, what I want to do is to clear the State of all of the fields of the previous page before they go back to it. I have tried doing something like this,
!insertmacro MUI_INSTALLOPTIONS_WRITE "ioAdv.ini" "Field 2" "State" ""
but it doesn't seem to allow me to clear the state. I know of the SendMessage and GetDlgItem commands, but am unaware of any methods that allow me to use them to clear the text boxes, check boxes, and list boxes of contained in the InstallOptions INI file.
Anyone who can point me in the right direction, thanks. If you want to see any more of the script, let me know.
So you should have the controls in the ini like this:
[Field 1]
Type=Label
Left=15
Top=7
Right=112
Bottom=16
Text=Text 1
then you can get a handle on the field like this:
ReadIniStr $0 $PLUGINSDIR\page_ini.ini "Field 1" "HWND"
So then you can use the SendMessage command with $0 like this:
SendMessage $0 ${WM_SETTEXT} 0 "STR:$InitialString"
This example should work on Text Boxes, for the other controls see the following:
In the NSIS Installation Path under "Include" there is the File Winmessages.nsh with the Message Keys to use.
In my tests i found the key for setting checkboxes:
SendMessage $0 ${BM_SETCHECK} 0 "0"
For ListBoxes i found: (untested)
LB_RESETCONTENT
LB_SELECTSTRING
Hope that helps.
PS: If you have any questions or critisism, please let me know.
PPS:
Alternatively, you could use the nsDialogs Macros with the HWND handle, i.e. for the Checkbox:
${NSD_Uncheck} $0
More Information to this Macros are here:
nsDialogs Readme - Macros
You can use SendMessage to reset each control but then you have to handle different types of controls, it is much better to just reset the .ini:
page custom custdircreate_1
page directory dirpagecreate
Function custdircreate_1
SetOverwrite on
!insertmacro INSTALLOPTIONS_EXTRACT "ioAdv.ini"
SetOverwrite lastused
!insertmacro INSTALLOPTIONS_DISPLAY "ioAdv.ini"
FunctionEnd
Function dirpagecreate
SendMessage $HWNDPARENT 0x408 -1 ""
FunctionEnd
..or reset the state and keep everything else:
Function custdircreate_2
; INSTALLOPTIONS_EXTRACT was called in .onInit
!insertmacro INSTALLOPTIONS_READ $1 "ioAdv.ini" "Settings" "NumFields"
StrCpy $0 1
loop:
!insertmacro INSTALLOPTIONS_WRITE "ioAdv.ini" "Field $0" "State" ""
IntOp $0 $0 + 1
IntCmpU $0 $1 loop loop
!insertmacro INSTALLOPTIONS_DISPLAY "ioAdv.ini"
FunctionEnd
(This will reset link and button controls so filter those out of the loop if required)

Resources