Monthly Archives: November 2015

POPUP Changes

The venerable Popup function has undergone something of a total rewrite for version 10, mainly in order for it to deal with High DPI displays and the new EditTable interface, but we’ve also added a few things along the way.  Here’s a list of what’s new so far:

  • The Popup window is now multi-instance
  • The Popup window can be resized
  • The Popup window is now handled correctly on multi-monitor displays
  • Added support for a “custom” button
  • Added support for an initialization callback procedure
  • Standard keyboard support

Custom button support

it is now possible to specify both the text to appear on a custom button, and the name of a stored procedure to execute when it is clicked.

Click me if you dare

Custom Popup button

The stored procedure is expected to be a subroutine and accept a single parameter, which is the fully-qualified name of the Popup EditTable containing the data.

Initialization callback procedure

It is now possible to specify a stored procedure that will be called during the popup loading process at the following points:

  • After each page of data is inserted into the popup
  • Before the popup is made visible
  • After the popup is made visible

The stored procedure is expected to be a subroutine and accept two parameters:

  1. The fully-qualified name of the Popup EditTable containing the data
  2. A value indicating the loading stage:
* // Initialization proc constants
equ PINITPROC_INSERTROWS$  to 1 ; * // Rows have just been inserted
equ PINITPROC_BEFORESHOW$  to 2 ; * // Popup is about to be shown
equ PINITPROC_AFTERSHOW$   to 3 ; * // Popup has just become visible

Standard keyboard support

Depending on the options enabled for the popup the following standard keyboard shortcuts will be enabled:

  • F9 – Save (for you Arev aficionados)
  • Ctrl-P – Print
  • Ctrl-A – Select All for multi-select popups
  • Ctrl-F – Show the Search dialog
  • F3 – Find Next
  • Shift-F3 – Find Previous

Improved ‘Empty’ Appearance

The EditTable control within the popup now uses it’s new EMPTYTEXT property to display a “No results” message (This message can also be customized if you wish).

Empty Popup

Empty Popup

(EDIT: 28 Mar 16 – Added Empty Popup Screenshot)

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

The CHOOSEDIR and CHOOSEFILE methods

In light of the Utility function being deprecated (as mentioned in this post) I was recently asked where the CHOOSEFILE and CHOOSEDIR methods had ended up.  There was some discussion about this as the aforementioned article cited that they were moved to the SYSTEM object, and a case was made for moving them to the FILESYSTEM object instead.

In the end it was decided to move them to the FILESYSTEM object (as feedback indicated that was where they were expected to be), but to expose them from the SYSTEM object as well, meaning that we wouldn’t have to alter any existing code.

For future reference here are the official details of both methods:

FILESYSTEM CHOOSEDIR method

This method displays the common “Choose Folder” dialog box to allow a user to select a folder.  It takes two arguments:

  1. The name of an owner window
  2. A @fm-delimited array of initialization data
<1> Dialog text
<2> Initial folder to select
<3> HideNewFolder flag: If TRUE$ then hide the "New Folder" button
<4> ShowFiles flag: If TRUE$ then show files in the dialog as well as folders

The CHOOSEDIR method is basically a wrapper around the Windows SHBrowseForFolder function.

Example:

dlgOptions    = ""
dlgOptions<1> = "Please select the destination RDK folder"
dlgOptions<2> = "c:\RevSoft\RDK"
dlgOptions<3> = FALSE$ ; * // allow new folders
dlgOptions<4> = FALSE$ ; * // don't show files

folderName = Exec_Method( "FILESYSTEM", "CHOOSEDIR", @window, dlgOptions )

// This works too...
folderName = Exec_Method( "SYSTEM", "CHOOSEDIR", @window, dlgOptions )

 

FILESYSTEM CHOOSEDIR method

This method displays the common “Choose File” dialog box to allow a user to open a folder.  It takes two arguments:

  1. The name of an owner window
  2. A @fm-delimited array of initialization data
<1> Mode: If FALSE$ then show an "Open File" dialog, if TRUE$ then show 
    a "Save As" dialog instead.
<2> Filters: contains an "/" delimited list of filter items in the format:
    
       <displayText> "/" <filter> "/"

    Where <displayText> is the string to show in the filter dropdown list
    and <filter> is the string to apply to the selected folder.

<3> Filter Index: Specifies the index of the filters in <2> to be displayed.
<4> Default file name
<5> OFN (OpenFileName) flags. This is a bitmask number specifying the flags 
    to apply to the dialog. They are defined in the following insert record:
    
        MsWin_GetOpenFileName_Equates

<6> Initial folder to select
<7> Default extension: This is appended to the file name if the user fails 
    to type an extension. This string can be any length, but only the first 
    three characters are appended. The string should not contain a 
    period (.). 
<8> Dialog title

The CHOOSEFILE method is a basically wrapper around the Windows GetOpenFileName function.

Example:

$insert msWin_GetOpenFileName_Equates

* // Create a filter string for common image files
filters = "Bitmap Files (*.bmp;*.rle;*.dib)/*.bmp;*.rle;*.dib/" |
        : "GIF Files (*.gif)/*.gif/"                            |
        : "JPeg Files (*.jpg,*jpeg,*.jpe)/*.jpg;*jpeg;*.jpe/"   |
        : "PNG Files (*.png)/*.png/"                            |  
        : "All Files (*.*)/*.*/"

* // Create a bitmask of flags
ofnFlags   = OFN_READONLY$
ofnFlags   = bitOr( ofnFlags, OFN_HIDEREADONLY$ )
ofnFlags   = bitor( ofnFlags, OFN_FILEMUSTEXIST$ )

dlgOptions    = ""
dlgOptions<1> = FALSE$  ;* // "Open"
dlgOptions<2> = filters
dlgOptions<3> = 4       ; * // Pre-select the PNG filter
dlgOptions<4> = "example.png"
dlgOptions<5> = ofnFlags
dlgOptions<6> = ".\images"
dlgoptions<7> = ""
dlgOptions<8> = "Please select an Image"

imageName = Exec_Method( "FILESYSTEM", "CHOOSEFILE", @window, dlgOptions )

* // This works too ...
imageName = Exec_Method( "SYSTEM", "CHOOSEFILE", @window, dlgOptions )

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

OpenInsight 10 and the Visual C++ 2015 Runtime

As we’re aiming to update the core OpenEngine code to be a cross-platform solution we spent some of last week moving the OpenInsight 10 C++ codebase from Visual Studio 2010 to Visual Studio 2015, to take advantage of better C++ standards support and the improved tools, such as the excellent C++ static code analyzer.

All in all it was a fairly smooth process, apart from a “hidden” default compiler setting that managed to temporarily break the High DPI and scaling code, but that sort of thing is expected when moving versions, so after a fair bit of Google-Fu we found the issue and fixed it.  One big difference we did find however, is how Microsoft have changed the way their C-runtime libraries are distributed, and it’s something of a departure from previous versions.

As you may or may not be aware, programs built with Visual C++ rely on a set of core DLLs, usually known as the “VC++ Redistributable” and this can be deployed in one of two ways:

  1. The DLLs can be included in the application directory – this is the “App-folder” method,
  2. The DLLs can be installed into the system directories via a “VC++ Redistributable” setup program, which is basically another client-install program.

In order to save you the extra pain associated with yet another client-install  we opted to use the App-Folder method for OpenInsight 10, as originally this meant we supplied you with just two extra DLLs.  However, for Visual Studio 2015 Microsoft have decided to do some refactoring to share their C-runtime code between Desktop apps and the new Universal Platform apps, and so at first glance it looked we needed to supply four DLLs instead, these being:

  • concrt140.dll
  • msvcp140.dll
  • vccorlib140.dll
  • vcruntime140.dll

But unfortunately this was not the end of the story, as early testing on some machines showed that there were still some required DLLs missing.  As it turns out these four DLLs rely on a further set of DLLs that Microsoft say are now “part of the operating system”, and although we could supply these too there are actually 41 of them!  Needless to say we won’t be cluttering up your OpenInsight folders with these.

On further investigation it appears that Microsoft are indeed releasing this 41-DLL set through Windows Update, but only as an Optional Update, so its quite possible that systems will not have these installed and this is something to bear in mind (The update in question is KB2999226).

So, when deploying OpenInsight 10 you have the choice of:

  1. Ensuring KB2999226 is installed on the workstation, or
  2. Using the “Visual C++ Redistributable for Visual Studio 2015” setup package instead.

At the moment we are going with option (1), but this post is basically a “heads-up” to make you aware of the choices.

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