Macro Guidelines

The following sections provide guidelines to follow when constructing Help macros. Read each section carefully and study the examples.

Macro Syntax

Help macro statements have two main components: the macro name and the macro parameters enclosed in parentheses. The most important rule to remember is that the macro name must be spelled exactly as it is given in the syntax and the parameters must be used in the order they are given in the syntax. Parameters provide information for the macro; for example, the JumpId macro, which executes a jump to a topic with a specific context string, has parameters for the name of the Help file and the topic’s context string.

All Help macros use the following format (or syntax):

MacroName("parameter1", "parameter2", ...)

The entire macro, including macro name, parentheses, and parameter list, can have a maximum of 512 characters. The opening parenthesis, closing parenthesis, quotation marks, and commas are required characters when included in the syntax statement for a macro.

Macro names are not case sensitive, so you can either use the capitalization shown in Chapter 15, “Help Macro Reference,” or you can adopt a different convention. For example, you can use any of the following forms:

IfThenElse
ifthenelse
IFTHENELSE
IFthenELSE

The parameter list consists of a series of parameters separated by commas. Parameters can be text strings or numbers. For example, the following macro creates a custom Help menu called Utilities:

InsertMenu("menu_util", "&Utilities", 3)

Some macros have no parameters, but the parentheses are still required. For example, the following macro displays the Search dialog box:

Search()

If you create custom macros, the macro name should begin with an alpha character, followed by any combination of alpha characters, numbers, or the underscore character, as in this example:

PlayAudio()

You can include more than one macro in a macro string by placing a semicolon (;) between each macro in the string. The Help compiler processes the macro strings as a unit and executes the macros sequentially. The following macro contains three different macro strings:

ChangeButtonBinding("btn_contents", "JumpID(`hgcd.hlp', `acc_idx_hg')"); EnableButton("btn_up"); ChangeButtonBinding("btn_up", "JumpID(`cdcd.hlp', `hlpidx_idx_card')")

Using String Parameters

You must enclose all string parameters within quotation marks. Quotation marks can be either double quotation marks or matching single quotation marks, as follows:

"string parameter"
`string parameter'

Note:

On US keyboards, the single opening quotation mark is different from the single closing quotation mark. The single opening quotation mark (`) is paired with the tilde (~) above the TAB key on extended keyboards; the single closing quotation mark ('), or apostrophe, is paired with the double quotation mark.

For example, the JumpId macro takes two string parameters enclosed in double quotation marks:

JumpID("hgcd.hlp", "acc_idx_hg")

You can also enclose the string parameters in single quotation marks, as follows:

JumpID(`hgcd.hlp', `acc_idx_hg')

Using the single quotation marks eliminates ambiguities in situations where strings are nested within other strings (see the following section).

Nested Macros and Nested String Parameters

Help supports nested macros, a macro that is included in another macro as a parameter value. Because nested macros often have their own string parameters, you must frequently specify a string enclosed within another string.

For example, the following macro creates a button called Time that uses the ExecProgram macro as a parameter. When the user chooses the button, Help starts the Microsoft Windows Clock application. Since the ExecProgram macro takes a string as its first parameter, the string is enclosed in single quotation marks:

CreateButton("btn_time", "&Time", "ExecProgram(`clock', 0)")

If the nested macro has any string parameters, they must have quotation marks that are different from the enclosing macro quotation marks. In other words, if double quotation marks enclose a macro, you must enclose any nested strings in single quotation marks.

You can also use single quotation marks for the outermost parameters. The following example produces the same results as the previous one:

CreateButton(`btn_time', `&Time', `ExecProgram(`clock', 0)')

You can avoid confusion with nested string parameters by using single quotation marks for all string parameters. Just be sure to match the opening and closing quotation marks correctly.

Some Incorrect Examples

The following example is incorrect because the “clock” string is enclosed in double quotation marks, even though it is nested within another string delimited by double quotation marks:

CreateButton("btn_time", "&Time", "ExecProgram("clock", 0)")

The following example is also incorrect because the “clock” string is enclosed in single quotation marks that are not matched correctly (two closing quotation marks):

CreateButton("btn_time", "&Time", `ExecProgram('clock', 0)')

The “ExecProgram(” string will be interpreted as the third parameter, and the rest of the string will produce a syntax error.

Some Complex Examples

You can use single quotation marks at any level of nesting. For example, the following macro creates a menu item that, when chosen, creates a button that, when chosen, displays the Windows Clock:

AppendItem("mnu_fun", "mnu_fun_makebutton", "Display Clock &button", "CreateButton(`btn_time', `&Time',`ExecProgram(`clock', 0)')")

Macro strings may not contain more than three other macro strings as parameters. The following macro shows the correct way to nest macros:

IfThen(1, `IfThen(1, `IfThen(IsMark(`Managing Memory'), `JumpId(`trb.hlp', `man_mem')')')')

The following macro string is nested too deeply:

IfThen(1, `IfThen(1, `IfThen(1, `IfThen(1, `BrowseButtons()')')')')

Note:

The Help compiler displays an error message if macros are nested too deeply, but it passes the macro to the Help file. The Help application, however, does not display an error message if the macro string is nested too deeply. Therefore, both of the above macros would supposedly work, even though one generates an error message during compilation and one does not.

Using Special Characters in Strings

To use certain characters as values within a macro string, you must preface the character with a backslash. (Adding a backslash before a character is known as “escaping” the character.) Use the following guidelines when using the double quotation mark ("), single opening quotation mark (`), single closing quotation mark ('), and backslash (\) in macros:

nTo use a backslash in a string parameter, you must type two backslashes.

In the following example, the JumpContents macro string includes two backslashes for each backslash character to specify the \\ROOT\PROJECT\SUBDIR\MYHELP.HLP network path for a Help file:

JumpContents("\\\\root\\project\\subdir\\myhelp.hlp")

nTo use a double quotation mark within a string that is enclosed in double quotation marks, you must preface the double quotation mark with a backslash:

"Chapter 8, \"Making Links Between Topics\""

If you must use quotation marks as part of the parameter, you can enclose the entire parameter in single quotation marks and omit the backslash escape character required for the double quotation marks delimiting the string:

ExecProgram(`command "string as parameter"', 0)

nTo use a single quotation mark within a string that is enclosed in single quotation marks, you must preface the single quotation mark with a backslash:

`This isn\'t easy'

You don’t have to use this form in a string delimited with double quotation marks. For example, you could use the following string in place of the previous example:

"This isn't easy"

nYou never have to escape commas (,) or parentheses () within a macro string.

Using Numeric Parameters

Help recognizes decimal and hexadecimal numbers for numeric parameters. Use a prefix of 0x to indicate a hexadecimal number. For example, the following numbers both represent decimal 64:

64
0x40

To specify a negative number, add a minus sign before the number. For example, the following numbers both specify decimal –18:

–18
–0x12

Note:

To accept a negative number, you must specify a numeric parameter as a signed number. If you use a negative number with an unsigned parameter, Help displays a “Parameter type wrong” error message.

Making Arbitrary DLL Calls in Help Macros

You can make arbitrary DLL calls only if you inform Help about the call by using the RegisterRoutine macro. For example, Microsoft Help Author defines a function called ClearRTFEditor with one valid parameter—a null string:

[CONFIG]
RegisterRoutine("hcparse.dll", "ClearRTFEditor", "")

For more information, see “Using DLL Calls as Help Macros,” later in this chapter.

Return Values in Help Macros

Generally, Help ignores return values in macros. However, the IsMark and IfThenElse macros can be used together to test a condition and execute a macro if the condition evaluates to a nonzero, or true, value. The following example shows a typical use of IsMark and IfThenElse:

IfThenElse(IsMark("Managing Memory"),"JumpID(`trb.hlp',`man_mem')", "JumpContents(`trb.hlp')")

The first parameter of the IfThenElse macro is a number. Since IsMark returns a number, it can be used as the first parameter. Help executes the IsMark and IfThenElse macros as follows:

1.1.Help executes the IsMark macro and obtains a numeric return value from it.

2.2.Help executes the IfThenElse macro. Help passes the number returned from IsMark to the first parameter and passes the JumpId and JumpContents macro strings to the second and third parameters.

3.3.If the number passed to the first parameter is not zero, the IfThenElse macro executes the JumpID macro; otherwise, it executes the JumpContents macro.

Note:

In this example, the use of the IsMark macro differs from the use of the jump macros. Help does not use the return values of the JumpID and JumpContents macros in the IfThenElse macro. Since they are enclosed in quotation marks, Help treats them as simple strings, not as macros.

Note:

You can also use DLL calls as conditions for the IfThen and IfThenElse macros.