This is a concise but comprehensive quick start tutorial for Quick Macros (QM). It introduces the core concepts, operations, and most important commands, designed for beginners and as a handy reference for experienced users.
- What is a Macro
- How Quick Macros Works
- Quick Macros Main Window
- Creating Macros, Menus, or Toolbars
- Adding Macro Commands
- Recording Operations
- Menus and Toolbar Buttons
- How to Launch Macros
- Macro Running Status
- How to End a Running Macro
- Using Variables and Strings
- Loops and Conditionals
- Top 20 Most Used Commands
A macro is a list of commands that are executed in sequence when the macro runs. These commands can perform the same actions as you can do manually: type text, click menus, run files, and more.
You can assign a trigger (such as a hotkey) to a macro, add it to a toolbar, or launch it by other means. Instead of repeating the same steps manually, you can run the macro with a single click or keystroke.
In the Quick Macros window, you can create macros and other items (functions, toolbars, menus, etc.). Each task you want to automate should have its own macro. Macros can be assigned triggers, e.g., hotkeys, mouse actions, window events.
While Quick Macros is running, it monitors for these triggers. When a trigger event occurs, Quick Macros executes the assigned macro. QM also manages your custom toolbars and menus.
- Top: Menu and toolbars.
- Left: List of QM items (macros, functions, menus, toolbars, etc.).
- Middle: Code editor. Here you edit the commands of the selected item.
- Bottom: Output area (shows errors and messages), Find, Tips, Status bar.
- To create a new macro, click the New Macro button on the toolbar and type a name in the field that appears.
- To create other item types (function, toolbar, etc.), use the popup menu beside the New Macro button.
- Macros are stored as plain text, usually with one command per line.
- You can add commands using dialogs from the code toolbar, but not all commands have dialog boxes—some must be typed manually.
- You can search for commands and dialogs using the Find help, functions, tools field above the code editor.
- The easiest way to add keyboard and mouse commands is to record them.
- You can record keyboard and mouse actions to create a macro, or just part of it.
- To start recording, click the Record button on the toolbar or press
Ctrl+Shift+Alt+R
. - After finishing, click Insert in the QM Recording dialog.
- Recorded macros usually require review and editing, e.g., adding delays or changing window names.
- When recording, prefer using keyboard shortcuts over mouse actions for more robust macros.
Menu text and toolbars are essentially lists of commands, each line creating a menu item or toolbar button. Each line uses the format: Label : Command
Example:
Macro18 : mac "Macro18"
Notepad : run "$system$\notepad.exe"
-
Email : key "my@ema.il" * text.ico
Login : key "abcd"; key T; key "1234"; key Y * text.ico
- To quickly add a macro, drag it from the item list to the menu/toolbar text.
- To add a file, use the Run File dialog or drag it from Explorer.
- Use
-
or|
to add a separator. - Use the Icons dialog to add icons to menu items or buttons.
You can launch macros in several ways:
- Run button on the QM toolbar
- Hotkey, mouse, window, or other trigger (set in Properties)
- Place macro in a custom menu or toolbar and launch from there
- Schedule to run at a certain time
- Create a desktop shortcut (set in Properties)
- Launch from another macro using the
mac
command - Use autotext (text replacement triggers)
Menus, toolbars, and functions can be launched in the same ways.
When a macro is running, the QM tray icon turns red.
When other QM items (functions, menus, etc.) are running, the tray icon does not change.
You can see all running items in the Running items pane in the QM window or in the Threads dialog in the QM tray menu.
- When a macro is running, press the Pause key (can be changed in Options).
- If input is blocked (due to
BlockInput
), first pressCtrl+Alt+Delete
. - For functions or macros with 'Run simultaneously' option, use the Running items pane or Threads dialog to end them.
- You can also add custom code in your macro to allow it to be stopped, e.g.:
rep ifk(F12) ret ;; end if F12 is pressed ...
You can use variables almost everywhere in QM code.
- Use
int
for integer values,double
for floating-point,str
for text.
Example (without variables):
lef 100 200 "Notepad"
Example (with variables):
str s="Notepad" ;; declare str variable s, assign "Notepad"
int x y ;; declare int variables x and y
x=100
y=x*2
lef x y s
To share a variable between macros, declare it with +
:
int+ global_var
Strings must be enclosed in double quotes. Use ''
to represent a quote and []
for a newline.
out "This is[]a multiline string[]with ''double quotes''."
You can also declare multiline strings:
str s=
This is
a multiline string
with "double quotes".
out s
Loop (repeat commands):
rep 10
lef 100 200
key Y
Conditional execution:
if i<5
out "variable i < 5"
i+1
else
out "variable i >= 5"
Here are the 20 most important QM commands, with descriptions and examples:
Command | Purpose & Example |
---|---|
lef, rig | Mouse clicklef 100 200 ;; left click at 100x200 lef 90 40 "Notepad" |
key | Keyboard actionskey "Australia" key F12 key Cv ;; Ctrl+V |
paste | Paste textpaste "New Zealand" paste s |
out | Output to QM windowout "I am here" out i |
mes | Show message boxmes "Important information" if(mes("Continue?" "" "YN")='N') ret |
run | Run file, open document or URLrun "C:\WINDOWS\system32\notepad.exe" run "http://www.quickmacros.com" |
act | Activate windowact "Notepad" |
win | Find window and get handleint hwnd=win("Internet Explorer" "IEFrame") act hwnd |
wait | Wait/delaywait 5 ;; wait 5 seconds wait 30 "Internet Explorer" |
mac | Launch another macromac "Macro9" |
err | Continue if error occurswait 2 "Window" err |
ret | Exit current macro/functionif(i=0) ret |
goto | Jump to labelif(i>=10) goto g1 g1: out "This line is always executed" |
if, else | Conditional executionif i<5 ... else ... |
rep, break | Loop and breakrep 10 ... break |
int, str | Declare variablesstr s="Notepad" int x y int+ g_var |
QM macro text is a sequence of statements. Usually, a statement is a single line of code that performs an operation or declares an identifier.
Examples:
lef+ 10 200 "Notepad"
lef
int a b c
a = b * 100
Func b 1
a = Func(b 1)
The first and second statements are macro commands. They consist of the following parts:
lef
is the command keyword.+
is an option.10
,200
, and"Notepad"
are arguments (the actual values for the command/function parameters).
The third statement declares variables a
, b
, and c
.
The fourth statement assigns the expression b*100
to variable a
.
In the fifth statement, the function Func
is called with arguments b
and 1
.
In the last statement, function Func
is called, and its return value is assigned to a
.
Numbers such as 10, 200, 100, and 1 are numeric constants.
"Notepad"
is a string constant.
=
and *
are operators.
Parts of statements must be separated by spaces (except command/option). In statements with operators (example 4), spaces may be omitted. Arguments can also be separated by commas (,
).
When using enclosed arguments, the (
must be immediately after the function name and option character (if any).
- Space,
;
,/
, or\
disables the line (useful for comments). - To disable/enable lines easily, right-click the selection bar.
- Comments can also follow a statement using
;;
.
Example:
; this is a comment
int a ;; declare integer a
Tabs or commas are used with flow-control statements (if
, rep
, etc).
Example:
; if a is less than 10, left-click, else exit
if a<10
lef
a + 1 ;; increment a
else ret
Note: In QM, indentation is used to express logical structure instead of curly braces
{}
.
Indentation must be done using tabs — using spaces is strictly prohibited.
The following code is incorrect:
int a = 10
if (a > 5)
{
mes "a is greater than 5"
}
else
{
mes "a is less than or equal to 5"
}
A single line can contain several statements separated by semicolons (;
). A semicolon is optional after a statement that begins with a command/function name and has enclosed arguments (or empty parentheses). It's also optional after else
, err
, and case
.
Examples:
lef+ 10 100 Notepad; lef; int a; a = b + 100; Func(a b); b = Func(a b)
rep() if(b>a) b=Func(a b); else break
Gray symbols in syntax descriptions have the following meanings:
Syntax Example | Meaning |
---|---|
[a] |
a is optional |
a|b |
a or b |
a&b |
a and/or b |
(a b)|(c d) |
a b or c d |
(space)a |
a must be preceded by space or semicolon |
(tab)a |
a must be preceded by tab or comma |
... |
More parameters or statements |
int a |
a is a function returning int |
Syntax description example:
lef[+|-] [x y] [window] [client]
- All parameters in
[]
are optional. [+|-]
means you can use option character+
or-
optionally.- The
lef
keyword at the beginning meanslef
is a command, not a function.
Real code examples based on the above syntax:
lef 10 200 "Notepad"
lef
lef+ 10 200
- Predefined commands and functions
- Constants
- Variables
- Operators
- Functions
- If-else
- Go to
- Repeat
- String manipulation
- Errors
- Threads
As described in the syntax topic, QM macro code is a sequence of various statements: macro commands, functions, calculations, declarations, flow-control, and everything needed for programming.
A single line can contain one statement or several statements separated by semicolons.
For comments, use a space at the beginning of a line or two semicolons after statements. Tabs at the beginning of a line are used for flow-control statements (if
, rep
, etc).
Example:
if a is less than 10, left-click, else exit
if(a<10)
lef 5 a "Some Window"; wait 1
a + 1 ;;increment a
else ret
Quick Macros has about 200 built-in keywords, including 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 provides several features to simplify programming. You can press F1 for help on functions and identifiers. Basic syntax or definitions are shown in the QM status bar. To browse and insert available identifiers, use member lists. Some commands can be entered via dialogs or recorded.
Constants are simple numeric or string values, such as 45
(integer), 0x1A
(hex integer), 10.57
(float), or "text"
(string).
String constants are enclosed in double quotes. To insert a double quote inside a string, use two single quotes (''
).
For new line, use []
.
Constants can be assigned to variables, used as arguments, and in expressions with operators.
You can also define named constants.
Variables temporarily store data (numeric, text, etc) at runtime. Data can be changed during various operations.
Variables can be assigned, used as arguments, and in expressions with operators.
Before using a variable, you must declare it (except predefined variables). Declaration includes type and name.
Common types:
int
(integer values)str
(strings)double
(floating-point)
Example:
int i
str S3
double+ g_var
i=5
S3="text"
g_var=15.477
You can use pointers and arrays:
ARRAY(str) a.create(10)
a[0]="abc"
You can define new types. User-defined types usually have several member variables.
For example, type POINT
has members x
and y
:
POINT p
p.y=10
Operators are special symbols for assignment, arithmetic, comparison, or other operations.
Examples:
i = 5 ;; assign 5 to i
i + 2 ;; add 2 to i
a = b + 10 ;; a = b + 10
ave = i + j / 2 ;; ave = i + (j / 2)
f = i - (10 * j) + func(a b) * -10 ;; complex expression
str s = "notepad" ;; declare s, assign "notepad"
s + ".exe" ;; append ".exe"
if(i<10 and s="notepad.exe") i = j/10 ;; logical and comparison
i = Func2(j s (i + 5) f) ;; call function with arguments
lef a-10 100 ;; left click at (a-10, 100)
Operators have 3 priority classes:
- Arithmetic/bitwise
- Comparison (
=
,!
,<
, etc) - Logical (
and
,or
)
Operators in the same class are evaluated left to right. Use parentheses to change order.
See also:
See also: functions, user-defined functions, sub-functions, function tips.
A function is a named code unit that can receive (via arguments) and return values.
Besides predefined functions, you can create your own.
Reuse code by placing it in a function and calling it from any macro.
Examples:
Func a "text" 100 ;; call Func with three arguments
a = Func2(10) ;; call Func2, assign return to a
Func3(a Func4(b c)) ;; nested function calls
d = e + Func5(b c) / 10 ;; use function in expression
Some variable types have member functions, called as: variable name, dot, function name.
str s s2="notepad"
s.from(s2 ".exe")
if(s.end(".exe")) out "s ends with ''.exe''"
To create a new user-defined function, select New Function from File/New.
To define return type and parameters, use the function
statement at the top.
To return a value, use the ret
statement.
By default, a function can be called from code or launched as a macro.
To make it callable only from code, start with a line containing space and /
:
/
function'int str'a str&b [int'c]
statements
ret 1
- This function returns
int
. - It has three parameters:
a
,b
(by reference),c
(optional). - If not returned explicitly, the return value is 0.
Use if
to execute or skip statements depending on a condition.
Example:
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"
Statements can also be in a single 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"
For comparing a variable to multiple constant values, use sel
.
The goto
statement jumps to another place in the code.
Example:
goto g1
statements
g1
statements
Statements after goto
are skipped; execution resumes after the label (g1
, with a space before the label).
The rep
statement repeats the following tab-indented statements.
You can specify the number of repetitions. To exit early, use break
.
Statements can also be in the same line.
Examples:
rep(100) i-1
This executes i-1
100 times.
i=0
rep
if(i>=100) break
out i
i+1
Equivalent using for
:
for i 0 100
out i
QM provides many functions for processing strings. Use str
variables to store and manipulate text.
Example:
str s = "Cat" ;; now s is "Cat"
val(s)
– numeric value of string s (0 if s doesn't start with digits)find(s "substring")
– index of "substring" in s (or -1 if not found)if(IsCharLower(s[0])) s[0]=CharUpper(+s[0])
– uppercase first character if lowercase
Called with the variable name and dot:
s.from("word1" ", " "word2") ;; s = "word1, word2"
s.ucase ;; s = "WORD1, WORD2"
str ss.get(s 7 5) ;; ss = substring of s, starting at 7, length 5
You can use +
and -
to append and prepend:
s + ".txt" ;; append ".txt"
s - "C:\Doc\" ;; prepend "C:\Doc\"
=
: equal, case sensitive~
: equal, case insensitive!
: not equal, case sensitive
To compare part of a string, use member functions like beg
, mid
, etc.
if(s~"Monday") ... ;; s is "Monday" (case insensitive)
if(s.endi(".exe")) ... ;; s ends with ".exe" (case insensitive)
When you launch a macro, QM compiles it, checking for syntax errors.
On error, QM highlights the error and shows the description. A macro with errors will not run.
At runtime, a macro command may fail, causing a runtime error and macro termination.
The err
statement allows continuation after a run-time error in the preceding command.
Examples:
clo "Notepad"; err
5 "Notepad"
err
run "$system$\notepad.exe"
In the first example, err
allows continuation if an error occurs. In the second, on error, the run "$system$\notepad.exe"
statement is executed.
A thread is like a subprogram in a running program. In QM, it is a running macro or function, including all functions 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 the 'Run simultaneously' option enabled.
Purpose:
This document provides a comprehensive syntax comparison between Quick Macros (QM) and the C++/C# programming languages.How to use:
If you are familiar with C++ or C# and want to quickly understand QM syntax (or vice versa), use this as a reference.AI/Reader note:
QM has its own unique syntax, which is more concise and sometimes less formal than C++/C#. Understanding these differences will help you translate logic and patterns between the languages.
QM Syntax | C++/C# Syntax |
---|---|
Function x y Function(x y) Function(x, y); |
Function(x, y); |
QM Syntax | C++/C# Syntax |
---|---|
code ;;comments |
code //comments //comments /* block of comments */ |
int variable
byte variable
word variable
long variable
double variable
lpstr variable
str variable
BSTR variable
ARRAY(int) variable
int a b(5) c=6
int handle hwnd
int functionAddress=&Function
int variable; // or long variable; also unsigned types: UINT, DWORD
BYTE variable; // or unsigned char variable
WORD variable; // or unsigned short variable
__int64 variable;
double variable;
LPSTR variable; // or char* variable
CString variable; // MFC/ATL
CComBSTR variable; // ATL
CArray <int> variable; // MFC
CSimpleArray <int> variable; // MFC
// More string and array classes are available from various libraries
int a, b=5, c=6;
HANDLE handle; HWND hwnd; // many handle types, in QM all are int
void Function(void); // function has no return value or no parameters
int (__stdcall* FunctionType)(int x, int y); FunctionType functionAddress=Function; // callback type and address
int variable; // uint for unsigned
byte variable; // sbyte for signed
ushort variable; // short for signed, char for Unicode UTF-16 character
long variable; // ulong for unsigned
double variable;
String variable; // Unicode UTF-16 string
int[] variable; // array
int a, b=5, c=6;
void Function(); // no return value
delegate int DelegateType(int x, int y); static DelegateType functionAddress; // callback type and address
QM | C++ | C# |
---|---|---|
int+ global_variable |
int global_variable; // not in function or class |
static int global_variable; // in class |
int- thread_variable |
__declspec(thread) int thread_variable; |
[ThreadStatic] static int thread_variable; |
int local_variable |
int local_variable; // in function |
int local_variable; // in function |
int* pointer1 pointer2 |
int* pointer1; int* pointer2; |
|
int& reference_variable=variable |
int& reference_variable=variable; |
|
int'member_variable int*member_variable2 |
int member_variable; int* member_variable2; // in class |
int member_variable; // in class |
QM | C++ | C# |
---|---|---|
def CO_NSTANT 5 |
#define CO_NSTANT 5 const int C1=5; enum CONSTANTS { C1=5, C2=5+6 }; |
const int C1=5; enum CONSTANTS { C1=5, C2=5+6 }; |
def CO_NSTANT2 5+6 |
#define CO_NSTANT2 (5+6) |
QM | C++ | C# |
---|---|---|
out variable |
printf("%i", variable); // ANSI printf(L"%i", variable); // Unicode |
Console.WriteLine(variable); |
if condition
code
else
code2
if(condition) {
code
} else {
code2
}
for i 0 5
code
for(i=0; i<5; i++) {
code
}
rep 5
code
for(int i=0; i<5; i++) {
code
}
rep
if(condition=0) break
...
while(condition) {
...
}
rep
...
if(condition=0) break
do {
...
} while(condition);
sel i
case 1
code
case 2
code
case else
code
switch(i) {
case 1:
code
break;
case 2:
code
break;
default:
code
break;
}
QM | C++/C# |
---|---|
goto label ... label |
goto label; ... label: |
QM | C++ | C# |
---|---|---|
code err code2 |
try { code } catch(...) { code2 } |
try { code } catch { code2 } |
QM Example | C++/C# Equivalent |
---|---|
i+1 ;;or: i+=1 |
i+=1; // or: i++; |
`a = b or c ;;or: a = b | |
if(a=b) code ;;or: if(a==b) code |
if(a==b) code // if(a=b) assigns b to a |
x = iif(condition A B) |
x = condition ? A : B; |
Most operators are the same in QM, C++, and C#.
QM | C++/C# |
---|---|
function'int x [y] ;;function name is not here code ret 1 |
int FunctionName(int x, int y=0) { code return 1; } |
QM | C++ | C# |
---|---|---|
dll "file.dll" int'Function int'x lpstr's |
#pragma comment(lib, "file.lib") int Function(int x, LPSTR s); |
[DllImport("file.dll")] public static extern IntPtr Function(int x, [MarshalAs(UnmanagedType.LPStr)] String s); |
QM | C++ | C# |
---|---|---|
type Type x y double'd |
struct Type { int x, y; double d; }; |
struct Type { public int x, y; public double d; }; |
class Class --m_private m_public ;;only member variables here
class Class {
int m_private;
public:
int m_public;
Class { code } // constructor
~Class { code } // destructor
void MemberFunction(int x, int y); // declaration
};
// function definition elsewhere
void Class::MemberFunction(int x, int y) {
code
}
class Class {
int m_private;
public int m_public;
public Class { code } // constructor
~Class { code } // destructor
public void MemberFunction(int x, int y) {
code
}
};
QM | C++/C# |
---|---|
category X : functions (QM does not have namespaces. Category is similar, but different.) |
namespace X { ... } |