Archive: License page


License page
Hiya folks,

Is there a script-based way to detect UI interaction events (callback functions) and manipuate UI components?

I want to have a standard "professional" license page in which there are 2 radio buttons ("I accept" / "I don't accept"), with the latter selected by default - and instead of the current "I Agree" button there will be a "Next >" (disabled if "I don't accept" is selected).

I can easily create the radio-button UI resources in an exe file (a most powerful feature in NSIS 2, wheeee!), rename "I Agree" to "Next >", and as far as I remember I can disable that button on will with window messages (right?). My only problem is catching click events in the radio buttons...

Any ideas?

And if not, I'd like to propose this stuff (license page + UI interaction) on the feature list.

Lastly, if there some rough idea when NSIS 2.0 will become official and feature-complete?

Thanks a bunch!


> as far as I remember I can disable that button on will with window
> messages (right?)
SendMessage WM_ENABLE with a wparam of TRUE or FALSE (enable & disable) respectively and a lparam of zero.

We could do with .onWindowEvent or somesuch I guess, is that feasible do you reckon KiCHiK (or even necessary?), you're most likely to know.

> .. NSIS 2.0 will become official
Justin is looking at making an official 2.0 release at the moment, I'd imagine it's a lot of work considering how much has gone into the unofficial 2.0ax branch.

> feature-complete?
It's not gonna stop until it takes over the world muahahaha! :D (but using DLLs & scripts of course, none of that nasty bloatware :))


Hello there fellow Israeli :D

I guess I could add a callback such as .onWindowEvent that will be called whenever you get WM_COMMAND, that would make sense now that you can customize the UI.

But (there is always a but :D), it won't help you here. You can't enable or disable anything with WM_ENABLE. WM_ENABLE is only sent by the EnableWindow function after it has done its stuff.

Luckily for you, it will be very easy to emulate EnableWindow because for the static control background color I have already added SetWindowLong so you can set the WS_DISABLED style. But (yet another one) you also need GetWindowLong to get the old style so you can or with it.

Wouldn't it just be simpler to add EnableWindow you ask? Yes, it would :)
But (third one but [fourth] who's counting?) it will be hell of a lot simpler to just add .onVerifyLicense, but not as useful.

I am for the .onWindowEvent and EnableWindow thingy, what do you all think?


"Attack of the Yerushalmim". heh. :) </offtopic>

Sorry. ;)


Originally posted by kichik
I guess I could add a callback such as .onWindowEvent that will be called whenever you get WM_COMMAND, that would make sense now that you can customize the UI.

Luckily for you, it will be very easy to emulate EnableWindow because for the static control background color I have already added SetWindowLong so you can set the WS_DISABLED style. But (yet another one) you also need GetWindowLong to get the old style so you can or with it.

Wouldn't it just be simpler to add EnableWindow you ask? Yes, it would :)
Hmmm... I browsed I little through MSDN, got a sickly feeling, thought about the beauty of the Java language and the simplicity of its documentation, and here are my $0.02:

1. I am *SO* happy I don't have to code in VisualStudio on a daily basis anymore!

2. What will ".onWindowEvent" return actually?

3. My vote goes to EnableWindow, but... (Ha! I can do it too! :D )

The 4 most common functionalities for controls are: show/hide, enable/disable, select/deselect (radio buttons / checkboxes), and set/kill focus. I think NSIS should support them all.

The Jerusalem Mafia lives on! :)

What will ".onWindowEvent" return actually?
Why should it return anythnig? NSIS functions can't return anything anyway :)
You will get wParam and lParam and do whatever you want with it.

Originally posted by kichik

Why should it return anythnig? NSIS functions can't return anything anyway :)
You will get wParam and lParam and do whatever you want with it.
That's what I was talking about - what is the meaning of the wParam and lParam values in this context?

How do I know which specific event fired this callback function, and relating to which control?

You go to this MSDN page and learn all about it :D
http://msdn.microsoft.com/library/en...wm_command.asp


:D Yeah, I already browsed it earlier at work ("Must... survive... Microsoft... Eeeegh... Uuuuggggh...").

Then I went to see what's the deal with that "Chinese" link that Nant mentioned in the NSIS 2 thread... :eek: And to make a long story short, if I'll get fired I'll start porting NSIS to Java as a hobby... :D


Yes, that's how it is with Microsoft :D

.onWindowEvent will basically give you the control id and the notification code (pushed, selected, etc.) and you will do with it whatever you want.


kichik wrote on 09-09-2002 08:05 PM:
I have been thinking about it a lot. There is a problem with it, in the install log there are two threads. If I give the UI thread an option to mess itself with NSIS functions, the installer thread wouldn't work as it should, would cause crashes, and would basically suck. Should the installer log not have a callback function?
I'm not sure I understand what you mean by "install log": the optional log that can be generated during the installation? the installer workflow?

Anyway, I think that NSIS already has some "dangerous" features, but they're mild and optional - and this is a good model in my opinion.

Take ".onVerifyDirectory" as an example: it doesn't crash anything if used incorrectly, but it can certainly cause a lot of troubles - so you don't have to use it, and if you do you get a decent warning in the NSIS help.

As for possible crashes - can you elaborate? Give some example scenarios? If the installer is multi-threaded, where's the problem?

The problem is that NSIS uses static buffers to execute instructions, that is, if two instructions are executed simultaneously, they will both use the same buffer at the same time, each will set it to what it needs, and non will work as should.

I'm not sure I understand what you mean by "install log": the optional log that can be generated during the installation? the installer workflow?
Nope, the visible install log, what the user sees.

Anyway, I think that NSIS already has some "dangerous" features, but they're mild and optional - and this is a good model in my opinion.
This is very dangerous, a lot of commands will not work, or get corrupted. Files can be extracted into places you never wished them to, files can get corrupted, your script will just not work as should.

Take ".onVerifyDirectory" as an example: it doesn't crash anything if used incorrectly, but it can certainly cause a lot of troubles - so you don't have to use it, and if you do you get a decent warning in the NSIS help.
It isn't executed with something else at the same time. If there was another NSIS code piece executed at the same time, it just wouldn't work.

As for possible crashes - can you elaborate? Give some example scenarios? If the installer is multi-threaded, where's the problem?
If one instruction sets a buffer to a number bigger than the installer size and then the File instruction comes and look for the file, and it has the file location in the installer in that buffer, it might read from a memory that does not belong to NSIS and crash NSIS.

Like I said, I still need to think of the best way of doing this.

Ah, I see now... The classic "Thread-safe by assumption" trick, and then you break the assumption. I also read your recent stuff about .onInitDialog... I see the gravity of the problem :(

<useless-preach-mode>
That's why I like Java so much, you don't have to bust your ass to have global, thread-safe data
</useless-preach-mode>

I guess I'm being silly because I haven't even glanced at the code, but why not just implement a mutex on that instructions buf? Worst-case scenario, the installer will appear to be stuck while a blocking command is being processed (ExecWait for example) which will slow things up, but the obvious logic is that it won't be stuck forever or the user shouldn't have used that blocking command in the first place...

Well, not exactly 100% worst-case, and anyway it gets far more complicated with a multiple buffers... Yep, I see your point. :cry:


Has anything happened with this? I'm using EnableWindow in my script right now, but I need .onWindowEvent.

I have added two radio buttons and a checkbox to my license (actually a readme) page. The radio buttons allow you to choose installation type A or B, and the checkbox is a sub-option for type B. I would like to disable the checkbox when the user selects type A. I would use a custom page, but I couldn't get the InstallOptionsEx RichEdit to work (It only displayed the first line, even though MULTILINE was set). Is there any way I can get the change event for the radio buttons in current NSIS?


Not without writing a plugin in Delphi or C/C++.

-Stu