Adding a colour picker lookup to an AX form

Here’s a quick and easy way to add a colour picker lookup to an AX form.

I’ve seen a number of different ways to add colour picker support to an AX form, but so far, this has been the easiest.  It is not ideal, because the colour picker opens up as a dialog window, something which can’t be easily worked around without resorting to using custom ActiveX or .NET controls.

Scenario

In one of my tables, I have a field containing a colour hex code.  It is used for choosing a background colour of certain elements in an SSRS report, and SSRS insisted on getting hex values.  To make it easy to edit, I chose to just do this as a string field containing the colour code as a hex value in the format #RRGGBB.

To make it even easier, I decided to add a colour picker lookup so users more used to selecting colours in Microsoft Office or other applications will have a familiar way of entering colours.

Customising the form

On the form that needs the colour picker, go to the relevant data source and override the lookup() field method.  (It is possible to do it on the form control instead, but best practice is to do it on the data source field.)

We declare a local string object to contain the current hex string, defaulted to #FFFFFF in case there is no value, yet.  We declare R, G, B values and an RGB container.   The container is used only to keep the return value from WinAPI::chooseColor().

public void lookup( FormControl _formControl, str _filterStr )
{
  str       hex = ( YourTableName.ColourFieldName != "" ? YourTableName.ColourFieldName : "#FFFFFF" );
  int       r = hex2Int( subStr( hex, 2, 2 ) ); // Characters 2 and 3
  int       g = hex2Int( subStr( hex, 4, 2 ) ); // Characters 4 and 5
  int       b = hex2Int( subStr( hex, 6, 2 ) ); // Characters 6 and 7
  container rgb;

  rgb = WinAPI::chooseColor( _formControl.hWnd(), r, g, b, null, true );

WinAPI::chooseColor() pops up a colour picker dialog.  Unfortunately, this is a separate dialog window, and we have no control over its positioning on the screen.  Its arguments are:

  • The window handle of the window owning the colour picker.  We give the hWnd of the calling form control.
  • R, G and B values of the currently selected colour.
  • A pointer to a set of custom colours.  This is used to provide custom colours to the picker, and as we’re not using it in this example, we pass a null.
  • A boolean flag to indicate whether the full version of the colour picker, or a trimmed down version with only colour selection boxes will be shown.  In this example, we want the full version, so we pass true.
  if( conLen( rgb ) == 3 )
  {
    [ r, g, b ] = rgb;

    YourTableName.ColourFieldName= strFmt( "#%1%2%3", int2Hex( r, 2 ), int2Hex( g, 2 ), int2Hex( b, 2 ) );
    _formControl.update();
  }
}

Next, we check the return value we got from WinAPI::chooseColor().  If we have a valid colour, the container will have 3 elements.  Otherwise, the colour is not valid.  If the colour is valid, we split the container into the R, G and B values and use that to build the hex string, which then gets put back into the same record field we got it from.  Finally, we tell the calling control to update itself so the user can see the newly selected value.

Using other data types

If you are using other data types to contain the colour values, for example an int to contain a 24-bit value or a container field to just keep the RGB container, you can still use the same concept as described above.  However, the code to get the current colour value from the record and also to write it back would need to change.