Any way to get which item has been clicked in a dialog?

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

Post Reply
User avatar
Phil Pendlebury
Automation Wizard
Posts: 518
Joined: Tue Jan 16, 2007 9:00 am
Contact:

Any way to get which item has been clicked in a dialog?

Post by Phil Pendlebury » Sat Jul 02, 2022 7:46 am

Hi all,

Always some new challenges eh...

I have a dialog that contains 24 small panels that behave as buttons. (Thanks JRL, indeed panels make great colourful buttons.)

Code: Select all

object Panel1: TPanel
    Left = 8
    Top = 8
    Width = 65
    Height = 25
    Caption = '1'
    ParentBackground = False
    TabOrder = 0
    TabStop = True
  end
  object Panel2: TPanel
    Left = 80
    Top = 8
    Width = 65
    Height = 25
    Caption = '2'
    ParentBackground = False
    TabOrder = 1
  end
  object Panel3: TPanel
    Left = 152
    Top = 7
    Width = 65
    Height = 25
    Caption = '3'
    ParentBackground = False
    TabOrder = 2
  end
etc.

At the moment I have added:

Code: Select all

AddDialogHandler>Dialog1,Panel1,OnClick,DOKEY1
AddDialogHandler>Dialog1,Panel2,OnClick,DOKEY2
AddDialogHandler>Dialog1,Panel3,OnClick,DOKEY3
AddDialogHandler>Dialog1,Panel4,OnClick,DOKEY4
etc...
An then I have created the 24 subroutines accordingly.

The thing is, if I knew which panel had been clicked. I can just have 1 instance of the dialog handler and the subroutine.

Something like this:

Code: Select all

AddDialogHandler>Dialog1,Panel[PANEL NUMBER THAT WAS CLICKED],OnClick,DOKEY
And then:

Code: Select all

SRT>DOKEY
GetDialogProperty>Dialog1,Panel[PANEL NUMBER THAT WAS CLICKED],Color,initcolour
   ReadIniFile>%inifile%,KEYS,keyPanel[PANEL NUMBER THAT WAS CLICKED]mod,modkey
END>DOKEY
etc.

I cannot see any way to do this though. Anyone any thoughts?
Phil Pendlebury - Linktree

hagchr
Automation Wizard
Posts: 314
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: Any way to get which item has been clicked in a dialog?

Post by hagchr » Sun Jul 03, 2022 12:36 pm

Hi,

I don't know if you can remove dialoghandlers by passing a parameter, but you can pass a parameter in the SRT call. Not sure if it helps...

Code: Select all

Dialog>Dialog1
object Dialog1: TForm
  Left = 266
  Top = 104
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 389
  ClientWidth = 661
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
    
  object Panel1: TPanel
    Left = 8
    Top = 8
    Width = 65
    Height = 25
    Caption = '1'
    ParentBackground = False
    TabOrder = 0
    TabStop = True
  end
  object Panel2: TPanel
    Left = 80
    Top = 8
    Width = 65
    Height = 25
    Caption = '2'
    ParentBackground = False
    TabOrder = 1
  end
  object Panel3: TPanel
    Left = 152
    Top = 7
    Width = 65
    Height = 25
    Caption = '3'
    ParentBackground = False
    TabOrder = 2
  end
  
end

EndDialog>Dialog1

Let>k=0
While>k<3
  Add>k,1
  AddDialogHandler>Dialog1,Panel%k%,OnClick,DOKEY(%k%)
EndWhile

SRT>DOKEY
  MDL>%DOKEY_Var_1% was pressed
END>DOKEY

Show>Dialog1,

User avatar
Phil Pendlebury
Automation Wizard
Posts: 518
Joined: Tue Jan 16, 2007 9:00 am
Contact:

Re: Any way to get which item has been clicked in a dialog?

Post by Phil Pendlebury » Sun Jul 03, 2022 3:35 pm

Thanks that looks intriguing. I will have play about and post back. :-)
Phil Pendlebury - Linktree

User avatar
JRL
Automation Wizard
Posts: 3460
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Re: Any way to get which item has been clicked in a dialog?

Post by JRL » Wed Jul 06, 2022 7:14 pm

Exactly what I would have suggested. There's no reason I can think of to remove the extra dialog handlers, they're created in a loop so their creation only takes a few lines.

You do want the "While" line in hagchr's code to be While>k<24 since you have 24 panels.

User avatar
Phil Pendlebury
Automation Wizard
Posts: 518
Joined: Tue Jan 16, 2007 9:00 am
Contact:

Re: Any way to get which item has been clicked in a dialog?

Post by Phil Pendlebury » Thu Jul 07, 2022 5:03 am

Hi guys, yes:

Code: Select all

Let>d=0
While>d<24
  Add>d,1
  AddDialogHandler>Dialog1,Panel%d%,OnClick,DOKEY(%d%)
EndWhile
Works for that area. The problem is there are so many other areas that have to be declared manually.

For example:

In my ini file I have feilds:

Code: Select all

key1txt=Mix 1
key1mod=CTRL+ALT
key1key=114
key1col=Green
etc.

And they are read by:

Code: Select all

ReadIniFile>%inifile%,KEYS,key1txt,key1text
But looping through them using (Let's use LOOPVAR as the example counter)

Code: Select all

ReadIniFile>%inifile%,KEYS,key%LOOPVAR%txt,key%LOOPVAR%text
Will not work.

Also:

Code: Select all

SetDialogProperty>Dialog1,Panel1,Caption,key1text
SetDialogProperty>Dialog1,Panel1,Color,%key1colour%
Could be:

Code: Select all

SetDialogProperty>Dialog1,Panel1,Caption,key%LOOPVAR%text
But it does not want to work.

And so on.

So if I increase the number of panels to 100 for example. I will still have to add 100 of the above lines.
Phil Pendlebury - Linktree

User avatar
JRL
Automation Wizard
Posts: 3460
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Re: Any way to get which item has been clicked in a dialog?

Post by JRL » Thu Jul 07, 2022 5:38 pm

The main issue with what you posted is that most functions don't allow you set sequential values in a loop. If you need to do that add an extra line and use Let>.

Code: Select all

ReadIniFile>%inifile%,KEYS,key%LOOPVAR%txt,key%LOOPVAR%text
Becomes

Code: Select all

ReadIniFile>%inifile%,KEYS,key%LOOPVAR%txt,value
Let>key%LOOPVAR%text=value
Try something like this.

Code: Select all

//DeleteFile>%script_dir%\PanelDef.ini

Let>vPanelCount=5

IfFileExists>%script_dir%\PanelDef.ini
Else
  WriteLn>%script_dir%\PanelDef.ini,wres,[Color]
  Let>cl=0
  Repeat>cl
    Add>cl,1
    Let>vcolor=30000*%cl%
    EditIniFile>%script_dir%\PanelDef.ini,Color,Col%cl%num,vColor
  Until>cl=vPanelCount
  WriteLn>%script_dir%\PanelDef.ini,wres,[Caption]
  Let>cp=0
  Repeat>cp
    Add>cp,1
    Let>vcolor=30000*%cp%
    EditIniFile>%script_dir%\PanelDef.ini,Caption,Cap%cp%num,Color Number = %vColor%
  Until>cp=vPanelCount
EndIf


Dialog>Dialog1
object Dialog1: TForm
  Left = 661
  Top = 207
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'Panels defined from INI Test'
  ClientHeight = 316
  ClientWidth = 263
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 39
    Top = 24
    Width = 185
    Height = 41
    Caption = 'Panel1'
    ParentBackground = False
    TabOrder = 0
  end
  object Panel2: TPanel
    Left = 39
    Top = 79
    Width = 185
    Height = 41
    Caption = 'Panel2'
    ParentBackground = False
    TabOrder = 1
  end
  object Panel3: TPanel
    Left = 39
    Top = 134
    Width = 185
    Height = 41
    Caption = 'Panel3'
    ParentBackground = False
    TabOrder = 2
  end
  object Panel4: TPanel
    Left = 39
    Top = 189
    Width = 185
    Height = 41
    Caption = 'Panel4'
    ParentBackground = False
    TabOrder = 3
  end
  object Panel5: TPanel
    Left = 39
    Top = 244
    Width = 185
    Height = 41
    Caption = 'Panel5'
    ParentBackground = False
    TabOrder = 4
  end
end
EndDialog>Dialog1

Let>kk=0
Repeat>kk
  Add>kk,1
  ReadIniFile>%script_dir%\PanelDef.ini,Caption,Cap%kk%num,vCap
  ReadIniFile>%script_dir%\PanelDef.ini,Color,Col%kk%num,vCol
  SetDialogProperty>Dialog1,Panel%kk%,Caption,vCap
  SetDialogProperty>Dialog1,Panel%kk%,Color,vCol
Until>kk=vPanelCount

Show>Dialog1,

User avatar
Phil Pendlebury
Automation Wizard
Posts: 518
Joined: Tue Jan 16, 2007 9:00 am
Contact:

Re: Any way to get which item has been clicked in a dialog?

Post by Phil Pendlebury » Thu Jul 07, 2022 6:24 pm

Thank you again JRL. These thing that I have discovered in the past but as you can see, I am rusty these days. Your message arrived in the nick of time as I was just about to move to excel in order to try and automate typing of 128 lines. I just spent the last 2 hours adding 64 new panels).

Image

So just for the record this worked (needed to put colour in %%, text was fine without but I do it anyway for consistency):

Code: Select all

Let>in=0
Repeat>in
  Add>in,1
  ReadIniFile>%inifile%,KEYS,key%in%txt,text
  ReadIniFile>%inifile%,KEYS,key%in%col,colour
  SetDialogProperty>Dialog1,Panel%in%,Caption,%text%
  SetDialogProperty>Dialog1,Panel%in%,Color,%colour%
Until>in=64
So you just saved my a lot of grief, beers on me one day. Huge appreciation.

Now if only there were a way to rename Tab Pages from page1 page2 at runtime. I cannot see any way to do this, as in the dialog they are all named object TTabSheet
Phil Pendlebury - Linktree

hagchr
Automation Wizard
Posts: 314
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: Any way to get which item has been clicked in a dialog?

Post by hagchr » Thu Jul 07, 2022 6:53 pm

Hi, Great that you have sorted it out.

Some more thoughts:

For "loading" the the entire ini file you could also read it as a normal file, into a variable, remove the [KEYS] row and simply add Let> at the beginning of each row using RegEx>. Then by using IncludefromVar> all ini-variables will be updated.

Second, if you have a "nailed" dialog layout, you can, instead of putting it in the beginning of the script, put the dialog code in a label. Use LabeltoVar> to read it into a variable. Then you can easily pull out all panel names by using RegEx. Since all panel names are then in an ordered array you can loop through and create all Dialog Handlers etc.

Then you can use IncludefromVar> to insert the dialog script into the main script.

Maybe here is where it all breaks, Ideally you want to be able to link the panel names in the dialog with the names used in the ini file.

Sample (pls fold if you do not want details):

Code: Select all

// Read ini file (from label below instead of file)
GoSub>readIni

// Create the Dialog using label to variable
GoSub>createDialog

// Find all panels (into var Panel_k, tot count into nPanels)
GoSub>findPanels

// Create Dialog Handlers (for all found panels)
GoSub>createDialogHandlers

// Update Dialog Properties (based on ini file)
GoSub>updateDialogProperties

Show>Dialog1,


// SRT to read ini
SRT>readIni
  LabelToVar>ini,ini

  // Remove group row [KEYS]
  Let>tmp0=(?m-s)^\[.+?\]\R
  RegEx>tmp0,ini,0,m,nm,1,,ini

  // Find all record for each panel
  Let>tmp0=(?ms)(key\d+).+?\R(\1.+?(\R))+
  RegEx>tmp0,ini,0,strRecord,nRecords,0,

  // Convert the init file to Let>xxx statements that can be included as script
  RegEx>(?m)^(.),ini,0,m,nm,1,Let>$1,ini

  IncludeFromVar>ini
END>readIni

// Create Dialog
SRT>createDialog
  LabelToVar>BaseDialog,BaseDialog
  IncludeFromVar>BaseDialog
  
  Let>WIN_USEHANDLE=1
  MoveWindow>dialog1.handle,10,10
  Let>WIN_USEHANDLE=0
END>createDialog

// Find all Panels
SRT>findPanels
  RegEx>\w+(?=:\s+TPanel),BaseDialog,0,Panel,nPanels,0
END>findPanels

// Create Dialog Handlers
SRT>createDialogHandlers
  Let>k=0
  While>k<nPanels
    Add>k,1
    Let>tmp=Panel_%k%
    AddDialogHandler>Dialog1,%tmp%,OnClick,DOKEY(%k%)
  EndWhile
END>createDialogHandlers

// SRT to handle panel clicks
SRT>DOKEY
  //index  = ID of clicked panel
  Let>index=DOKEY_Var_1
  
  // Caption of clicked panel
  Let>clickedCaption=key%index%txt
  
  // All ini items for clicked panel
  Let>strPanelRecord=strRecord_%index%
    
  Let>MSG_HEIGHT=250
  Let>MSG_WIDTH=300
  
  MDL>%clickedCaption% was pressed%CRLF%%CRLF%%strPanelRecord%
  
END>DOKEY

// SRT to Update Dialog Properties
SRT>updateDialogProperties
  Let>k=0
  While>k<nPanels
    Add>k,1

    // Update color and caption from ini file. 
    
    // Panel_k contains name (id) of panel k
    Let>tmp=Panel_%k%
    
    // Color and caption from ini file
    Let>tmpCol=key%k%col
    Let>tmpCap=key%k%txt

    SetDialogProperty>Dialog1,%tmp%,Color,tmpCol
    SetDialogProperty>Dialog1,%tmp%,Caption,tmpCap
EndWhile

END>updateDialogProperties

// Base Dialog
/*
BaseDialog:
Dialog>Dialog1
object Dialog1: TForm
  Top = 10
  Left = 10
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 850
  ClientWidth = 500
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left =              10
    Top =               50
    Width =             65
    Height =            25
    Caption =           '1'
    ParentBackground =  False
    TabOrder =          1
  end

  object Panel2: TPanel
    Left =              85
    Top =               50
    Width =             65
    Height =            25
    Caption =           '2'
    ParentBackground =  False
    TabOrder =          2
  end

  object Panel3: TPanel
    Left =              160
    Top =               50
    Width =             65
    Height =            25
    Caption =           '3'
    ParentBackground =  False
    TabOrder =          3
  end

  object Panel4: TPanel
    Left =              235
    Top =               50
    Width =             65
    Height =            25
    Caption =           '4'
    ParentBackground =  False
    TabOrder =          4
  end

  object Panel5: TPanel
    Left =              310
    Top =               50
    Width =             65
    Height =            25
    Caption =           '5'
    ParentBackground =  False
    TabOrder =          5
  end

  object Panel6: TPanel
    Left =              10
    Top =               80
    Width =             65
    Height =            25
    Caption =           '6'
    ParentBackground =  False
    TabOrder =          6
  end

  object Panel7: TPanel
    Left =              85
    Top =               80
    Width =             65
    Height =            25
    Caption =           '7'
    ParentBackground =  False
    TabOrder =          7
  end

  object Panel8: TPanel
    Left =              160
    Top =               80
    Width =             65
    Height =            25
    Caption =           '8'
    ParentBackground =  False
    TabOrder =          8
  end

  object Panel9: TPanel
    Left =              235
    Top =               80
    Width =             65
    Height =            25
    Caption =           '9'
    ParentBackground =  False
    TabOrder =          9
  end

  object Panel10: TPanel
    Left =              310
    Top =               80
    Width =             65
    Height =            25
    Caption =           '10'
    ParentBackground =  False
    TabOrder =          10
  end
end
EndDialog>Dialog1

*/

// Sample ini file
/*
ini:
[KEYS]
key1txt=Mix 1
key1mod=CTRL+ALT
key1key=114
key1col=15431178
key2txt=Mix 2
key2mod=CTRL+ALT
key2key=114
key2col=1516390
key3txt=Mix 3
key3mod=CTRL+ALT
key3key=114
key3col=4616657
key4txt=Mix 4
key4mod=CTRL+ALT
key4key=114
key4col=12879931
key5txt=Mix 5
key5mod=CTRL+ALT
key5key=114
key5col=4852408
key6txt=Mix 6
key6mod=CTRL+ALT
key6key=114
key6col=665170
key7txt=Mix 7
key7mod=CTRL+ALT
key7key=114
key7col=8198960
key8txt=Mix 8
key8mod=CTRL+ALT
key8key=114
key8col=927917
key9txt=Mix 9
key9mod=CTRL+ALT
key9key=114
key9col=16677175
key10txt=Mix 10
key10mod=CTRL+ALT
key10key=114
key10col=3651357
*/

User avatar
Phil Pendlebury
Automation Wizard
Posts: 518
Joined: Tue Jan 16, 2007 9:00 am
Contact:

Re: Any way to get which item has been clicked in a dialog?

Post by Phil Pendlebury » Thu Jul 07, 2022 7:03 pm

@hagchr

This is fascinating and very cool thanks for the insights. These are all things that I have never really considered doing with Dialogs before.

I wonder if this will be my key to let the user name the page1 page2 etc in my ini file. (if nothing else). As we are basically talking about reading the ini file and then creating the dialog as text, I can then name page1 whatever the user wants.

Cheers, P.
Phil Pendlebury - Linktree

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts