Archive: Call $Var


Call $Var
  Just wondering if it is possible do this within a section?


Call $Var 

>
I have many Functions on a particular installer and have $Var set prior to using Call. However, compilation fails with install function "variablename" not referenced

You could make it one big function with a ${Select} $Var / ${Case} inside it. But why do you think you need this? Functions are defined at compile-time, so function names are as well. Runtime-dynamic function names therefore make no sense.


Thanks for the reply MSG. Here is the situation:

I have a huge dropdown list and of course when the user selects an option a variable is populated.

I have specific functions set for each available item in that dropdown list.

In a section, I currently use If and ElseIf to compare the variable and then call the corresponding section for that selection.

As you can see, the larger the dropdown list becomes, the more of a mess I end up with. I simply want to trim the fat!


What I am trying to do is replace If and ElseIf portions in Section DoStuff with something like Call $ItName

Here is a small example of how the code currently looks. Maybe someone can direct me to a better way to do this?


OutFile "test.exe"

>SetCompressor LZMA
CRCCheck On
XPStyle on
>!include MUI2.nsh

>Var Dialog
>Var Selection
>Var It
>Var ItName

Page custom CustomPage
>!insertmacro MUI_PAGE_INSTFILES

>Function CustomPage
nsDialogs
::Create 1018
Pop $Dialog
${NSD_CreateLabel} 0 0 100% 15 "Choose Something"
Pop $Selection
${NSD_CreateDroplist} 0 20 45% 15 ""
Pop $It
${NSD_OnChange} $It OnSelectIt
${NSD_CB_AddString} $It "one"
${NSD_CB_AddString} $It "two"
${NSD_CB_AddString} $It "three"
${NSD_CB_SelectString} $It $ItName
nsDialogs::Show
FunctionEnd

>Function OnSelectIt
Pop $It
${NSD_GetText} $It $ItName
StrCpy $ItName "$ItName"
>FunctionEnd

>Function "Main one"
>MessageBox MB_OK "One was selected"
>FunctionEnd

>Function "Main two"
>MessageBox MB_OK "Two was selected"
>FunctionEnd

>Function "Main three"
>MessageBox MB_OK "Three was selected"
>FunctionEnd

Section DoStuff
>${If} $ItName == "one"
Call "Main one"
>${ElseIf} $ItName == "two"
Call "Main two"
>${ElseIf} $ItName == "three"
Call "Main three"
${EndIf}
>SectionEnd
>

It seems like you want to decrease the amount of code, but that is of course impossible: You want different behavior for each option, so you need to code each option separately.

Anyway, if you'd make a function for every option, you'd only be increasing the fat, not reducing it. If you want the code out of your nsi file, simply add a macro:

!macro mymacro
${If} $ItName == "one"
Call "Main one"
${ElseIf} $ItName == "two"
Call "Main two"
${ElseIf} $ItName == "three"
Call "Main three"
${EndIf}
!macroend

and save it as mymacro.nsh, then add !include mymacro.nsh to the top of your .nsi and in your section do !insertmacro mymacro.


That is the perfect compromise and solution MSG. The sample I gave above was just thrown together as a single example file. Most probably noticed that it would make more sense to eliminate the Main functions and simply include the if else statements in the section.

My actual installer does use a separate .nsh file containing those Main functions to reduce clutter. However, it appears to have slipped my mind that those could have been condensed into a macro (eliminating redundancy). A simple solution I overlooked.

Thanks for the help MSG!


For anyone else who may be wondering how the completed results look. Here is a finished example:

Test.nsi


OutFile "test.exe"

>SetCompressor LZMA
CRCCheck On
XPStyle on
>!include MUI2.nsh

>Var Dialog
>Var Selection
>Var It
>Var ItName

Page custom CustomPage
>!insertmacro MUI_PAGE_INSTFILES

>Function CustomPage
nsDialogs
::Create 1018
Pop $Dialog
${NSD_CreateLabel} 0 0 100% 15 "Choose Something"
Pop $Selection
${NSD_CreateDroplist} 0 20 45% 15 ""
Pop $It
${NSD_OnChange} $It OnSelectIt
${NSD_CB_AddString} $It "one"
${NSD_CB_AddString} $It "two"
${NSD_CB_AddString} $It "three"
${NSD_CB_SelectString} $It $ItName
nsDialogs::Show
FunctionEnd

>Function OnSelectIt
Pop $It
${NSD_GetText} $It $ItName
StrCpy $ItName "$ItName"
>FunctionEnd

>!include "MainMacro.nsh"

>Section DoStuff
>!insertmacro Main
SectionEnd
>
And MainMacro.nsh


macro Main

>${If} $ItName == "one"
>MessageBox MB_OK "One was selected"
>${ElseIf} $ItName == "two"
>MessageBox MB_OK "Two was selected"
>${ElseIf} $ItName == "three"
>MessageBox MB_OK "Three was selected"
>${EndIf}
!macroend
>