MortScript Manual
MortScript Manual
2
(c) Mirko Schenk
[email protected]
http://www.sto-helit.de
Contents
1 What is MortScript? / License......................................................................................................................5
2 Functional range...........................................................................................................................................5
3 Installation....................................................................................................................................................6
3.1 Different MortScript variations................................................................................................................................6
3.2 PC Setup...................................................................................................................................................................6
3.3 CAB file...................................................................................................................................................................6
3.4 Binaries....................................................................................................................................................................6
4 Usage............................................................................................................................................................7
4.1 Create and execute scripts........................................................................................................................................7
4.2 Parameters for MortScript.exe.................................................................................................................................7
4.3 Multiple instances and aborting scripts....................................................................................................................7
5 Additional tools............................................................................................................................................8
5.1 Execute scripts when a storage card is inserted or removed....................................................................................8
5.2 “Dummy exe” for scripts.........................................................................................................................................8
5.3 Supporting scripts for CAB installations (setup.dll)................................................................................................8
6 Important general informations.....................................................................................................................9
6.1 Glossary...................................................................................................................................................................9
6.2 Syntax style in this manual......................................................................................................................................9
6.3 Spaces, tabulators, and line breaks........................................................................................................................10
6.4 Case sensitivity......................................................................................................................................................10
6.5 Directories and files...............................................................................................................................................10
6.6 Comments..............................................................................................................................................................10
7 Supported parameters and assignments.......................................................................................................11
7.1 Expressions............................................................................................................................................................11
7.2 Data types...............................................................................................................................................................12
7.3 Fixed strings...........................................................................................................................................................12
7.4 Fixed numbers........................................................................................................................................................12
7.5 Variables................................................................................................................................................................13
Predefined variables..............................................................................................................................................................................................13
Variable scope......................................................................................................................................................................................................14
Arrays (Lists)........................................................................................................................................................................................................15
References ([variable name])................................................................................................................................................................................15
7.6 Operators................................................................................................................................................................15
List of all possible operators.................................................................................................................................................................................16
Logical and binary operators................................................................................................................................................................................16
Comparisons.........................................................................................................................................................................................................16
Concatenation of strings and paths.......................................................................................................................................................................17
8 Control structures.......................................................................................................................................18
8.1 Conditions..............................................................................................................................................................18
8.2 Simple branchings (If)...........................................................................................................................................18
8.3 Branching by values (Switch)................................................................................................................................19
8.4 Branching with selection dialog (Choice, ChoiceDefault)....................................................................................19
8.5 Conditional loop (While).......................................................................................................................................20
8.6 Iteration over multiple values (ForEach)...............................................................................................................20
Looping over data values (list of expressions, array contents, splitted strings, characters of a string)................................................................21
Looping over INI file values (sections, values of a section)................................................................................................................................21
Looping over registry entries (subkeys, values of a key).....................................................................................................................................22
Looping over files and directories........................................................................................................................................................................22
8.7 Fixed number of repeatings (Repeat).....................................................................................................................22
8.8 Simple iteration (For).............................................................................................................................................22
8.9 Sub routines (Sub, Call/CallFunction)...................................................................................................................23
2 Functional range
MortScript supports among others.:
3.2 PC Setup
Just execute the MortScript-4.1-system.exe (e.g. MortScript-4.1-PPC.exe) from the “exe” directory
in the archive on your desktop PC and follow the directives...
Currently, there's no setup for the PC variation, please see “Binaries” for that...
3.4 Binaries
Copy the contained files from the archive's subdirectory of “bin” that's named after the desired
device type (e.g. “bin/PPC”) to any place on the device (e.g. to “\Program files\MortScript”). Then
run MortScript.exe there, so the required registry entries will be created (for the assignments to the
script extensions .mscr and .mortrun).
To activate the setup.dll, it must be set as setup DLL of the CAB file. If you're using the CAB
wizard from Microsoft, this is done with CESetupDLL = "setup.dll" in the .inf file, other
tools should offer a menu entry or option for it.
MortScript.exe and – if you use ZIP archives – mortzip.dll must be installed to the default
installation directory (%InstallDir%) by the CAB installation. Same goes for install.mscr (executed
after installation) and uninstall.mscr (executed before deinstallation), whereby those two can be
omitted. But of course that only makes sense for one of them, cause otherwise the setup.dll wouldn't
do anything...
6.1 Glossary
Constant: A fixed value, i.e. numbers like “100” or strings like "Test"
Variable: A string that identifies an assigned value.
E.g. “x = 5” (“5” is assigned to variable “x”) or “Message( x )” (The value “5”, which
is assigned to variable “x”, will be displayed).
Expression: A combination of variables, constants, functions (see below) and operators, which
results in a single value (e.g. “5*x” or ”"Script type: " & ScriptType()”)
Assignment: Setting a value to a variable, usually done with “variable name = expression“
Parameter: Expression results which are passed to commands or functions
Command: An instruction without a return value, e.g. MouseClick or Message
Function: An instruction which returns a value, e.g. SubStr. It's used in expressions, so it can
only be used in assignments or parameters.
Control structure: Instructions, which modify the course of the script, like If, Choice, ...
If the characters are bold, they must be entered that way, e.g. parentheses ((...)).
When using one of the (few) commands, which don't require any parameters, the parentheses after it
are optional, i.e. it's up to your liking whether you write e.g. „RedrawToday“ or „RedrawToday()”.
But this is NOT that way for function calls! (That's because in expressions, the parentheses define
that the name in front of them defines a function call, otherwise it would be a variable name.)
6.6 Comments
Comments are possible by writing the character “#” at the beginning of the line. Spaces in front of
the ”#” are allowed.
In INI files, comments are possible with a “;” at the beginning of the line (as usual with INI files...).
7.1 Expressions
All parameters for functions and commands, conditions for control structures, and values assigned
with ”=” are expressions. (Exception: Old syntax, see 10 Old syntax and commands)
That sounds more complicated than it is. A few examples will clarify that:
Message( "Hallo!" )
The command “Message” is invoked with the fixed string “Hallo!” as parameter
Sleep( 500 )
The command “Sleep” is invoked with the fixed number “500” as parameter
If ( BatteryPercentage() > 20 )
# instructions
EndIf
An expression as condition
More informations about how constants and variables must be written, and which operators are
available, follows in the next few chapters.
The available functions are documented in 9 Commands and functions.
In Windows, a new line in text files usually is the combination of carriage return and line feed
(^CR^^LF^ = ^NL^). But sometimes there are also files in Unix style, which use only ^LF^.
Example:
Local()
x = "Test"
Call( "Sub1" )
Call( "Sub2" )
Message( x ) will show „Test“, because the local variable can't be changed in subs
Message( y ) will show nothing, because there's no local variable y (only global, see below)
Sub Sub1
x = 5 will set the global variable
Local( x )
y = "Hi!" global variable! (only x is local)
Message( x ) will show nothing (the local variable's not initialized!)
EndSub
Sub Sub2
Global( x )
Message( x ) will show the global value „5“
Message( y ) will show nothing, because there's no local variable y
EndSub
Examples:
array[ "1" & 1 ] = "eleven"
Message( array[ (2-1) & "1" ] )
list[1] = "a"
list[2] = "b"
list[5] = "f"
list["a"] = "A"
idx = Choice( "Selection", "Choose something", 0, 0, list )
Only “a” and “b” will be shown in the choice dialog.
7.6 Operators
The difference between AND and && resp. OR and || is that for && and || every value which isn't
0 is handled like 1 (because 2 is as “true” as 1). If you use those operators only to combine the
results of comparisons or check functions, there'll be no difference, because they'll only return 1
(true) and 0 (false) anyway.
The binary operators AND and OR additionally are useful for are bitwise checks, e.g. ”(x AND 4)
= 4” will check whether the 3rd bit (4 = binary 100), is set in the value of variable “x”.
The logical operators && and || are primarily thought for “C hackers”, which are used that 1 AND
2 is not 0 (binary 01 AND 10 would result in 0) but 1 = “true”.
7.6.3 Comparisons
Numerical and alphanumerical comparisons have the same priority, they've been split in the
operator list only for better overview.
Since MortScript doesn't support typing, the operator has to decide whether the values are compared
as numbers or as strings. This means, "123" < "20" is “false” (because 20 is smaller than 123),
but 123 lt 20 is “true” (because the character “1” is smaller than “2”, just like “a” is smaller
than “b”).
If you can't memorize the alphanumerical operators: they're just the abbreviations of „greater than“,
„greater/equal“, „less than“, ”(not) equals“, etc.
Example:
"\My documents\" \ "\file.txt"
"\My documents" \ "file.txt"
"\My documents\" \ "file.txt"
will all result in "\My documents\file.txt".
Compared to this:
"\My documents\" & "\file.txt"
"\My documents\\file.txt"
"\My documents" & "file.txt"
"\My documentsfile.txt"
"\My documents\" & "file.txt"
"\My documents\file.txt" – the only valid file name!
8.1 Conditions
As condition, any expression in parentheses can be used. The condition is fulfilled, if its result (if
necessary, after converting to a number) is not 0 (zero, also predefined as variables FALSE and
NO).
Possible functions are listed in the fitting category of “9 Commands and functions”. Read also the
chapter 7, esp. 7.2 Data types for further informations.
Examples:
If ( wndExists( "Word" ) )
EndIf
While ( x <> 5 )
EndWhile
Executes the lines between If and Else or EndIf, if the condition is fulfilled, or the lines between
Else and EndIf (if Else exists), if it's not.
If ElseIf is used, only the lines between the first true condition (including the initial If) and the
upcoming ElseIf, Else resp. EndIf are executed. Only if no condition is fulfilled, the Else block is
executed (if it exists).
If, Else, ElseIf, and EndIf each must be in a separate line.
Depending on the result of the expression, the blocks which have listed the value in the “Case” line
are executed.
The values can appear in multiple case blocks (e.g. „Case( 1, 2 )” and „Case( 2, 3 )”). The “fitting”
Blocks will then be executed in the order of appearance.
“Slipping through” or “break” like in C is not possible, but similar things can be done much more
clearly arranged by using a value in multiple “Case”s.
You can use different value types for each value, the switch expression's result will be converted to
the value's type for comparison.
However, floating point values are a bit difficult for two reasons: 1st, there could be rounding
troubles. Two seemingly identical values might differ somewhere after e.g. 15 decimals. 2nd, if you
enter something like “Case( 2 )”, it will be valid for 1.5 and 2.4, too, because 2 is an integer and
thus the result is converted and rounded. You'd need to use “Case( 2. )” for float comparisons.
Shows a selection with the given values. At "Case", you have to use the number of the entry
(starting with 1). Pressing “Cancel” or no selection will return 0.
Apart from that, it works similar to “Switch”.
In theory, you could also use Switch( Choice( ... ) ) (Choice as function, see 9.20.6
Selection from a list (Choice)), but Choice as control structure looks better.
ChoiceDefault is a variation which enables to set a default selection and a timeout after which the
selected entry is used. If the user selects another entry, the countdown will be restarted.
The default value must be given as index (i.e. “2” for the 2nd entry).
0 is allowed for no default (i.e. "Cancel" if the user doesn't select an entry).
The timeout is given in seconds. With 0, no timeout will be used.
See also 9.20.9 Set entry size and font for choices (SetChoiceEntryFormat)
Executes the lines between While and EndWhile as long as the condition is fulfulled.
While and EndWhile must be in separate lines.
This is quite a mighty tool. The given variable(s) is/are set to the values defined by the type and
parameters in each iteration. This varies from simple value lists (type “values”) to keys and values
of sections in INI files (“iniKeys”).
Please note: If an array element is used as iterator variable, its index will only be parsed when the
loop is entered. This means if “i” is 1 when the ForEach loop is entered, “array[i]” will assign
“array[1]” in every iteration, no matter whether “i” is assigned another value in the loop block!
Same goes for the parameters: They're evaluated when the loop is entered.
If not told otherwise, you can use expressions for all parameters, just like with almost every other
commands.
8.6.1 Looping over data values (list of expressions, array contents, splitted
strings, characters of a string)
Assigns the element values of the array to the variable. Only elements from 1 to the first number
that isn't assigned as index are regarded. Lower values, alphanumerical indexes, and values after a
gap are ignored.
This loops over all elements in the array, setting the index to the first variable and the value to the
second.
Similar to the Split function (see 9.5.3 Spit a string to multiple variables/array elements (Split)), but
the single parts are assigned to the variable one after the other.
Assigns the variable each character of the string one after the other. Since MortScript automatically
converts types, this also works for numbers – it'll assign e.g. “4” and “2” (for 42).
Returns the single sections ("[Section]", without brackets) of the given INI file.
Returns all subkeys of the given key. See 9.19.1 Reading registry entries (RegRead) for
parameters.
In the first iteration, variable is set to start, then it's increased (or decreased, if step is negative) by
step in every further iteration, until end is exceeded (variable's value bigger than end if step is
positive, smaller if step is negative).
If step is omitted, it's 1 if end is bigger than start or -1 if end is smaller than start.
This works with both integers and float values. For float values, a precision of 6 digits is used for
the end value comparison (see 9.4.8 Compare float values (CompareFloat), too).
Please note that any expressions (for start, end, or step) are only evaluated at the first iteration. For
example, if you use a variable for end or step (“For i = 1 to end step x”), and modify this variable
during the iteration, the given variable (“i”) will still be increased and checked against the values
the variables had before “For”.
With “Call”, the script will continue at the line following the “Sub” with the same parameter.
When the end of the subroutine (EndSub) is reached, it returns to the line after “Call”.
Unlike most other commands, for “Sub” the subroutine name must be given without parentheses
and expressions are not allowed.
For Call/CallFunction, please be aware you have to use quotes around the subroutine name, since
it's an expression like every other parameter. You might even use something like
“Call( variableContainingMySubroutine )” as some kind of “On ... gosub ...” (for those who
remember that BASIC command), but it's not good programming style, and might cause troubles if
you forget a possible subroutine.
For Call, the old syntax style (“Call SubFunction”) might be handy, too, but it's only recommended
if you don't use parameters.
If you pass parameters, the subroutine will have two local variables (see 7.5.2 Variable scope)
defined: argc contains the number of passed parameters, argv is an array with all passed parameters.
So if you pass two parameters, argc is 2, argv[1] the first parameter, and argv[2] the second.
If you use CallFunction, a value set with “Return( value )” in the subroutine is set to the given
variable. Return() doesn't leave the subroutine like in many other languages, it only sets the return
value! If Return() is not invoked, the variable will be empty (see 9.2.4 Check if variable is defined
(IsEmpty)).
The subroutines must follow the main program, MortScript exits on the first “Sub” it encounters.
With Include, all Sub blocks of the given file will be included as if they were defined in the current
script.
The file embedded with Include may contain other Include commands itself, but shouldn't contain
any other commands outside of the Sub blocks. (They'd be simply ignored)
Include commands should be at the beginning of the script. They're interpreted before the script is
executed, because otherwise Call commands might not find the required routine.
Please regard that with many Includes there's an increased risk you use the same Sub name twice. In
this case, MortScript will exit with an error message before executing the script.
To execute other applications or „independent“ scripts, there are own commands. see 9.6 Execute
applications or open documents.
Decides which error messages will be shown. The error level has to be a string (e.g. "syntax"), i.e.
not “ErrorLevel( syntax )” - except „syntax“ would be a variable which contains "syntax"...
The default is „error“.
It also might change the program flow: If the errorlevel is "warn" or "error", the program will be
terminated if an error event (see list below) occurs. If the level's "off" to "syntax", the error will be
ignored, so you can check it e.g. with “If ( wndExists(...) )”.
The levels include all levels that are listed above, i.e. with “error” the messages of the levels
“syntax” and “critical” are shown, too.
Example:
x = Eval( "1+5*x" )
x = 26, if x was 5 before
Clear will remove the variable or array element. Contrary to setting the variable or array element to
an empty string, IsEmpty() will return TRUE (see below) and an array element won't be there in
ForEach, Choice, etc.
Returns TRUE if the variable (or array element) wasn't assigned so far or removed with Clear(),
FALSE if the variable's assigned – even if it's just an empty string.
With Local(), the given or all (if no variables are passed) variables will be local to the current block
(subroutine or main script function).
Global() works the other way around: The given variables are accessed globally, while everything
else is local to the current block.
See 7.5.2 Variable scope for more informations.
Example:
x = Length( "This is a test" )
x = 14
Examples:
x = SubStr( "abcdef", 2, 3 )
x = "bcd"
x = SubStr( "asdf", -3 )
x = "sdf"
Returns the character at the given position. If the string doesn't contain enough characters,
„nothing“ is returned (see 9.2.4 Check if variable is assigned (IsEmpty)).
Splits the string on each occurrence of the separator, and returns the part with the given index (i.e.,
2 for the 2nd part). You can use negative indexes, too. -1 is the last part, -2 the part before the last,
and so on.
If "trim?" is TRUE or omitted, any spaces surrounding the part will be removed.
See also 9.5.3 Spit a string to multiple variables/array elements (Split)
Examples:
x = Part( "a | b | c", "|", 2 )
x = "b" (2nd part, spaces trimmed)
Returns the position of the first character where the searched string is found.
If a start position is given, searching starts from that position.
If the searched string is not contained, it returns 0. This should be checked, to avoid invalid
functions like SubStr with a start position of 0.
Examples:
x = Find( "abcdefcd", "cd", 5 )
x=7
Returns the position of the last occurrence of “character” in the “string”. Unlike Find, only a single
character is allowed.
If the character is not contained, the function returns 0.
Example:
x = ReverseFind( "abcba", "b" )
x=4
Replaces all occurrences of “old” in the “source” string with the “new” string.
Example:
x = Replace( "My old string", "old", "new" )
x = "My new string"
Returns the given string converted to upper (ToUpper) resp. lower (ToLower) case.
If a variable is passed as parameter, its content will not be modified (unlike the old commands
MakeUpper/MakeLower).
Depending on your system and localization, “special characters” like “ä” or “è” will not be
converted!
Examples:
x = ToUpper( "Abcba" )
x = "ABCBA"
x = ToLower( "AbcBA" )
x = "abcba"
UcChar returns the charater for a given Unicode value, UcValue returns the value for a given
charater (single character string as parameter, otherwise only the first character is regarded!).
Examples:
x = UcValue( "A" )
x = 65
c = UcChar( x + 1 )
c = "B"
Returns the value as string with the given precision. The value will be rounded commercially if
necessary.
Examples:
x = Format( 123.456789, 2 )
x = "123.46"
x = Format( 12, 2 )
x = "12.00"
NumberToHex converts an integer value (floats are rounded) to a string with the hexadecimal
value. The string is formatted to use full bytes, i.e. an even number of characters (like "0100" for
256 or "0a" for 11).
HexToNumber works the other way: It converts a string with an hexadecimal value to its integer
value. It will work to the first invalid character, e.g. HexToNumber( "axe" ) will return 10, because
"a" is a valid hex digit. Is also allows uppercase ("ADE").
Please note these functions will only work reliable with numbers from 0 to 2,147,483,647 (7fffffff).
Numbers from 2,147,483,648 (80000000) to 4,294,967,295 (ffffffff) will be converted fine from
decimal to hexadecimal, but will return negative values when converted from hexadecimal to
decimal. Also, -1 to -2,147,483,647 will return 8 byte hex values from ffffffff (-1) to 80000001 (-
2,147,483,647). That's because of the way negative values are stored internally (the first bit is the
“negative” flag).
Values exceeding this range will cause errors or strange results.
Please note these functions use the radians as parameter! If you've got the degree (like 45°), you can
convert it with “degree * PI / 180”.
Log calculates the logarithm based on e (MortScript variable EULERT), Log10 based on 10.
Calculates the square root of the given value. The square root of 2 is also available in the variable
SQRT2.
Comparing float values is a bit tricky because there can be rounding errors. A zero might not be a
“real” zero, but something like 1*10-20.
With this little helper function, the values are rounded to the given precision and then compared.
It returns -1 if value1 < value2, 1 if value1 > value2, and 0 if both values are equal.
Returns the biggest (Max) resp. smallest (Min) value of the parameter list (at least 2 parameters).
The values are compared numerically, the return value will be the one of the corresponding
parameter. I.e., Max( 1, 2.5, "3.33" ) will return the string "3.33".
will return 3.
MortScript handles string indexes with numerical contents like numerical indexes (to be precise,
rather the other way round: numerical values are stored as strings), so "2" is regarded, while "x"
isn't.
Because 4 is missing, 5 will be ignored. It would be the same if array[4] was defined and cleared
with Clear() afterwards.
Contrary to MaxIndex, this returns the count of all array elements that were ever assigned,
including those “removed” with Clear() (which only removes the element's value, but not the
element itself).
For the array in the MaxIndex example, ElementCount would return 5.
Splits the string on each occurrence of the separator. If the separator consists of multiple characters,
they must occur that way in the string which is splitted.
If you use the command version with multiple variables, the parts are assigned to the to given
variables. If there are more variables than parts, the remaining variables will be empty, if there are
more parts than variables, they'll be ignored.
If only a single variable is given or the function is used, the assigned variable will be an array with
the single parts, i.e., variable[1] to variable[n]. Each assigned part will be a string value.
If "trim?" is TRUE (or omitted in the function), any spaces surrounding the parts will be removed.
Examples:
Split( "a | b | c", "|", 1, a,b,c,d )
a="a", b="b", c="c", d=""
Runs the application. The script continues while the application is loaded and executed.
Links (*.lnk), parameters, and documents are possible, too.
The complete path must be specified.
Examples:
Run( "\Windows\StartMenu\Messages.lnk" )
Run( "\Windows\PWord.exe", "\My documents\doc.psw" )
Sadly, this useful function isn't as easy to use since Windows Mobile 5. In this case, you'll either
have to try it, or look in the registry in
HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Extensions\NewMenu.
Example:
New( "Appointment" )
Runs the application at the given time. For this, the program is added to the so called “Notification
Queue”. The PPC will wake up from standby if necessary.
The “Unix timestamp” is the time in seconds since 01/01/1970. This variant is interesting in
combination with TimeStamp(), e.g. TimeStamp()+86400 for an execution in 24 hours (* 60
minutes * 60 seconds = 86400).
On many devices, MortScripts can't be executed directly. Instead, you have to invoke
MortScript.exe with the script as parameter, e.g.
RunAt( starttime, SystemPath( "ScriptExe" ) \ "MortScript.exe", \
"""" & SystemPath( "ScriptPath" ) \ "notify.mscr" & """" )
Another problem: On many PPCs with WM5, the device wakes up and runs the program, but the
display stays off, and the device goes back to standby shortly after the program was started. It often
helps to invoke ToggleDisplay(ON) at the start of the scheduled script, if not, only a system update
or registry hacks might help.
Not available for: PC
Executes a program every time the device is switched on. For this the program is added to the so
called “Notification Queue”.
You should think twice about using this command, since for example there can be nagging error
messages if the given program is deleted or moved.
Please regard the hints in RunAt about running scripts or WM5.
Not available for: PC
Removes the program from the “Notification Queue”, i.e., it will no more be executed automatically
at given times (RunAt) or events (like RunOnPowerOn).
If there are multiple entries (e.g. multiple “RunAt”s), all of them will be removed.
If a parameter is given, it will be checked and only entries with the corresponding parameter will be
removed. Otherwise, all entries with the program will be removed, no matter which parameter is
entered in the notification. To remove only entries without a parameter, use an empty string ("") as
paremter.
Not available for: PC
Minimizes (or, on Windows Mobil systems, rather hides) the window with the given title.
Closes the window with the given title. If it's the main window of the application, the application
usually is closed (exited), too. However, some rare programs ignore it.
Returns TRUE, if a window with the given title is active, otherwise FALSE.
The given text can appear anywhere in the window title, the comparison is case sensitive. I.e.,
WndActive("top") returns TRUE, if the Today screen is active (it's title is "Desktop"), but not if
"Top program“ is active.
Similar to WndActive(), but also returns TRUE if the window exists in background.
Waits (max. the given time) until the given window exists.
Waits (max. the given time) until the given window is active.
Receives the window text of the element that's located at the given position. In most dialogs you
can get labels, button labels, or contents of edit boxes that way.
It doesn't work as intended for application drawn elements (like in most games) or e.g. list boxes. In
this cases, it'll usually return nothing (empty string) or the application's title.
SendCommand allows you to send any command id you want (usually all buttons and menu
entries), but this'll require good connections to the programmer, because the command ids are
different for every program and might even be different after an update.
Same goes for SendMessage and PostMessage, which are a more generic approach. You need good
connections to the application programmer to use those, it could also cause big troubles (usually
program crashes) if unexpected data is sent. SendMessage causes the message to be handled
immediately, and thus also allows to get a return value. With PostMessage, the message is added to
the message queue, so your script continues immediately, while the message is handled some time
later. MortScript only supports numerical parameters.
Sends the string as keystrokes to the given or currently active (if no window title was given)
window.
Examples:
SendKeys( "My window", "Hi, how are you?" )
SendKeys( "Some text" )
Activates the given window and sends the given special character. If no window title is given, the
currently active window is used.
Ctrl?, Shift?, and Alt? are switches for the corresponding keys. If the parameter is TRUE, the key is
pressed with the special character.
Examples:
SendCR( "ERROR" )
SendDown
SendHome( "",0,1 ) (highlight to beginning of line)
Activates the given window (if a parameter is passed) and copies the screen contents to the
clipboard. (“Print screen” function of the system, might not work with every program).
The Right... and Middle... commands simulate mouse clicks with the right resp. middle mouse
button, and are only available in the PC variant.
Simulates pressing resp. releasing the mouse button. The parameters are as those of MouseClick.
These two commands should be used together. With those, you can simulate “Tap&Hold” (Sleep
between them) or “Drag&Drop” (MouseUp on another position).
The Right... and Middle... commands simulate mouse clicks with the right resp. middle mouse
button, and are only available in the PC variant.
TimeStamp() returns the value for the current system time, MakeTimeStamp(...) for the given
date/time combination. If you omit time parameters, “0” is assumed, so if you omit all three of
them, midnight is used.
Returns the time of the timestamp, or the current time if none is given, formatted corresponding to
the format string.
Examples:
x = FormatTime( "h:i:s a" )
x = FormatTime( "m/d/Y", TimeStamp() + 86400 )
Retrieves the current time into three variables for hour, minute, and seconds.
Like above, but three more variables for day (of month), month, and year (4 digits).
Note all variable values will be strings. This is to allow leading zeroes, like "02" for february, which
is handy to combine filenames.
Sets the system time to the given time resp. date. With SetDate, the time will not be modified.
Hint: Please don't use this command to bypass evaluation periods. Be honest and pay for the
programs you're using or try to find free alternatives.
Copies a file.
The target must contain a filename, too. (I.e., not only the path!)
If overwrite? is FALSE or omitted, already existing files won't be overwritten.
Example:
Copy( "\My documents\test.txt", "\Storage\text.txt" )
Creates a shortcut (link) to the target file. This can be an entry in the start menu, for example.
If overwrite? is FALSE or omitted, already existing files won't be overwritten.
Example:
CreateShortcut("\Windows\Start Menu\Test.lnk","\Storage\Test.exe")
ReadFile reads the entire contents of a text file into the variable. The file size is limited to length,
1 MB or the available memory (whichever is the least). If length is 0, the default maximum (1 MB)
is used.
ReadLine reads a single line of the given text file. The next time ReadLine is invoked, it returns the
next line, etc. If there are no more lines in the file, it returns an empty value (see 9.2.4 Check if
variable is assigned (IsEmpty)). Opposed to ReadFile, ReadLine only works with “real” files, not
with serial ports (see 9.13.5 Access serial ports (SetComInfo)) or Internet access.
Possible values for the codepage are either the codepage numbers (if you know them) like 1252
(Western Europe), 437 (American DOS), ... or any of those strings:
● "latin1" (Western Europe)
● "jis" (Japanese)
● "wansung" (Korean)
● "johab" (Korean)
● "chinesesimp" (Chinese simplified)
● "chinesetrad" (Chinese traditional)
● "hebrew"
● "arabic"
● "greek"
● "turkish"
● "baltic"
● "latin2" (mostly Eastern Europe)
● "cyrillic"
● "thai"
● "utf8" (special encoding only for non-ASCII characters)
● "unicode" (2 bytes for each character, to be more precise UTF-16 little endian)
● "utf8-prefix" (like "utf8", but file starts with the hex values EF BB BF, which is an indicator
for some editors/programs)
● "unicode-prefix" (similar to "utf8-prefix", but with FF FE prefix and unicode)
Default is the system's default codepage, which depends on your Windows localization. UTF8 or
Unicode encoded files are also recognized, if they start with the corresponding prefixes (see “-
prefix” encodings above).
You can parse the file e.g. with ForEach line in split ( contents, "^LF^", TRUE )
See also the ForEach possibilities for INI files and ReadINI/WriteINI!
Reads an entry from an INI file. The section name must be passed without the brackets.
Example:
x = IniRead( "\My documents\test.ini", "Settings", "Test" )
Writes an entry to an INI file. The section name must be passed without the brackets.
Be aware this causes MortScript to load, parse, and write the entire file. It might be better to do this
yourself (ReadFile, ForEach with split, WriteFile) if many values are modified.
Example:
IniWrite( "\My documents\test.ini", "Settings", "Test", "x" )
Hint: Depending on system, drivers, and device, not all parameters are always used correctly.
Especially the timeout seems to be handled differently, sometimes it's even ignored completely.
Returns the free disk space in the given directory. By default, it's in bytes, you can specify another
unit by passing BYTES, KB, MB, or GB as unit parameter (constants, i.e. without quotes). The
maximum return value is 2147483147, which is about 2GB for size in bytes, 2TB for KB, etc.
On Windows Mobile devices, the directory (e.g. “\Storage“ for the storage card), on PCs the drive
letter (“D:\...”) is regarded.
Returns the size of the disk of the given directory. By default, it's in bytes, you can specify another
unit by passing BYTES, KB, MB, or GB as unit parameter (constants, i.e. without quotes). The
maximum return value is 2147483147, which is about 2GB for size in bytes, 2TB for KB, etc.
On Windows Mobile devices, the directory (e.g. “\Storage“ for the storage card), on PCs the drive
letter (“D:\...”) is regarded.
I know, 2GB isn't much, but handling larger numbers would be quite complicated, because that
number is the highest value a 32 bit system can handle without workarounds... (Yes, 4GB would be
possible, too, but then negative numbers wouldn't be supported at all in MortScript...)
Sets (set?=TRUE) resp. removes (set?=FALSE) the given file attribute. All other attributes remain
unmodified.
Examples:
SetFileAttribute("\Test.txt", "hidden", TRUE)
hides the file
Sets the given file attributes. With TRUE (or any other numeric value except 0/FALSE) the
attribute is set, with FALSE it'll be removed. An empty string ("") will keep the attribute
unmodified.
Examples:
SetFileAttribs("\Test.txt", "", TRUE)
hides the file, read only (and other attributes) remains unmodified
SetFileAttribs("\Test.txt", FALSE)
removes read only attribute, all other attributes remain unmodified
Gets the version number in the resources, either as string ("a.b.c.d") or into single variables (integer
values).
This information isn't contained or accurate in all files. If contained, the version is always in four
levels, usually major, minor, patch, and build version.
When using the function FileVersion, the parts are concatenated with dots, (e.g. "3.1.2.0"), the
command GetVersion assigns each part to a separate variable.
Adds the given file to the archive. The source file (the file to compress) and the ZIP file must be
given with the complete path. Contrary to this, the file name in the archive is usually with a relative
path, or completely without a path.
The compression rate ranges from 1=no compression to 9=best, if omitted, it defaults to 8.
Example:
ZipFile( "\Storage\Test\manual.psw", "\Storage\mans.zip", \
"test\testman.psw" )
Adds the given files to the archive. The source files are given, like for XCopy or Move, with a fixed
path and wildcards in the file name (e.g. "\My documents\*.psw").
If subdirectories? is TRUE, the filename filter is also used for subdirectories, i.e., "\My documents\
*.psw" would include "\My documents\Word\x.psw", too.
In the archive, the given path of the source files is omitted, and – if one is passed – prefixed with
the path in archive. I.e., if no path in archive is given, "\My documents\Word\x.psw" will become
"Word\x.psw" in the archive, "\My documents\x.psw" will become "x.psw", etc. If the path in
archive was e.g. "docs", the file names in the archive would become "docs\Word\x.psw" resp.
"docs\x.psw".
Examples:
ZipFiles("\Storage\Test\*.psw", "\Storage\mans.zip", TRUE, "test")
Compresses all *.psw files from \Storage\Test and subdirectories to the directory “test” in the
archive \Storage\mans.zip
Example:
UnzipFile( "\Storage\mans.zip", "test\test.psw", \
"\Storage\test.psw" )
Unzips the file „test\test.psw“ of the archive ”\Storage\mans.zip“ to ”\Storage\test.psw“
Unzip all files contained in the archive to the given directory. Paths contained in the archive will be
used and, if necessary, created.
Unzips all files located in the given path in the given archive.
Subdirectories of that path are unzipped, too. The given path name is not created in the target
directory, but its subdirectories will. The target directory must exist.
Example:
UnzipPath( "\Storage\mans.zip", "test", "\Storage\test-unzip" )
Unzips all files contained in the directory “test” and its subdirectories of the archive
“\Storage\mans.zip” to “\Storage\test-unzip”. I.e., “test\sub\x.psw” would be extracted to
“\Storage\test-unzip\sub\x.psw”.
CloseConnection releases a connection that's been established with Connect. This only signals the
system, MortScript won't use this connection anymore. It's up to the system how it reacts to this, so
the connection might stay established.
Contrary to this, Disconnect terminates all connections, including ActiveSync. Sadly, since WM5
AKU3, this doesn't work anymore. Currently, there's no known way to hang up a connection from a
program.
Not available for: PC, PNA
Connected checks, whether there is an “RAS connection” (“Remote Access”). This is always the
case for ActiveSync connections, for other connections on most devices – but not all...
Returns TRUE if a connection exists, FALSE if not.
InternetConnected checks, whether a connection to the Internet exists. Sadly, most devices return
“true” for a pure connection check (i.e., the function returns TRUE) and checks the connection only
if a target server is accessed. Due to this, you can pass an URL, which will be used for a connection
test (e.g. "http://www.google.com").
Set the proxy for http access. Using Windows Mobile, it's not quite easy to use the proxy from the
system configuration...
Should be something like "proxy.foo.bar:8080".
Similar to Copy, but uses an URL ("http://..." or "ftp://...") as source and shows a progress window,
because this usually takes a bit longer...
Example:
Download( "http://www.sto-helit.de/test.txt", \
"\Storage\text.txt" )
Possible values:
ProgramsMenu..........“Programs” in the start menu
StartMenu..................The start menu, doesn't work on Smartphones
Startup.......................Startup folder (entries are run after soft reset resp. if Windows is started)
Documents.................”\My documents” or localization, doesn't work on devices with PPC2002
ProgramFiles.............”\Program files” or localization, doesn't work on devices with PPC2002
AppData.....................”\Application data” or localization
ScriptExe...................Path to MortScript.exe (without file name), doesn't work on Smartphones
ScriptPath..................Path to the current script (without file name)
ScriptName................Name of the current script (no path+extension)
ScriptExt....................Extension of the current script (".mscr" or ".mortrun").
Opens a simple dialog that allows to enter any text, which will be returned by the function.
If numeric? is TRUE, only digits can be entered (no ”-” or ”.”, too!).
If multiline? is TRUE, a multi line text box is displayed. On most devices, numeric? will be ignored
if this option is used.
If you've given a default, it will be shown in the edit box.
Note the return value will be a string even if numeric? is TRUE.
See also 9.20.10 Set font for big messages (SetMessageFont)
Similar to Message, but doesn't use the system's message box function, which resizes to the
contained text (except for Smartphones). Instead, a fixed sized internal dialog is used, which shows
the text in a scrollable text box.
See also 9.20.10 Set font for big messages (SetMessageFont)
See 9.10.2 Wait message with countdown / condition (SleepMessage) and 9.20.10 Set font for big
messages (SetMessageFont)
Shows a simple question. This uses a default dialog from the system, so the button labels are
localized by Windows.
Allowed types:
"YesNo"..................Shows “Yes” and “No” (default)
"YesNoCancel".......Shows “Yes”, “No”, and “Cancel”
"OkCancel".............Shows “OK” and “Cancel”
"RetryCancel".........Shows “Retry” and “Cancel”
The type must be a string, so you have to use quotes ("YesNo") or e.g. a variable assigned with the
wanted type string.
Return values:
“Yes”, “OK”, “Retry”: 1 (predefined variable “YES”)
“No”: 0 (predefined variable “NO”)
“Cancel”: 2 (predefined variable “CANCEL”)
Be aware, that “Cancel” would be a fulfilled condition in statements like If or While, so you either
have to use something like “If ( Question( ...., "OkCancel" ) = CANCEL )” or
“Switch( Question(....) )” to handle it correctly.
Works similar to 8.4 ChoiceDefault, but returns the selected entry instead of starting a control
structure.
I.e., Switch( Choice( ... ) ) and ChoiceDefault( ... ) do the same.
It's handy to use Choice as function, if the value is required later on or at different locations.
See also 9.20.9 Set entry size and font for choices (SetChoiceEntryFormat)
Shows a dialog to select an existing directory. If a default is given, the path is preselected if it
exists.
This modifies the height of each entry and – if given – the font of choice lists. That regards all
choice dialogs shown after the command is invoked, including both the function and the control
structure.
The entry size is in pixels. It will – like the font size – be doubled for mobile devices with VGA.
The font size is in points, the font name is e.g. “Courier”, “Tahoma”, etc. Keep in mind not all
devices include all fonts, “Tahoma” (for mobile devices) or “Arial” (for desktop) usually are a good
idea.
See also 8.4 Branching with selection dialog (Choice, ChoiceDefault) and 9.20.6 Selection from a
list (Choice)
This modifies the font for message dialogs created by MortScript, i.e. BigMessage, SleepMessage,
and Input. “Message” and “Question” use a system dialog which doesn't support own fonts.
The parameters are like the font parameters in SetChoiceEntryFormat above.
See also 9.20.3 Big message with scrollbar (BigMessage), 9.20.1 Free text input (Input) and 9.20.4
Message with countdown/condition (SleepMessage).
As already mentioned in 9.21.1 What is the status window?, the status window keeps in background
if the user activated another application and new messages are added. With this command, the
status window will become visible and active.
Returns TRUE, if process functions like Kill and ProcExists are supported on the device.
This function is thought for PNAs, but is also supported on other devices.
MortScript functions like Kill or ProcExists require a system library (toolhelp.dll), which is not
included on all “stripped down” Windows CE devices. Thus, if you try to use those functions on a
device without it, it will cause an error message. With this function, you're able to avoid it (e.g. by
using window functions as makeshift) or show your own error message.
If “full path?” is TRUE, the complete path is included, otherwise it's the executable without path.
With desktop Windows, it's not always possible to get the entire path.
Returns the program name of the window with the given title.
If “full path?” is TRUE, the complete path is included, otherwise it's the executable without path.
With desktop Windows, it's not always possible to get the entire path.
Terminates the application. The parameter must be either the name of the exe without path (e.g.
solitare.exe) or include the entire path. Like with ProcExists, you should prefer the version without
path. See 9.21.2 Checking existence of a process (ProcExists) for more details.
WARNING: This command kills the process regardless of any losses!
It could cause data loss, crashes, or error messages.
Wherever possible, you should use Close instead, which allows the application to end gracefully
(save/close files, etc.).
Ends the given script. KillScript waits up to 3 seconds for the current command of the script to be
finished, to avoid troubles with improperly terminated actions. If that doesn't work, the process is
terminated similar to Kill.
The script name can be either the script name without path (e.g. “myscript.mscr”) or with the full
path (e.g. “\My documents\myscript.mscr”), in the PC version, also the drive letter is required.
If the script name is given without path, it's possible that another script with the same name as the
one you wanted, but from another path, is running. So it might be a good idea to give the full path if
it's possible (e.g. with 9.18.4 Getting system paths (SystemPath)).
Keep in mind a script can't be run twice. If you want to start and stop a background task, it might be
a good idea to create an additional script that starts the task (Run command) if it isn't running (use
ScriptProcExists for that), and kill the script with KillScript if it is running.
Do NOT use RunWait or CallScript, because with this, the invoking script would remain active
until the background task is finished, and thus couldn't be invoked a second time to kill the
background script!
Example:
backScript = SystemPath( "ScriptPath" ) \ "background.mscr"
If ( ScriptProcExists( backScript ) )
If ( Question( "Stop background process?" ) = YES )
KillScript( "background.mscr" )
EndIf
Else
Run( backScript )
EndIf
Sets resp. retrieves the system volume. Possible values are 0 (off) to 255 (loudest).
Some devices, like the Loox720, round to certain steps between (usually 4 or 16 levels), most
devices really support all 256 levels.
Plays the given file. The script is paused until the sound is played.
Gets the color of the screen's pixel at the given position. At least on some devices, the title bar is
ignored, i.e. it receives the color of the underlying today background.
Converts a part of the screen to a text array, using a given color to separate between foreground and
background.
For example, if there's a black circle on the screen, and ScreenToChars is invoked with color 0
(=black), it would be converted to an array like this:
array[1] = "___####___"
array[2] = "_########_"
array[3] = "##########"
array[4] = "##########"
array[5] = "##########"
array[6] = "_########_"
array[7] = "___####___"
So it's “only” something like an extended ColorAt, not a text recognition. It allows you to check
more reliably than with single ColorAts to check whether a certain text or image is displayed.
However, the result might become unusable if ClearType („softening“ of font borders, a system
option of windows) is enabled.
If background color? is set to TRUE, every color but the given one is treated as foreground.
Otherwise, only the given color is treated as foreground.
By default, “#” is used for the foreground and “_” for the background. You can change this with the
two char parameters.
Converts the decimal values of red, green, and blue parts (0-255 each) into the the same format as
used by ColorAt(...), so it's useful for comparisons.
These functions are the counterpart to RGB. They extract the red, green, resp. blue part (0-255
each) of a color code returned by ColorAt or RGB.
Returns TRUE, if the screen fulfills the type condition, FALSE if it doesn't.
Allowed values for type:
"landscape" (in landscape orientation?)
"portrait" (in portrait orientation?)
"square" (square screen?)
"vga" (VGA resolution – no matter if “default” or “real/true VGA”)
"qvga" (QVGA resolution)
Redraws the Today screen. Useful if you did any modifications in the registry...
Not available for: PC
Shows (ShowWaitCursor) or hides (HideWaitCursor) the hourglass (or rotating disc in Windows
Mobile). With desktop windows and on some PNAs, this might only work if a status window is
displayed.
Retrieves the type of the current mouse cursor of the given window. If no window name is given, it
uses the current foreground window.
Possible return values are "arrow" (default arrow), "wait" (hourglass), "cross" (target cross), "help"
(question mark), "uparrow", and "other" (e.g. application defined cursors).
This function does not necessarily return the cursor the user sees. For example, Windows Mobile
shows the hourglass (or rather rotating disk) while applications are started or applications without
window, desktop Windows might show an “application start” cursor (arrow with small hourglass)
or window resize arrows. There's no reliable way to retrieve those cursors. It's only possible to get
the cursor a window wants Windows to show.
Sets the current input type, e.g. SetInput( "Keyboard" ) or SetInput( "Transcriber" ).
If you want to publish a script with this command, please regard the input types might be localized
on other devices!
9.26 Memory
Returns the available main memory. By default, it's in kilobytes, you can specify another unit by
passing BYTES, KB, MB, or GB as parameter (constants, i.e. without quotes).
Devices with an older system than Windows Mobile 5 dynamically split the device's memory
between memory for programs (FreeMemory()) and a “RAM disk” for the main directory
(FreeDiskSpace("\")).
Returns the total size of the main memory. By default, it's in kilobytes, you can specify another unit
by passing BYTES, KB, MB, or GB as parameter (constants, i.e. without quotes).
Returns the current battery level in percent. If the device is externally powered, this value might be
incorrect on some devices.
About the same goes for the backup battery. Be aware this isn't supported on every device, because
some use condensers, some just don't support querying, and some don't have a backup battery (esp.
cheap devices with not exchangeable battery or devices with WM5 and newer, which keep their
data also without backup battery). It's device dependent what this function returns in those cases.
The PC variant always returns 100, even if it's a notebook powered by battery.
Turns off the device (to standby mode). After power on, the script is continued. Be aware that
accessing the storage cards usually doesn't work directly after power on. Thus, a Sleep and/or
While( not FileExists( ... ) ) might be useful to avoid errors...
Resets the idle timer of the system. This way, you can avoid (if called in a loop) or postpone the
automatic power off.
Sadly, the system uses another timer for turning off the background light, which can't be queried or
modified (at least there's no documentation about it). So there's no way to avoid that.
Also, there seem to be some rare devices where IdleTimerReset has no effect.
Returns the version of the system. If no or an invalid parameter is given, it returns a string in the
format major.minor.build, for example 5.1.2600 for XP with SP2 or 5.1.195 for WM5.
Returns, which MortScript variation is used to execute the script. Currently, there are these return
values:
"PPC"........PocketPC
"PC"..........PC (Desktop)
"SP"...........Smartphone
"PNA".......PocketNavigation (downsized Windows Mobile devices for navigation)
Gets the version number of MortScript, either as string ("a.b.c.d") or into single variables (integer
values).
When using the function MortScriptVersion, the parts are concatenated with dots, (e.g. "4.1.0.0"),
the command GetMortScriptVersion assigns each part to a separate variable.
Executes a soft reset. Please use it only in scripts used only by yourself or after a warning / query.
They're primarily listed in this manual to allow you to understand (and maybe convert) old scripts.
expression expression
{ expression }
Returns true if the two values are equal. Usually only makes sense, if at least one of the parameters
is a variable.
Checks whether the given file exists. If the parameter identifies a directory, the condition will be
false!
dirExists directory
Checks whether the given directory exists. If the parameter identifies a file, the condition will be
false!
procExists application
Checks whether the given application is running. The parameter must be the name of the exe
without path (e.g. solitare.exe).
Checks whether a window exists, which includes with the given string in it's title. E.g. “If
wndExists Word” will be true if a window named "PocketWord" exists.
Similar to “wndExists”, but it's only true if the given window is the active (foreground) window.
Will show a simple Yes/No dialog with the given text (Yes/No will be localized by Windows). The
condition's true if "Yes" was chosen.
screen landscape|portrait|vga|qvga
Is true if the given registry key exists. Parameters are like those of RegDelete.
MakeUpper( variable )
MakeLower( variable )
Similar to “ToLower” resp. “ToUpper”, modifies the contents of the given variable
GetColorAt( x, y, variable )
Like “ColorAt”, result is saved in given variable instead of being returned
GetWindowText( x, y, variable )
Like “WindowText”, result is saved in given variable instead of being returned
GetClipText( variable )
Like “ClipText”, result is saved in given variable instead of being returned
GetActiveProcess( variable )
Like “ActiveProcess”, result is saved in given variable instead of being returned
GetTime( variable )
Like “TimeStamp”, result is saved in given variable instead of being returned
GetActiveWindow( variable )
Like “ActiveWindow”, result is saved in given variable instead of being returned
GetMortScriptType( variable )
Like “MortScriptType”, result is saved in given variable instead of being returned
Just go to www.paypal.com, register or log on, and send the money to “[email protected]”.
You can get my bank account data by request, I don't like to publish it for everyone to see... And it's
only useful if you're living in the EU.