Author Topic: how to stay a window on top  (Read 13825 times)

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
how to stay a window on top
« on: April 02, 2020, 09:15:25 pm »
OS/2 distinghishes between a standard "window" and a "dialog window". A visible difference is that a standard window has got an arbitrary icon on the system menu button. A dialog window has only a drop down array icon. Both windows can run in modal and non-modal state. The standard "window" is created with the API call "WinCreateWindow" or "WinCreateStdWindow". A dialog window is created with WinCreateDlg or with WinLoadDlg (from a resource) and a parameter is the address of a message processing function.

An interesting difference in the behaviour of both types of window is that a dialog window continously stays on top, even another window of the program gets the focus, also in non-modal state.

My question: Is there a flag where a window created with WinCreateWindow gets the same behaviour of staying on top like a "dialog window" does?

The reason is that I want to add a specific property to the WDsibyl component library. In Freepascal Lazarus, such a property exists (tForm.Formstyle = fsStayOnTop). The WDsibyl tForm component is completely based on WinCreateWindow, also all standard controls do so.

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: how to stay a window on top
« Reply #1 on: April 03, 2020, 09:32:13 am »
The FCF_SYSMODAL creation flag creates a system modal window. You can also use the WinSetSysModalWindow call to change a window into being the system modal window or from being the system modal window.

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: how to stay a window on top
« Reply #2 on: April 03, 2020, 11:18:20 am »
Quote
The FCF_SYSMODAL creation flag creates a system modal window

But I want that the child window floats only over the main window of my appliction, not system wide. And it should be non-modal.

Alex Taylor

  • Sr. Member
  • ****
  • Posts: 387
  • Karma: +5/-0
    • View Profile
Re: how to stay a window on top
« Reply #3 on: April 03, 2020, 06:43:16 pm »
For a PM frame window, try this:
Code: [Select]
#define WS_TOPMOST      0x00200000L
WinSetWindowBits( hwndFrame, QWL_STYLE, WS_TOPMOST, WS_TOPMOST );

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: how to stay a window on top
« Reply #4 on: April 03, 2020, 11:21:38 pm »
I'm sorry, but the WinSetWindowBits code seems not to work.

A system wide Float to top would be helpful, too, because it is also part of the Freepascal Lazarus code. (FormStyle = fsSystemStayOnTop) But all variants are non-modal.

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: how to stay a window on top
« Reply #5 on: April 03, 2020, 11:29:10 pm »
I'm sorry, but the WinSetWindowBits code seems not to work.

A system wide Float to top would be helpful, too, because it is also part of the Freepascal Lazarus code. (FormStyle = fsSystemStayOnTop) But all variants are non-modal.

Laurence Pithie

  • Jr. Member
  • **
  • Posts: 62
  • Karma: +1/-0
    • View Profile
Re: how to stay a window on top
« Reply #6 on: April 04, 2020, 12:51:15 am »
One option would be to place the Main window behind the client window using WiinSetWindowPos when the client program is active. One way to  achieve that is by placing a check for the clinet program being active and calling WinSetWindowPos at the end of processing the WM_PAINT message in the main window procedure. Essentially what you woulld be doing is swapping the Z order of the two windows if the user brings the main window to the front while the client program is active.

Lars

  • Hero Member
  • *****
  • Posts: 1271
  • Karma: +65/-0
    • View Profile
Re: how to stay a window on top
« Reply #7 on: April 04, 2020, 09:35:59 pm »
If your child window is a sibling of your main window (whatever "child" and "main" window means in your context), you can use WinSetWindowPos with SWP_ZORDER to place your child window on top of any other sibling windows.

Sibling windows have a common parent window. If you can show us the relationship between your "child" window and "main" window (using PMTree, for example) then it should be possible to come up with a solution.

Lars

  • Hero Member
  • *****
  • Posts: 1271
  • Karma: +65/-0
    • View Profile
Re: how to stay a window on top
« Reply #8 on: April 04, 2020, 09:45:20 pm »
Or try WinSetActiveWindow. See the help for this function. The active window will be placed above all other top-level windows on the screen (see "Window activation" in the help).

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: how to stay a window on top
« Reply #9 on: April 07, 2020, 09:36:27 pm »
Both "WinSetWindowPos with SWP_ZORDER" and "WinSetActiveWindow" let the window appear on top, but only for the moment until another window gets the focus. I am searching for a permanent way that another window cannot float above my window.

Dave Yeo

  • Hero Member
  • *****
  • Posts: 4786
  • Karma: +99/-1
    • View Profile
Re: how to stay a window on top
« Reply #10 on: April 08, 2020, 01:29:23 am »
The screensaver seems to use this,
Code: [Select]
      {
        SWP *pSWP;

        // The following is required so that this window will be on
        // top of the xCenter window, evenif that is set to be always on top!

        // Real screensaving, here we should stay on top!
        // Set WS_TOPMOST flag again!
        WinSetWindowBits(hwnd, QWL_STYLE, WS_TOPMOST, WS_TOPMOST);

        pSWP = (SWP *) mp1;
        pSWP->hwndInsertBehind = HWND_TOP;
        pSWP->fl |= SWP_ZORDER;
      }

Not an expert though and not sure about the SWP stuff.

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: how to stay a window on top
« Reply #11 on: April 08, 2020, 12:22:36 pm »
I think that in this code the last API call where the new pSWP values are sent to the system is missing.

Doodle

  • Newbie
  • *
  • Posts: 6
  • Karma: +1/-0
    • View Profile
Re: how to stay a window on top
« Reply #12 on: April 09, 2020, 03:55:45 pm »
Once you set your window to be styled WS_TOPMOST, it gets above all other windows, even previous topmost ones.
Fortunately, when the Z-Order of the windows changes, the affected windows get a window message WM_ADJUSTWINDOWPOS, in which you can realize that some other app has gone above your window, and you can set your window to be topmost again then.

It's a bit risky, as when this meets other similar code, they will "fight" being topmost, and probably cause flicker and eat up CPU.

Still, this seems to work in DSSaver, as Dave has pointed out.

For an example, please download the source code of DSSaver, and check one of the modules (preferable the Blank module, as that has the least additional code) on how it's done:
ftp://ftp.netlabs.org/pub/dssaver/dssaver_v20_srcbin.zip
Once unzipped, check the file Modules\Blank\Blank.c, search for lines containing "topmost", and you'll see how it's done in there.

Good luck!

Dave Yeo

  • Hero Member
  • *****
  • Posts: 4786
  • Karma: +99/-1
    • View Profile
Re: how to stay a window on top
« Reply #13 on: April 09, 2020, 04:56:01 pm »
It's a bit risky, as when this meets other similar code, they will "fight" being topmost, and probably cause flicker and eat up CPU.

Which will happen when the screensaver kicks in. https://hobbes.nmsu.edu/download/pub/os2/apps/scrnsave/dss_rmt_v13.zip is an example of a REXX script to control the screensaver, including a watchdog to disable the screensaver if certain processes are running.
Perhaps the always on top should be an option?

Martin Vieregg

  • Sr. Member
  • ****
  • Posts: 278
  • Karma: +2/-0
    • View Profile
Re: how to stay a window on top
« Reply #14 on: April 11, 2020, 10:57:12 am »
Quote
WS_TOPMOST

I have no such constant in Borland C 2.0 for OS/2 and a in WDsibyl a constant WS_EX_TOPMOST 0x00000008

Is 8 the right value for WS_TOPMOST ? In pmwindow.h I have got a value
#define WS_THICKFRAME       0x00000008L