Hi Alex,

fwiw:  I tried with 32-bit 6.11 on Win7 and it messes up also.


On 5/8/2018 6:24 AM, Alex Harsanyi wrote:
I had a look at the application windows using Spy++ and all three windows (the main frame and the two dialog ones) are toplevel windows, as expected; however they are linked together as GetNextWindow/GetPreviousWindow correctly. Unfortunately, I am not very familiar with Windows GDI programming, but I will try to trace the messages to the windows themselves.

I now also have taken a look with Spy.  The problem is that the windows should NOT all be top level.  Per the code, dialog1 should be a child of the frame, and dialog2 a child of dialog1.

On my system, Spy shows:

Window 00010010 "" #32769 (Desktop)
    :
    Window 00320BCC "Dialog 2" #32770 (Dialog)
        Window 001E0C6C "" PLTPanel
            Window 00DF0854 "" PLTTabPanel
                Window 003A052E "Close Dialog 2" PLTBUTTON
    Window 000F03D2 "Dialog 1" #32770 (Dialog)
        Window 00370596 "" PLTPanel
            Window 001806EE "" PLTTabPanel
                Window 0057098A "Open Dialog 2..." PLTBUTTON
                Window 001807D4 "Close Dialog 1" PLTBUTTON
    Window 0017076E "Hello World" PLTFrame
        Window 00430564 "" PLTPanel
            Window 000B03F8 "" PLTTabPanel
                Window 003704DA "Open Dialog 1..." PLTBUTTON
    :

When the dialogs are "closed", they persist as hidden / deactivated windows.


With this organization the GDI  GetNextWindow()  function can't be relied on to find the right focus target.   It doesn't matter that the windows persist when not in use.  Nor does it really matter whether they have a parent and child relationship or are siblings [created in the right order].   But for  GetNextWindow()  to work properly, it *does* matter that they are top level and that there is no "root" application window that is the parent of all the others.


See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633509(v=vs.85).aspx
The important part is right at the beginning:

   /If the specified window is a topmost window, the function searches
   for a topmost window. If the specified window is a top-level window,
   the function searches for a top-level window. If the specified
   window is a child window, the function searches for a child window./

The problem is: every application has at least one top level window.  If the Z-order gets disturbed - say by another application activating momentarily - or if  GetNextWindow()  searches in the wrong direction[*],  then a window belonging to another application may be found. [*] searching next vs previous doesn't matter with only 2 choices, but it does matter with more and when extraneous choices are intermixed.

Also, the "topmost" part is a bit misleading:  WS_EX_TOPMOST is a window style intended for things that should *always* stay on top [of other same application windows] when visible.   It isn't used very often as there are other ways of keeping things visible: e.g., by using panels.  And modal dialogs stay on top because their handler code won't permit switching to another [same application] window until the dialog is hidden / closed.



Ignoring Racket's extraneous added panels, a better organization would be:

Window 00010010 "" #32769 (Desktop)
    :
    Window 0017076E "Hello World" PLTFrame
        Window 000F03D2 "Dialog 1" #32770 (Dialog)
            Window 00320BCC "Dialog 2" #32770 (Dialog)
                Window 003A052E "Close Dialog 2" PLTBUTTON
            Window 0057098A "Open Dialog 2..." PLTBUTTON
            Window 001807D4 "Close Dialog 1" PLTBUTTON
        Window 003704DA "Open Dialog 1..." PLTBUTTON
    :

but it would work even if the dialogs were just siblings under the top level frame [assuming their creation Z-order was correct].



I'm not sure how to verify it at the moment, but my suspicion is that - on Windows at least - Racket somehow is searching wrongly with GetNextWindow().  That might be a simple fix.

Apart from that I don't see an easy work-around.  Maybe creating custom window class(es) that focus the parent explicitly when a window object is hidden or destroyed.   But right now I don't see a way to make it work using the stock gui objects .

It would best if the GDI object hierarchy accurately reflected the Racket object hierarchy, but that's probably a whole lot of work.

Sigh!,
George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to