Tag Archives: Controls

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).

 

 

 

 

 

Size and Position

In previous versions of OpenInsight the position of a Window or control has always been determined by its SIZE property – an @fm-delimited array comprised of the Left, Top, Width and Height values.  This means, of course, that all of these values have to be processed together at the same time.

For example, if you only want to update a control’s Top attribute then you first have to get the current SIZE property, update the second field, and then set the entire array again like so:

ctrlSize    = get_Property( ctrlID, "SIZE" )
ctrlSize<2> = 100
call set_Property_Only( ctrlID, "SIZE", ctrlSize )

This can become tedious to write and it is also inefficient.

For version 10 we’ve exposed each of the SIZE fields as separate properties so you can now access them directly.  The new properties are:

  • LEFT
  • TOP
  • WIDTH
  • HEIGHT

Here’s the previous example updated to use the TOP property:

call set_Property_Only( ctrlID, "TOP", 100 )

Positioning using rectangle (RECT) coordinates

Those of you used to working with the Windows API will know that many API functions don’t use Width and Height values when dealing with positioning: they work with a “RECT” structure that uses Left, Top, Right and Bottom values to define an object’s position instead (i.e. the coordinates of the top-left corner and the bottom-right corner).

In some cases being able to update a position using Right and Bottom instead of Width and Height can actually be more efficient because it can mean less calculations needed in your own code, and so a new RECT property has been added to enable this functionality.

The new RECT property works in exactly the same way as the current SIZE property except that the Width and Height fields have been replaced by the Right and Bottom fields like so:

* // RECT property structure
* // 
* //   <1> Left
* //   <2> Top
* //   <3> Right
* //   <4> Bottom

As with the SIZE property we’ve also exposed the  individual fields as separate properties so there are two new properties to complement RECT which are:

  • RIGHT
  • BOTTOM

 

 SIZE, RECT and “stealth mode”

As you may know, when using the SIZE property with the Set_Property function you can set a “visible” attribute in the 5th field that can control the visibility of the object when it is moved. For example, setting the SIZE of an invisible WINDOW makes it visible by default unless you set this visible flag to “-1”.  This is still the case in version 10 and it also applies to the new RECT property as well.

However, we have also added a new 6th field that can contain a “Suppress Change Notification” flag.  When this flag is set to TRUE$ the object that has been moved receives no internal notification from Windows that it has been updated, so this will stop any MOVE and SIZE events from begin raised as well as preventing any autosize processing.  This is sometimes necessary when you have complex positioning requirements.

* // Full SIZE property structure when used with Set_Property
* // 
* //   <1> Left
* //   <2> Top
* //   <3> Width
* //   <4> Height
* //   <5> Visibility
* //   <6> Suppress Change Notification
* // Full RECT property structure when used with Set_Property
* // 
* //   <1> Left
* //   <2> Top
* //   <3> Right
* //   <4> Bottom
* //   <5> Visibility
* //   <6> Suppress Change Notification

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

A last word on EditLines (for now)

We’ve taken a look over the last few posts at some of the new features we’ve added to EditLine controls, but before we leave them we’ll mention a few miscellaneous new properties that you might find useful:

  • AUTOSELECT
  • CUEBANNER
  • EXITCHARS
  • VALIDCHARS

 

AUTOSELECT Property

This is a simple boolean property.  When set to TRUE all text in the control will be selected when the EditLine is given focus.

CUEBANNER Property

This is a string property that contains the text to display when an EditLine has no data.  The text is normally displayed in a faded style to differentiate it from “real” text.  It is intended primarily to give the user a simple hint on the purpose of the EditLine, or on the format of the data it should contain.

EXITCHARS property

This property allows you to specify one or more characters as “Exit” characters, which means that if a user types any of them into the control the focus is automatically moved to the next control in tab-order as though they had hit the Tab key. This property is a simple string containing the Exit characters.

// Move to the next control if the user enters a "." or a space
exitChars = ". "
call set_Property( @window : ".EDL_IP1", "EXITCHARS", exitChars )

Note this property does not work if the PASSWORDSTYLE property is TRUE.

VALIDCHARS Property

This property allows you to specify one or more characters that are “Valid” characters, which means that the user can only enter these characters into the control. This property is a simple string containing the characters that are allowed.

// Only allow numeric characters in EDL_NUMBER
validChars = "0123456789"
call set_Property( @window : ".EDL_NUMBER", "VALIDCHARS", validChars )

Note this property does not work if the EDITMASK property is set or the PASSWORDSTYLE property is TRUE.

 

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

 

Edit controls and the Image API

In a previous post we mentioned that the EditLine control now supports the Glyph API, we’ve also extended the Image API to both EditLines and EditBoxes, along with gradient background colors and translucency.  Here are a few examples showing the results:

Gradient BACKCOLOR

EDIT Control with Gradient BACKCOLOR

EDIT Control with Gradient BACKCOLOR

TRANSLUCENCY Property

EDIT Control with TRANSLUCENCY of 50

EDIT Control with TRANSLUCENCY of 50

IMAGE Property

EDIT Control with background image

EDIT Control with background image

IMAGETRANSLUCENCY Property

EDIT Control with translucent background image

EDIT Control with translucent background image

 

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

EditLines and the Glyph API

As you know some controls in OpenInsight support a set of properties called the Glyph API, and this has now been extended to EditLine controls as well.  Of course it’s not the full API (see the supported properties below), as that wouldn’t make sense, but it does allow you to insert an image to the left or right of your text:

EditLine GLYPH

EditLine GLYPH with CueBanner

So now you can insert a handy search icon into your control, or perhaps a warning icon if the data in the control is invalid.

The following Glyph API properties are supported for EditLines:

  • GLYPH (similar to the BITMAP or IMAGE property)
  • GLYPHALIGN (Vertical and center settings are ignored)
  • GLYPHCOLORKEY
  • GLYPHCOUNT
  • GLYPHFRAMECOUNT
  • GLYPHFRAMENUMBER
  • GLYPHOFFSET
  • GLYPHORIGIN
  • GLYPHSIZE
  • GLYPHTRANSLUCENCY

 

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

EditLines and EditMasks

The ability to apply VALID and CONV properties to an EditLine control is a very powerful way to validate and format data entered in your applications, but this commonly relies on the user knowing how the data should be input without any visual clues being provided by the UI. Some formats like dates are fairly obvious, but others are not, and this can lead to user frustration when they are presented with a message box containing some cryptic and obscure error text from the depths of a custom Iconv() routine like this:

Cryptic IConv Message

Cryptic IConv Message

In order to improve this situation the EditLine control now supports a new property called EDITMASK, which allows you to specify the input format of the data in a visual manner, along with the type of character that may be entered at each character position, thus reducing the probability of typing errors and thereby leading to a smoother user experience.  For example here are two EditLine controls with an EDITMASK set for a phone number and a date respectively:

EDITMASK example

EDITMASK Phone and Date example

EDITMASK Property

This property is a dynamic array composed of three fields:

<1> The Input Mask
<2> The Format Mask
<3> The Default Character

The Input Mask is what the user sees in the control when no data has been entered.  The characters that they may edit are denoted by the “_” character, which is used as a placeholder. So, for a date the input mask could be “__/__/____”, meaning that they are allowed to edit the first two characters, the fourth and fifth character, and the last four characters. They will not be able to change either of the “\” characters.

The Format Mask controls the type of character that may be entered at each position where there is a placeholder “_” in the Input Mask. There should be one type specifier for each “_” character in the Input Mask, and a space character for the non-editable characters. The type specifiers are:

  • “D” – A digit
  • “d” – A digit or a space
  • “C” – An alpha character
  • “c” – An alpha character or space
  • “A” – an alphanumeric character
  • “a” – an alphanumeric character or space
  • “X” – a hexadecimal character
  • “x” – a hexadecimal character or space
  • “*” – any printable character
  • “+” – a “+” character, a “-” character, or space

So, for our date example we could have “dd dd dddd”. Note that the Format Mask must always be the same length as the Input Mask, otherwise the EDITMASK property will not work.

The Default Character is the character used for each invalid character in the user input. This defaults to an underscore (“_”).

To create the phone and date examples shown above you would set the following EDITMASK properties like so:

phoneMask =       " ddd ddd dddd"    |
          : @fm : "(___) ___-____"   |
          : @fm : "_"

dateMask  =       "Dd Dd dddd"        |
          : @fm : "__/__/____"        |
          : @fm : "_"

objxArray =        @window : ".EDL_PHONE"
propArray =        "EDITMASK"
dataArray =        phoneMask

objxArray := @rm : @window : ".EDL_DATE"
propArray := @rm : "EDITMASK"
dataArray := @rm : dateMask

call set_Property( objxArray, propArray, dataArray )

There are also some other supporting properties that can be used with the EDITMASK property:

  • GETMASKEDCHARSONLY
  • SETMASKEDCHARSONLY
  • MASKEDTEXT

GETMASKEDCHARSONLY property

This is a boolean property that affects how the TEXT property works when an EDITMASK property is applied.  When set to TRUE getting the TEXT property only returns the characters that can be entered by the user, ignoring any of the non-placeholder characters in the Format Mask.  By default this property is FALSE.

SETMASKEDCHARSONLY property

This is a boolean property that affects how the TEXT property works when an EDITMASK property is applied.  When set to TRUE setting the TEXT property only updates the characters that can be entered by the user, ignoring any of the non-placeholder characters in the Format Mask.  By default this property is FALSE.

MASKEDTEXT property

This property is essentially a wrapper around the normal TEXT property, behaves as if both GETMASKEDCHARSONLY and SETMASKEDCHARSONLY were set to TRUE, so in effect it is a “shorthand” way of accessing and updating the text that can be edited.

In the example below the EditLines on the right contain the MASKEDTEXT property of the EditLines on the left:

MASKEDTEXT example

MASKEDTEXT example

(EDIT: 21 Aug 15 – Corrected EDITMASK member positions)

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

Password-style EditLines

During the recent Antipodean roadshow a request was made for some new EditLine functionality typically found on mobile operating systems such as Android. Specifically this was to provide a way for a password-style edit control to allow each typed character to be shown briefly before being masked like so:

New Password Functionality

New Password Functionality

Thankfully this was a relatively simple request and we soon added two new properties to implement this:

  • PASSWORDSTYLE
  • PASSWORDPEEKTIME

 

PASSWORDSTYLE Property

This is a  boolean property that changes the EditLine into a password-entry style control when set to TRUE.  When set to FALSE the control acts as a normal EditLine. This property can be set at runtime to mask or unmask the entire password if desired.

PASSWORDPEEKTIME Property

This property contains the number of milliseconds to display an entered character before masking it.  When set to 0 the entered character is never displayed. This property also requires PASSWORDSTYLE to be set to TRUE, otherwise it has no effect.

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

OLE Control Integration

One of the goals for version 10 is better OLE control (OCX) integration and support.  A major part of that objective is the ability to register OLE controls with the IDE and bind them to the database in a similar fashion to the standard controls such as Edit Lines, Edit Tables and so on. In this post we’ll be taking a brief look at how this new functionality is being implemented.

Registering OLE Controls

OpenInsight 10 supports a new repository type called “OLECONTROL”. This represents an OLE control “registration record” (stored in the new SYSREPOSOLECONTROLS table) which contains basic information, such as its CLSID and description, and the information needed for data binding, such as the name of the OLE property to use for the DEFPROP property.

The simple form below shows the information that can be held for an OLECONTROL entity (Note that this form isn’t final, right now it’s a “bare-bones” version that is being developed further to integrate with the new IDE, but it does allow full testing and validation).

OLE Control Registration

OLE Control Registration

The CLSID

The first, and most critical item of data, is the Class ID (CLSID) of the OLE control, which is a 128-bit number (called a GUID, or Globally Unique IDentifier) that uniquely identifies it. When you install an OLE control onto a system, the CLSID is used as a key in the registry where various bits of information about the control are stored.

Older versions of OpenInsight have always required you to enter the CLSID manually when using OLE controls with the Form Designer, and this can be a tedious task if not provided with the control’s documentation, usually needing a good trawl through your Windows Registry or a special tool like Microsoft’s OLEView to find it. With version 10 we’ve included a new dialog that does the heavy lifting for you when you want a CLSID: It enumerates all the OLE controls that are installed on your system and presents them as a list for you to choose from, returning the CLSID when you click “OK”.

Select OLE Control

Select OLE Control

Once you have specified the CLSID you can save the record without any further input if you wish.  The control won’t be data-bound but it will be added to the tool palette in the Form Designer as a new item so it is readily available for subsequent development purposes.

Data-binding OLE controls

If you wish to support data-binding the next item to specify is the DEFPROP property, which is a “synthetic” property that maps onto a “real” property (such as TEXT, VALUE, ARRAY etc.) at run-time. All data-binding in OpenInsight is handled through the DEFPROP property and it is the sole mechanism by which the form IO layer accesses data in the user interface.

For an OLE control DEFPROP can be mapped in one of two ways:

  1. By specifying an actual OLE property of the control (such as “Text” for example), or,
  2. By specifying the name of a Basic+ handler function that the form IO layer calls to handle the request. This latter method can be useful when dealing with a complex control such as a grid, that might need to insert/delete rows and set cells individually if it doesn’t have something like an intrinsic OpenInsight-style ARRAY property.

If you do specify a Basic+ DEFPROP handler function it must conform to the following interface:

   defPropVal = myDefPropHandler( ctrlEntID, flags, newValue, index )

      ctrlEntID -> ID of the control to get the value for 
      flags     -> Denotes if this is a GET or SET/SETONLY request
      newValue  -> The new value if this is a SET/SETONLY operation
      index     -> Property index:
                       <1> Col
                       <2> Row

Note that the Option (“…”) buttons on the form present a popup of OLE properties and events, or matching Stored Procedures, as appropriate:

Select OLE Property

Selecting an OLE Property for the Web Browser control

Binding multi-column (AMV) controls

If your OLE control can support multiple data columns like the standard OpenInsight EditTable, there are two more items needed to allow the form IO layer to understand how to use your control:

  1. The new DEFPOSPROP property, and
  2. The name of an OLE event that maps to the equivalent of OpenInsight’s POSCHANGED event.

The DEFPOSPROP property is used to access the current column/row/cell position within the control, in a similar fashion to the standard SELPOS or CARETPOS properties.  It can be mapped in one of three ways:

  1. By specifying a single actual OLE property of the control (such as “SelPos” for example) that implements an @fm-delimited column and row index format (like CARETPOS)
  2. By specifying a comma delimited pair of properties representing the column and row positions respectively, e.g. “CurrCol,CurrRow”
  3. By specifying the name of a Basic+ handler function that the form IO layer calls to handle the request in a similar fashion to the DEFPROP handler.

A Basic+ DEFPOSPROP handler should have the following interface:

   defPosPropVal = myDefPosPropHandler( ctrlEntID, flags, newPos )

      ctrlEntID -> ID of the control to get the value for 
      flags     -> Denotes if this is a GET or SET/SETONLY request
      new       -> The new position if this is a SET/SETONLY operation
                       <1> Col
                       <2> Row

  defPosPropVal <- Returns the current position in the format:
                       <1> Col
                       <2> Row

The final item needed is the POSCHANGED event name so that the form IO layer can check when data has been entered into a cell for validation and update purposes.

Control Semantics

The next set of information is used by the Form Designer to indicate what extra features it needs to present when the OLE control is being edited:

  • Allow Data-Binding: Checking this box tells the Form Designer to allow TABLE and COLUMN properties to be entered.  This must be set if you wish to actually bind your control to the database at runtime.
  • Required Support: Checking this box tells the Form Designer to allow the REQUIRED property to be specified.
  • IConv Support: Checking this box tells the Form Designer to allow the VALID property to be specified.
  • Oconv Support: Checking this box tells the Form Designer to allow the CONV property to be specified.

CLICK Event Data-Binding

Some controls, such as Checkboxes, update their data when clicked rather when they lose focus or change cell position. In this case the form IO layer needs to know the name of the OLE event to track if the control exhibits this behavior and this should be entered here.

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

Split-Button controls

Continuing with the recent focus on Button controls, this time we’re going to take a look at another new Button feature: Split-Buttons.

Split-Button

Split-Button using Aero styling

This button style was introduced with Windows Vista (*) and basically divides the button into two parts: The main part behaves like a normal push-button and fires a CLICK event when pressed, whilst the other part (normally drawn with a down arrow) fires a DROPDOWN event instead of a CLICK (if a context menu is linked to the button then this is displayed instead).

Split-Button support in OpenInsight 10 is exposed via the following properties:

  • SPLITBUTTON
  • SPLITWIDTH
  • SPLITSEPARATOR

SPLITBUTTON property

To enable Split-Button functionality the SPLITBUTTON property can be set to one of the following values:

  • “R” – creates a Split-Button with the main part to the left and the drop-down arrow part on the right.
  • “L” – creates a Split-Button with the main part to the right and the drop-down arrow part on the left.
Left-aligned Split-Button

Left-aligned Split-Button using XP-styling

Setting the SPLITBUTTON property to NULL (“”) removes the Split-Button styling from the control.

SPLITWIDTH property

This property specifies the size in pixels of the arrow part of the control.

SPLITSEPARATOR property

The functionality of a Split-Button can be changed by the SPLITSEPARATOR property.  By default the property is TRUE (“1”), but when set to FALSE (“0”) the line between the two parts of the button is removed and the entire button then behaves as a “drop-down button” – i.e. clicking the button displays a context menu or fires a DROPDOWN event.

Split-Button without separator

Aero-style Split-Button without separator

The Split-Glyph API

For those of you who really can’t help customizing as much as possible the Split-Button also supports an API to allow you to change the default down arrow in the drop-down part of the control. This is the “Split-Glyph API” and mirrors most of the normal Button control “Glyph API” described previously. The only difference is the name of the properties – they are all prefixed with “SPLIT”, i.e.

  • SPLITGLYPH
  • SPLITGLYPHCOLORKEY
  • SPLITGLYPHCOUNT
  • SPLITGLYPHFRAMECOUNT
  • SPLITGLYPHFRAMENUMBER
  • SPLITGLYPHOFFSET
  • SPLITGLYPHORIGIN
  • SPLITGLYPHSIZE
  • SPLITGLYPHTRANSLUCENCY
Split-Button with split-glyph

Split-Button with split-glyph using XP styling

(*) Although Microsoft only introduced Split-Buttons into Windows with the release of Vista, (and then only with visual styles enabled) it should be noted that the OpenInsight Split-Button is supported on XP as well, even running under the Windows Classic theme.

Classic mode Split-Button

Classic mode Split-Button

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

Button controls

Perhaps one of the controls most in need of a face-lift in OpenInsight is the Button (a.k.a PUSHBUTTON) control, and in this post we’ll take a look at some of the new features we’ve added to it for version 10.

Image API

Buttons in OpenInsight have always supported background images and version 10 is no different.  However we’ve extended the number of image states from 6 to 10 to give you a few more options if you want to use them:

  1. Up
  2. Down
  3. Disabled
  4. <not used>
  5. Up with focus
  6. Down with Focus
  7. Hot
  8. Hot with focus
  9. Default
  10. Default with focus

Of course you don’t have to supply all of these images – the system will attempt to pick the closest match based on the IMAGECOUNT supplied.  Access to the image properties is exposed via the normal Image API with the exception of the IMAGENUMBER property which is managed automatically depending on the button state.

Glyph API

One of the biggest drawbacks with using buttons in previous versions of OpenInsight is that images have only ever been applied to the background as a whole.  In order to create a button with an icon (or glyph, as we’ll refer to it henceforth) it has always been necessary to provide an image file with the entire button background drawn on it as well as the required glyph and text.  This makes it very difficult to provide a solution that looks good across different color schemes and visual styles, and it also makes any sort of runtime customization problematic too.

For version 10 a new API has been added for buttons called the “Glyph API”. This allows you to specify an image for the button that is drawn on top of the normal background like so:

Classic-style button with glyph

Classic-style button with glyph

XP-style button with glyph

XP-style button with glyph

Aero-style button with glyph

Aero-style button with glyph

Win8-style button with glyph

Windows 8-style button with glyph

It is exposed via the following properties:

  • GLYPH (similar to the BITMAP or IMAGE property)
  • GLYPHALIGN
  • GLYPHCOLORKEY
  • GLYPHCOUNT
  • GLYPHFRAMECOUNT
  • GLYPHFRAMENUMBER
  • GLYPHOFFSET
  • GLYPHORIGIN
  • GLYPHLAYOUT
  • GLYPHSPACING
  • GLYPHSIZE
  • GLYPHTRANSLUCENCY

These properties are very similar to their counterparts in the normal Image API with the exception of the following Button-glyph specific ones:

GLYPHLAYOUT property

This property specifies how the glyph is laid out in relation to the text, and can be one of the following values:

  • “0” – Glyph to the left, text to the right
  • “1” – Glyph to the top, text to the bottom
  • “2” – Glyph to the right, text to the left
  • “3” – Glyph to the bottom, text to the top.
Buttons showing  glyph layouts

Aero-style buttons showing glyph layouts

GLYPHSPACING property

This property is simply the number of pixels between the glyph and the text.

Where’s the GLYPHNUMBER property?

Just as the Button Image API has no IMAGENUMBER property there is no corresponding GLYPHNUMBER property either – this is because you can provide more than one image for a glyph and the system will automatically select one for you based on the button state (just like with background images).  These states are:

  1. Button up
  2. Button down
  3. Button disabled
  4. Button hot
  5. Button default

Note that if you don’t supply a disabled Glyph image and you disable the button the system will draw a grayed version of the glyph for you:

Button with disabled glyph

Aero-style buttons with system-drawn disabled glyph

Flat buttons

Flat “toolbar” style buttons are supported by the boolean FLAT property.  I.e. the actual background is not painted until the mouse is moved over the button.

Flat button

Aero-style flat button

Flat button with translucency

Aero-style flat buttons with 50% translucency

Custom colors

The button BACKCOLOR property fully supports custom colors and generates a set of matching 3D highlight and shadow colors to use when rendering.

Button with red BACKCOLOR

XP-style button with red BACKCOLOR

The FORECOLOR property also makes a welcome return and is now respected regardless of the visual style in use.

Button with red FORECOLOR

Aero-style button with red FORECOLOR

Extended mouse support

Like the updated Label control the Button now supports the following new properties when the button is in the “hot” state (i.e. the mouse is moving over it):

  • HOTFONT
  • HOTFORECOLOR
  • HOTBACKCOLOR

It also supports the new MOUSEOVER event so you can easily track mouse movements without having to resort to using WINMSG events.

Text Alignment and position

TEXTORIGIN property is provided that allows you to specify the exact XY position that you wish the text to be drawn at in a similar manner to the GLYPHORIGIN property.  Horizontal text alignment is also supported by the TEXTALIGN property.

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