Programming in QM

Predefined commands and functions






Go to


String manipulation




As you can read in the syntax topic, QM macro code is a sequence of various statements - macro commands, functions, calculations, declarations, flow-control and everything you need for programming. A single line of code can contain a single statement or several statements separated by semicolons. For comments, use space at the beginning of line, or two semicolons after statements. Tabs at the beginning of a line are used with flow-control statements (if, rep and other). Example:


 if a is less than 10, left-click, else exit
	lef 5 a "Some Window"; wait 1
	a + 1 ;;increment a
else ret

Predefined commands and functions

Quick Macros has about 200 built-in keywords. They include macro commands, functions, member functions, flow control statements, declaration statements, intrinsic types, compiler directives and operators. You can also use dll functions, COM functions, and user-defined functions.


QM offers several features to simplify programming. You can use F1 to get help for functions and other identifiers. Basic syntax or definition of these identifiers also is displayed in QM status bar. To browse and insert available identifiers, you can use lists of members. Some commands may be entered through dialogs, or recorded.


Constants are simple numeric or string values, such as 45 (integer constant), 0x1A (integer constant in hexadecimal format), 10.57 (floating-point constant), "text" (string constant). String constants are enclosed in double quotes. To insert a double quote in a string, use two single quotes (''). For new line, use []. Constants can be assigned to variables, used as arguments of macro commands and functions, and in expressions with operators. You can also define named constants.


Variables are used to temporarily store data (numeric, text, etc) at run time. The data can be changed during various operations. Like constants, variables can be assigned to variables, used as arguments of macro commands and functions, and in expressions with operators.


Before using a variable, you must declare it (except predefined variables). Declaration includes type and name. Mostly used types are int (for numeric integer values), str (for strings) and double (for numeric floating-point values). In the following example, we declare local variable i of type int, local variable S3 of type str, and global variable g_var of type double. Then we assign some values:


int i
str S3
double+ g_var


You can also use pointers and arrays. In the following example, we declare array a of str variables, allocate 10 elements, then store string "abc" into element with index 0:


ARRAY(str) a.create(10)


You can define new types. User-defined types usually have several member variables that may have different types. For example, type POINT has members x and y. In the following example, we declare variable p of type POINT, and assign 10 to its member y:




An operator is a special symbol used to perform assignment, arithmetic, comparison or other operation. Several examples with comments:


i = 5 ;;assign 5 to variable i
i + 2 ;;add 2 to variable i
a = b + 10 ;;calculate sum of b and 5 and assign it to variable a
ave = i + j / 2 ;;add j to i, divide by 2, then assign result to variable ave
f = i - (10 * j) + func(a b) * -10 ;;multiply 10 and j, extract result from i, call function Func and add its return value, multiply by -10, then assign result to variable f
str s = "notepad" ;;declare variable s and assign string "notepad"
s + ".exe" ;;append ".exe"
if(i<10 and s="notepad.exe") i = j/10 ;;if i is less than 10, and s is equal to "notepad.exe", then calculate j / 10 and assign result to variable i
i = Func2(j s (i + 5) f) ;;call function Func2 and assign its return value to variable i; pass four arguments; the third argument is sum of i and 5 
lef a-10 100 ;;left click; x is a-10, y is 100


In QM, operators belong to 3 priority classes: first are calculated arithmetic and bitwise operators, then comparison operators (=, !, <, etc), and lastly logical operators (and, or). Operators that belong to the same priority class are calculated from left to right. Parentheses can be used to change this order.


See also: unary operators ( - and other), member access operator . and array element access operator [].


See also: functions, user-defined functions, sub-functions, function tips.


A function is a named piece of code executed as a unit. It can receive several values (arguments) and return some value. Beside the predefined functions, you can create your own (user-defined) functions. Usually, you create a function when you want to have a piece of code that can be executed more than once, in any macro. Instead of placing the same code in each macro, you place it in a function, and then call the function by name from any macro. Like constants and variables, functions can be assigned to variables, used as arguments of macro commands and other functions, and in expressions with operators. Examples:


Func a "text" 100 ;;call function Func with three arguments
a = Func2(10) ;;call function Func2 with one argument, and assign its return value to variable a
Func3(a Func4(b c)) ;;call function Func4 with arguments b and c, then call function Func3 with two arguments (second argument is return value of Func4)
d = e + Func5(b c) / 10 ;;use function Func5 in expression with operators


Some variable types have member functions. A member function is called with a variable of that type. Example:


str s s2="notepad"
s.from(s2 ".exe")
if(s.end(".exe")) out "s ends with ''.exe''"


To create new user-defined function, select New Function from the File/New menu and type function's name in the temporary edit field. To define function's return type and parameters, use the function statement at the beginning. To return a value, use the ret statement. By default, a function can be called from code or launched as a macro. To allow it only to be called from code, the first line should be space and /, as in the following example:


function'int str'a str&b [int'c]
ret 1


This function returns a value of type int. It has three parameters (local variables that receive the passed values (arguments) when the function is called). Variables a and c receive copies of passed values. Variable b is reference to the str variable that is passed. When this function modifies b, it actually modifies that variable. The last argument is optional, that is, caller can omit it, in which case c is 0. The function executes statements and returns 1. If it returns not through ret, or ret is without a value, the return value is 0.


Often you need to execute or skip several statements depending on some condition. Example:


if a>0
	out "a is greater than zero"
else if a=0
	out "a is equal to zero"
	out "a is less than zero"


The if statement evaluates some expression (in this case, a>0), and, if the expression is true (nonzero), allows to execute the following tab-indented statements. The if statement optionally can be combined with the else statement, which allows to execute the following tab-indented statements if the expression is false (zero). As you see in the example, else if can be used to evaluate more expressions. The statements also can be in the same line:


if(a>0) out "a is greater than zero"; a-1
else if(a=0) out "a is equal to zero"
else out "a is less than zero"


When need to compare a variable with multiple constant values, it is more convenient to use sel.

Go to

The goto statement is used to jump to some other place in code. Example:


goto g1


In the example, statements after goto are skipped, and execution continues from the statement that follows the label g1. Note that the label is preceded by single space (same as comments).


The rep statement is used to repeatedly execute the following tab-indented statements. It optionally can include number of times to repeat. To exit the loop, use the break statement. The statements also can be in the same line. Examples:


rep(100) i-1


In this example, i-1 is executed 100 times. In the following example, out i is executed while i is less than 100, that is, also 100 times:


	if(i>=100) break
	out i


You can also use for (repeat with counter variable) and foreach. Example:


for i 0 100
	out i


This example does the same job as the second example with rep. Initially, variable i is set to 0. Then, out i is repeatedly executed, and after each loop i is incremented. This process stops when i becomes equal to 100.

String manipulation

QM has a set of functions to process strings (text). To store and manipulate strings, use variables of type str. In the following example, we declare variable s and assign string "Cat".


str s = "Cat" ;;now variable s is "Cat" (string "Cat" is stored in variable s).


There are two groups of string functions. The first group - global functions - are used to get certain information about a string (length, numeric value, find substring, etc) or a character. Examples:


i=val(s) ;;i = numeric value of string s (or 0, if s does not begin with digits).
i=find(s "substring") ;;i = index of first character of "substring" in string s (or -1, if "substring" is not found in s).
if(IsCharLower(s[0])) s[0]=CharUpper(+s[0]) ;;if first character of string s is lowercase, convert it to uppercase.


The second group - str member functions. Most of them are used to build or modify string. The calling syntax slightly differs: function's name is preceded by variable's name and dot. Examples:


s.from("word1" ", " "word2") ;;build string variable s from three strings (join). Now s is "word1, word2". Here s is variable of type str.
s.ucase ;;make s uppercase. Now s is "WORD1, WORD2".
str ss.get(s 7 5) ;;declare str variable ss and get part of s. Now ss is "WORD2".


With str variables, you can use operators + and - to append and prepend:


s+".txt" ;;append ".txt"
s-"C:\Doc\" ;;prepend "C:\Doc\"


To compare str variables, use operators = (equal, case sensitive), ~ (equal, case insensitive) and ! (not equal, case sensitive). To compare part of string, use str member functions beg, mid and other. Examples:


if(s~"Monday") ... ;;if s is "Monday" (case insensitive) ...
if(s.endi(".exe")) ... ;;if s ends with ".exe" (case insensitive) ...


When you launch a macro, QM compiles it, which includes checking for syntax errors. On error, QM highlights the error place and gives error description. Macro with errors is not executed.


At run time, in certain conditions, a macro command may fail. Then QM generates run-time error, and the macro ends. The err statement allows you to continue execution after a run-time error in the preceding statement. Examples:


clo "Notepad"; err

5 "Notepad"
	run "notepad.exe"


In the first example, err allows to continue if an error occurs. In the second example, on error is executed run "notepad.exe" statement, which would not be executed otherwise.


A thread is like a subprogram within a running program. In QM it is a running macro or function, including all functions that it calls. Multiple function threads can run simultaneously, including several instances of the same function. Multiple macro threads can run simultaneously if the macro has option 'Run simultaneously'.