Archive: FlipPages - Paging non-linearly between custom pseudopages


FlipPages - Paging non-linearly between custom pseudopages
I stumbled across a script I started many years ago that was supposed to let me move an overly complex installer back-and-forth between custom pages non-linearly;
you know the kind: you have a main page with components with sub-settings, let the user configure that component in further pages, and you want to end up back at the main page. Could 'solve' that with a secondary installer that gets run and stores the settings somewhere (temp file, registry, etc.), or you could get tricky..

..but then deguix wrote the RelGotoPage function ( http://nsis.sourceforge.net/Go_to_a_NSIS_page ) and I quickly dropped what I was working on.

Nevertheless, when I saw it again I thought I'd give it a renewed shot now with the awesomeness of nsDialogs.. and lo-and-behold it actually works.


I can't think of any -good- reason to use it given RelGotoPage's existence (although I think a recent post mentioned a crash, I suspect that's user error.. but who knows), but I'm dropping it in here anyway. It's a complete example script, rather than an implementation guide, but figuring out what goes where should be pretty self-explanatory (there's comments, of course).


I noted at the top (and in the thread title) that it was a method to move between custom pseudopages (the FlipPages) - so just to stress that... it can -only- be used to move between FlipPages within a single Custom Page - not any built-in or MUI or whatnot pages.
So if you have a typical flow (using, say, MUI) might look like:
1. MUI Welcome page
2. Custom Page with FlipPages
2.1 FlipPage 1
2.2 FlipPage 2
2.3 FlipPage 3
3. MUI Components Page
4. MUI InstFiles page
5. MUI Finish page
Then you can move around inside 2.x, but page 2 can only go back to page 1 or forward to page 3. Page 4 can't go back to Page 2 (except if it first passes Page 3, of course). Page 1 can go forward to any Page 2.x, just as Page 3 can go back to any Page 2.x, by messing with the current page variable in those pages, though.
Confusing? Good ;)


There's two pieces of hack code in there that I'd like to get rid of, but not sure I can (or want to bother to at this time).

The first is detecting which button was pressed. The überhack method does that by getting the hwnd of the control that currently has focus and comparing that to the hwnds of the next/back/cancel buttons. This does mean that Alt+Letter combinations to access those buttons cannot be used (as they don't change the focus like a mouse-click/keyboard navigation do).. hence re-setting the button texts so that no hotkey accessors are available for those buttons. The slightly less hacky method does it through the WndSubClass plug-in ( http://nsis.sourceforge.net/WndSubclass_plug-in ). Ideally, nsDialogs would store the action that caused it to exit. ( There is an onBack event, but that doesn't trigger until the NSIS custom page end )

The second is getting a custom button to cause navigation to another FlipPage. For this nsDialogs needs to exit.. the most logical option there was to 'press' the Next button by making NSIS believe the next button was pressed using BN_CLICKED in a Sendmessage.


For the code to make everybody flee back to RelGotoPage like I did those years ago, hit the ZIP attachment.


Originally posted by Animaether
The first is detecting which button was pressed. The überhack method does that by getting the hwnd of the control that currently has focus and comparing that to the hwnds of the next/back/cancel buttons.
I circumvented this problem by defining a PAGE_NUMBER for every defined page, and before I jump to another page I set a PREVIOUS_PAGE variable to the page I'm about to leave. I then use this variable to see whether I should skip 'ahead' or skip 'backward'. This can make your page functions rather messy, though.

Originally posted by MSG
I circumvented this problem by defining a PAGE_NUMBER for every defined page, and before I jump to another page I set a PREVIOUS_PAGE variable to the page I'm about to leave. I then use this variable to see whether I should skip 'ahead' or skip 'backward'. This can make your page functions rather messy, though.
I'm pretty sure that doesn't apply to the FlipPages (pseudo pages inside a regular page) - maybe I'm mistaken, though?

If you're referring to regular pages, shouldn't you have enough info from the .onUserAbort and nsDialogs::OnBack callbacks? (Next being the one left if the other 2 aren't what triggered a page change).

Originally posted by Animaether
I'm pretty sure that doesn't apply to the FlipPages (pseudo pages inside a regular page) - maybe I'm mistaken, though?

If you're referring to regular pages, shouldn't you have enough info from the .onUserAbort and nsDialogs::OnBack callbacks? (Next being the one left if the other 2 aren't what triggered a page change).
Ah, very true. I stand corrected. :)