Archive: nsdialogs - Any way to override/get a callback on the <Cancel> button?


nsdialogs - Any way to override/get a callback on the <Cancel> button?
Hi all,

I was wondering if there was any "new" way of overriding or getting a callback on the button press of <Cancel> ?

The old method was to provide an override to the Abort function, specifically:

!define MUI_CUSTOMFUNCTION_ABORT "CustomAbort"

However, I was hoping that maybe now with nsdialog, we might be able to register a Abort callback on a per page basis, rather than a global Abort function that would get called from any page when the user presses <Cancel> ...

I have some code that I use to override the text <Cancel> to <Skip> on a specific page, and if they press <Skip> (Cancel), I skip forward a page, rather than Abort the whole Installer...

I was hoping things might have changed so that I don't have to install a global handler for <Cancel>...

Thanks!
Scott


I guess we need a function nsDialogs::OnCancel here. I wonder if it's possible...
In the meantime this workaround should do the trick:

EDIT: In order to work even if a control has triggered before the cancel button, it needs a pop in every function that is called by the controls, see bellow the edited scenario.

showinstdetails show
outfile test.exe

!include nsdialogs.nsh

page license
page custom myFirstCustomPage
page custom mySecondCustomPage
page directory
page instfiles


var myFirstCustomPage
var mySecondCustomPage


Function myFirstCustomPage

nsDialogs::Create /NOUNLOAD 1018
Pop $myFirstCustomPage

${IfThen} $myFirstCustomPage == error ${|} Abort ${|}

${NSD_CreateGroupBox} 0u 10u 100% 50% "This is my first custom page:"
Pop $0

${NSD_CreateRadioButton} 10 25u 40% 12u "button 1"
Pop $R0

${NSD_CreateRadioButton} 10 45u 40% 12u "button 2"
Pop $R1

${NSD_AddStyle} $R0 ${WS_GROUP}

${NSD_SetState} $R0 ${BST_CHECKED}

${NSD_OnClick} $R0 myfunc

${NSD_OnClick} $R1 myfunc

GetDlgItem $myFirstCustomPage $myFirstCustomPage 1200

nsDialogs::Show

FunctionEnd


Function mySecondCustomPage

nsDialogs::Create /NOUNLOAD 1018
Pop $mySecondCustomPage

${IfThen} $mySecondCustomPage == error ${|} Abort ${|}

${NSD_CreateGroupBox} 0u 10u 100% 50% "This is my second custom page:"
Pop $0

${NSD_CreateCheckBox} 10 25u 40% 12u "checkbox 1"
Pop $R0

${NSD_CreateCheckBox} 10 45u 40% 12u "checkbox 2"
Pop $R1

${NSD_SetState} $R0 ${BST_CHECKED}

${NSD_SetState} $R1 ${BST_CHECKED}

${NSD_OnClick} $R0 myfunc

${NSD_OnClick} $R1 myfunc

GetDlgItem $mySecondCustomPage $mySecondCustomPage 1200

nsDialogs::Show

FunctionEnd


Function myfunc

pop $1

FunctionEnd


Function .onUserAbort

Pop $0
${If} $0 = $myFirstCustomPage
MessageBox MB_OK "I'm gonna do crazy things now..."
${ElseIf} $0 = $mySecondCustomPage
MessageBox MB_OK "Now what?"
${EndIf}

FunctionEnd


section

sectionend

Can't edit the damn thing above :(
The function .onUserAbort:

Function .onUserAbort

Pop $0
${Unless} $0 == ""
${If} $0 = $myFirstCustomPage
MessageBox MB_OK "I'm gonna do crazy things now..."
${ElseIf} $0 = $mySecondCustomPage
MessageBox MB_OK "Now what?"
${EndIf}
${EndUnless}

FunctionEnd

Thanks RedWine.

Yeah, I was hoping we could do away with the whole global function to trap Cancel events on any page.

It would really be nice to be able to register a "cancel_function" callback per page, like we can with the "leave_function" when we call the "Page" function.
ie, maybe we could change:

4.5.4 Page
custom [creator_function] [leave_function] [caption] [/ENABLECANCEL]

to:

4.5.4 Page
custom [creator_function] [leave_function] [cancel_function][caption] [/ENABLECANCEL]


Hmmm, just looking at the nsdialog code, this should actually be pretty trival to do!

There is already code to trap the <Back> button with "onBack".

Surely we can add one to trap the <Cancel> button as well.

Assuming I can get NSIS to compile, I will try adding this code tonight/tomorrow.


Well, I got it half done.
I can get the callback into OnCancel, but there is some stuff in exehead/Ui.c that causes NSIS to bail regardless if we Abort the Cancel or not.
But here is a small patch for the half I did get done so far:

===================================================================
RCS file: /cvsroot/nsis/NSIS/Contrib/nsDialogs/nsDialogs.c,v
retrieving revision 1.5
diff -r1.5 nsDialogs.c
36a37,43
> if (wParam == (WPARAM) 120)
> {
> if (g_pluginParms->ExecuteCodeSegment(g_dialog.callbacks.onCancel - 1, 0))
> {
> return 0;
> }
> }
390a398,402
> void __declspec(dllexport) OnCancel(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra)
> {
> SetDialogCallback(DLG_CALLBACK_IDX(onCancel));
> }
>


===================================================================
RCS file: /cvsroot/nsis/NSIS/Contrib/nsDialogs/defs.h,v
retrieving revision 1.2
diff -r1.2 defs.h
25a26
> nsFunction onCancel;