Window Placement Extensions

——————————————————————————–

Window Placement Extensions 2016 Release 1

Domador Software Components for Xojo

Copyright 2016 Domador Software S.R.L.

http://www.domador.net

support@domador.net

——————————————————————————–

———

Overview

———

Domador Software’s Window Placement Extensions make it easier and more natural to position and resize windows as desired, in many cases.

——

Usage

——

Before calling any other method in this library, you’ll need to call the RegisterLicenseKey function with your license key:

WindowPlacementExtensions_Domador.RegisterLicenseKey(“PlaceYourLicenseKeyHere”)

or

WindowPlacementExtensions_Domador_Private.RegisterLicenseKey(“PlaceYourLicenseKeyHere”)

This method only needs to be called once (but calling it multiple times does no harm, other than slowing your

program down a bit). Not calling this method will cause an exception to be raised in compiled programs, and

a registration reminder to be displayed in debugging builds.

It would be highly advisable for you to obfuscate the string and/or encrypt your license key in any applications

you release. The last part of this reference document provides additional information, including tips on how

to accomplish this.

Please make sure to include at least the following modules in your project, in order for the main module’s functions to work:

WindowPlacementExtensions_Domador_Private

ScreenExtensions_Domador_Private

The demo project for the Window Placement and Screen Extensions can be used as a starting point for a

new application. In order to adapt it to your needs, you are free to do the following:

1) You can delete/modify anything outside the Domador Software folder.

2) Within the Domador Software folder, you can delete the Tests folder and its contents. They are not needed for the extensions to work.

3) You are free to adapt and use anything inside the Tests folder in your project, as well as anything outside the Domador Software folder.

4) You are also free to modify the WindowPlacementExtensions_Domador module, with the exception of the EULA note, which you may delete

but not alter. Even if you delete it from your project, you need to abide by its terms.

5) Usage of the WindowPlacementExtensions_Domador_Private and ScreenExtensions_Domador_Private modules

is regulated by the EULA, the Window Placement and Screen Extensions End-User License Agreement.

—————–

Special Features

—————–

– This library is designed to prevent namespace clashes as much as possible, and also to make it easy to resolve such clashes if they occur.

– The WindowPlacementExtensions_Domador module can be renamed if desired.

– Any of the methods in WindowPlacementExtensions_Domador can be renamed or deleted as needed or desired.

– All user-accessible methods and properties in WindowPlacementExtensions_Domador_Private have Protected scope.

None of these methods’ and properties’ names will conflict with names in the Global namespace.

– For a tiny increase in speed, you can copy the method calls inside the methods WindowPlacementExtensions_Domador and

use them directly within your own code.

– You can change the default values for methods in WindowPlacementExtensions_Domador if you prefer different defaults.

————-

Compatibility

————-

Some of the methods in this library are currently only available for Windows, namely functions that refer to a window’s external,

non-client area (methods that contain the word True).

Windows-only methods:

CenterTrueHorizontallyOnScreen

CenterTrueOnScreen

CenterTrueVerticallyOnScreen

IsOffscreenTrue

IsOnscreenTrue

MaxTrueLeftForFullDisplay

MaxTrueTopForFullDisplay

OnscreenSectionTrueCornersXY

OnscreenSectionTrueDimensionsXY

OnscreenSectionTruePositionAndDimensionsXY

OnscreenSectionTruePositionXY

ScreenForTrueCenter

TrueBottom

TrueDefaultScreen

TrueHeight

TrueHorizontalCenter

TrueLeft

TrueMainScreen

TrueRight

TrueTop

TrueVerticalMiddle

TrueWidth

All of the other methods should work on Mac and Linux. (Light testing has been performed on a Mac. The methods are untested on Linux.)

———-

Examples

———-

1) Place a window (wnd2) ten pixels to the right of another window (wnd1)

wnd2.Left = wnd1.Right + 10 ‘ For the client area of wnd2 to be 10 pixels to the right of wnd1

wnd2.TrueLeft = wnd1.TrueRight + 10 ‘ For the left, outer edge of wnd2 to be 10 pixels to the right of the right, other edge of wnd1 (Windows-only)

2) Align the vertical centers of two windows, making wnd2’s center match wnd1’s

wnd2.VerticalMiddle = wnd1.VerticalMiddle ‘ To align the vertical centers of the client areas of both windows

wnd2.TrueVerticalMiddle = wnd1.TrueVerticalMiddle ‘ To align the vertical centers of the whole area of both windows (Windows only)

3) Place a window on the bottom, right hand corner of the main screen (Screen(0)).

‘ Client area

wnd1.Left = wnd1.MaxTrueLeftForFullDisplay

wnd1.Top = wnd1.MaxTrueTopForFullDisplay

‘ Full window (Windows only)

wnd1.TrueLeft = wnd1.MaxTrueLeftForFullDisplay

wnd1.TrueTop = wnd1.MaxTrueTopForFullDisplay

3) Place a window on the bottom, right-hand corner of the screen (the screen corresponding to the windows’ center).

‘ Align the inner, client area to the bottom, right-hand corner

wnd1.Left = wnd1.MaxTrueLeftForFullDisplay

wnd1.Top = wnd1.MaxTrueTopForFullDisplay

‘ Align the full window, including its outer borders, if any (Windows only)

wnd1.TrueLeft = wnd1.MaxTrueLeftForFullDisplay

wnd1.TrueTop = wnd1.MaxTrueTopForFullDisplay

4) Extend a window’s left edge to the left by ten pixels, enlarging its width by ten pixels as well.

wnd1.GrowLeft(10)

5) Move a window’s left edge to the right by ten pixels, shrinking its width by ten pixels as well.

wnd1.GrowLeft(-10)

””””””””””””””””””””””””””””””””””””””””

‘ Method Reference

””””””””””””””””””””””””””””””””””””””””

‘ Parameters in [ ] (square brackets) are optional and can be omitted, as long as the remaining non-optional parameters appear in the correct order.

Dim wnd as Window

””””””””””””””””””””””””””””””””””””””””

‘ Sections

””””””””””””””””””””””””””””””””””””””””

‘ Border and dimension adjustment

‘ Position information and adjustment

‘ Centering

‘ Positioning-limit information

‘ Screen information

‘ Onscreen section information

‘ Licensing and registration

‘ Module properties

””””””””””””””””””””””””””””””””””””””””

‘ Border and dimension adjustment

””””””””””””””””””””””””””””””””””””””””

‘ Adjust the position of of the window’s borders outward by Difference number of pixels,

‘ leaving the rest of the window’s borders in their current position.

‘ Positive values extend the border outward, increasing the window’s width or height.

‘ Negative values retract the border inward, decreasing the window’s width or height.

wnd.GrowBottom( Difference as Integer )

wnd.GrowLeft( Difference as Integer )

wnd.GrowRight( Difference as Integer )

wnd.GrowTop( Difference as Integer )

‘ Adjust the position of of the window’s borders inward by Difference number of pixels,

‘ leaving the rest of the window’s borders in their current position.

‘ Positive values retract the border inward, decreasing the window’s width or height.

‘ Negative values extend the border outward, increasing the window’s width or height.

wnd.ShrinkBottom( Difference as Integer )

wnd.ShrinkLeft( Difference as Integer )

wnd.ShrinkRight( Difference as Integer )

wnd.ShrinkTop( Difference as Integer )

‘ Adjusts the placement of a window’s edge without affecting the position of the opposite edge.

‘ If the new value is beyond the window’s opposite edge, then the two edge’s values will be exchanged,

‘ and the opposite edge will be set to the new value.

wnd.OnlyBottom = IntegerValue

wnd.OnlyLeft = IntegerValue

wnd.OnlyRight = IntegerValue

wnd.OnlyTop = IntegerValue

‘ Example A

‘ If originally wnd.Left = 100 and wnd.Right = 200,

‘ then after a call to wnd.OnlyLeft = 50, the new values will be

‘ wnd.Left = 50 and wnd.Right = 200,

‘ Example B

‘ If originally wnd.Left = 100 and wnd.Right = 200,

‘ then after a call to wnd.OnlyLeft = 300, the new values will be

‘ wnd.Left = 200 and wnd.Right = 300,

‘ Gets/sets the width/height of the whole window, which includes its client area and borders (if any)

‘ Get the dimension (Windows only)

IntegerValue = wnd.TrueHeight

IntegerValue = wnd.TrueWidth

‘ Set the dimension (Windows only)

wnd.TrueHeight = IntegerValue

wnd.TrueWidth = IntegerValue

‘ Provides the effective minimum/maximum dimensions for the window

‘ These methods resize the window to determine how small or large it can actually shrink or grow, before restoring it to its original size

‘ Values may differ from the theoretical values provided by .MinWidth, .MinHeight, .MaxWidth, and .MaxHeight

IntegerValue = wnd.EffectiveMaxHeight

IntegerValue = wnd.EffectiveMaxWidth

IntegerValue = wnd.EffectiveMinHeight

IntegerValue = wnd.EffectiveMinWidth

””””””””””””””””””””””””””””””””””””””””

‘ Position information and adjustment

””””””””””””””””””””””””””””””””””””””””

‘ Get a position’s value

IntegerValue = wnd.Bottom

IntegerValue = wnd.HorizontalCenter

IntegerValue = wnd.Right

IntegerValue = wnd.TrueBottom ‘ (Windows-only)

IntegerValue = wnd.TrueHorizontalCenter ‘ (Windows-only)

IntegerValue = wnd.TrueLeft ‘ (Windows-only)

IntegerValue = wnd.TrueRight ‘ (Windows-only)

IntegerValue = wnd.TrueTop ‘ (Windows-only)

IntegerValue = wnd.TrueVerticalMiddle ‘ (Windows-only)

IntegerValue = wnd.VerticalMiddle

‘ Set a new value for the corresponding position, repositioning the window, while maintaining its current size)

wnd.Bottom = IntegerValue

wnd.HorizontalCenter = IntegerValue

wnd.Right = IntegerValue

wnd.TrueBottom = IntegerValue ‘ (Windows-only)

wnd.TrueHorizontalCenter = IntegerValue ‘ (Windows-only)

wnd.TrueLeft = IntegerValue ‘ (Windows-only)

wnd.TrueRight = IntegerValue ‘ (Windows-only)

wnd.TrueTop = IntegerValue ‘ (Windows-only)

wnd.TrueVerticalMiddle = IntegerValue ‘ (Windows-only)

wnd.VerticalMiddle = IntegerValue

””””””””””””””””””””””””””””””””””””””””

‘ Centering

””””””””””””””””””””””””””””””””””””””””

‘ Place the window on the horizontal and/or vertical center of a screen.

‘ There are two optional parameters, either/both of which can be omitted

‘ 1) ScreenNumber : A screen object (e.g., Screen(0) ) or the number of the screen (e.g., 0 ) on which the window should be centered.

‘ If omitted, defaults to .ScreenForCenter. If nil, then it is set to the value in the .DefaultScreenForAllWindows module property)

‘ 2) AccountForAvailableArea: Whether to account for the space used for the Windows Taskbar or Mac Dock.

‘ If set to true, the window is centered in the space not covered by the Taskbar/Dock, rather than the screen as a whole.

‘ Defaults to False (so as to center the window on the screen, not just in the available area).

‘ Center according to the center of the window’s client area

wnd.CenterHorizontallyOnScreen( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = false] )

wnd.CenterOnScreen( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = false] )

wnd.CenterVerticallyOnScreen( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = false])

‘ Center according to the center of the whole window, including its borders (Windows-only)

wnd.CenterTrueHorizontallyOnScreen( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = false] )

wnd.CenterTrueOnScreen( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = false] )

wnd.CenterTrueVerticallyOnScreen( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = false])

””””””””””””””””””””””””””””””””””””””””

‘ Positioning-limit information functions

””””””””””””””””””””””””””””””””””””””””

‘ Indicates the rightmost/lowest value to which Left/Top or TrueLeft/TrueTop

‘ can be set in order for the window to still fit inside the screen.

‘ Setting Left/Top or TrueLeft/TrueTop to the value returned by these functions would place

‘ the window at the rightmost/lowest edge of the screen (or available area on the screen).

‘ There are two optional parameters, either/both of which can be omitted

‘ 1) ScreenNumber : A screen object (e.g., Screen(0) ) or the number of the screen (e.g., 0 ) for which to return positioning information.

‘ If omitted, defaults to the screen corresponding to the center of the window’s client area ( ScreenForCenter )

‘ 2) AccountForAvailableArea: Whether to account for the space used for the Windows Taskbar or Mac Dock.

‘ If set to true, then the value returned will be just far enough to the left or top of the screen

‘ that the window won’t be covered by the Taskbar/Dock.

‘ Defaults to True.

the window is centered in the space not covered by the Taskbar/Dock, rather than the screen as a whole.

‘ Client area

IntegerValue = wnd.MaxLeftForFullDisplay( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = true])

IntegerValue = wnd.MaxTopForFullDisplay( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = true])

‘ Full window, including borders, if applicable (Windows only)

IntegerValue = wnd.MaxTrueLeftForFullDisplay( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = true])

IntegerValue = wnd.MaxTrueTopForFullDisplay( [Scr as Screen/ScreenNumber as Integer,] [AccountForAvailableArea as Boolean = true])

””””””””””””””””””””””””””””””””””””””””

‘ Screen information functions

””””””””””””””””””””””””””””””””””””””””

‘ Determines whether the window contains the specified point

BooleanValue = wnd.ContainsPointXY(X as Integer, Y as Integer) ‘ Whether the point is in the window’s client area

BooleanValue = wnd.ContainsPointTrueXY(X as Integer, Y as Integer) ‘ Whether the point is in the window’s whole area (Windows only)

‘ Whether the window is fully offscreen (not on any given screen) or partially/fully onscreen (on any screen)

BooleanValue = wnd.IsOffscreen ‘ All of the client area lies offscreen

BooleanValue = wnd.IsOffscreenTrue ‘ All of the window lies offscreen (Windows only)

BooleanValue = wnd.IsOnscreen ‘ At least part of client area lies inside any of the screens

BooleanValue = wnd.IsOnscreenTrue ‘ At least part of window’s area lies inside any of the screens (Windows only)

‘ Whether the window is fully offscreen relative to the specified screen, or partially/fully onscreen relative to that screen

BooleanValue = wnd.IsOffscreen( Scr as Screen ) ‘ All of the client area lies offscreen, relative to the specified screen

BooleanValue = wnd.IsOffscreenTrue( Scr as Screen ) ‘ All of the window lies offscreen, relative to the specified screen (Windows only)

BooleanValue = wnd.IsOnscreen( Scr as Screen ) ‘ At least part of client area lies inside the specified screen

BooleanValue = wnd.IsOnscreenTrue( Scr as Screen ) ‘ At least part of window’s area lies inside the specified screen (Windows only)

‘ Provides the screen on which the point at the center of the window is located

‘ Screen for the point at the center of the client area

ScreenObject = wnd.ScreenForCenter

‘ Screen for the point at the center of the whole window (Windows only)

ScreenObject = wnd.ScreenForTrueCenter

‘ Determines which screen contains most of the window’s area

‘ Only considers the window’s client area

ScreenObject = wnd.MainScreen

‘ Considers the window’s whole area, including its borders (Windows only)

ScreenObject = wnd.TrueMainScreen

‘ Determines the “default screen” for a window.

‘ The screen provided by these functions is the the value provided by MainScreen / TrueMainScreen.

‘ However, if these functions return nil, then the value set in the .DefaultScreenForAllWindows module property is used.

‘ Calls MainScreen

ScreenObject = wnd.DefaultScreen

‘ Calls TrueMainScreen (Windows only)

ScreenObject = wnd.TrueDefaultScreen

””””””””””””””””””””””””””””””””””””””””

‘ Onscreen section information

””””””””””””””””””””””””””””””””””””””””

‘ Provides information about the section of a window or its client area present on a specific screen.

‘ If the screen is not specified, the screen provided by MainScreen/TrueMainScreen is the one used implicitly.

‘ Provides the corners of the section of the window that are present on a particular screen, if any

‘ Returns True if the information was successfully retrieved into the variables passed in by reference.

‘ If False, then either the client area or window is completely offscreen relative to the specified screen, or the information could not be retrieved for some reason.

‘ Client area

BooleanValue = OnscreenSectionCornersXY([Scr as Screen,] ByRef Left as Integer, ByRef Top as Integer, ByRef Right as Integer, ByRef Bottom as Integer)

‘ Whole window (Windows only)

BooleanValue = OnscreenSectionTrueCornersXY([Scr as Screen,] ByRef Left as Integer, ByRef Top as Integer, ByRef Right as Integer, ByRef Bottom as Integer)

‘ Provides the dimensions of the section of the client area or window that are present on a particular screen, if any.

‘ Returns True if the information was successfully retrieved into the variables passed in by reference.

‘ If False, then either the client area or window is completely offscreen relative to the specified screen, or the information could not be retrieved for some reason.

‘ Client area

BooleanValue = OnscreenSectionDimensionsXY([Scr as Screen,] ByRef Width as Integer, ByRef Height as Integer)

‘ Whole window (Windows only)

BooleanValue = OnscreenSectionTrueDimensionsXY([Scr as Screen,] ByRef Width as Integer, ByRef Height as Integer)

‘ Provides the position (specified by the top-left corner) and the dimensions of the section of the client area or window that are present on a particular screen, if any.

‘ Returns True if the information was successfully retrieved into the variables passed in by reference.

‘ If False, then either the client area or window is completely offscreen relative to the specified screen, or the information could not be retrieved for some reason.

‘ Client area

BooleanValue = OnscreenSectionPositionAndDimensionsXY([Scr as Screen,] ByRef Left as Integer, ByRef Top as Integer, ByRef Width as Integer, ByRef Height as Integer)

‘ Whole window (Windows only)

BooleanValue = OnscreenSectionTruePositionAndDimensionsXY([Scr as Screen,] ByRef Left as Integer, ByRef Top as Integer, ByRef Width as Integer, ByRef Height as Integer)

‘ Provides the position (specified by the top-left corner) of the section of the client area or window that are present on a particular screen, if any.

‘ Returns True if the information was successfully retrieved into the variables passed in by reference.

‘ If False, then either the client area or window is completely offscreen relative to the specified screen, or the information could not be retrieved for some reason.

‘ Client area

BooleanValue = OnscreenSectionPositionXY([Scr as Screen,] ByRef Left as Integer, ByRef Top as Integer)

‘ Whole window (Windows only)

BooleanValue = OnscreenSectionTruePositionXY([Scr as Screen,] ByRef Left as Integer, ByRef Top as Integer)

””””””””””””””””””””””””””””””””””””””””

‘ Licensing and registration

””””””””””””””””””””””””””””””””””””””””

‘ Verifies the license key and unlocks access to the methods in this module (if the license key is valid)

Protected RegisterLicenseKey( LicenseKey as String )

””””””””””””””””””””””””””””””””””””””””

‘ Module properties

””””””””””””””””””””””””””””””””””””””””

‘ Gets or sets the default screen used by the methods in this module when

‘ a screen isn’t specified or can’t be determined by a better method.

‘ Can be set to nil if desired. This value is initially set to Screen(0).

ScreenObject = DefaultScreenForAllWindows

DefaultScreenForAllWindows = ScreenObject

‘ Determines whether a PlatformNotSupportedException is raised if you call

‘ a function that’s not supported on your operating system or platform.

‘ If set to False, unsupported subroutines will have no action,

‘ while unsupported functions will return a default or uninitialized value.

‘ Initially set to True.

BooleanValue = RaiseExceptionIfPlatformUnsupported

RaiseExceptionIfPlatformUnsupported = BooleanValue

””””””””””””””””””””””””””””””””””””””””

‘ Protecting your license key

””””””””””””””””””””””””””””””””””””””””

‘ It would be highly advisable for you to obfuscate and/or encrypt the string(s) containing your license key in any applications that

‘ include these extensions. This will make it harder for your license key to obtained by unauthorized users (if they inspect

‘ the binary file for your application). Domador Software S.R.L. reserves the right to invalidate keys that are disclosed to

‘ unauthorized users. Domador Software S.R.L. will decide at its own discreation whether to provide a free replacement key

‘ to the legitimate user of an invalidated key.

‘ Invalidated keys will keep working where used, but won’t be usable in newer releases of this library.

‘ Please help protect our livelihood by obfuscating and/or encrypting your license key. Here are some ideas for doing this.

‘ You can also design your own obfuscation/encryption schemes, if you have the corresponding skills.

””””””””””””””””””””””””””””””””””””

‘ Idea A: Encrypt your application with an application packer.

””””””””””””””””””””””””””””””””””””

‘ Before releasing your application, pack and encrypt it with an executable packer, such as The Enigma Protector (http://enigmaprotector.com/).

‘ Using a packer has its pros and its cons (such as a greater likelihood of false-positive virus detections in your application by antivirus engines).

””””””””””””””””””””””””””””””””””””

‘ Idea B: Obfuscate the strings in your project

””””””””””””””””””””””””””””””””””””

‘ You can use Arbed (http://www.tempel.org/Arbed/Arbed) to obfuscate the license key’s string

‘ (along with other strings, if desired), before releasing your application.

””””””””””””””””””””””””””””””””””””

‘ Thank you very much for your help.

Copyright © 2020 Domador Software S.R.L.