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.