Tag Archives: Methods

Sorting in EditTables

In previous versions of OpenInsight, EditTable sorting has been implemented by the SORTEDCOL property, which simply performs a Quicksort on a single column and then only on the visible text contained in each cell.  This latter trait is particularly sub-optimal because it pays no attention to the actual type of data represented in the cell itself; for example, if you wish to sort on a column containing dates, you usually have to write code to convert the data to a numeric format first, and then pass the results onto the V119 sort function, all of which gets tedious very quickly.

In OpenInsight 10 the SORTEDCOL property has been deprecated and has been replaced by the new SORT method detailed below:

The SORT method

This method allows you to perform a multi-column sort on an EditTable, along with the ability to convert the data to an appropriate format before the sort takes place.

Call Exec_Method( CtrlEntID, "SORT", SortCriteria, SortOptions )

The method takes two parameters.  The first, SortCriteria, which is a dynamic array structured as follows:

<0,1> @svm'd list of column numbers to sort by
<0,2> @svm'd list of sorting directions/justifications for each column 
      passed in field <0,1>.  Available values are:

         0 - Descending Left
         1 - Ascending Left
         2 - Descending Right
         3 - Ascending Right

<0,3> @svm'd list of ICONV patterns used to convert the column data to its
      internal format before the sort takes place.

The default ICONV pattern used for sorting a column is taken from it’s VALID property.  This means that you can flag a column as a date (e.g. “DE”) in the Form Designer, and have it sort properly in a numeric fashion without any extra coding needed.

The second parameter, SortOptions, is a dynamic array structured as follows:

<1> If TRUE$ then perform a trim operation before the sort takes place, or
    FALSE$ to prevent the trim. If this field is null then the SORTTRIM 
    property is used to decide if a trim operation takes place.

(A trim operation is the removal of “blank” rows from the EditTable control.  A description of trim functionality will appear in a future post).

Using the SORT method triggers a new event called SORTED:

The SORTED event

This event takes the same parameters as passed to the SORT method described above.  This event is fired before any sorting takes place, thereby giving you the chance to modify the criteria or options, or even prevent it by using the Set_EventStatus() function.  All event script and QuickEvent handlers are processed before sorting.

The COLHEADERSORTINGMODE property

This is another new property for EditTable controls and can be set to one of the following values:

  • 0 (Disabled – this is the default value)
  • 1 (Sort on single-click)
  • 2 (Sort double-click)

When set to to 1 or 2, clicking or double-clicking on a column header will automatically sort the contents of the control by that column, in a similar manner to Popup entity sorting.  The SORTED event is still raised in the manner described above however, so you may still intercept and modify the process if you wish.

The SORTTRIM property

When set to TRUE a sort operation automatically performs a trim operation before sorting.  This property can be overridden by passing a flag in the SORT method SortOptions parameter described above.

We hope these improvements make sorting in EditTables a little less onerous.

 

[EDIT: 27 Sep 15, Updated for SortOptions argument and SORTTRIM property]

[EDIT: 17 Nov 15, Updated for COLHEADERSORTINGMODE property]

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

 

 

 

 

 

The SCALED event

As covered in our recent posts on scaling and High-DPI, OpenInsight now has the capability to dynamically alter the scale of a form at runtime, taking care of layout, fonts and images.  However, there may be circumstances where this is not sufficient – perhaps you need to tweak the layout yourself, or perhaps you need to display a specific image rather than rely on a DPI Image List.  In this case you will need to know when the scaling operation has taken place, and you can handle this in the new SCALED event:

SCALED event

This WINDOW event is triggered when the SCALEFACTOR property is changed or when the form is moved to another monitor with a different DPI.

bForward = SCALED( ctrlEntID, ctrlClassID, origDpiX, origDpiY, origScaleFactor, |
                                           newDpiX, newDpiY, newScaleFactor )

The event is passed the following event-specific arguments:

  1. The original X DPI value
  2. The original Y DPI value
  3. The original SCALEFACTOR value
  4. The new X DPI value
  5. The new Y DPI value
  6. The new SCALEFACTOR value

The system performs no default processing for this event.

 

Handling layout for scaled forms

Of course, this leads us to one of the main issues with handling scaling: how do you get and set layout properties like SIZE for a scaled form? What units are used?

There are basically two choices available:

  1. Use Device Independent Pixels (DIPs): With this method all coordinates are treated as though the form is scaled at 96 DPI with a scale factor of 1.  The system is then responsible for mapping them to actual pixels at runtime.
  2. Use Pixels (PX): With this method the coordinates passed are treated as actual screen pixels regardless of the DPI or scale factor.

Using DIPs may seem easiest at first, especially in terms of backwards compatibility with existing code, but it does have some drawbacks:

  • Positioning can be imprecise due to integer rounding, and you may sometimes find a case where you need complete accuracy.
  • Some properties and events cannot use DIPs at all (mainly those that relate to screen coordinates), thereby leading to the need for some type of dual coordinate system, resulting in added complexity and possible confusion.

So, to keep things simple, OpenInsight operates in Pixel mode by default, which means it keeps a single and accurate coordinate system.  Remember, scaling is an “opt-in” system, meaning that none of your existing forms will scale unless you specify otherwise (via the DPISCALING and SCALEFACTOR properties), so you can review your code before enabling it and ensure that you don’t encounter any problems.

However, even though the default coordinate system is Pixels we don’t want to remove the choice of using DIPs if you prefer, so forms now support a new SCALEUNITS property that allows properties like SIZE to operate in either DIP or Pixel mode.

SCALEUNITS property

This is a WINDOW property that defines the units used when accessing layout properties like SIZE, CLIENTSIZE, TRACKINGSIZE and so on.  Note that it also affects events like BUTTONDOWN and methods like TEXTRECT too.

It accepts the following values:

  • “0” – Scaling units are Pixels
  • “1” – Scaling units are DIPs

Example: Scale a form and examine it’s SIZE using different SCALEUNITS

* // SCALEUNITS property equates - (from PS_WINDOW_EQUATES)
 equ PS_SCU_PIXELS$ to 0
 equ PS_SCU_DIPS$   to 1

* // Assume we are currently running with Pixel units
call set_Property_Only( @window, "SIZE", 10 : @fm: 10 : @fm : 400 : @fm : 300 )

* // Now scale the window to twice its normal size ( actual XY remains constant
* // for a form when setting SCALEFACTOR - only the width and height change)
call set_Property_Only( @window, "SCALEFACTOR", 2 )

* // SIZE returns 10x10x800x600 
pxSize = get_Property( @window, "SIZE" )

* // Now set the scaling units to DIPS
call set_Property_Only( @window, "SCALEUNITS", PS_SCU_DIPS$ )

* // SIZE returns 5x5x400x300 
dipSize = get_Property( @window, "SIZE" )

* // Note that the X and Y returned in the DIPs SIZE above have also been scaled. 
* // The form hasn't moved, but the units of measurement have changed, so the 
* // location is reported relative to a _theoretical_ scaled desktop size.

At first glance it may seem that the SCALEUNITS property should be a SYSTEM property rather than a WINDOW one, but bear in mind that OpenInsight applications may inherit from one another, and executing a form designed for one set of units while running in another application with a different “global” setting would undoubtedly cause problems.  Of course there’s nothing to stop you setting the SCALEUNITS to DIPs in a promoted CREATE event for your own applications but that’s another story…

 

Scaling helper methods

There are six new WINDOW methods you can use to help with manual scaling – they convert between Pixels and DIPs based on the form’s current DPI and SCALEFACTOR (They are not affected by the SCALEUNITS property):

  • SCALEFONT
  • SCALESIZE
  • SCALEVALUE

The “SCALE” methods perform a DIPs to Pixel conversion.

  • UNSCALEFONT
  • UNSCALESIZE
  • UNSCALEVALUE

The “UNSCALE” methods perform a Pixel to DIPs conversion.

(You only really need the SCALEVALUE and UNSCALEVALUE methods, but the other four have been added to make things a little more convenient for you).

SCALEFONT method

This method takes an unscaled FONT property and scales it relative to the current scale factor of the form.

scaledFont = exec_Method( @window, "SCALEFONT", origFont )

SCALESIZE method

This method takes an unscaled SIZE property and scales it relative to the current scale factor of the form.

scaledSize = exec_Method( @window, "SCALESIZE", origSize )

SCALEVALUE method

This method takes an unscaled value and scales it relative to the current scale factor of the form.

scaledVal = exec_Method( @window, "SCALEVALUE", origVal )

UNSCALEFONT method

This method takes a scaled FONT property and unscales it relative to the current scale factor of the form.

unscaledFont = exec_Method( @window, "UNSCALEFONT", scaledFont )

UNSCALESIZE method

This method takes a scaled SIZE property and unscales it relative to the current scale factor of the form.

unscaledSize = exec_Method( @window, "UNSCALESIZE", scaledSize )

UNSCALEVALUE method

This method takes a scaled value and unscales it relative to the current scale factor of the form.

unscaledVal = exec_Method( @window, "UNSCALEVALUE", scaledVal )

Example: Moving a control using DIP coordinates on a form with Pixel SCALEUNITS

* // Example - Move a control using DIP coordinates. We get the current pixel
* //           size, unscale it so we have the value as it _would_ be at
* //           96DPI/ScaleFactor 1 (i.e. DIPs), offset it by 10 DIPs, scale
* //           it back to Pixels and and then move it.
* // Get the current scaled size (pixels) - assume we have a SCALEFACTOR of 1.5
ctrlSize = get_Property( myCtrl, "SIZE" )

* // Unscale it back to 96DPI/ScaleFactor 1.0 - i.e. to DIPs
ctrlSize = exec_Method( @window, "UNSCALESIZE", ctrlSize )

* // Adjust it to whatever we need (assume we want to offset it by 10 DIPs
* // (10 pixels at 96 DPI)
ctrlSize<1> = ctrlSize<1> + 10
ctrlSize<2> = ctrlSize<2> + 10
 
* // And ask the parent form to calculate where it _should_ be using the 
* // current scale factor
ctrlSize = exec_Method( @window, "SCALESIZE", ctrlSize )
 
* // And move it using pixels ...
call set_Property_Only( myCtrl, "SIZE", ctrlSize )

The previous example is rather contrived and is really only there to highlight how the methods can be used.  Another way of doing this would be to switch to DIPs using the SCALEUNITS property like so:

* // SCALEUNITS property equates - (from PS_WINDOW_EQUATES)
equ PS_SCU_PIXELS$ to 0
equ PS_SCU_DIPS$   to 1

* // Set the scaling units to DIPS 
scaleUnits = set_Property( @window, "SCALEUNITS", PS_SCU_DIPS$ ) 

ctrlSize = get_Property( myCtrl, "SIZE" )

* // Offset the control by 10 DIPs
ctrlSize<1> = ctrlSize<1> + 10 
ctrlSize<2> = ctrlSize<2> + 10

call set_Property_Only( myCtrl, "SIZE", ctrlSize )

* // And restore the SCALEUNITS
call set_Property_Only( @window, "SCALEUNITS", scaleUnits )

The AUTOSCALE property

By default OpenInsight maintains automatic scaling for all controls on a form, even after you’ve manually set a scaled property yourself.  However, you can opt out of this behaviour by using the boolean AUTOSCALE property:

  • When set to TRUE (the default value) it enables scaling for a control.
  • When set to FALSE no automatic scaling is performed.

This property applies to all controls (but not to WINDOW objects for obvious reasons).

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

The FILESYSTEM WATCHDIR method

We’ve already taken a look at the new FILESYSTEM object in a previous post, but this time we’re going to focus on a new method we’ve added called WATCHDIR.

This method allows you to monitor the contents of one or more directories on the system and be notified of any changes occurring within them.  It’s API is quite simple and takes up-to three arguments:

  1. The name of the directory to watch (required).
  2. A optional boolean flag denoting if you wish to include sub-directories. (defaults to FALSE$).
  3. An optional set of bit-flags detailing the kind of changes you are interested in.  By default WATCHDIR notifies you of file creation, changes to the name, and changes to the “Last-Write” time.

Example:

$insert msWin_FileNotify_Equates

// Only watch for files being created in the specified dir ...
watchFlags      = FILE_NOTIFY_CHANGE_CREATION$
bIncludeSubDirs = FALSE$
call exec_Method( "FILESYSTEM", "WATCHDIR", "c:\temp\incoming", |
                  bIncludeSubDirs, watchFlags )

When a change occurs the FILESYSTEM object raises a CHANGED event to notify you of the fact,  As with any other OI window or control you can write your own FILESYSTEM CHANGED event handler to respond to this – note that this event is per application, not per window.

Like the standard CHANGED event the relevant change information is passed in the “NewData” argument – in this case “NewData” contains a dynamic array with two fields:

<1> The name and path of the file being changed
<2> A code specifying the type of change

Example FILESYSTEM CHANGED event:

$insert msWin_FileNotify_Equates

changeFile = newData<1>
changeCode = newData<2>

info = ""

begin case
   case ( changeCode = FILE_ACTION_ADDED$ )
      info = "Added"
   case ( changeCode = FILE_ACTION_REMOVED$ )
      info = "Deleted"
   case ( changeCode = FILE_ACTION_MODIFIED$ )
      info = "Modified"
   case ( changeCode = FILE_ACTION_RENAMED_OLD_NAME$ )
      info = "Renamed From"
   case ( changeCode = FILE_ACTION_RENAMED_NEW_NAME$ )
      info = "Renamed To"
end case

call send_Info( info : " " : changeFile )

Technical note: The WATCHDIR method is based on the underlying ReadDirectoryChangesW Windows API function, details of which can be found here.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

The IDLEPROC Queue

One of the new features added to the SYSTEM object is the “IDLEPROC queue”.  This is an enhancement to the existing IDLEPROC property as it allows you to queue multiple requests via the new SYSTEM ADDIDLEPROC method like so:

* // Run a process in the future 
procID   = "RUN_SOME_PROCESS"
procArg  = "42"
procTime = "12:00:00"  ; * // midday
procDate = oconv( date() + 1, "D4/" ) ; * // tommorrow

call exec_Method( "SYSTEM", "ADDIDLEPROC", procID, procArg, procTime, procDate )

* // Run a process ASAP...
procID = "RUN_SOME_OTHER_PROCESS"
procArg = "X43"
procTime = "" ; * // ASAP
procDate = "" ; * // ASAP

call exec_Method( "SYSTEM", "ADDIDLEPROC", procID, procArg, procTime, procDate )

The contents of the queue can be examined via the new SYSTEM IDLEPROCQUEUE property:

ipQ    = get_Property( "SYSTEM", "IDLEPROCQUEUE" )
xCount = fieldCount ( ipQ, @fm ) 
for x = 1 to xCount
   ip       = ipQ<x>
   procID   = ipQ<0,1>
   procArg  = ipQ<0,2>
   procTime = ipQ<0,3>
   procDate = ipQ<0,4>
next

The normal IDLEPROC property works just as it always has done with the following caveats:

  • Setting the IDLEPROC property will replace the entire contents of the queue (so you can use this to clear the queue if you wish).
  • Getting the IDLEPROC property will only return the first item in the queue if there are multiple items.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

Progress Bar controls

One of the new controls supported by OpenInsight 10 is the Windows Progress Bar control which is used to display the progress of lengthy operations.

Progress Bar

Windows 7 Aero Progress Bar

Windows XP Progress Bar

Windows XP Progress Bar

It is a fairly simple control and supports the following properties:

  • BORDER
  • ERRORCOLOR
  • MARQUEE
  • NORMALCOLOR
  • PAUSEDCOLOR
  • RANGE
  • SHOWTEXT
  • SMOOTH
  • STATE
  • STEP
  • SYNCTASKBAR
  • TEXT
  • TRANSLUCENCY
  • VALUE
  • VERTICAL

And the following methods:

  • DECREMENT
  • INCREMENT

BORDER property

Setting this boolean property to TRUE (“1”) draws a border around the control.  This is the default value.

XP Progress Bar without border

Translucent XP Progress Bar without a border

ERRORCOLOR property

This property is a standard color value and sets the color of the bar when it is in the “error” state (see the STATE property below).  Depending on the visual style in use this property normally defaults to a red color.

Red Progress Bar

Windows Classic smooth style Progress Bar with an ERRORCOLOR of 255 (red)

MARQUEE property

This property is an integer value that contains the time in milliseconds between marquee animation updates.  Setting it to 0 stops the marquee animation.

Progress Bar with marquee effect

Aero Progress Bar with a MARQUEE property of 50 (i.e. it animates every 50 ms)

XP Progress Bar with marquee effect

Windows XP Progress Bar with a MARQUEE property of 50

NORMALCOLOR property

This property is a standard color value and sets the color of the bar when it is in the “normal” state (see the STATE property below).  Depending on the visual style in use this property normally defaults to a green color, though in other schemes like “XP Olive” this defaults to an orange color instead.

Purple Progress Bar

Windows 7 Aero progress Bar with a purple NORMALCOLOR (255,0,255)

PAUSEDCOLOR property

This property is a standard color value and sets the color of the bar when it is in the “paused” state (see the STATE property below).  Depending on the visual style in use this property normally defaults to an amber or yellow color.

Windows 7 Aero paused progress bar

Windows 7 Aero segmented Progress Bar with a STATE of “3” (paused)

RANGE property

This property is an @fm-delimited array of two integers containing the upper and lower limits of the progress bar.

<1> Low limit
<2> High Limit

The VALUE property must be between these two values.

SHOWTEXT property

Setting this property to TRUE (“1”) will display the contents of the TEXT property in the center of the progress bar.  The default is FALSE ( “0”).

SMOOTH property

Setting this property to TRUE (“1”) causes the progress indicator to be drawn as a continuous bar rather than in the usual segmented style.

Smooth Progress Bar

Windows Classic Smooth Progress Bar – i.e. a SMOOTH style of TRUE (“1”)

Segmented Progress Bar

Windows 7 Aero segmented Progress Bar – i.e. a SMOOTH style of FALSE (“0”)

STATE property

This property sets the visual state of the progress bar.  It can be one of the following values:

  • “1” – Normal (green)
  • “2” – Error (red)
  • “3” – Paused (yellow)

Each of these states has a default color as indicated above but this can be changed by one of the bar color properties (NORMALCOLOR, ERRORCOLOR and PAUSEDCOLOR).

Examples:

Progress Bar Error

Windows 7 Aero Progress bar with a STATE property of 2

Progress Bar Paused

Windows 7 Aero Progress bar with a STATE property of 3

STEP property

This property is a simple integer and is used in conjunction with the INCREMENT method.  If the latter is called with no value the progress bar is incremented by the amount specified in this property.

SYNCTASKBAR property

When set to TRUE (“1”) the parent form’s taskbar button is automatically updated to mirror the state of the Progress Bar control (as per our previous post on Taskbar Integration).

Synchronized Progress Bar

Windows 7 Aero Progress Bar with SYNCTASKBAR set to TRUE (“1”)

This property has no effect unless the application is running on Windows 7 or higher.

TEXT property

This property is the same as the standard TEXT property.  However, any occurrences of the substring “%p%” within the text will be replaced with the current percentage complete.

Progress Bar with TEXT

Windows 7 Aero Progress Bar with a TEXT property of “%p% Complete”

TRANSLUCENCY property

This property specifies the transparency of the control’s background (i.e. the progress bar itself is not affected).  It is based on simple percentage amount, “0″ being fully opaque and “100″ being fully transparent (and therefore not visible).

Translucent Progress Bar

Windows 7 Aero Progress Bar with a TRANSLUCENCY of 50

VALUE property

This simple integer property sets the current value (position) of the progress bar.  It should be a value between the limits set by the RANGE property.

Progress Bar 25% complete

Windows 7 Aero Progress Bar with a RANGE of [0,200] and a VALUE of 50

VERTICAL property

Setting this property to TRUE (“1”) draws the progress bar in a vertical fashion – i.e. it increments from the bottom to the top.

Vertical Progress Bar

Windows 7 Aero Progress Bar with a VERTICAL property of TRUE (“1”)

DECREMENT method

exec_Method( ctrlEntID, "DECREMENT", amount )

This method decrements the progress bar by a specified amount.  If no amount is specified the bar is decremented by the value contained in the STEP property instead.

INCREMENT method

exec_Method( ctrlEntID, "INCREMENT", amount )

This method increments the progress bar by a specified amount.  If no amount is specified the bar is incremented by the value contained in the STEP property instead.

Further reading

More information on Progress Bars can be found on the MSDN site here, along with some user interface guidelines here.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

Date and Time Picker controls

Another Windows Common Control exposed by OpenInsight 10 is the Date and Time Picker (DTP) control. This presents a simple interface for a user to enter date and/or time information in a standard or custom format.  It also provides an option to display a drop-down calendar for picking a date.

Date and Time Picker control

Date and Time Picker control

Date and Time Picker control with calendar

Date and Time Picker control with calendar

It supports the following properties:

  • CALALIGN
  • CALBACKCOLOR
  • CALFONT
  • CALFORECOLOR
  • CALMONTHBACKCOLOR
  • CALTITLEBACKCOLOR
  • CALTITLEFORECOLOR
  • CALTRAILINGFORECOLOR
  • CHECK
  • CHECKBOX
  • CUSTOMFORMAT
  • FORMAT
  • IDEALSIZE
  • MAXVALUE
  • MINVALUE
  • UPDOWN
  • VALUE

It supports the following method:

  • CLOSECAL

And the following events:

  • CHAR
  • CHANGED
  • CLOSEUP
  • DROPDOWN
  • GOTFOCUS
  • LOSTFOCUS

CALALIGN property

This property controls the alignment of the drop-down calendar and can be one of the following values:

  • “L” (Left – the default)
  • “R” (Right)

CALBACKCOLOR property

This property is an RGB color value that specifies the background color displayed between months of the drop-down calendar.  Setting this property has no effect if visual styles are enabled.

CALFONT property

This property specifies the font of the drop-down calendar – it has the same structure as the regular OpenInsight FONT property.  Setting this property has no effect if visual styles are enabled.

CALFORECOLOR property

This property is an RGB color value that specifies the text color of the drop-down calendar. Setting this property has no effect if visual styles are enabled.

CALMONTHBACKCOLOR property

This property is an RGB color value that specifies the background color displayed within the month of the drop-down calendar.  Setting this property has no effect if visual styles are enabled.

CALTITLEBACKCOLOR property

This property is an RGB color value that specifies the background color displayed in the title of the drop-down calendar.  Setting this property has no effect if visual styles are enabled.

CALTITLEFORECOLOR property

This property is an RGB color value that specifies the text color displayed in the title of the drop-down calendar.  Setting this property has no effect if visual styles are enabled.

CALTRAILINGFORECOLOR property

This property is an RGB color value that specifies the text color used to display the header day and trailing day text in the drop-down calendar.  Setting this property has no effect if visual styles are enabled.

CHECK property

This is a boolean value that specifies if the DTP checkbox is ticked.  It only applies if the DTP control contains a checkbox (see the CHECKBOX property below).

CHECKBOX property

This is a boolean value that specifies if a checkbox is shown within the DTP control. Normally the DTP control always contains a date/time value (i.e. it is never considered empty).  However if a checkbox is shown then it is only considered to contain a valid date/time if the checkbox is ticked (see the CHECK property above).

CUSTOMFORMAT property

By default the format of the date and time displayed by the DTP control is one of the standard formats as defined in the user’s Windows environment settings:

Windows date and time settings

Windows date and time settings

The FORMAT property (see below) can be used to specify one of these.

However, it is possible to use a custom format and this can be set using either a standard Windows format string or a standard Revelation Date and Time IConv/Oconv format (“D”, “DT”  and “MT”) which sets the underlying Windows format appropriately.

e.g.  “D4/E” will be translated to “dd/MM/yyyy” and so on.

FORMAT property

This property specifies the format of the date and time displayed in the control and can be one of the following values:

  • “0” – Custom format (set when using the CUSTOMFORMAT property – don’t set this yourself!)
  • “1” – Windows Long Date format
  • “2” – Windows Short Date format
  • “3” – Windows Time format

IDEALSIZE property

This get-only property returns the size needed to display the control without any clipping as an @fm-delimited array:

<1> Ideal width in pixels
<2> Ideal height in pixels

MAXVALUE property

Specifies the maximum date and time that can be entered in the control. This is a standard Revelation DateTime format of:

<date> : "." : <time>

Where date is the number of days elapsed since 31/12/1967, and time is the fraction (percentage) of the day that has elapsed.

MINVALUE property

Specifies the minimum date and time that can be entered in the control. This is a standard Revelation DateTime format of:

<date> : "." : <time>

Where date is the number of days elapsed since 31/12/1967, and time is the fraction (percentage) of the day that has elapsed.

UPDOWN property

By default the DTP control displays a button to access a drop-down month calendar for modifying the date.  Setting this property to TRUE (“1”) displays a Windows UpDown control to modify date-time values instead.

Date and Time Picker with an UpDown control

Date and Time Picker with an UpDown control

VALUE property

This property specifies the current value of the DTP control in the standard Revelation DateTime format of:

<date> : "." : <time>

Where date is the number of days elapsed since 31/12/1967, and time is the fraction (percentage) of the day that has elapsed.

While the TEXT property is supported the VALUE property should be used to access the DTP date-time values to avoid possible complications with custom formatting strings.

CLOSECAL method

This method simply closes a dropped-down month calendar. It takes no arguments.

call exec_Method( ctrlEntID, "CLOSECAL" )

Further reading

More information on the Date and Time Picker control can be found on the MSDN site here,

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

OpenInsight and High-DPI

With the increasing popularity of high-resolution monitors, one of the biggest usability problems today is the display size of text and UI controls, because they appear smaller as the screen resolution increases. The recommended advice to overcome this is to increase the DPI (dots-per-inch) setting of the system, thereby enlarging these elements and making them easier to see and read. If you’ve been using Windows Vista and above you’ve probably already seen this Control Panel applet that allows you to easily change your DPI settings:

DPI Control Panel Applet

Windows 7 DPI Control Panel Applet

However, unless an application is designed to be DPI-aware this can result in some unsatisfactory results, such as over-large fonts, clipped controls and blurry windows. This is because many older Windows applications assume a constant DPI (96) when setting font and size coordinates and they do not apply any scaling to these values, thereby resulting in the aforementioned problems.

(NB. The “magic number” of 96 that you’ll see throughout this post is due to the fact that at 96 DPI one logical pixel is equal to one screen pixel – this is the “100%” setting in the Control Panel applet shown above).

In an effort to accommodate these applications Microsoft have introduced a couple of OS features over the years:

  • On Windows XP the system fonts and some system UI elements are scaled up at runtime, but this leads to the common problem of text appearing larger and being clipped as the actual size of the bounding control is usually not scaled.
  • On Windows Vista and above a feature called “DPI-virtualization” automatically scales windows belonging to an application not marked as “DPI-aware” – in effect they are rendered at 96 DPI to an off-screen bitmap, resized, and then drawn to the screen, but this can result in some blurry windows due to pixel stretching.  OpenInsight 10 is marked as a DPI-aware application so will not be subjected to DPI-virtualization.

OpenInsight 10, High-DPI and automatic scaling.

OpenInsight 10 supports High-DPI by automatically scaling-up all GUI objects at runtime when created through the SYSTEM object’s CREATE method (formerly known as the “Utility CREATE service”). This affects the following two properties:

  • Size coordinates
  • Fonts

The actual scaling for coordinates is calculated by the following simple formula:

screenPixels = logicalPixels * ( currentDPI / 96 )

For example, if you create a control with a size of 200×100 and you are running at 144 DPI (i.e. 150% as per the Control Panel applet above) then the control will be created with an actual size of 300×150 pixels.

The font point size is similarly multiplied by the scaling factor (i.e. currentDPI / 96 ).

Supporting images under High-DPI

Another noticeable issue when running at high DPI settings are images, which are assumed to have been designed for 96 DPI and therefore have to be scaled up at runtime leading to a potential loss of quality due to the resize.  To help with this the tool-set has been extended to allow repository BITMAP entities to specify multiple image files when being defined. The first will be used for 96 DPI (100%), the second for up to 120 DPI (125%), the third for up to 144 DPI (150%) the fourth for up to 192 DPI (200%) and so on, with further images being defined at 48 DPI (50%) increments (for future-proofing). When a control is created at runtime the system picks the appropriate image size and scales it as needed (preferably down where possible) before applying any other transformations.

Note that this does NOT apply to images set at runtime in code via the BITMAP property.  In this case the developer is assumed to have selected the correct image file size regardless of the DPI setting.

Designing under High-DPI

If you design your forms when running under a High-DPI setting the Form Designer will save and compile all coordinate and font information as though you were developing at 96DPI, so the values will be scaled down appropriately.

Opting out of automatic scaling

Of course, we always try our best not to break existing applications so you can set an option in the RXI file to turn off the automatic DPI scaling if you wish (this option is exposed at runtime via the read-only SYSTEM DPISCALING property).

This same principle can also be applied to individual windows at design-time so you can use it selectively as needed (WINDOW objects also support the read-only DPISCALING property).

Further reading

If you want to find out more information on this topic please see the following link to Microsoft’s documentation on MSDN:

Writing High-DPI Win32 Applications

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).