September 4, 2012

Custom Dialogs: How to make a keypress alter a button click outcome

Filed under: Scripting — Marcus Tettmar @ 2:35 pm

Today I was asked how the outcome of a button click on a custom dialog could be altered if the ALT or CTRL key was pressed down at the time of the click.

This is possible by trapping the dialog’s OnKeyDown and OnKeyUp handlers. Using these we can detect if ALT or CTRL is pressed/released and set a flag accordingly. Then in the button’s OnClick handler we can check the value of this flag and decide what we should do.

Here’s some example code. Run it and click the button without holding down any keys. You’ll see a message saying that ALT was not pressed. Now click the button while holding down the ALT key and you’ll see the “you clicked the button while ALT was pressed” message.

Dialog>Dialog1
object Dialog1: TForm
  Left = 467
  Top = 241
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 212
  ClientWidth = 431
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object MSButton1: tMSButton
    Left = 147
    Top = 47
    Width = 75
    Height = 25
    Caption = 'MSButton1'
    TabOrder = 0
    DoBrowse = False
    BrowseStyle = fbOpen
  end
end
EndDialog>Dialog1

AddDialogHandler>Dialog1,MSButton1,OnClick,doClick
AddDialogHandler>Dialog1,,OnKeyDown,doKeyDown
AddDialogHandler>Dialog1,,OnKeyUp,doKeyUp

Let>CTRL_DOWN=FALSE
Let>ALT_DOWN=FALSE

Show>Dialog1,r

SRT>doClick
    //button was clicked, which key is down
    If>ALT_DOWN=TRUE
      MessageModal>You clicked the button while ALT was pressed
    Else
      MessageModal>You clicked the button without pressing ALT
    Endif
END>doClick

SRT>doKeyDown
    //is CTRL key pressed
    If>DoKeyDown_Key=17
      Let>CTRL_DOWN=TRUE
    Endif
    //is ALT key pressed
    If>DoKeyDown_Key=18
      Let>ALT_DOWN=TRUE
    Endif
END>doKeyDown

SRT>doKeyUp
    //was ctrl released
    If>doKeyUp_Key=17
      Let>CTRL_DOWN=FALSE
    Endif
    //was ALT released
    If>doKeyUp_Key=18
      Let>ALT_DOWN=FALSE
    Endif
END>doKeyUp

You might be wondering how I know that the CTRL key is number 17 and the ALT key is 18. To find out the value of a key press the simplest way is just to pop a breakpoint at the start of the doKeyDown subroutine, then run the script in the debugger, press a key and look in the watch list to see what value is produced. Alternatively there’s a table here. Note that ALT is known as VK_MENU and CTRL is VK_CONTROL.