Buttons in pushed state

See for an improved version: Buttons in pushed state

This example works best with Progress version 9.
When you create a 'toolbar' with buttons, you may sometimes want to keep a button in a 'pushed' state indicating if the functionality for the button is toggled 'on'.
In that case you could run the following ToggleButton procedure during the ON CHOOSE event of the button widget:

{windows.i}
PROCEDURE ToggleButton :
  DEFINE INPUT PARAMETER hbutton AS HANDLE.
 
  DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
  &SCOP BM_SETSTATE 243
 
  IF hbutton:TYPE NE 'button' THEN RETURN.
 
  IF hbutton:PRIVATE-DATA = 'pushed' THEN DO:
     hbutton:PRIVATE-DATA = ''.
     RUN SendMessageA IN hpApi ( hbutton:HWND, 
                                 {&BM_SETSTATE}, 
                                 0,   /* FALSE, remove BST_PUSHED style */
                                 0, 
                                 OUTPUT ReturnValue).
  END.
  ELSE DO: 
     hbutton:PRIVATE-DATA = 'pushed'.
     RUN SendMessageA IN hpApi ( hbutton:HWND, 
                                 {&BM_SETSTATE}, 
                                 1,  /* TRUE, set BST_PUSHED style */
                                 0, 
                                 OUTPUT ReturnValue).
  END.
 
END PROCEDURE.

Notes

There are several button types in Progress: flat, no-focus, buttons with images and 'normal' buttons with text. In version 9 this procedure works for all button types, but in version 8 it works only for buttons with no images.

This enhancement is undocumented.

I have used the private-data attribute to store the current state of the button. It would also be possible to use the BM_GETSTATE message to query if the button is in it's 'pushed' state, but this is not useful during the ON CHOOSE event. After all, the button is always pushed during the ON CHOOSE event!
There is a however a problem: when focus moves away to another (non-Progress) application, all pushed buttons become 'unpushed'. This problem is reported to PSC and may be fixed in the future, but unfortunately it has a very low priority.