I have a script dialog with several checkboxes that are initialized between dlg.Create() and dlg.Show(). Each of those results in a click event, although the dialog isn't visible yet. And since it's a fairly complicated dialog with interdependent controls, it's a pain to figure out how to ignore those clicks. My current workaround is to count the number of initialization "clicks" and then to ignore the first n events that are generated, but that doesn't seem very reliable.
I understand that those events come from Windows and are only passed through by DOpus, but I found an old thread from 2016 where Jon announced they would be blocked with the next update. Somehow they seem to have snuck back in... Is there something you can do against that?
FWIW, I have some scripts that actually relies on that behaviour, Thus there will also be other users in the same scenario. I don't think it's a good idea to break existing scripts by changing this.
That said, personally I don't think what was you mentioned is an error either, since technically you are changing the checkbox value after it has been created, so it shouldn't make any difference if you change the value later. (your script should have the wording implemented for that change by the user anyway)
If you want those controls to start with a fixed value, you can set that value as default, or change it once the dialog is created, and process the change as if it were a change made by the user.
In my experience, if multiple controls changes can trigger an event, it's good practice to use timers instead of processing them directly.
I have to admit I didn't consider this possibility since for me this behavior was clearly undesirable. In the ui projects I've been involved in we always made it a point to give each control its explicit initial value and then start the event queue. So relying on controls "initializing each other" never came into play. Different philosophies, I guess.
But considering this I fully agree with you: Changing the mechanism now would potentially break existing scripts. A solution might be something like
dlg.Flush()
to clear all messages or an additional flag in
dlg.GetMsg(true)
to immediately retrieve all currently existing messages (even if none exist). Either of those could be called before the dialog is shown to ensure a clean start.
Or maybe
dlg.Show(true)
to clear pre-existing messages?
In my mind everything I do before showing the dialog is the initialization and has nothing to do with any user interaction and the logic involved with it. Obviously, a hard-coded default doesn't always work, so making changes after dialog creation is a necessity. Again, I guess it's just a different approach and not worth fighting over.
Yes, different philosophies is something very common.
I'm not sure if this applies to checkboxes, but if you only want to react to events triggered by user interaction, you can check if the control has focus at the time of the event (with msg.focus).
That said, I think a golden solution that doesn't break existing scripts and doesn't continue with this confusion would be a new option when creating the dialog in the Script Editor, where you can specify if a control can produce events from the moment it is visible (when using dlg.Show()) or from when it is initialized (when using dlg.Create()). Not sure if that's technically possible though.
Oh, that's an excellent idea; I might try that as a workaround.
Yes, that would be another good solution.
ATM I think I'd favor dlg.Flush() because it's the most versatile. I can't think of one right now, but there might be more situations where this command could come in handy.