Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET
  • Page:
  • 1

TOPIC:

Bringing a VO window to the top 09 Nov 2022 04:14 #24376

  • JohnBonnett88
  • JohnBonnett88's Avatar
  • Topic Author


  • Posts: 34
  • Hi All,

    I have another VO GUI problem.

    The VO application I have converted to X# starts with a main shell window with a number of buttons. Clicking on one of those brings up various MDI shell windows for different application areas in the system.

    When it was running in VO, clicking one of those buttons, pushed the main shell into the background and brought the newly opened window to the top. This does not happen in the X# version.

    The relevant code, exported from VO, seems to be

    oWin := CreateInstance(symShell, SELF)
    BringWindowToTop(oWin:Handle())

    That BringWindowToTop doesn't, and on searching for ideas I see other people have this problem too, completely outside of VO.

    I have also tried replacing BringWindowToTop with SetForegroundWindow, as suggested in other forums, but that does not work either.
    Even just having a way to minimise the initial window would be a solution.
    Any ideas about what I should try?

    Is there a source of VO GUI documentation about this sort of thing? I also have some differences from VO in which control receives focus when a form opens that I need to resolve.

    Best Regards,
    John Bonnett

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 09 Nov 2022 08:40 #24378

    • Chris
    • Chris's Avatar


  • Posts: 3667
  • Hi John,

    Not aware of anything like this, can you please create and send a small sample showing how this works as you expect in VO, but not in X#?
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 09 Nov 2022 11:28 #24382

    • FFF
    • FFF's Avatar


  • Posts: 1378
  • John,
    i can't remember ever having seen a "Shellwindow" with buttons, always thought it can contain only Datawindows, dialogs, menu and toolbar. Equally, didn't know a shellwindow can hold other shellwindows. So, as Chris said, give us a minimal sample, pls.
    Regards
    Karl (X# 2.13.0.6; Xide 1.32; W8.1/64 German)

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 09 Nov 2022 18:34 #24386

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774

  • The relevant code, exported from VO, seems to be

    oWin := CreateInstance(symShell, SELF)
    BringWindowToTop(oWin:Handle())

    I doubt that the window becomes visibel if you´re running such code with VO . You don´t need BringWindowToTop(oWin:Handle()) or SetForegroundWindow(oWin:Handle()). What´s missing is a Show().

    oWin := CreateInstance(symShell, SELF)
    oWin:Show()

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    Bringing a VO window to the top 10 Nov 2022 00:29 #24388

    • JohnBonnett88
    • JohnBonnett88's Avatar
    • Topic Author


  • Posts: 34
  • Thanks to all who replied, I will reply to each of you.

    Firstly to Chris,
    I will try to make a small sample, but I don't have VO, and never have. I am working totally in X# in VS. The creators of the system are effectively defunct now, so I got the AEF files, ran the Xporter and have been working in X# since. It's a big system and we now have lots working. We are now cleaning up details like which window is on top, which control has focus etc.

    To FFF,
    You are right, on closer inspection the initial window inherits from DATAWINDOW, and so can have buttons. I was misled by the fact that the window class in the code is called WholeShell2.
    The sub-windows that get opened from this startup window do inherit from ShellWindow and are MDI windows. What I am trying to achieve is that, when a sub-window is opened, it becomes the top window. Currently the startup window stays on top.

    To Karl-Heinz,
    I did not show the full story. Here is more complete code

    oWin := CreateInstance(symShell, SELF)
    BringWindowToTop(oWin:Handle())
    AAdd(SELF:aWindowsUp,{Upper(cName), oWIn:Handle(), oWin:Caption})
    oWin:Show(iif(lZoomed,SHOWZOOMED,NIL))

    That AAdd is about keeping track of which sub-windows are currently open. The Show is there, but it occurred to me that perhaps I should only try bring to top after the Show, so one variation I tried was this

    oWin := CreateInstance(symShell, SELF)
    AAdd(SELF:aWindowsUp,{Upper(cName), oWIn:Handle(), oWin:Caption})
    oWin:Show(iif(lZoomed,SHOWZOOMED,NIL))
    SetForegroundWindow(oWin:Handle())

    This uses that alternate way of making a top window, but it did not work either.

    In my researches I discovered there are lots of rules in Windows about who can bring windows to the top, so perhaps I am still doing something wrong. I will keep trying.

    Best Regards,
    John

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 10 Nov 2022 08:20 #24392

    • jonhn
    • jonhn's Avatar


  • Posts: 66
  • I use this in my app to check if the window class is already open, and check if it is for the same job, or a different one and bring it to the top if
    correct. It works like magic.
    
      //   See if the JobPlanWindow is open and if so, bring it to top and focus!
      aBrse:={}
      aBrse:=SELF:Owner:GetAllChildren()
       FOR i:=1 TO ALen(aBrse)
             IF ClassName (aBrse [i]) = #JobPlanWindow2
                  	TheWindow :=aBrse[i]:oDCsleHireNo:TextValue
             	IF AllTrim(TheWindow) = AllTrim(TheHireNo)
             	     * Then it is open on this very machine, already...
                           GotIt:=TRUE
                           aBrse[i]:show()
                          aBrse[i]:ToTop()
             	      aBrse[i]:SetFocus()
             	      EXIT
             	ENDIF  //  It is the actual matching window
             ENDIF  //   If you actually found a JobPlanWindow
       NEXT i


    HTH. Jonathan

    Please Log in or Create an account to join the conversation.

    Last edit: by robert. Reason: formatted the code

    Bringing a VO window to the top 10 Nov 2022 15:51 #24398

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hi John,

    There must be something else going wrong on your side. As a test i created a Datawindow with two Pushbuttons. Each time i open a new Shell window.the window becomes the Top window - no matter if i´m using VO or X#.
    oWin := CreateInstance(symShell, SELF)
    oWin:Show()

    To see what i did extract the attached WinShell.zip and then doubleclick the WinShell.gif

    btw. What happens when you try SetWindowPos() ?
    oWin := CreateInstance(symShell, SELF) 
    SetWindowPos(oWin:Handle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE  | SWP_SHOWWINDOW )	

    regards
    Karl-Heinz
    Attachments:

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    Bringing a VO window to the top 11 Nov 2022 05:24 #24404

    • JohnBonnett88
    • JohnBonnett88's Avatar
    • Topic Author


  • Posts: 34
  • Hi Karl-Heinz,

    Thanks for your reply. Your suggestion about SetWindowPos fixed it for me.

    By the way, that example you sent was neat. I had never seen a GIF used to make a short animation like that!

    Thanks again,
    John

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 11 Nov 2022 07:53 #24405

    • FFF
    • FFF's Avatar


  • Posts: 1378
  • John,
    I think he used screen2gif, it's free and very simple to use. Hint: you have to hide the gif into a zip, if you want to use it on this site, if you post directly, somehow the animation gets lost...
    Regards
    Karl (X# 2.13.0.6; Xide 1.32; W8.1/64 German)

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 29 Nov 2022 01:06 #24568

    • JohnBonnett88
    • JohnBonnett88's Avatar
    • Topic Author


  • Posts: 34
  • Hi All,
    Karl-Heinz suggestion certainly got the window to the top for me but it had the undesirable property of wanting to stay on top regardless of anything else. I guess that's what TOPMOST means! I first encountered this when debugging, the window had become TOPMOST and VS had stopped at a breakpoint but VS was behind the window so I could not access it. Various tricks of moving things to other monitors got me untangled but I also got feedback from users of the application that these TOPMOST windows were a pain.

    I chatted with one of my C++ colleagues and he said that he had also encountered this sort of thing. He had got around it by making the window TOPMOST, but also setting a timer to make the window only TOP shortly after. I set about implementing that using the VO SetTimer function. I stumbled a bit with this because, although there were SetTimer calls already in the app I am working on, none of them called a timer function, and I could not find an example anywhere else where the TimerFunc was anything but NULL_PTR.

    Since I am running in X# and have all the .NET environment with other timers available, I switched to using System.Threading.Timer. Curiously I had a similar problem with getting the syntax of the parameter that specified the timer function, even though I had good documentation and examples to follow, but not in X#. I got another colleague to look over my code and he made one suggestion that fixed it. In X# you learn to treat USUAL as the equivalent of OBJECT in .NET, and notionally it is, but apparently not quite equivalent enough for function signatures to match.

    Here is the code I came up with in case it helps someone else.
    The following code creates the window I want to come up on top, adds it to an array of currently open windows, sets it TOPMOST, sets up the timer and shows the window.

    oWin := CreateInstance(symShell, SELF)
    AAdd(SELF:aWindowsUp,{Upper(cName), oWIn:Handle(), oWin:Caption})
    SetWindowPos(oWin:Handle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW )
    // Set timer to stop window being TOPMOST after a half second
    System.Threading.Timer{TimerCallback{oWin:ShownTopMost}, null, 500, Timeout.Infinite}
    oWin:Show(iif(lZoomed,SHOWZOOMED,NIL))

    Here is the function that executes when the the timer elapses after half a second. That "As Object" in the parameter is the last thing I fixed to make it work. I previously had "AS Usual". This method is in the base class of the family of windows I need to go to the top

    /// <summary>
    /// Sets window shown as TOPMOST back to just TOP
    /// </summary>
    /// <param name="stateInfo">Unused, but needed to match Delegate System.Threading.TimerCallback</param>
    METHOD ShownTopMost(stateInfo AS Object) AS VOID
    SetWindowPos(SELF:Handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW )
    RETURN NIL

    Best Regards,
    John

    Please Log in or Create an account to join the conversation.

    Bringing a VO window to the top 09 Dec 2022 03:08 #24708

    • JohnBonnett88
    • JohnBonnett88's Avatar
    • Topic Author


  • Posts: 34
  • Just one follow-up to what I wrote before. I found that changing that SetWindowPos in the timer routine to
    SetWindowPos(SELF:Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW )
    gave a better user experience.
    That is change in the window position from HWND_TOP to HWND_NOTOPMOST.
    The result is the window comes to the top when you want, but does not hog the top position, and the user can change window positions easily as they want.

    Cheers,
    John

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1