Archive: Selectively display pages?


Selectively display pages?
I'm trying to write an installed using the ModernUI that selectively displays certain pages. In particular the installation directory page. I want to create a single installer that can either install my program, or update an existing install (finding its directory from a registry key). If it finds that registry key, I obviously don't need to be asking the user where to install the program, because the key tells me, and worst of all, if the user tries to change it, things won't happen as they'd expect.

I've been trawling through the MUI include file to find some clues but it's incredibly hard to follow with so many function and macro names and calls being defined by variables (shouldn't this be illegal?) and very few comments.

How can this be done?


Add abort in MUI_PAGE_CUSTOMFUNCTION_PRE


That's got it! :up: Except there is no MUI_PAGE_CUSTOMFUNCTION_PRE in the include file, instead it's hidden behind a myriad of macro's and functions using variables in their name declarations. So it's more like:


!macro MUI_FUNCTION_LICENSEPAGE PRE SHOW LEAVE

Function "${PRE}"
abort
...
FunctionEnd

...

!macroend


I'll probably be back with more questions later. :D


Hang on, I think I see now what you meant, more like:

!define MUI_PAGE_CUSTOMFUNCTION_PRE MyCustom
; License page
!insertmacro MUI_PAGE_LICENSE "mylicensefile.txt"


Where MyCustom is a function that contains abort, or the code to check if it should be aborted.

Except there is no MUI_PAGE_CUSTOMFUNCTION_PRE in the include file, ...
Cute ;)
What about taking a look on MUI documentation?

http://nsis.sourceforge.net/Docs/Mod...ustomFunctions

Originally posted by Red Wine
Cute ;)
:confused:


Referring to my above edit, I got that now. The scripting language in NSIS is totally new to me, so that it even has function pointers is a bit of a surprise.

I'm trying to understand the underlying operation here, I can see that...


!macro MUI_FUNCTION_LICENSEPAGE PRE SHOW LEAVE
Function "${PRE}"
!insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
...
FunctionEnd
...
!macroend


Calls


!macro MUI_PAGE_FUNCTION_CUSTOM TYPE
!ifdef MUI_PAGE_CUSTOMFUNCTION_${TYPE}
Call "${MUI_PAGE_CUSTOMFUNCTION_${TYPE}}"
!undef MUI_PAGE_CUSTOMFUNCTION_${TYPE}
!endif
!macroend


Which in turn calls whatever function I've defined MUI_PAGE_CUSTOMFUNCTION_PRE to point to. But what I can't figure out is how this:


PageCallbacks ${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}...


Ends up calling this:

!macro MUI_FUNCTION_LICENSEPAGE PRE SHOW LEAVE
Function "${PRE}"
...


I can see by the behaviour that it does, but I don't understand the translation of "${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}" to that function.

That last macro gets "${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}" as PRE and creates a function named ${PRE}. That function is defined by PageCallbacks as the pre callback function of the page and is therefore called by the paging system.


Originally posted by kichik
That function is defined by PageCallbacks as the pre callback function of the page and is therefore called by the paging system.
I understand that part, because it's like any callback or function pointer. What I don't follow is the function signatures. I've been an OO programmer for quite a while now, and I've been used to recognising function calls by their signature. So you'll have:
public void MyFunction(someparams)
{
// Declarations in here
}

and call it by:
MyFunction(someparams);

I don't understand how the call "${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}" gets to:

!macro MUI_FUNCTION_LICENSEPAGE PRE SHOW LEAVE
Function "${PRE}"

The names are completely different, the signatures don't match. Is there an intermediary involved that I'm not seeing? Does it have something to do with this line?

!insertmacro MUI_FUNCTION_LICENSEPAGE${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}
${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicenseShow_${MUI_UNIQUEID}
${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicenseLeave_${MUI_UNIQUEID}

That's explained in the first part of my post that you didn't quote ;)

Again, the MUI_FUNCTION_LICENSEPAGE macro accepts three arguments. One of them is PRE, which is defined as the value passed in !insertmacro. On the macro insertion, "${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}" is passed as the first argument which is PRE. Therefore, when the macro is processed, PRE will be defined as "${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}". In the macro itself, PRE is used as the function name for the pre callback function.


Ok so the answer to:
"The names are completely different, the signatures don't match. Is there an intermediary involved that I'm not seeing? Does it have something to do with this line?"
is yes?

That line:

!insertmacro MUI_FUNCTION_LICENSEPAGE 
${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicensePre_${MUI_UNIQUEID}
${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicenseShow_${MUI_UNIQUEID}
${MUI_PAGE_UNINSTALLER_FUNCPREFIX}mui.LicenseLeave_${MUI_UNIQUEID}

Is used to create the actual functions with their names as defined in that call? So if I changed that to something like:
!insertmacro MUI_FUNCTION_LICENSEPAGE Func1 Func2 Func3

The PageCallbacks line would then be:
PageCallbacks Func1 Func2 Func3

Correct?

If so, then I suppose my last question would be why it's done this way? Why not simply have 3 functions defined as MUI_FUNCTION_LICENSEPAGE_PRE, SHOW and LEAVE?

The answer to first question is yes. There is an intermediary step and it's the macro insertion where PRE is defined as the function name.

The second question also gets a yes. That's how macro parameters work.

Why do it this way? So you can have multiple pages of the same type. That's what ${MUI_UNIQUEID} is for. The other define is for uninstaller pages.