Archive: How to write a function?


How to write a function?
sorry for the dummy question but NSIS still looks like martian to me (or worst, venusian!)...

Anyway I found this in 'makensis.nsis':
======
ReadRegStr $R0 HKCR ".nsi" ""
StrCmp $R0 "NSISFile" 0 +2
DeleteRegKey HKCR "NSISFile"

WriteRegStr HKCR ".nsi" "" "NSIS.Script"
WriteRegStr HKCR "NSIS.Script" "" "NSIS Script File"
WriteRegStr HKCR "NSIS.Script\DefaultIcon" "" "$INSTDIR\makensisw.exe,1"
ReadRegStr $R0 HKCR "NSIS.Script\shell\open\command" ""
StrCmp $R0 "" 0 no_nsiopen
WriteRegStr HKCR "NSIS.Script\shell" "" "open"
WriteRegStr HKCR "NSIS.Script\shell\open\command" "" 'notepad.exe "%1"'
no_nsiopen:
======

How could I:
1. make this a function which takes 3 parameter
1 para for extension (.nsis), 1 for app name (NSIS.Script), 1 for description (NSIS Script File)
(could you show me how to use the parameter as well)

2. How could I call this function (once it is done)?


I also read on another post I should call that if I want the icon of my files to be updated without rebooting:
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_DWORD, NULL, NULL);

but if I write this in the NSIS file, that (of course) doesn't work, any tips?


In NSIS, functions don't take parameters.

I know. It's weird.

You can use macros instead. A macro's code is not called at runtime, it is inserted at compile time. This makes some extra tricks possible.

To make a macro:

!macro NAME PARAM1 PARAM2 ; ... any additional params
; your code here...
!echo "Parameter 1 is ${PARAM1} (param2 is ${PARAM2})"
!macroend
As you can see, referencing parameters is quite easy - you can do anything you want with these types of variables. Any variable that has braces around it - like ${THIS_IS_A_SYMBOL} - can contain code, a string, a prefix such as "un.", or anything - its value is set at compile time. This allows you to (for example) make your own commands:
!macro SOME_MACRO PARMS
MessageBox MB_OK "${PARMS}"
!macroend
!define SomeMacro "!insertmacro SOME_MACRO"

Section
${SomeMacro} "This is the text that goes on the message box"
SectionEnd
To define a global symbol, use:
!define SYMBOL_NAME "Value"
In macros, the parameters are accessed the same way symbols are - but the macro parameters don't exist outside of the macro.

And to refresh the shell icons: (use this only in a section or function)
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'


One last hint - code in macros is not processed (compiled) until the macro is inserted. You can have any gibberish you want in a macro, as long as you don't insert it.

-dandaman32

thanks dandaman32, that's very helpfull....


Well, functions do not take parameters as default, but you can do so by using the run-time stack along with a compile-time macro.

Example:


Function MyFunc
Exch $R0 ; get 3rd param
Exch
Exch $R2 ; get 2nd param
Exch
Exch 2
Exch $R2 ; get 1st param
Exch 2
Push $R3 ; save value of $R3 before use in this function

IntOp $R3 $R2 * $R1
IntOp $R0 $R3 + $R0

Pop $R3 ; set old value of $R3 back
Pop $R2
Pop $R1
Exch $R0 ; return output
FunctionEnd

!macro MyFunc ReturnVar Param1 Param2 Param3
Push "${Param1}"
Push "${Param2}"
Push "${Param3}"
Call MyFunc
Pop "${ReturnVar}"
!macroend
!define MyFunc '!insertmacro MyFunc'

Section "Call MyFunc"
${MyFunc} $R0 10 9 3
; at this point, $R0 == 93
SectionEnd


Yes it is long, but using a macro to insert the actual code (rather than placing the code inside a function) means that the code will be inserted again for each !insermacro instruction you use.
Placing the code in a function will mean that the code is only included once and this will decrease the installer overhead (in theory).

-Stu

Man, no wonder Afrow UK, you are a forum king!

...this was helpfull info, even for me, to refresh my memory just in a night when I need it.. deep into debugging my NSIS script, thanks!


in nsis functions work like in asm :)
they get their "parameters" by the stack.

in oldschool nsis (below 1.x series), plugin calls worked the same way. in nsis2 this has been changed to the parameter syntax like used in other script languages, but just for plugin calls.