Understanding Paint Event Precedence and Timing in Win32 Builds

One of my applications has a pretty complex UI, with stuff like the following (I’ll attempt to show hierarchy of UI elements with indentation):

Window
   Canvas (to have custom background)
         Page Panel
             Page 1: 
                 Page Panel: 
                      Page 1: 
                         Container Control
                            Canvas*
                            Buttons
                            Listbox
                      Page 2:
                         Listboxes
                         HTMLViewer
                         Canvases
                         Buttons
                Page 2:
                     Another Page Panel similar to the one on the first page
                Etc.

The issue I’m having is that I’m getting stuff drawing in the wrong order: The Canvas* on the first page of the deepest page panel are painting before the custom background canvas… so when the window finishes painting, all I see is the background canvas where the Canvas* should be. The other items on that container control are not affected… the buttons, listboxes, etc show up as they should. This only happens with certain code paths - anything that changes the value of the page of the innermost page panel causes my Canvas* to disappear. Hitting buttons on the same container control where Canvas* live makes the Canvas* reappear.

This is only happening on Windows (7-10), and only with the latest Xojo release.

How can I get the paint events to fire in the correct order so that my Canvas* is drawn last?

You can always prevent Paint to execute by placing a return as first line.

With a clever use of flags, you can very well make sure a canvas is drawn last, either by invalidating it from another canvas, or by using a Timer, and setting the value of the flag.

If dontDraw then return

Could the implementation of Direct2D have changed the order of drawing ?

The simple answer to that question is: you can’t.
Burying canvases deeply into page panels is always a recipe for headaches. I’m sure you’re not willing to refactor your code at this point, so I think Michel’s suggestion of “clever use of flags” might be your best path.

Ugh. Thanks for the responses, guys. I was afraid of that.

Refactoring to solve this is out of the question…

Guess I’m doing the timer / flag dance.

Before that I would wait.
Make a test project and report a bug if you can demonstrate it.
Release app with older Xojo version.
If it gets fixed for 2017 you don’t need to rewrite app.

I’ll go back to building with prior version of Xojo first, if that does not fix it, I have to move forward with something to get the behavior working correctly…unfortunately timelines / deadlines don’t give me the time to burn a day re-creating the drawing behavior. The example I provided above is vastly simplified in order to convey the idea of lots of nested stuff… my actual UI is hugely more complex.

IF they are actually parented as indicated they should draw back to front
And they do here in a sample I put together to mimic your earlier project layout explanation
Certainly in 2016r4.1 they do at least on the initial paint
I just put system.debuglog calls in paint events and watched them in DebugView on Windows 10 and Windows 7

The IDE would be completely borked if this was not true as its containers in containers in containers (at least 3 maybe 4 layers deep in some cases) and we do use a couple page panels too

@Norman Palardy - I have multiple ways / times that paint can get fired… when switching to the tab, manually calling invalidate on a canvas, or one of the parent controllers, etc. I am quite certain that I’m doing something unexpected (invalidating a canvas on a tab panel before switching to that tab, for example…will the canvas paint 2x that way?)

I found that if I built the app with 2016R3.1, things paint as they are supposed to (i.e., my customers can see their UI)… so as a quick fix that is what I’ve done. I’m planning to dig into this further later this week with 2016R4, after I’ve finished triage for my customers.

One of the really difficult things about this case in particular is that I develop on a mac, but these issues only happen on Windows. I remote debug to several different windows machines on my lan, but each debug run takes about 5-8 minutes just to transfer the app to the target windows machine. The build .tgz file that xojo’s debugger sends over is around 350MB, and it takes F O R E V E R to transfer. So, the “change a line of code, run in the debugger, see if the behavior has been altered, change another line, lather, rinse, repeat” process takes a very long time. This is a large project, and I may have to spend some time tomorrow getting Xojo installed on one of my windows test boxes, and setting up the project on that locally (lots of bits and bobs to get placed in the right places, build scripts to update / modify, etc… headache all around) just so the debug cycles don’t take so friggin’ long.

what I’ve done with the IDE is copy the required source items (frameworks, images, etc) to the target machine then have the remote stub put the exe to be debugged in the right spot so it will use those resources instead of having to send them all across the network
that way I just send the exe + any libs (which we dont have a ton of)

not sure if thats a possibility for you or if the 350 mb is all exe and required libs

maybe remote debug to a VM on your local machine ? do you see this issue there ?
I find that because you never hit the real network its a lot faster
and since my vms run on an ssd they move really quickly for unpacking etc

Since I am developing for Windows and Mac I use Xojo on a windows machine and use remote debugging to mac. It turns out, according to GUI development, that you will face more issues with the Windows version of your project than you’ll see in the OSX version, so you save a lot time consuming remote debugging.

Is there any reason to have a Canvas in Window at the first level ?
You could do the drawing in the Window paint event and remove one level of complication.

[quote=314565:@JrmieLeroy]Is there any reason to have a Canvas in Window at the first level ?
You could do the drawing in the Window paint event and remove one level of complication.[/quote]
I’ve found that the paint event on a window was unreliable for my specific use-case. I put the canvas there in the first place because my early prototypes were having drawing problems where the background of the window would draw over some of the contents. Putting a canvas at the back of the window solved this, until 2016R4. This morning I’m going to be putting a bunch of logging in all the paint events that I care about and test the runtime paint order in a build from 2016R4 vs 2016R3.1.

I understand better now. Had the same issue a few years ago.

As an update for anyone who cares: The paint events appear to fire in the exact same order when building in 2016R3.1 vs 2016R4. Here are some logging screenshots of the paint events I care about… and they are firing in the correct order. But the canvas I care about simply does not show up when I build with 2016R4.