I’m not sure if this is a bug or I’m just doing something that should obviously be forbidden but I’ve found that if a MsgBox call is made during a canvas Paint event the app crashes.
- Create a new desktop app,
- Add a Canvas control to the window
- Add the Paint event to the canvas
- In the Paint handler type MsgBox(“Test”)
- Then run the app.
I get an instant crash each time.
Canvas.Paint event should be used to draw and not to call a
MessageBox. You can also call the
MessageBox using the
Paint should be for drawing code only, even try to avoid doing calculations as every slow down in the paint event, affects the application’s redraw ability. Interjecting a Modal dialog, will cause the paint event to be stopped, which as you’ve found causes things to go wonky.
The only exception to this rule is setting label colors to match theme colors with a Xojo made application. Xojo uses rasterized colors (not color constants) and the only time you’re pretty sure that the color constant is correct for rasterization is during a paint event.
This came up recently. A bug report already exists.
Thanks all for the replies.
Yes, I can see why it is a philosophically bad thing to do but I have a semi-legitimate reason for doing it - or so I claim.
Nonetheless, I’d be happier if it threw an exception rather than crash the app completely.
This may not be something that Xojo can capture, as the crash may be occurring in the bowels in the system (which change almost yearly as Apple accelerate the merger of macOS with iOS).
If Xojo can raise an exception for trying to inject any GUI action that may cease the paint event, without the action of raising an exception having the same result, I am all for it. @Greg_O_Lone would be the most likely candidate to tell you if this is possible or not.
maybe you do this for debug purposes? If so, use Bleep or system.debug instead.
It would be nice if there would be a flag to check in order to know whether you are in a paint event.
It is a design flaw.
What do the Paint Event does ?
Refresh the Canvas contents.
How many times does it do that ?
I do not know, but as often as needed, I suppose.
So, hw one will place there a Message Box (or display anything lke a window - or dialog, or…) ?
The result will be a ton of MessageBox(es) displayed ad nferno to the user.
Just like if you do the same in a long, very long loop !
You better follow System.DebugLog way to get debug information.
Sure, but paint may invoke some code where I put a msgbox to report a problem.
If CurrentMethodname.IndexOf(".Paint") > -1 then
// in the paint event
Still the messagebox is blocking the paint event. Doing the exact thing that should not be done in the paint event; blocking…
Again, not directly invoked.
The paint method may ask some class for a property and the method has a check to show msgbox with some condition not being met. Crashes.
It’s simple: Now you know it doesn’t work.
I don’t think it’s illogical at all; if you text while driving at 200 km/h, you’re not surprised when it „crashes“, are you?
It doesn’t crash in Windows
What works on one plattform, doesn‘t work on another platform is expected, isn‘t it?
The reason I wanted to do this is that I am reverse engineering a file structure and painting it to a canvas. As I do this, and the file structure evolves in the future, I am bound to come across file elements that I haven’t handled and I’m using message boxes to flag when the app finds such a file element.
Yes, message boxes are not the right way to debug but this isn’t just debugging because it may be users who find these unhandled elements and they cannot me expected to check system console output. They need an “in their face” message to contact me so I can deal with it.
Yes, I could validate and prepare all data before it reaches the paint event, and that’s probably the best way to do it. However, this isn’t a commercial app, it’s just something I’m knocking together quickly as a freebie for anyone interested so I was hoping to not have to do all of that extra work.
Defintely the right way until you have an event called „ValidateAndPaint“
If you’re not going to validate the data before painting (which you should), then you can use System.DebugLog to send strings to the Messages pane of the IDE:
System.DebugLog( "Test" )
If this means that the error message gets displayed to the user and not just in your coding environment then you should probably track in a flag somewhere that an error has occurred and save the message as text elsewhere outside of the Paint event. A timer, which you turn off at the start of the Paint event and back on at the end, could then poll the variable for the error flag and pop up a messagebox then if an error had been detected.
What’s important is that the Paint event be allowed to finish before doing something that can block it or cause a re-entrant situation.
He already said that the messages need to be at RUN TIME and in the end user computer, not in his IDE.
Well, the lazy way to do it could be having a string Variable in your app (errmsg), clear ir at the start of the paint, on each problem append the message, at the end of the paint code, check if the variable is empty and if has some text, activate a timer to show the msgbox with this text outside the paint code.