Archive: Disabling Next Btn on Custom Page


Disabling Next Btn on Custom Page
I've searched the forum and found some generic info on hiding a button, but I cannot get it to work on a custom page:

Page custom CustomPage
.
.
.
ReserveFile ${CustomPageINI}
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
.
.
.
Function CustomPage
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_DISPLAY ${CustomPageINI}

(some logic check here)
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 ${SW_HIDE}

EndFunction

I know everything else work because the custom page does indeed display, but the Next button (nor any others I've tried) is hidden by the above code.

Help!


Instead of the following line: "GetDlgItem $0 $HWNDPARENT 1", you should use the HWND key from the specific field found in the INI file using the ReadINIFile instruction as follows:

ReadINIFile $out_var "ini_file.ini" "Field #" "HWND"


Where "#" stands for the field number of the specific control.

deguix: is that new? In my version of installoptions, no such HWND value is written out, and I most certainly -do- have to pop the hwnd of the inner dialog after initializing the installoptions dialog, and then use "GetDialogItem $var $popped_hwnd index(1200+item-1)" to get at the control inside the installoptions dialog.

RossW - do either as deguix said (if your stuff matches his), or read the installoptions docs carefully on customizing the dialogs and whatnot.

The 'Next' button is actually outside of the InstallOptions inner dialog. You can hide it by using:


GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0


Before you initialize/show/create the installoptions dialog. Note that you can't hide it -after- the dialog is shown/created in the function that creates it. You can, of course, unhide the button again in the page's leave function.

I tried

ShowWindow $0 0

but that didn't work, either. For standar pages, it appears you can use the above by defining MUI_PAGE_CUSTOMFUNCTION_PRE function, but what can I do for a custom page?


really no different.. sample files:

test.ini


; Ini file generated by the HM NIS Edit IO designer.
[Settings]
NumFields=2

[Field 1]
Type=Button
Text=This button to be disabled
Flags=NOTIFY
Left=80
Right=170
Top=17
Bottom=32

[Field 2]
Type=Button
Text=Show Next button
Flags=NOTIFY
Left=92
Right=158
Top=33
Bottom=49


.nsi file

!include "WinMessages.nsh"

Name ""
OutFile "Setup.exe"

var hwnd

Page Custom ShowCustom LeaveCustom

Page InstFiles

Section "Test"

SectionEnd

Function .onInit
InitPluginsDir
File /oname=$PLUGINSDIR\test.ini test.ini
FunctionEnd

Function ShowCustom
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0

InstallOptions::initDialog /NOUNLOAD "$PLUGINSDIR\test.ini"
Pop $hwnd

GetDlgItem $0 $hwnd 1200
EnableWindow $0 0

InstallOptions::show
Pop $0
FunctionEnd

Function LeaveCustom
ReadINIStr $0 "$PLUGINSDIR\test.ini" "Settings" "State"

IntCmp $0 0 _next
IntCmp $0 2 0 _abort
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 1

_abort:
Abort

_next:
FunctionEnd

My .ini file doen't have a listing for the 'Next' button - I'm trying to disable/hide the standard one.


the source above doesn't have a "Next" button either - it hides/unhides the standard one.


I guess I'm confused by your .ini file - what are those 2 fields for?


they're just examples.. the first button gets disabled by the script by..


GetDlgItem $0 $hwnd 1200
EnableWindow $0 0


The Next button gets hidden before that by..

GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0


Presumably, you'd want to make the Next button visible again at some point, depending either on user input, or a variable, or somesuch. The example does it by user input - namely clicking that second button..

IntCmp $0 2 0 _abort
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 1


If you just copy/paste them into files and compile it all, it'll make itself much clearer %)

Do I need

!include "WinMessages.nsh"

in order to use ShowWindow? Maybe that was my problem ...


Only if you're using the constants like ${SW_HIDE}. You're not so you don't need to include WinMessages.nsh

-Stu


yeah, sorry.. remnant from my template :)


Animaether - will your example work in MUI? I implemented my custom page based on the documentation in the Modern UI Readme and the ModernUI examples; it looks totally different than yours (e.g. ReserveFile ${CustomPageINI})


For anyone who's interested, the order is important:

; This code hides the Next button
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0

!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_DISPLAY ${CustomPageINI}


While testing I discovered that if I disable the Next button on my custom page (because th prerequisite check turned up a missing dependency), if I click the Back btn to return to the Welcome page the Next btn is still invisible! To get around this, I had to add a custom function to the Welcome page using MUI_PAGE_CUSTOMFUNCTION_SHOW that does this:

GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 1


Yep.. the order is important, as noted before ;)

Before you initialize/show/create the installoptions dialog. Note that you can't hide it -after- the dialog is shown/created in the function that creates it. You can, of course, unhide the button again in the page's leave function.
Your other point is a good one as well, and I'm glad you figured that out :) Happy NSIS'ing!

There's no need to add code to the welcome page callback functions. The code after the InstallOptions call (MUI_INSTALLOPTIONS_DISPLAY) is always executed, even if the Back button was clicked. You can re-enable the button there.

 GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0

!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
!insertmacro MUI_INSTALLOPTIONS_DISPLAY ${CustomPageINI}

ShowWindow $0 8 # ${SW_SHOW}

I think that's "there's no need ... in this case"? Basically what's happening there is that you're re-showing the Next button (8 is SW_SHOWNA?) -after- the dialog is displayed. So although it isn't currently shown, the next time the dialog is refreshed it'll be back.

But should a user have code -on- that dialog that hides the Next button again (for whatever reason), and -then- clicks the Back button, the Next button will happily remain hidden. So in terms of coding practices, wouldn't it be best to make sure the button is visible on the welcome page by means of a pre-fuction for the welcome page?


If you want the button to remain hidden even after the user goes back from the page into the welcome page, so be it. But I don't believe that's the case. And so, it'd be best if the code will be self-contained in the page. If it's on the welcome page, it won't work once you move the page to another location. If, for example, you add another page between the welcome page and this custom page, it won't have the Next button visible or enabled. The user will have to go back to the welcome page in order to get the Next button back.


I'm not quite sure I'm following you... but let's try with a few examples..

Say I'm on the custom page, and I hide the Next button by means of some piece of code on that custom page's Leave function.
Now I press the "Back" button. Whatever page I go back to that came before this Custom page will not not show the "Next" button.

So in whatever page I would go "Back" to, I would have to make sure that the "Next" button does become visible.

Now you mention that "what if there is a page in-between?". Sadly, -that- page would have to have that same "Next" button-showing code.

You are right in that ideally the code to restore the "Next" button would be on the Custom page. Unfortunately, however, the "Back" button doesn't register in the Leave function - so it can't be done there.

Thoughts?


Exactly, it can't be done in the leave function. That's why I suggested to put it in the custom page show function. Notice the code is located after MUI_INSTALLOPTIONS_DISPLAY. There's no reason to require other pages to be aware of the custom's page games with the Next button.


err... I see now where I made an assumption I shouldn't have >_<

I thought the following code would execute immediately:


MessageBox MB_OK "A"
InstallOptions::dialog "$PLUGINSDIR\test.ini"
MessageBox MB_OK "B"

While in reality, "B" messagebox doesn't get displayed until the custom dialog is closed (by means of Next, Back, etc.).

My mistake. Now to go and take advantage of that.