You are on page 1of 11

08/06/2021 HID macros

HID macros: Software for sending keyboard macros activated from different USB devices

What is it? Overview


Download From version 2.0 HIDmacros can execute scripts as macro actions. Any scripting language installed to
windows active scripting can be used. Windows contain by default
VBscript and JScript.
News
Application possibilities are extended with scripting support. Inside the script several special commands
Videos provided by HIDmacros application can be used.
Putting all together typical tasks handled by scripts are

FAQ extended keystrokes with windows management


mouse events - single clicks, double clicks, all buttons
Wish list windows script host - Shell or Network objects are accessible
FSX events - any FSX event can be sent by HIDmacros command from script
Docs & Tips FSX variables - HIDmacros can monitor selected FSX variables and their values can be read by
special command
Scripting FSUIPC interface - access to FS variables
buffer - simple input interface for scripts
XPL map game devices - support for toggle switches
game axis - read joystick position in script
Forum X-plane - read & set X-plane variables, execute commands


Architecture
Every macro can contain script source which is executed when macro is activated. Apart of these script
codes there is one global section used for global definitions and initialization code.
This section is
accessible on Script page.

This is good place do define routines (procedures and functions) that will be used from macro scripts. Also
any variable defined here is globally available in macro scripts. Global variables are usable for example for
keyboard profiles. You can have global variable called e.g. PROFILE and based on its value (assigned by
some macro = key on keyboard)
other macros with script code can behave differently. This is used in
scripting example described below.

There are compile buttons available to compile routines code or macro code. There is also Compile all
button that compiles routines code and all scripted macros. Macro script code must be compiled. Otherwise
it is not executed when macro is activated.
There is also red/green indicator next to script window showing
whether current code is compiled or not. Global indicator is located
in application status bar. If it says
"Scripts compiled" it means routines code (the global code) and all scripted code in macros are compiled.

Technical note: As all the code is scripted the process behind is not real compilation. When you hit Compile
button HIDmacros just take the code and load it to scripting engine. Only syntax check is done at that time.
But note that initialization code in routines source which is not inside procedure or function is executed
during compilation (load to scripting engine).
www.hidmacros.eu/scripting.php 1/11
08/06/2021 HID macros
Keystroke sending
There are 2 possibilities how to send key sequence from script.

1. HIDMacros command SendKeys: procedure has one string parameter with keys sequence. Format is
exactly the same as used in macro definition.
2. using scripting language possibilities. Some script languages have wrappers for Windows API calls -
this is what HIDMacros do internally.

Following example shows both methods. The example is in VBscript.

'HIDmacros command

HIDMacros.SendKeys "+a"

'Windows way

Dim wsh

Set wsh = CreateObject("Wscript.Shell")

wsh.AppActivate "Notepad"

SendKeys "Hello"

On second example you can see how to activate some window using standard VB script command. When
you work with Wscript.Shell object often in your macros, it's better to dim & create this variable in routines
section.

The AppActivate method


takes as parameter window title or its handle. If you're not sure what is window
title, check titles of all currently visible windows on Script tools tab.

Mouse events
There is a command to send mouse click:

HIDMacros.MouseClick x, y, action

Parameters are:

x x coordinate
y y coordinate
number saying what should be done at coordinates
0 - just move mouse pointer
1 - left click
2 - middle click
action 3 - right click
4 - left double click
5 - middle double click
6 - right double click

All clicks returns mouse pointer to current position. It means mouse pointer moves to
new position,
performs operation (click or double click) and returns where it was before
macro execution. For action 0
(mouse move) this return is of course not done.

A few words about delays. I've got many requests to include delays into keyboard sequence
in HIDmacros.
With scripting it's quite easy so there is a command HIDMacros.Sleep which
takes number of miliseconds
as parameter. However it's not that easy in reality.
If you try to use delay together with key operations, you
realize that Active scripting
somehow delays keyboard messages and delay between keystrokes doesn't
work. Whole execution
gets delayed and keystrokes are sent at once. Mouse operations seem to work fine
with delays
so you can send e.g. 2 mouse clicks with delay between - giving some time to paint a menu
for
example. But there is one more problem. With delays and generally with scripting (loops)
it can happen that
macro execution takes quite a long time and HIDmacros gets blocked.
My original plan was move script
execution to new thread and keep HIDmacros to process other
keyboard triggers. But it doesn't seem to be
that easy to move all the DOM stuff around scripting
to special thread, so this is my next plan and
investigation. Until I have macro execution
in threads, it's always your risk & responsibility to create quick
macros. During
macro execution another macro is not activated

So finally example of Start - Run activation at screen 1280x1024 with delay.

HIDMacros.MouseClick 49, 980, 1

HIDMacros.Sleep 600

HIDMacros.MouseClick 90, 875, 1

Windows Scripting Host


WSH can be used in macro script. Global object WScript is not available, but you
can create WshShell and
WshNetwork objects via CreateObject command.

In that case it is better to create such object in routines script

www.hidmacros.eu/scripting.php 2/11
08/06/2021 HID macros

'Routines

Dim wsh

Set wsh = CreateObject("Wscript.Shell")

and in macro only call methods of this object

wsh.AppActivate "Notepad"

FSX events
FSX events can be sent also from script using command:

HIDMacros.FSXEvent event_name, parameter

Parameters are:

event_name name of the event as listed in documentation


some events can have parameter and its value is provided here. Use 0 when there's no
parameter
parameter for your event.

You can also send some text to FSX screen by command:

HIDMacros.FSXtext "Text to be sent"

Example for both commands:

HIDMacros.FSXtext "Setting NAV1 stand by frequency to 112.6"

HIDMacros.FSXEvent "NAV1_STBY_SET", &H11260

FSX variables
You can also read and write FSX variables through commands using SimConnect interface.
However there
are some limitations. Currently HIDmacros work only with float and sting values.

Reading FSX variable through SimConnect is not simple, because the interface is
message driven. So you
first ask SimConnect to send you values of some variable
and then you receive messages when value
changes. It means you must first tell HIDmacros
that you will need some variable and only then you can
read its value. Writing is easier,
because here we don't need to wait for message with result.

So here are the commands for FSX variables management.

HIDMacros.RegisterFSXVariable var_name, var_units

HIDMacros.GetFSXVariable var_name

HIDMacros.SetFSXVariable var_name, var_units, var_value

Parameters are:

var_name variable name as listed in documentation


var_units variable units as listed in documentation. Use "STRING" to read string variable.
var_value value in units to be set

Only some variables are writable. When possible it's better to use FSX event to control simulator.
Variables
should be registered only once, so routines section is good place. Do not register too many variables.
Once
variable is registered, FSX will send a message to HIDmacros every second when value changes, even if
you
don't read the variable. If you try to read variable that was not registered, you'll get 0.

Example, in routines:

'Routines

HIDMacros.RegisterFSXVariable "PLANE ALTITUDE", "FEET"

HIDMacros.RegisterFSXVariable "ATC MODEL", "STRING"

and in macro

' read

Dim MyVar

MyVar = HIDMacros.GetFSXVariable("INDICATED ALTITUDE")

if HIDMacros.GetFSXVariable("ATC MODEL") = "DHC-6" then

HIDMacros.FSXtext(MyVar)

end if

' write

HIDMacros.SetFSXVariable "GENERAL ENG THROTTLE LEVER POSITION:1", "percent", 100

FSUIPC interface
With Peter Dowson's FSUIPC
you can access simulator variables in similar way as with SimConnect for
FSX. I would
say Peter's interface is more "technical", but works with other simulators like FS2004 or

www.hidmacros.eu/scripting.php 3/11
08/06/2021 HID macros
FS2002.
For all details about supported simulators, variables mapping etc please refer to Peter's web page
and mainly FSUIPC SDK package.

HIDmacros brings several functions to read and write variables through FSUIPC. To use those functions
FSUIPC of course must be installed.

HIDMacros.GetFSUIPCInt offset, size

HIDMacros.GetFSUIPCFloat offset, size

HIDMacros.GetFSUIPCString offset, size

HIDMacros.GetFSUIPCRaw offset, size

HIDMacros.SetFSUIPCInt offset, size, value

HIDMacros.SetFSUIPCFloat offset, size, value

HIDMacros.SetFSUIPCString offset, size, value

Parameters are:

offset variable's memory offset from FSUIPC SDK.


size size of variable in bytes, also mentioned in SDK
value value to be set

Size parameter tells how many bytes will be read or written. For int functions (GetFSUIPCInt and
SetFSUIPCInt) this can be between 1 and 8. For float functions only size 4 and 8 bytes is supported (float
or double float).
Function GetFSUIPCRaw read part of memory and return string representing memory
dump.
It means every byte is represented by 2 characters in hex format, for example byte 44 would be
returned as 2C. By writing a string to offset 0x0D70 you can execute FSUIPC macro or LUA script (in
registered version).

Example

' read

Dim isPaused

Set isPaused = HIDMacros.GetFSUIPCInt(&H262, 2)

Dim rawClock

Set rawClock = HIDMacros.GetFSUIPCRaw(&H238, 3)

' write

HIDMacros.SetFSUIPCInt &H262, 2, 1 'pause sim

HIDMacros.SetFSUIPCInt &H330, 2, 16096 'alt set 1006 mBars

' write string

HIDMacros.SetFSUIPCString &H3380, 128, "Hello world"

HIDMacros.SetFSUIPCInt &H32FA, 2, 5

Input buffer
Sometimes you need enter some value for your script. You may wish to enter
how many times macro action
will be repeated. Or you may wish to enter numeric
value and then use it to set heading in flight simulator.
Or tune some radio.

There's special buffer built in HIDMacros. It can be set by script or directly from keyboard. Its value is
accessible via script commands.

To set buffer content via keyboard you have to define new macro for each key
and as action choose "Send
to buffer".

www.hidmacros.eu/scripting.php 4/11
08/06/2021 HID macros

So if you define such macro for example for numpad "3" and then hit this key, value "3" will be added to
the buffer. In settings tabs you can define if buffer
content is shown or not. If content is shown the buffer
value will appear in application title in task bar. If application is minimized to tray content is shown as
baloon hint.

In settings you can also choose if buffer content should be cleared after some
timeout. In this case you press
keys and add values in the buffer. Once you stop
adding content in the buffer, its value is cleared after
defined period of time.
The value is entered in miliseconds and 0 means buffer is never cleared
automatically.
In this case you must clear the buffer using script command.

There are several commands available for buffer operations:

HIDMacros.GetBuffer 'gets buffer content as string

HIDMacros.SetBuffer value 'sets whole buffer to value

HIDMacros.AddToBuffer value 'adds value to the end of buffer

www.hidmacros.eu/scripting.php 5/11
08/06/2021 HID macros
HIDMacros.ClearBuffer 'clears buffer

HIDMacros.StrRPad value, append, count

StrRPad is string padding function that adds append char to value


string to have count characters. If
provided string is longer than count,
it's truncated from left.

Example

' suppose we have numpad numbers defined as "send to buffer"

' set heading

HIDMacros.FSXEvent "HEADING_BUG_SET", HIDMacros.GetBuffer

' set NAV1 stand by frequency

Dim frq

frq = HIDMacros.GetBuffer

frq = HIDMacros.StrRPad(frq, "0", 5)

HIDMacros.FSXEvent "NAV1_STBY_SET", "&h"&frq

Game devices
Game devices are supported because their buttons can be used as toggle switches (with
permanent on or off
position). To use this funcionality in scripts there is special
method:

HIDMacros.IsButtonPressed DeviceName, ButtonNumber

Parameters are:

DeviceName Game device name from Devices tab


ButtonNumber Button number, starting from 1

Example

' set NAV1 or NAV2 radio based on toggle switch

if HIDMacros.IsButtonPressed("Saitek X52 Flight Controller", 13) then

HIDMacros.FSXEvent "NAV1_STBY_SET", &h11450

else

HIDMacros.FSXEvent "NAV2_STBY_SET", &h11450

end if

Game device axis


There is special function that returns position of game device axis (e.g. joystick position).

HIDMacros.GetAxis DeviceName, AxisName

Parameters are:

DeviceName Game device name from Devices tab


AxisName Name of the axis (e.g. X, Y...)

Of course you have a question: What are the names of axis that my joystick supports? The
answer is easy:
check yourself. Switch to Script support tab and Game axis sub-tab and see
all possible axis names that
HIDMacros recognize and moving you joystick you can see what
is the axis name and what are possible
values.

www.hidmacros.eu/scripting.php 6/11
08/06/2021 HID macros

Want more? It's nice to read axis value in the script when button or key is pressed. But what
if you need to
control something directly with axis. What if axis movement could call a script...

Sub AxisXChange(dev, axis, val)

Dim Message

Message = "Axis " & axis & " of device " & dev & " moved, value is " & val

end sub

HIDMacros.RegisterAxisEvent "Saitek X52 Flight Controller", "X", "AxisXChange", 5

With RegisterAxisEvent you can tell HIDMacros to call some procedure present in routines section
every
time when axis of your game device changes by some delta value. Parameters are:

DeviceName Game device name from Devices tab


AxisName Name of the axis (e.g. X, Y...)
Name of procedure present in your routines section. This procedure is called with 3
arguments: device name, axis name and axis value. For 1:1 registration
parameters can
ProcedureName
be redundant, but you can register more axis to call one procedure and then it's quite
usefull to see what axis has changed.
After what change of axis value the procedure is called.
Choose bigger number for
Delta
better performance (script is not called so often) and lower number
for precise control.

With this feature you can control more things with one axis, you can use keys to change axis meaning,
you
can set up your own null zones for axis etc. There's also similar function to unregister
axis callback:

HIDMacros.RegisterAxisEvent DeviceName, AxisName

For most axis values provided by DirectX are between 0 and 65535. Usually you need to
recalculate this
value to your own range. There are 3 supportive functions:

HIDMacros.Axis2Int AxisValue, LowValue, HighValue

HIDMacros.Axis2Float AxisValue, LowValue, HighValue

HIDMacros.AxisRemap AxisValue, RangeLow, RangeHigh, LowValue, HighValue, DefaultValue

Function Axis2Int takes AxisValue between 0 and 65535 and returns appropriate integer value from
interval between LowValue and HighValue. It means LowValue is returned
for axis value = 0 (and close
values) and HighValue for axis value 65535 (and close values).
If LowValue is bigger than HighValue axis
seems to be reversed. For axis value 0 you again get LowValue but it's bigger then HighValue this time. So
rising the axis value
you'll be getting lower numbers down to highValue. Axis2Float works in the same way
but
with float (fraction) values = no rounding to integer.

Function AxisRemap is used for mapping part of device axis to some range of values.
It has following
parameters

AxisValue Axis value between 0 and 65535

www.hidmacros.eu/scripting.php 7/11
08/06/2021 HID macros
RangeLow Bottom range of axis that should be mapped. Float fraction value between 0 and 1 (e.g.
50% of axis range is 0.5).
Top range of axis that should be mapped. Float fraction value between 0 and 1 (e.g. 50%
RangeHigh
of axis range is 0.5).
LowValue Result float value that will be returned for AxisValue at RangeLow
HighValue Result float value that will be returned for AxisValue at RangeHigh
DefaultValue Result float value that will be returned when AxisValue is out of input range

Example 1: Following example should make this complicated description more clear. Imagine we have
throttle axis
that should be mapped to forward throttle and reverse with some null zone between. Forward
value (sent to simulator) is
between 0 and 100, reverse value is between 0 and 60. And to make it more
complex (however based
on my real Saitek's throttle lever) let's have game axis returning 0 for fully
extended lever (100% throttle) and
65535 for no throttle. If we want to map reverse between 0 and 20%
then have 20-30% null zone and 30-100% throttle
then AxisRemap should be called with those parameters.

Example 2: use joystick to emulate keyboard. Store letter to buffer and emulate key press on button.

' rotuines section

Sub Axis2Char(dev, axis, val)

Dim CharCode

CharCode = HIDMacros.Axis2Int(val, 122, 97)

if (HIDMacros.GetAxis("Saitek X52 Flight Controller", "X") > 50000) then

CharCode = CharCode - 32 ' capital letters

end if

HIDMacros.SetBuffer Chr(CharCode)

end sub

HIDMacros.RegisterAxisEvent "Saitek X52 Flight Controller", "Y", "Axis2Char", 5

' macro on joystick button

if (HIDMacros.GetBuffer > "") then

HIDMacros.SendKeys HIDMacros.GetBuffer

end if

Example 3: map reverse to throttle axis in FSX. Don't forget to unassign axis in FSX, throttle is controlled
by script only.
AxisRemap is not used here to demonstarte how to calculate values in script.

' rotuines section

Dim ZeroT

Dim AxisPercent

Dim FinalThrottle

ZeroT = 0.2 ' bellow 20% apply reverse

AxisPercent = val / 65535

if (AxisPercent < ZeroT) then

' set reverse, which is negative throttle for FSX

FinalThrottle = (AxisPercent-ZeroT)*100 / ZeroT

else

' set throttle

FinalThrottle = (AxisPercent - ZeroT)*100 / (1-ZeroT)

end if

HIDMacros.SetFSXVariable "GENERAL ENG THROTTLE LEVER POSITION:1","Percent", FinalThrottle

HIDMacros.SetFSXVariable "GENERAL ENG THROTTLE LEVER POSITION:2","Percent", FinalThrottle

www.hidmacros.eu/scripting.php 8/11
08/06/2021 HID macros
X-plane interface
X-plane variables can be read and set by script commands. List of accessible
variables can be found in X-
plane SDK.

From version 2.1 it is also possible to execute X-plane commands. Those commands
are the same as in
controls assignment in XPL. XPL commands can be executed via script
command or directly in macro
definition.

Important: For X-plane access special plugin must be added to X-plane which
HIDmacros uses to
exchange data. This plugin is file HidMacrosXpl.xpl located in xpl
subdirectory of HIDmacros. You have to
manually copy this file to X-plane Resources\plugins
subdirectory.

Following methods are used for X-plane access:

HIDMacros.GetXplVariable pName 'returns variable content

HIDMacros.SetXplVariable pName, pValue 'sets variable content

HIDMacros.GetXplArrayItem pName, pIndex 'returns array item

HIDMacros.SetXplArrayItem pName, pIndex, pValue 'sets array item

HIDMacros.XPLCommand pCommand 'executes command pCommand

HIDMacros.XPLCommandBegin pCommand 'starts command pCommand

HIDMacros.XPLCommandEnd pCommand 'ends command pCommand

For array operations indexes are zero based. To find out array size, provide any negative number as pIndex.
Strings are also supported in GetXplVariable and SetXplVariable. However X-plane offers only a few string
variables.

Example

' get tail number (string)

var = HIDmacros.GetXplVariable("sim/aircraft/view/acf_tailnum")

' get flaps position (float)

var = HIDmacros.GetXplVariable("sim/flightmodel/controls/wing1l_fla1def")

' get current heading (float)

var = HIDmacros.GetXplVariable("sim/cockpit/gyros/psi_vac_ind_degm")

' get NAV1 active frequency (integer)

var = HIDmacros.GetXplVariable("sim/cockpit/radios/nav1_freq_hz")

' array example

' array size

var = HIDmacros.GetXplArrayItem("sim/cockpit/engine/fuel_pump_on", -1)

' fuel pump no 1 position (0/1)

var = HIDmacros.GetXplArrayItem("sim/cockpit/engine/fuel_pump_on", 0)

' fuel pump no 2 position (0/1)

var = HIDmacros.GetXplArrayItem("sim/cockpit/engine/fuel_pump_on", 1)

' set NAV1 frequency to 111.30

HIDmacros.SetXplVariable "sim/cockpit/radios/nav1_freq_hz", 11130

' set autopilot's heading bug to 190

HIDmacros.SetXplVariable "sim/cockpit2/autopilot/heading_dial_deg_mag_pilot", 190

' turn on both fuel pumps

HIDmacros.SetXplArrayItem "sim/cockpit/engine/fuel_pump_on", 0, 1

HIDmacros.SetXplArrayItem "sim/cockpit/engine/fuel_pump_on", 1, 1

'toggle landing gear

HIDMacros.XPLCommand "sim/flight_controls/landing_gear_toggle"

'engage starters

HIDMacros.XPLCommandBegin "sim/engines/engage_starters"

'release starters

HIDMacros.XPLCommandEnd "sim/engines/engage_starters"

Complex example
With my keyboard I used numeric pad to quickly set autopilot heading or VOR1 course bug to specific
value.

www.hidmacros.eu/scripting.php 9/11
08/06/2021 HID macros

Buttons HDG and CRS at the top switch between heading and course bug, button Curr HDG sets value to
current heading.

Source code below was copied from routines and macros for each key

.
' Routines:

Dim Mode

Mode = "HDG"

HIDMacros.RegisterFSXVariable "PLANE HEADING DEGREES MAGNETIC", "degrees"

HIDMacros.RegisterFSXVariable "AUTOPILOT HEADING LOCK DIR", "degrees"

HIDMacros.RegisterFSXVariable "NAV OBS:1", "degrees"

Sub SetHdgCrs(value)

if Mode = "HDG" then

HIDMacros.FSXEvent "HEADING_BUG_SET", value

end if

if Mode = "CRS" then

HIDMacros.FSXEvent "VOR1_SET", value

end if

end sub

function CurHdgCrsValue()

CurHdgCrsValue = 0

if Mode = "HDG" then

CurHdgCrsValue = HIDMacros.GetFSXVariable("AUTOPILOT HEADING LOCK DIR")

end if

if Mode = "CRS" then

CurHdgCrsValue = HIDMacros.GetFSXVariable("NAV OBS:1")

end if

end function

' Macro heading 0

call SetHdgCrs(0)

' Macro heading 45

call SetHdgCrs(45)

' etc

' Macro set as current heading

Dim CurHdg

CurHdg = HIDMacros.GetFSXVariable("PLANE HEADING DEGREES MAGNETIC")

call SetHdgCrs(Round(CurHdg))

' Macro +10

call SetHdgCrs(Round(CurHdgCrsValue()+10))

' Macro +1 - the easiest way

if Mode = "HDG" then

HIDMacros.FSXEvent "HEADING_BUG_INC", 0

end if

if Mode = "CRS" then

HIDMacros.FSXEvent "VOR1_OBI_INC", 0

end if

My whole FSX keyboard is used mainly for Twin Otter offline flying. It's wireless and has those stickers:

www.hidmacros.eu/scripting.php 10/11
08/06/2021 HID macros

XML configuration file for FSX can be downloaded here.

Last update: 15-Jul-2017

© 2008-2021 Petr Medek - contact author

www.hidmacros.eu/scripting.php 11/11

You might also like