Show a window from a modal dialog

  1. ‹ Older
  2. 4 months ago

    Kevin G

    Mar 12 Pre-Release Testers, Xojo Pro Gatesheed, England

    If you have the MBS plugins and are willing to draw the content as a graphic and handle hit testing take a look at OverlayMBS.

  3. Massimo V

    Mar 12 Pre-Release Testers, Xojo Pro Europe (Germany, Würzburg)
    Edited 4 months ago

    @Kevin G If you have the MBS plugins and are willing to draw the content as a graphic and handle hit testing take a look at OverlayMBS.

    I did take this approach for something but I found impractical for my general need. Some controls would require to completely reinvent the wheel and requiring too much time.
    And btw, we handle a code base of 100+ (growing) applications ;)

    But thanks for your suggestion.

  4. Julian S

    Mar 12 Pre-Release Testers, Xojo Pro UK

    Just getting my head around what you're trying to do. So you have a window, you then open a modal window, you then open a window from the modal? That last window would be a popup type window that would auto-close if focus was lost?

    If I've not got this right could you pop up a quick demo app that I could tweak?

  5. Isaac R

    Mar 12 Pre-Release Testers, Xojo Pro Minnesota, USA

    @Massimo V I tried to replicate the above, and wrote this:
    [...]
    but seems to do nothing. Worse, the SWP_NOACTIVATE completely prevent the window to get keyboard focus. Removing it, the above code behave like if it's not called, that is, the window is set to front, the keyboard input is active, only the mouse is not captured.

    Can you try it without SWP_NOACTIVATE but with addition of SetCapture to capture mouse events?

  6. Isaac R

    Mar 12 Pre-Release Testers, Xojo Pro Minnesota, USA

    My last comment probably isn't going to work, apparently only the active window can capture the mouse. Working through an old SDK example to see if I can find something that will work.

  7. Anthony C

    Mar 12 Pre-Release Testers, Xojo Pro GraffitiSuite Developer
    Edited 4 months ago

    It sounds like what you want is a tool window. Something like this should do it.

    Private Sub SetToolWindow(w as Window)
      #if TargetWindows
        Dim oldFlags, newFlags, styleFlags As Integer
        
        Const WS_EX_TOOLWINDOW = &h00000080
        
        Const SWP_NOSIZE = &H1
        Const SWP_NOMOVE = &H2
        Const SWP_NOZORDER = &H4
        Const SWP_FRAMECHANGED = &H20
        
        Const GWL_EXSTYLE = -20
        
        dim flag as Integer = WS_EX_TOOLWINDOW
        
        Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (hwnd As Integer,  _
        nIndex As Integer) As Integer
        Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (hwnd As Integer, _
        nIndex As Integer, dwNewLong As Integer) As Integer
        Declare Function SetWindowPos Lib "user32" (hwnd as Integer, hWndInstertAfter as Integer, _
        x as Integer, y as Integer, cx as Integer, cy as Integer, flags as Integer) as Integer
        
        oldFlags = GetWindowLong(w.Handle, GWL_EXSTYLE)
        newFlags = BitwiseOr( oldFlags, flag )
        
        
        styleFlags = SetWindowLong( w.Handle, GWL_EXSTYLE, newFlags )
        styleFlags = SetWindowPos( w.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE +_
        SWP_NOSIZE + SWP_NOZORDER + SWP_FRAMECHANGED )
      #endif
    End Sub

    Some really old code there, and could probably be finessed to be a bit more efficient. I think I last worked on that when Aaron Ballman was around.

    EDIT: Cleaned it up a bit. Then it's just a matter of parent/child positioning.

  8. Massimo V

    Mar 13 Pre-Release Testers, Xojo Pro Europe (Germany, Würzburg)

    @Anthony C It sounds like what you want is a tool window. Something like this should do it.

    Private Sub SetToolWindow(w as Window)
      #if TargetWindows
        Dim oldFlags, newFlags, styleFlags As Integer
        
        Const WS_EX_TOOLWINDOW = &h00000080
        
        Const SWP_NOSIZE = &H1
        Const SWP_NOMOVE = &H2
        Const SWP_NOZORDER = &H4
        Const SWP_FRAMECHANGED = &H20
        
        Const GWL_EXSTYLE = -20
        
        dim flag as Integer = WS_EX_TOOLWINDOW
        
        Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (hwnd As Integer,  _
        nIndex As Integer) As Integer
        Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (hwnd As Integer, _
        nIndex As Integer, dwNewLong As Integer) As Integer
        Declare Function SetWindowPos Lib "user32" (hwnd as Integer, hWndInstertAfter as Integer, _
        x as Integer, y as Integer, cx as Integer, cy as Integer, flags as Integer) as Integer
        
        oldFlags = GetWindowLong(w.Handle, GWL_EXSTYLE)
        newFlags = BitwiseOr( oldFlags, flag )
        
        
        styleFlags = SetWindowLong( w.Handle, GWL_EXSTYLE, newFlags )
        styleFlags = SetWindowPos( w.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE +_
        SWP_NOSIZE + SWP_NOZORDER + SWP_FRAMECHANGED )
      #endif
    End Sub

    Some really old code there, and could probably be finessed to be a bit more efficient. I think I last worked on that when Aaron Ballman was around.

    EDIT: Cleaned it up a bit. Then it's just a matter of parent/child positioning.

    Thanks for sharing this. Unfortunately this doesn't work for my case.

  9. Massimo V

    Mar 13 Pre-Release Testers, Xojo Pro Europe (Germany, Würzburg)

    @Julian S Just getting my head around what you're trying to do. So you have a window, you then open a modal window, you then open a window from the modal? That last window would be a popup type window that would auto-close if focus was lost?

    If I've not got this right could you pop up a quick demo app that I could tweak?

    Here it's a test project showing what I need to do. It's a fictionary project, just to exemplify my use.
    It basically have a base window where you can open Modal dialog and from it open a "popup" window.
    There are two example popup windows, one without anything special which works for everything except it doesn't capture the mouse events (clicks truly).
    A second one just use a Timer to set SetCapture() continuosly. It's a bit clunky, but so far this is the only solution I found.

    Thanks for everyone helping me on finding a solution.

    https://www.dropbox.com/s/wc2okfvte8u9ie4/PopWindowTest.xojo_binary_project.zip?dl=0

  10. Anthony C

    Mar 13 Pre-Release Testers, Xojo Pro GraffitiSuite Developer

    I dug in to this a bit. It looks like Xojo is doing something when creating the Sheet Window, Moveable Modal, and Modal DIalog window types that's borking things here (that I remember working). If I set the Window.Type to Document, then use the SetToolWindow method I supplied above, everything works as expected in my testing. You can use ShowModalWithin on the parent, and you call SetToolWindow in the desired window's Constructor.

  11. Massimo V

    Mar 14 Pre-Release Testers, Xojo Pro Europe (Germany, Würzburg)

    @Anthony C I dug in to this a bit. It looks like Xojo is doing something when creating the Sheet Window, Moveable Modal, and Modal DIalog window types that's borking things here (that I remember working).

    So you mean this will never work?

    @Anthony C If I set the Window.Type to Document, then use the SetToolWindow method I supplied above, everything works as expected in my testing. You can use ShowModalWithin on the parent, and you call SetToolWindow in the desired window's Constructor.

    I'm not sure to understand if this works for you, sorry.
    I tried to use the call to SetToolWindow in the Constructor as you suggested on my example linked above, but still doesn't work.

    If this works for you, can you please explain me how?
    You can download the above example, it already has the method you posted, just not used at the moment.

    Thanks anyway.

  12. Julian S

    Mar 14 Pre-Release Testers, Xojo Pro UK

    This as good as I could get it, it's not 100% correct.

    https://www.dropbox.com/s/sok4hws650l1pzq/PopWindowTest.xojo_binary_project?dl=0

    There are a few limitations of the framework that won't allow me to do this 100% correctly, I can do it in other languages but the inability to click on those controls on the popup is, from my limited knowledge of the framework, a fundamental issue in the framework when modal windows are shown. At a guess, it's not responding to the events of controls that are not on the last opened modal window, which is an oversight that this use case highlights. I could be wrong (it wouldn't be the first time) this is just my gut feeling.

    It might be possible to get around all the above with a custom WndProc, I don't know without trying but I've spent enough time on this one, I'll let someone else try that ;)

  13. Isaac R

    Mar 14 Pre-Release Testers, Xojo Pro Minnesota, USA
    Edited 4 months ago

    Yeah I’m coming to similar conclusions, something doesn’t seem right in the modal window’s event processing but it’s hard to nail down. I have an example that almost works, with a custom message pump loop, but I can’t quite get it to work so far. Going to keep fiddling with it for awhile.

    I think the problem might be something to do with the fact that the message pump can’t be in a Xojo event, otherwise it blocks further Xojo event processing on that thread. That’s barely more than a guess though. Might have to go multithreaded.

  14. Julian S

    Mar 14 Pre-Release Testers, Xojo Pro UK

    After a quick chat and RubberDuck with @Anthony C he suggested trying Floating Windows.

    That looks like its done the job as its setting the parent, which is needed, then some liberal declare sprinkles sort out the enable/disable of parent windows.

    You'll just need to move the windows into the correct positions for your popups and you should be good to go, we think :)

    https://www.dropbox.com/s/gv3pdyf8g3trlqs/PopWindowTest2.xojo_binary_project?dl=0

  15. Lennox J

    Mar 14 Jamaica. West Indies
    Edited 4 months ago

    @Julian S After a quick chat and RubberDuck with @Anthony C he suggested trying Floating Windows.

    That looks like its done the job as its setting the parent, which is needed, then some liberal declare sprinkles sort out the enable/disable of parent windows.

    You'll just need to move the windows into the correct positions for your popups and you should be good to go, we think :)

    https://www.dropbox.com/s/gv3pdyf8g3trlqs/PopWindowTest2.xojo_binary_project?dl=0

    I am getting this on macOS Mojave Version 10.14.3 and Xojo 2018 Release 4
    x86 64 bit

    Linking Executable
    ld: framework not found User32

    and with x86 32 bit it compiles but "My Application cannot be opened because of a problem".
    Process: My Application [798]
    Path: /Users/USER/Downloads/*/My Application.app/Contents/MacOS/My Application
    Identifier: info.sacosoftwareconsultinggmbh.myapp
    Version: ??? (1.0.0.0.0)
    Code Type: X86 (Native)
    Parent Process: ??? [1]
    Responsible: My Application [798]
    User ID: 501

    Date/Time: 2019-03-14 07:41:51.723 -0500
    OS Version: Mac OS X 10.14.3 (18D109)
    Report Version: 12
    Anonymous UUID: BDA6A01F-92C6-AC8E-17F0-7DDBFA91B9DA

    Time Awake Since Boot: 4200 seconds

    System Integrity Protection: enabled

    Crashed Thread: 0

    Exception Type: EXC_CRASH (SIGABRT)
    Exception Codes: 0x0000000000000000, 0x0000000000000000
    Exception Note: EXC_CORPSE_NOTIFY

    Termination Reason: DYLD, [0x1] Library missing

    Lennox

  16. Massimo V

    Mar 14 Pre-Release Testers, Xojo Pro Europe (Germany, Würzburg)

    First of all, thank you @Julian S @Anthony C and everyone else spent time and efforts for helping me on finding a solution.

    @Julian S your solution works pretty much well for this case.
    However this solution has some major flaws for my prospected use that make it impossible or really hard to use it:

    - As I initially stated, this is a cross platform solution. Setting the modal dialog as a Floating window prevent to show it on Mac as a Sheet, and this is not acceptable for my requirements. Moreover, the floating window disappear when the whole app goes in background, but most important, with this approach it would require a Mac solution to behave like on Windows due the standard way is broken. That is, would be like fixing something which is already working.

    - The popup window I have to show is part of a component (actually many different components) which have no knowledge of the Base window that ultimately fired its execution. But this approach rely on disabling the base window before opening the popup and enabling it again from the popup on close. This means redesign everything to pass along the base window to modal dialogs and redesign as well the components to take this base window reference. This for something like 100+ applications. ugh...

    - The fake ModalDialog is indeed only mocking the modal UI behaviour but it remain modeless, that is the base window still execute code after showing the (fake) modal dialog. Again this can be handled in some way, but again this would be a huge amount of work on refactoring how applications works.

    In the end, this would require a major refactor of my codebase that I can't afford at this time. And still I feel there could be other unwanted side effects.
    I guess at this point I will go with my solution of keeping a timer running and check/set the SetCapture method. Still far from perfect but at least easy to implement and effective.

    Nonetheless, I do understand the problem (probably) lies on a limitation on the Xojo framework and/or the Win32 framework and this is probably one of the best solutions to solve the problem. I also do understand you guys tried hard to help me and spent time on it, so I wish to thank you all again for the efforts and please don't feel offended by my critics.

    :D

  17. Julian S

    Mar 14 Pre-Release Testers, Xojo Pro UK
    Edited 4 months ago

    @Lennox J I am getting this on macOS Mojave Version 10.14.3 and Xojo 2018 Release 4

    I only worked on the windows part of it, it won't run on the mac as it is.

    No offence at all, I enjoy tinkering, I forgot you needed it xplat and its a shame we can't alter Window Frame Type at runtime.

  18. Massimo V

    Mar 14 Pre-Release Testers, Xojo Pro Europe (Germany, Würzburg)

    @Julian S its a shame we can't alter Window Frame Type at runtime

    The Window class of the Xojo framework is one of the weakest point in general. As not being able to create windows by code in 2019 really set some limitations.

  19. Lennox J

    Mar 14 Jamaica. West Indies

    Thanks Julian, "no sweat", it's Ok.
    Lennox

  20. Isaac R

    Mar 14 Pre-Release Testers, Xojo Pro Minnesota, USA
    Edited 4 months ago

    I'm attaching my project at this point since it might help with the frame type issues -- I have logic to re-parent a Xojo window to a Win32 API window. This should allow you to leave the frame type as Sheet and act like it isn't such on Windows (I think). You'll need to extract that bit of the code, however, as this still has my message pump in it. The uploaded version actually does have this separated as the third button on wBackground, without a message pump.

    Oh, and the code is an absolute mess of inconsistent styles, sorry about that.

    https://www.dropbox.com/s/0jr0cs5x1x7yonu/PopupTest5.xojo_binary_project?dl=0

  21. Newer ›

or Sign Up to reply!