Chapter 5

Conditional, Loop, and Calling Statements
Some statements can alter the sequential play of macro commands. For example,
SetBrushWidth(BrushWidth: 25)
SetBrushWidth(BrushWidth: 75)
sets a 25-pixel Paint Brush width and then a 75-pixel Paint Brush width. The second command overrides the first. A control statement can select which SetBrushWidth to play depending on a condition being true.
Switch (Test)
Caseof 1: SetBrushWidth(BrushWidth: 25)
Caseof 2: SetBrushWidth(BrushWidth: 75)
Default: SetBrushWidth(BrushWidth: 50)
Endswitch
Explanation: If variable Test equals 1, set a 25-pixel Paint Brush width. If Test equals 2, set a 75-pixel Paint Brush width. If Test equals any value except 1 or 2, set a 50-pixel Paint Brush width. The value of Test can be determined by a programming command such as Menu or GetNumber.
Macros support conditional statements, loop statements, and miscellaneous control statements such as Call, Go, and Quit.
Conditional statements execute a statement or statement block when an expression is true, or when a variable matches a constant.
Macros support the following conditional statements:
Case executes a Label statement when Test (user-defined variable) matches a constant value.
Case (Test; {1; Start; 2; Next}; Other)
...(other statements)...
Label (Start)
...statement block...
Label (Next)
...statement block...
Label (Other)
...statement block...
Explanation: If Test matches 1, call Label(Start). If Test matches 2, call Label(Next). If there is no match, call Label(Other).
Case Call is a similar statement which expects a Return after a Label statement. See also PerfectScript Case and Case Call commands.
If-Else-Endif executes a statement or statement block when an expression is true.
If (x = 5)
...statement block...
Else
...statement block...
Endif
Explanation: Execute the first statement block if the expression x = 5 is true (if x equals 5). If not true, execute the second statement block. Else is optional.
If (Expression)
...statement block...
Endif
Explanation: If Expression is true, execute the statement block. If not true, execute the first statement after Endif. Expression must evaluate to true or false. See Relational Expressions in Chapter 4: Expressions and PerfectScript If command.
Switch-EndSwitch executes a statement or statement block when <Test> matches <Selector>.
Switch (<Test>)
Caseof <Selector>:
...statement block...
Caseof <Selector>:
...statement block...
Caseof <Selector>:
...statement block...
Default:
...statement block...
EndSwitch
Explanation: If <Test>matches <Selector>, the statement block after Caseof <Selector> is executed.
Statement blocks can include calling a subroutine; see Subroutines later in this chapter. If Continue follows a statement block, the next statement block is automatically executed. See also PerfectScript Switch command.
Loop statements execute a statement or statement block a specified number of times, until an expression is true, or while an expression is true.
Macros support the following loop statements:
For-EndFor executes a statement or statement block a specified number of times.
For (<ControlVariable>; <InitialValue>; <TerminateExp>; <IncrementExp>)
...statement block....
EndFor
Explanation: <InitialValue> initializes <Control Variable>. <TerminateExp> tests the value of <ControlVariable>. <IncrementExp> increases the value of <ControlVariable> until <TerminateExp> is false and the loop ends. If <TerminateExp> is initally False, then the statements will not execute since the test is checked at the start of the loop.
For(x; 1; x <5; x + 1)
...statement block...
EndFor
Explanation: x is initialized to 1, statement block executes while x is less than 5, and x is incremented by 1 at the end of each loop.
Similar loop statements are ForEach and ForNext. See Relational Expressions in Chapter 4: Expressions, and PerfectScript For, ForEach, and ForNext commands.
Repeat-Until executes a statement or statement block until an expression is true. All Repeat statements execute at least once because the expression is checked at the end of the loop.
Repeat
...statement block...
Until (x > = 10)
Explanation: Execute statement block until the expression x >= 10 is true (until x is greater than or equal to 10). The value of x must change in the loop to make the expression true or the loop never ends. For example,
Repeat
...statement block...
x := x + 1
Until (x >= 10)
Explanation: Increment x by 1 (x := x + 1) at the end of each loop until x is greater than or equal to 10. See Relational Expressions in Chapter 4: Expressions and PerfectScript Repeat command.
While-EndWhile executes a statement or statement block while an expression is true. While statements never execute unless the expression is true because the expression is checked at the start of the loop.
While (x <= 10)
...statement block...
EndWhile
Explanation: Execute statement block while the expression x <= 10 is true (while x is less than or equal to 10). If x is greater than 10, the loop does not execute. The value of x must change in the loop to make the expression true or the loop never ends.
While (x <= 10)
...statement block...
x := x + 1
EndWhile
Explanation: Increment x by 1 (x := x + 1) at the end of each loop while x is less than or equal to 10. See Relational Expressions in Chapter 4: Expressions and PerfectScript While command.
Calling statements call a subroutine, which is one or more statements grouped as one item. (Subroutines are explained later in this chapter.)
Macros support the following calling statements:
Call has one parameter, which is the name of a subroutine to call. Return directs macro execution to the statement that follows Call (see PerfectScript Call and Run commands).
Call (ExSub)
...other statements...
Label (ExSub)
...statement block...
Return
Explanation: Call(ExSub) directs macro execution to Label(ExSub), where the statement block is executed. Return directs macro execution to the first statement after Call(ExSub).
Go has one parameter, which is the name of a subroutine to jump to. Macro execution continues from the point of the subroutine and does not return (statements between Go and the subroutine do not execute). Return ends a macro or directs macro execution to the statement that follows a Run command (see PerfectScript Go and Run commands).
Go (ExSub)
...other statements...
Label (ExSub)
...statement block...
Return
Explanation: Go(ExSub) directs macro execution to Label(ExSub), where the statement block is executed. Return ends the macro.
Subroutine name performs the same action as a Call statement. For example,
Call InitializeVariables (<Parameter>; <Parameter>)
InitializeVariables (<Parameter>; <Parameter>)
both call a function or procedure named InitializeVariables. (Functions and procedures are explained below.) If the second example calls a function, you can assign a return value to a variable with a statement such as
x := InitializeVariables (<Parameter>; <Parameter>)
Subroutines consist of one or more statements that execute when the subroutine is called by Call, Go, Case, Case Call, or the name of the subroutine.
Macros support the following subroutines:
Labels have one parameter, which is the name of the subroutine. Label names must begin with a character, consist of one or more letters or numbers, are limited to 30 characters, and can have an optional trailing @ sign. Labels generally include one or more statements followed by Return or Quit. Label statements execute the same as other macro statements and do not have to be called. See also PerfectScript Label command.
Functions can have zero or more parameters which receive values from a calling statement (calling statements are explained earlier in this chapter) and return a value. A function without parameters performs like a Label, except it cannot execute unless called. Function names must begin with a character, consist of one or more letters or numbers, are limited to 30 characters, and can have an optional trailing @ sign. The following rules apply to functions:
Procedures can have zero or more parameters which receive a value from a calling statement (calling statements are explained earlier in this chapter). A procedure cannot return a value. A procedure without parameters performs like Label, except it cannot execute unless called. Procedure names must begin with a character, consist of one or more letters or numbers, are limited to 30 characters, and can have an optional trailing @ sign. The following rules apply to procedures:
When a macro executes a callback routine, global return and parameter array variables are automatically created by the macro system that are accessible to the callback routine. The callback routine can access the callback parameter array for information about the callback event, and will place its return value (if any) in the callback return variable.
The parameters for the callback are placed into a global array variable that has the same name as the callback label. The return value (if any) returned from callback routines is placed in a (non-array) global variable that has the same name as the callback label. For example, parameters would be passed to callback routine 'MsgHandler' in an array called 'MsgHandler[ ]', and any return value would be placed into a variable called 'MsgHandler'.
The return value, the number of callback array entries, and the values contained in the callback array depend on the type of callback being called. The callback type is found in the first ([1]) entry of the callback array. The callback array element count can be retrieved by using the Dimensions command, or by accessing the [0] callback array element.
Callback Data Description
When a macro executes a callback routine, global return and parameter array variables are automatically created by the macro system that are accessible to the callback routine. The callback routine can access the callback parameter array for information about the callback event, and will place its return value (if any) in the callback return variable.
The parameters for the callback are placed into a global array variable that has the same name as the callback label. The return value (if any) returned from callback routines is placed in a (non-array) global variable that has the same name as the callback label. For example, parameters would be passed to callback routine ‘MsgHandler’ in an array called ‘MsgHandler[ ]’, and any return value would be placed into a variable called ‘MsgHandler’.
The return value, the number of callback array entries, and the values contained in the callback array depend on the type of callback being called. The callback type is found in the first ([1]) entry of the callback array. The callback array element count can be retrieved by using the Dimensions command, or by accessing the [0] callback array element.
Callback array entries
RTN Callback return value (depends on [1])
[0] Count of elements in callback array
[1] Callback type:
[2...] (Repeating depends on [1])
Entries for Mouse callback (type 0 - CBTYPE_MOUSE)
This type of callback is no longer supported.
Entries for Key and Keystring callback (type 1 - CBTYPE_KEY)
This type of callback is no longer supported.
Entries for Product token (command) callback (type 2 - CBTYPE_TOKEN)
This type of callback is no longer supported.
Entries for Dialog callbacks (type 3 - CBTYPE_DIALOG)
This type of callback is setup by the DialogShow and CoachSetDialogFilter commands.
|
RTN |
Callback return value (only if [5] = WM_COMMAND (273) and from CoachSetDialogFilter, else not used): |
|
undefined = |
Send the event to the application |
|
0 = |
Send the event to the application |
|
1 = |
Do not send the event to the application |
|
[0] |
Callback array contains 11 elements |
|
[1] |
Callback type 3 = CBTYPE_DIALOG |
|
[2] |
Dialog name |
|
[3] |
Control name = |
If [5] = WM_COMMAND (273), WM_HSCROLL (276), WM_VSCROLL (277), WPMSG_SETNSLB_POPUP (4104), OR TCN_SELCHANGING (-552) |
|
“” = |
Other messages have no control name |
|
[4] |
Dialog window handle |
|
[5] |
Windows* message id being sent (see below) |
|
[6] |
Value of the 32-bit DWORD wParam parameter that was received with the message |
|
[7] |
Value of the 32-bit DWORD lParam parameter that was received with the message |
|
[8] |
Value of the HIWORD of the lParam parameter [7] that was received with the message |
|
[9] |
Value of the LOWORD of the lParam parameter [7] that was received with the message |
|
[10] |
Value of the HIWORD of the wParam parameter [6] that was received with the message |
|
[11] |
Value of the LOWORD of the wParam parameter [6] that was received with the message |
Elements [6] to [11] have different meanings for each Windows message (contained in [5]). See Windows 95 documentation for more information. When [5] is:
272 = WM_INITDIALOG
Sent just before the dialog is first displayed. This message is sent BEFORE the values of the controls are set from their associated variables. If the values of any controls are changed when responding to this message, the values will be changed again by the macro system to reflect the contents of the variables associated with the controls.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..5], [8..11] are described above.
|
[3] |
“” = No control name |
|
[6] |
Window handle of the control that will receive focus |
|
[7] |
0 = Sent from WM_INITDIALOG of the dialog callback procedure. |
|
1 = Sent from DialogLoad if dialog did not exist. |
|
|
2 = Sent from DialogLoad if dialog already existed. |
1272 = MX_POST_INITDIALOG (only sent from DialogShow, not sent from CoachSetDialogFilter)
This message is sent when the dialog is first displayed, AFTER the values of the controls are set from their associated variables. If the values of any controls need to be changed when the dialog is displayed to something other than the initial values from the associated variables, they should be set in response to this message. This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..5], [7..11] are described above.
|
[3] |
“” = No control name |
|
[6] |
Window handle of the control that will receive focus. |
2 = WM_DESTROY
Sent when the dialog goes down.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..11] are described above
|
[3] |
“” - No control name |
6 = WM_ACTIVATE
Sent when the dialog is activated or deactivated.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..6], [8..9] are described above
|
[3] |
“” - No control name |
|
[7] |
Window handle of the window being activated or deactivated |
|
[10] |
Minimized flag (non-zero means minimized) |
|
[11] |
Dialog activation state: 0 = WA_INACTIVE (dialog becomes inactive) 1 = WA_ACTIVE (dialog becomes active) 2 = WA_CLICKACTIVE (dialog becomes active from mouse click) |
3 = WM_MOVE (sent from Dialog Show and CoachSetDialogFilter commands)
Sent when the dialog is moved to a new location.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..7], [10..11] are described above
|
[3] |
“” - No control name |
|
[8] |
New X position |
|
[9] |
New Y position |
5 = WM_SIZE (only sent from DialogShow, not sent from CoachSetDialogFilter)
This message is sent when the dialog is sized.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..5], [7], [10..11] are described above
|
[3] |
“” - No control name |
|
[6] |
Size type: 0 = SIZE_RESTORED - Dialog has been restored, but not minimized of maximized 1 = SIZE_MINIMIZED - Dialog has been Minimized 2 = SIZE_MAXIMIZED - Dialog has been Maximized 3 = SIZE_MAXSHOW - Some other window has been restored 4 = SIZE_MAXHIDE - Some other window is maximized |
|
[8] |
New x size (width) of client area |
|
[9] |
New Y size (height) of client area |
22 = WM_ENDSESSION (only sent from DialogShow, not sent from CoachSetDialogFilter)
This message is sent when the Windows session is about to be terminated.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..5], [8..11] are as described above
|
[3] |
"" - No control name |
|
[6] |
True = The session is being ended False = Otherwise |
|
[7] |
True = The user is logging off False= The user is shutting down |
-552 = TCN_SELCHANGING
Sent when a different tab on a tab control is selected.
This message can be altered by the callback by returning a value in the callback return variable.
|
RTN |
Callback return value (used only from CoachSetDialogFilter command): undefined = Send the event to the application 0 = Send the event to the application 1 = Do not send the event to the application |
[0..2], [4..7], [10] are as described above
|
[3] |
Control name of tab control |
|
[8] |
Zero based tab index number (the first tab is 0) of old tab |
|
[9] |
Zero based tab index number (the first tab is 0) of new tab |
|
[11] |
Tab control id |
4104 = WPMSG_SET_NSLB_POPUP
Sent when a name search text box pops up on a name search list box.
RTN Callback return value not used
[0..2], [4..7] are as described above
|
[3] |
Control name of ScrollBar control. |
|
[8] |
Coordinate of bottom edge of text box |
|
[9] |
Coordinate of right edge of text box |
|
[10] |
Coordinate of top edge of text box |
|
[11] |
Coordinate of left edge of text box |
276 = WM_HSCROLL (sent from DialogShow, and not from CoachSetDialogFilter)
277 = WM_VSCROLL (sent from DialogShow, and not from CoachSetDialogFilter)
Sent when the user clicks on a scroll bar control.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..6], [8..9] are as described above
|
[3] |
Control name of name search listbox |
|
[7] |
Window handle of the ScrollBar control |
|
[10] |
Position of thumb in ScrollBar control (if [11] = 4 or 5, else not used) |
|
[11] |
Scroll notification code: |
|
6 = |
SB_TOP (HOME key pressed - scroll to the top or left) |
|
7 = |
SB_BOTTOM (END key pressed - scroll to the bottom or right) |
|
8 = |
SB_ENDSCROLL (Scroll bar activity ended) |
|
0 = |
SB_LINEDOWN (Down or Right arrow clicked - scroll ahead 1 line) |
|
1 = |
SB_LINEUP (Up or Left arrow clicked - scroll back 1 line) |
|
2 = |
SB_PAGEDOWN (Area between Down or Right arrow and thumb clicked - scroll ahead 1 page) |
|
3 = |
SB_PAGEUP (Area between Up or Left arrow and thumb clicked - scroll back 1 page) |
|
4 = |
SB_THUMBPOSITION (Position of thumb after it is dragged is in [10]) |
|
5 = |
SB_THUMBTRACK (Current position of thumb as it is dragged is in [10]) |
274 = WM_SYSCOMMAND (only sent from DialogShow, an not from CoachSetDialogFilter)
Sent when the user presses Alt+F4, chooses Close from the system menu, or double clicks the system menu.
This message is for notification only, and cannot be altered or prevented.
RTN Callback return value not used
[0..2], [4..10] are as described above
|
[3] |
Control name of name search listbox |
|
[11] |
Menu item id of system menu item selected: 61536 = SC_CLOSE - Close, Alt+F4 or double click on system menu |
273 = WM_COMMAND
Sent when the user interacts with a control or menu item on the dialog.
These messages can be altered by the callback if sent from the CoachSetDialogFilter command, by returning a value in the callback return variable.
|
RTN |
Callback return value (used only from CoachSetDialogFilter command): |
|
undefined = |
Send the event to the application |
|
0 = |
Send the event to the application |
|
1 = |
Don’t send the event to the application |
[0..2], [4..6], [8..9] are as described above
|
[3] |
Control name or number, or: |
|
“” |
if from a menu item |
|
“OKBttn” |
if from the predefined OK button |
|
“CancelBttn” |
if from the predefined Cancel button |
|
[7] |
Control window handle (“” if from a menu item) |
|
[10] |
Notification code (depends on the control type): |
Popup Button Menu items:
|
0= |
(not used) |
Windows ListBox:
|
1 = |
LBN_SELCHANGE - Item selection changed (not sent from CoachSetDialogFilter) |
|
2 = |
LBN_DBLCLK - Item was double clicked |
WP ListBox:
|
1 = |
WLBN_SELCHANGE - Item selection changed (not sent from CoachSetDialogFilter) |
|
2 = |
WLBN_DBLCLK - Item was double clicked |
|
10 = |
WLBN_RBUTTONDOWN - The right mouse button was clicked in the list box (not sent from CoachSetDialogFilter) |
|
11 = |
WLBN_VK_DELETE - The delete key was pressed in the list box (not sent from CoachSetDialogFilter) |
|
12 = |
WLBN_VK_INSERT - The insert key was pressed in the list box (not sent from CoachSetDialogFilter) |
|
13 = |
WLBN_CHECKCHANGE - The check box next to an item was clicked in a list box with the CheckBoxes! style (not sent from CoachSetDialogFilter) |
Windows ComboBox:
|
1 = |
CBN_SELCHANGE -Item selection changed (not sent from CoachSetDialogFilter) |
|
2 = |
CBN_DBLCLK - Item was double clicked |
WP ComboBox:
|
1 = |
WCBN_SELCHANGE -Item selection changed (not sent from CoachSetDialogFilter) |
|
2 = |
WCBN_DBLCLK - Item was double clicked |
Color control:
|
5123 = |
HLSN_NEWVALUEDONE - A new color was selected (not sent from CoachSetDialogFilter) |
Counter control:
|
907 = |
CNTN_STEPUP - Up arrow was clicked, stepping up to next value (not sent from CoachSetDialogFilter) |
|
908 = |
CNTN_STEPDOWN - Down arrow was clicked, stepping down to previous value (not sent from CoachSetDialogFilter) |
Push Button:
|
0 = |
BN_CLICKED - Button was clicked |
|
5 = |
BN_DBLCLK - Button was double clicked (not sent from DialogShow) |
Radiexo Button:
|
0 = |
BN_CLICKED - Button was clicked |
|
5 = |
BN_DBLCLK - Button was double clicked (not sent from DialogShow) |
Checkbox:
|
0 = |
BN_CLICKED - Button was clicked |
|
5 = |
BN_DBLCLK - Button was double clicked (not sent from DialogShow) |
Edit Box:
|
(none) |
FileNameEntry:
|
0 = |
FNEN_DLGDISMISS - File dialog was dismissed (not sent from CoachSetDialogFilter) |
|
1 = |
FNEN_DLGRAISE - File dialog was displayed (not sent from CoachSetDialogFilter) |
|
2 = |
FNEN_PFMK_DLGRAISE - File dialog was displayed (not sent from CoachSetDialogFilter) |
|
3 = |
FNEN_DLGDISMISS_OK - File dialog was dismissed by OK button (not sent from CoachSetDialogFilter) |
|
4 = |
FNEN_DLGDISMISS_CANCEL - File dialog was dismissed by Cancel button (not sent from CoachSetDialogFilter) |
Date control:
|
0 = |
DATEN_DLGRAISE - Date dialog was displayed (not sent from CoachSetDialogFilter) |
|
1 = |
DATEN_DLGDISMISS - Date dialog was dismissed (not sent from CoachSetDialogFilter) |
|
2 = |
DATEN_DLGDISMISS_OK - Date dialog was dismissed by OK button (not sent from CoachSetDialogFilter) |
|
3 = |
DATEN_DLGDISMISS_CANCEL - Date dialog was dismissed by Cancel button (not sent from CoachSetDialogFilter) |
Bitmap:
|
(none) |
HotSpot:
|
0 = |
BMPN_CLICKED - Bitmap was clicked |
|
1 = |
BMPN_DOUBLECLICKED - Bitmap was double clicked |
Popup Menu Button:
|
500 = |
WPN_MENUCLOSE - Popup menu was closed (not sent from CoachSetDialogFilter) |
|
[11] |
Control id or menu item id (depends on the control type): Menu item: |
Menu item id - Dividing this by 100 gives the position of the item in the menu
Controls:
Control id or:
|
1 = |
from the predefined OK button |
|
2 = |
from the predefined Cancel button |
Entries for MessageBox callback (type 4 - CBTYPE_CBTMSGBOX)
This type of callback is no longer supported.
Macro file libraries contain functions and/or procedures that can be called from another macro and must be compiled.
The command Use specifies a macro that contains functions and/or procedures. It usually precedes calling statements to a macro file library. The following example contains two functions:
Function Add(x)
x := x + 50
Return (x)
EndFunc
Function Subtract(x)
x:= x - 25
Return (x)
EndFunc
Explanation: Function Add receives a value in variable x. 50 is added to x and returned to the function’s caller. Function Subtract receives a value in another variable named x. 25 is subtracted from x and returned to the function’s caller. If this example was saved and compiled as LIBRARY.WCM, the next example includes statements that call the Add and Subtract functions:
Application (WP; “WordPerfect”; Default; “EN”)
Use (“C:\...\LIBRARY.WCM”)
z := Add(50)
z := Subtract(z)
If (z = 75)
Beep // computer beeps because z equals 75
EndIf
Explanation: After function Add is called, 100 is returned in variable z. After function Subtract is called, 75 is returned in variable z. The computer beeps because the expression z = 75 is true.
The previous example with function calling statements in shorthand notation:
Application (WP; “WordPerfect”; Default; “EN”)
Use (“C:\...\LIBRARY.WCM”)
z := Add(Subtract(50))
If (z = 75)
Beep // computer beeps because z equals 75
EndIf