Tips_gui   >   Windows   >   Window Positioning

Window Positioning

This section covers various topics relating to opening windows and controlling the size and position of the window instance.

When you open a window instance of a window class, by default, the window size and location matches the size and location of the window class.

There are several problems you can run into with this default behavior:

  1. If the user's screen size is small than the default window class, the window instance will run off the side or bottom of the user's screen.
  2. If you are using the same window class for different instances you may want to have different window sizes for each window instance. This is especially a problem if you want to store the last window size and location for each window instance and user so that you can later reopen it to that same size for the user.

Open Window Instance

You can open a window instance using $open, $openonce, or $openmodal.

; Open a single instance of a window class.
Do $clib.$windows.wWinClass.$openonce('WinInstName') Returns rWin

If you reuse a window class for different window instances you can not use $openonce.

In my applications I declare a unique WinInstID for each window instance. The WinInstID is langauge independent, so that the window title can be mapped by the WinInstID to different languages.

; Open a new instance of a window class.
Do $clib.$windows.wWinClass.$open('UniqueWinInstName') Returns rWin

The possible iLocn parameters are found in the F9 Catalog > Constants tab. (e.g. kWindowCenter, kWindowCenterRelative,kWindowNormal, kWindowStack, kWindowMaximize, kWindowMinimize, ...)

; Open a new instance of a window class.
; kWindowNormal = the same size and position as the window class.
Do $clib.$windows.wWinClass.$open('*',kWindowNormal) Returns rWin

; Open a new instance of a window class.
; kWindowStack = offset from the top window.
Do $clib.$windows.wWinClass.$open('*',kWindowStack) Returns rWin

; kWindowCenter = centre of the screen.
Do $clib.$windows.wWinClass.$open('*',kWindowCenter) Returns rWin

; kWindowCenterRelative = centred relative to the specified window instance.
Do $clib.$windows.wWinClass.$open('*',kWindowCenterRelative,$topwind) Returns rWin

; kWindowMaximize = maximized
Do $clib.$windows.wWinClass.$open('*',kWindowMaximize) Returns rWin

Warning

kWindowMaximize will only work if the window class property $zoombox is set to kTrue.

kWindowMinimize will only work if the window class property $minimizebox is set to kTrue. (I could not get kWindowMinimize to work on opening a new window instance with Omnis Studio v4.1.5 on Mac OS X.)

Click the Run Demo button in the StudioTips Browser for a demo of opening window instances using the various kWindow... constants.

Check Size Window And Position

When a window is instantiated you should check the size and location to make sure it fits within the boundaries of the user's screen and then if necessary move and resize the window so that it does fit.

The following code is used to check the size and position of window instances in StudioTips to make sure they fit on the user's screen. This method can be called from the $construct method, or the $event method On evToTop.

; Superclass method: $setWindowSizeAndPosition

; Only run this code if we are not a subwindow.
If $cinst=$cwind
   
   ; Only run this code if we are not currently minimized.
   If not($cinst.$minimized)
      
      ; Make sure the window is small enough to fit in the screen.
      If $cinst.$height>$modes.$height
         Do $cinst.$height.$assign($modes.$height-25)
      End If
      If $cinst.$width>$modes.$width
         Do $cinst.$width.$assign($modes.$width)
      End If
      
      ; If the window is too low or high on the screen, adjust it.
      If $cinst.$top+$cinst.$height>$modes.$height
         Do $cinst.$top.$assign($modes.$height-$cinst.$height-25)
      Else If $cinst.$top<0
         Do $cinst.$top.$assign(0)
      End If
      
      ; If the window is too far left or right on the screen, adjust it.
      If $cinst.$left<0
         Do $cinst.$left.$assign(0)
      Else If $cinst.$left+$cinst.$width>$modes.$width
         Do $cinst.$left.$assign($modes.$width-$cinst.$width)
      End If
      
   End If
   
End If

Quit method kTrue

Save Window Size And Position

When a window instance is being close you can save the window size and position so that when the window instance is reopened you can restore it to the same size and location.

If the window class is being used for a specific window instance you can save the window instance $left, $right, $width, and $height properties to the window class properties.

; Superclass method: $saveWindowSizeAndPosition

; Save the window instaance size to the window class size if we are not a subwindow.
If $cinst=$cwind
   
   ; If the window is minimized, bring it to the front, then save the current size/location.
   If $cinst.$minimized
      Do $cinst.$bringtofront()
   End If
   
   ; Set a reference to the window instance's class.
   Set reference rClass to $cinst().$class
   
   ; Top and left can not be assigned as negative values.
   Do rClass.$top.$assign(pick($cinst.$top>0,0,$cinst.$top))
   Do rClass.$left.$assign(pick($cinst.$left>0,0,$cinst.$left))
   
   Do rClass.$width.$assign($cinst.$width)
   Do rClass.$height.$assign($cinst.$height)
   
End If
Quit method kTrue

Warning

If you attempt to assign a negative value to the $left or $top window class property Omnis Studio will not assign the value. That is why the sample code above uses the pick() function for the $left and $top values.

In my applications I reuse the same window class for many different window instances. Saving the window instance size and location to the window class is not really a great solution because when you issue a new release to the client, they will lose all of their last window size and location. A better solution is to use a unique ID for each window instance and then save/restore the window size and location for each window instance in the user's profile in the database. Normally you will have a table in the database where you have a record for each user and store information like their password, email address, etc. Added a WindowsUsedList column to this table and on opening the application load the WindowsUsedList into memory, and on closing the application save the WindowsUsedList back to the user profile in the database. The list definition of the WindowsUsedList could be: (WinInstID, Left, Top, Width, Height, LastUsedDateTime). Instead of saving and restoring the window size and location from the window class, you save and restore the window save and location from the WindowsUsedList.

In my applications I create an oWindows object class which is instantiated by the Startup_Task variable wn. The oWindows object can be made responsible for loading and saving the WindowsUsedList. The oWindow methods $saveWindowSizeAndLocation(prWinInst) and $restoreWindowSizeAndLocation(prWinInst) are called from the $construct and $destruct methods of each window instance as follows:

; Superclass window $construct method.

; Set the window size and location.
Do wn.$restoreWindowSizeAndLocation($cinst) Returns FlagOK

; Superclass window $destruct method.

; Save the window size and location.
Do wn.$saveWindowSizeAndLocation($cinst) Returns FlagOK