Using a dialog box

The next mIRC scripting feature I shall talk about is how to create and use dialog boxes from withon your scripts. I found dialog boxes quite complicated to understand at first, but once I had started to play around with them I realised that they're nowhere near as bad as I first thought. I shal attempt to explain how they work here.

Dialog boxes are defined in a table in the Remotes section, like the example here:

dialog Settings {
  title "Script switches"
  size -1 -1 200 100
  check "Auto-whois", 1, 10 10 75 30
  check "Auto-greet", 2, 10 30 75 30
  check "Auto-spell", 3, 90 10 75 30
  check "Colour Nicknames", 4, 90 30 120 30
  button "Ok",5,80 70 30 20,(default,ok)
}

Ok, line by line we have:

dialog Settings {

This says we're going to define a dialog box called Settings

  title "Script switches"

The title of the window will be "Script switches"

  size -1 -1 200 100

The dialog box will be placed at the default window position (i.e. in the centre of the screen) and will be 200 pixels wide and 100 pixels high.

  check "Auto-whois", 1, 10 10 75 30

Here we're defining a check box to go in the dialog. Its title will be "Auto-whois", it will have a unique identifying number of 1, it will be 10 pixels from the left of the box, 10 pixels from the top of the box, 75 pixels wide and 30 pixels high. Similar lines define the other three check boxes, note that each has been given a unique alias.

  button "Ok",5,80 70 30 20,(default,ok)

This line defines a button on the dialog. Its caption is "Ok", the id number, position and size parameters are as described above, and the button has a style of (default,ok). This means that the button is the default control on the dialog box (the one that the cursor is on when the dialog box is opened) and it is an ok button. A dialog box must have an ok and/or a cancel button on it otherwise mIRC will not accept it as a proper dialog box.

This dialog box will look like this:

Now add the following code to the Status menu in the popup editor:

-
Settings: dialog -m test Settings

This means that we can open the dialog box by right-clicking in the status window and selecting Settings from the bottom of the pop-up menu. The dialog command opens the dialog defined in the table called Settings, and the -m parameter means that it is a "modeless" dialog. Modeless dialogs run in the background, as it were, and lets mIRC carry on as normal while the dialog box is opened. A modal dialog box, on the other hand, will insist that you press the ok or cancel button before letting you get back to the mIRC. When the dialog is open mIRC will refer to it using the name "test". Giving a dialog a name like this when it is opened means that you can use the same dialog definition table to describe two simultaneuosly open dialog boxes. For example:

-
Settings: dialog -m test Settings
Settings1: dialog -m test1 Settings

(You may or may not be able to find a use for this!)

Once the dialog box is initialised, the DIALOG:INIT remote event is triggered. We can use this event to populate the controls in the dialog box. If we didn't, all the check boxes would be blank all the time, regardless of whether the setting was on or off.

on 1:DIALOG:test:init:0: {
  if ( $group(#autowhois) == on ) { did -c test 1  }
  else { did -u test 1 }
  if (  $group(#autogreet) == on ) { did -c test 2 }
  else { did -u test 2 }
  if (  $group(#autospell) == on ) { did -c test 3 }
  else { did -u test 3 }
  if (  $group(#cnicks) == on ) { did -c test 4 }
  else { did -u test 4 }
}
on 1:DIALOG:test:init:0: {

test = on the Status window popup menu we're opening the dialog box and calling it 'test', so the remote events must relate to the dialog box called 'test' as well.
init = the name of the dialog event we're looking at.
0 = normally this number relates to the unique id number of the control we're looking at, however the init event relates to the whole dialog, so we use a zero here.

did -c test 1

The did command is used to change the settings of a control inside a dialog box. Again we have to refer to our dialog box by its name, 'test'. The number 1 is the unique id number of the control we're looking at, and the -c switch tells mIRC to check the box.

did -u test 1

This command clears the control with the id number of 1 (in our case it will uncheck the checkbox). We have to make sure that each test relates to the correct control in the dialog box, otherwise you could switch on auto-whois, close the dialog box, reopen it and find that auto-greet is checked.

Basically this init event runs four commands. Each command looks to see if one of the groups is turned on or off. If the group is switched on, the checkbox is checked, if the group is switched off, the ckeckbox is unchecked.

Now we need some events which respond when you click in the checkboxes:

on 1:DIALOG:test:sclick:1:{ if ($group(#autowhois) == on) { .disable #autowhois }
else { .enable #autowhois } }

This event is triggered when the control in the dialog "test" which has the id number of 1 is single-clicked. The code executed by the event is the same code that was used in the custom menu on the previous page, except that the command to change the text on the menu has been removed - we don't need to change anything in the dialog box to see whether the option is on or off, we just have to look at the check box. Simple, huh? Create three more events for the other check boxes and we're done.

on 1:DIALOG:test:sclick:2:{  if ($group(#autogreet) == on) { .disable #autogreet }
else { .enable #autogreet } }

on 1:DIALOG:test:sclick:3:{  if ($group(#autospell) == on) { .disable #autospell }
else { .enable #autospell } }

on 1:DIALOG:test:sclick:4:{  if ($group(#cnicks) == on) { .disable #cnicks | colnames}
else { .enable #cnicks | blacknames }

That's about it for this simple dialog box, however in the next section I'm going to expand on it and add a lot more functionality.

New Techniques introduced in this section - see mIRC help file for more information
dialog tables - used to define the structure dialog box
dialog command - used to open a dialog box
on DIALOG:init event - triggered when the dialog box is initialised
on DIALOG:sclick event - triggered when a control in the dialog box is single-clicked
did command - used to set the controls in the dialog box to the correct values

Improving the dialog box

Now I'm going to take the basic dialog box we've already defined and alter it so that we can give the user a lot more control over the script. In the colourful nicknames script described a few pages back the colours I used were hard-coded. In other words, they were fixed within the script. If you wanted to use different colours, you had to edit the script. Now this isn't very user-friendly, but we can improve the situation using some drop-down combo boxes and some variables. Here goes!

Replace the original dialog definition table with this one:

dialog Settings {
  title "Script Control Panel"
  size -1 -1 200 205
  check "Auto-whois", 1, 10 10 75 30
  check "Auto-greet", 2, 10 30 75 30
  check "Auto-spell", 3, 90 10 75 30
  check "Colour Nicknames", 4, 90 30 120 30
  box "Nickname Colours",5, 5 60 130 120
  text "Ops", 6,  10 75 35 30, right
  combo 7,  50 75 70 100, drop
  text "Voiced", 8, 10 100 35 30, right
  combo 9, 50 100 70 100, drop
  text "Others",  10, 10 125 35 30, right
  combo 11,50 125 70 100, drop
  button "Apply", 12, 45 155 60 20
  button "Ok",13, 80 185 30 20,(default,ok)
}

What have we changed here? Well, we've changed the title to "Script Control Panel", we've made the dialog box itself a bit bigger, and we've added a box called "nickname colours", three items of text ("ops", "voiced" and "others"), three combo boxes and a button called "Apply". The new dialog box looks like this:

When we initialise the dialog box, there is a bit more setting up to do. Replace the original init event with this one:

on 1:DIALOG:test:init:0: {
  if ( $group(#autowhois) == on ) { did -c test 1  }
  else { did -u test 1 }
  if (  $group(#autogreet) == on ) { did -c test 2 }
  else { did -u test 2 }
  if (  $group(#autospell) == on ) { did -c test 3 }
  else { did -u test 3 }
  if (  $group(#cnicks) == on ) { did -c test 4 | did -e test 5,6,7,8,9,10,11,12 }
  else { did -u test 4 | did -b test 5,6,7,8,9,10,11,12 }
  didtok test 7,9,11 46 white.black.blue.green.light red.brown.purple.orange.yellow.light green.cyan.light cyan.light blue.pink.grey.light grey
  did -c test 7 %opcol
  did -c test 9 %voicecol
  did -c test 11 %othercol
}

Here's what the new stuff means:

did -e test 5,6,7,8,9,10,11,12

This command enables the controls with the specified id numbers.

did -b test 5,6,7,8,9,10,11,12

This command disables the controls with the specified id numbers. We're doing this so that when the "colourful nicknames" option is turned off, the controls which relate to it are greyed out. The did command has two more switches we could have used here, the -v switch makes a control visible and the -h switch hides the control. However, when all these controls are hidden, the dialog box will have a large, seemingly unused area, which I think looks untidy, so I prefer to enable and disable the controls.

  didtok test 7,9,11 46 white.black.blue.green.light red.brown.purple.orange.yellow.light green.cyan.light cyan.light blue.pink.grey.light grey

This command populates the combo boxes (the controls with the id numbers 7, 9 and 11) with the tokens in the string. The number 46 is the ASCII code for a full stop, which I'm using in the string to separate the different list items.

  did -c test 7 %opcol

This line sets control number 7 (the combo box which selects the colour used to operator's nicknames) to the value in the variable %opcol. If %opcol is 3, then the text in the combo box is set to the third item in the list (blue). Note that combo box selections start counting at one.

  did -c test 9 %voicecol
  did -c test 11 %othercol

These two lines set the other two combo boxes to the values specified by the other variables. So where do these variables come from? Simple, we have to put them there. This script has a slight flaw in that it won't work if the variables it refers to don't exist (I haven't put any code in the script to cope with this eventuality) so the simple solution is to make sure they do exist before we start. Go to the variables section in the mIRC Editor and type in:

%opcol 1
%voicecol 1
%othercol 1
Next, change the click event for the colour nicknames checkbox and add events for the combo boxes and the button.
on 1:DIALOG:test:sclick:4:{  if ($group(#cnicks) == on) { .disable #cnicks | blacknames | did -b test 5,6,7,8,9,10,11,12 }
else { .enable #cnicks | colnames | did -e test 5,6,7,8,9,10,11,12 } }

on 1:DIALOG:test:sclick:7: %opcol = $didwm(test,7,$did(test,7))
on 1:DIALOG:test:sclick:9: %voicecol = $didwm(test,9,$did(test,9))
on 1:DIALOG:test:sclick:11: %othercol = $didwm(test,11,$did(test,11))

on 1:DIALOG:test:sclick:12: colnames
When we click on the colour nicknames checkbox we want to make sure that the other controls are enabled or disabled as necessary. When we click on a selection in the combo box we need to set the variable to the correct number. The way we do this is a bit topsy-turvy, but this is what happens.
$did(test,7)

This identifier tells me the text in whetever control has the id number 7. If we selected "blue" from the drop-down list then this is what the $did identifier will tell me.

$didwm(test,7,blue)

This searches all the text items in the drop-down box and tells me the line number of the text which matches the colour we've selected. In this case it is line number three (because "blue" is the third item in our list), so we set %opcol to 3.

Finally, we have to modify the colour nicknames alias to look at the variables instead of hard-coding the numbers. Here's the version that will run with the dialog box:

colnames {
  var %channo = $chan(0)
  var %oc = %opcol - 1
  var %vc = %voicecol - 1
  var %otc = %othercol - 1
  while (%channo >= 1) {
    var %ch = $chan(%channo)
    var %i = $nick(%ch,0)
    while (%i > 0) {
      if ($nick(%ch,%i) isop %ch) { cline %oc %ch %i }
      elseif ($nick(%ch,%i) isvo %ch) { cline %vc %ch %i }
      else { cline %otc %ch %i }
      dec %i
    }
    dec %channo
  }
}

There are a couple of points to make about this script. I mentioned earlier that when you select text from a list of selections in a combo box, mIRC starts counting that list at one. However, mIRC's colours start with a value of zero, so if you select white from the list (item number one), you have to subtract one from it in order to get the correct colour code of zero. This is why the %oc, %vc and %otc variables are set as the original values minus one. I'm also using some other variables later (%ch,%i) which makes the rest of the code a little shorter and, I hope, easier to read.