The binary keyword was used in the DOS version to do things that
were hard or impossible to do in the macro language. This,
coupled with the Intr() (also deprecated) allowed the editor to
access DOS system services through interrupts. Typically, you
would write a small assembly routine, compile it to a .com file,
make sure you get the entry points right, and declare it as a
binary in TSE. This concept is very similar to what you could do
with old DOS basic and Turbo Pascal 2 and 3.
In the Windows version, the replacement for both of these is the
DLL statement.
With this, you can access virtually any Windows API function.
Additionally, you can write callable routines (in any language
that can build DLL's, which includes C, C++, Pascal, Delphi, and
so on) to do basically what you want. For instance, the spelling
checker decompressor and checker is written in C, and compiled to
a DLL. The spellchk macro links to this DLL. The entire thing
could have been written in the macro language (a spelling checker
for the Tagabawa language was written in the macro language), but
compiled C is 10 to 100 times faster than compiled SAL.
DLL's are also not nearly as limited as binary's are the in DOS
version. In the DOS version, a binary had to be less than 16k in
size. User-written DLL's can be as large as needed.
So those are the good points about replacing binary and intr()
with DLL.
The bad point is that it is not an easy conversion, to go from
binary's to DLL's. In some cases there are Windows API functions
that essentially accomplish what the binary was trying to do. In
those cases, the conversion is much easier.
Examples of TSE macros that used binary in the DOS version, and
have been converted to use DLL (or just SAL) in the Windows
version include:
cd.s
clock.s
fnexp.s
tabutil.s
where.s
whtspc.s
I've included the documentation on using DLL here:
Using DLLs
──────────
The "DLL" directive allows the user to extend the editor to include
additional procedures which cannot be written using the macro language.
Since this is a very advanced feature, great care must be exercised when
using DLLs.
Basically, DLLs are procedures written using another programming language,
but which can interface with the editor's calling convention. DLLs must be
written in a specific format to properly interface with the editor. DLLs can
be written in C, C++, Pascal, Delphi, or any other language that allows the
creation of DLLs.
The syntax to declare DLL procedures is:
DLL "dll_file"
type proc [PASCAL] Proc1(parm_list) [: import_name]
type proc [PASCAL] Proc2(parm_list) [: import_name]
...
type proc [PASCAL] ProcN(parm_list) [: import_name]
end
where:
∙ DLL specifies that the procedures which follow reside in the named DLL.
∙ dll_file is the name of the file containing the DLL procedures.
If dll_file is enclosed within <>, the editor allows the operating
system to search the default DLL search path. Thus, a dll_file of
"<kernel32.dll>" would be found in the Windows system directory.
If dll_file is simply enclosed in quotes, the editor searches for the
DLL using the same search method employed when searching for macros.
∙ type is an integer or nothing. DLL string procedures are NOT currently
supported.
∙ proc specifies that a procedure follows.
∙ Proc1...ProcN are descriptive name(s) of each procedure.
The procedure name is used within the editor macro to identify (that
is, to call) the specified function. This name is case sensitive and
must match the DLL export name exactly unless the import_name directive
is used.
∙ PASCAL is an optional modifier that specifies that this DLL is compiled
using the PASCAL calling convention. For cdecl and syscall calling
conventions, omit this modifier. For more information on calling
conventions, see your vendors compiler reference manual.
∙ parm_list is a comma-separated list of parameters. (See
"DLL Parameters and Return Values" below, and see
"Arguments - Passing and Retrieving Parameters" earlier in this
chapter.)
∙ import_name is the optional name of the DLL entry point for this
procedure, if different from the procedure name.
In many cases the procedure name is not exactly the same as the DLL
name. In this case the import_name may be used to specify the name
within the DLL.
For example, Windows includes a function called MessageBox, but the
actual DLL export name is either MessageBoxA or MessageBoxW. You could
declare this as:
integer proc MessageBoxA(...)
and always call MessageBoxA(). Or you could declare it as:
integer proc MessageBox(...) : "MessageBoxA"
and then just call MessageBox() to invoke it.
This parameter is also useful for PASCAL-style functions whose internal
DLL name is often upper-cased. For example:
integer proc Operate(...) : "OPERATE"
∙ end signifies the end of the DLL procedures in the named DLL.
DLL Parameters and Return Values
To interface with the internal types, integer and string, it is necessary to
understand their formats.
Integers are stored using 32 bits, or 4 bytes.
In the C programming language, the macro language declaration "integer n" is
simply expressed as:
int n
or
long n
The format of a string is a structure as follows:
bytes 1-2: length of string (0 to 255)
byte 3..n: actual string data
In the C programming language, string s may be expressed as a structure
similar to:
struct {
unsigned short len;
char data[maximum string length];
} s;
The len field indicates the length of data.
Parameters are passed as follows:
integer n 32-bit integer n (4 bytes) - by value
var integer n 32-bit pointer to integer n (4 bytes) - by address
string s 32-bit pointer to string structure discussed above
var string s 32-bit pointer to string structure discussed above,
and a 32-bit integer specifying string's maximum
length
To improve interfacing with DLLs, the macro language allows an additional
optional modifier to be used in a DLL parameter list, as follows:
[VAR] INTEGER integer_name [: modifier]
[VAR] STRING string_name [: modifier]
To modify the parameters, the following keywords are available (some do not
make sense in all contexts):
byte passes signed 8-bit char as 32-bit integer
word passes signed 16-bit word as 32-bit integer
long passes signed 32-bit word as 32-bit integer
strval passes 32-bit pointer to string data followed by 32-bit
integer length
strptr passes 32-bit pointer to string data (no length byte)
strptrref passes 32-bit pointer to string data followed by 32-bit
integer specifying the string's maximum length
strref passes 32-bit pointer to SAL-style string followed by
32-bit specifying the string's maximum length
cstrval creates a local copy of an ASCIIZ string into which the
editor copies and null-terminates the string before passing a
32-bit pointer to the copy of the string. Use this modifier
for ASCIIZ string parms to ensure a null terminator is placed
on the end of the string.
When a DLL procedure returns nothing or returns an integer, the parameters
are first passed as described above. Then, the return address is pushed on
the stack and control is passed to the DLL procedure at the specified
location within the DLL.
Any DLL procedure that returns an integer must place the result in the EAX
register. In most programming languages, this is performed with a simple
return statement.
Only 32-bit DLLs are supported.
Example:
dll "<user32.dll>"
integer proc MessageBox(
integer hwndOwner, //handle of owner window
string lpszText : cstrval, //address of text in message box
string lpszTitle: cstrval, //address of title of message box
integer fuStyle //style of message box
) : "MessageBoxA"
end
#define NULL 0
// some sample styles
#define MB_OK 0x00000000
#define MB_OKCANCEL 0x00000001
#define MB_ABORTRETRYIGNORE 0x00000002
#define MB_YESNOCANCEL 0x00000003
#define MB_YESNO 0x00000004
#define MB_RETRYCANCEL 0x00000005
#define MB_ICONHAND 0x00000010
#define MB_ICONQUESTION 0x00000020
#define MB_ICONEXCLAMATION 0x00000030
#define MB_ICONASTERISK 0x00000040
proc PopMsg(string title, string text)
MessageBox(GetWinHandle(), text, title, MB_OK)
end
<F12> PopMsg("Title goes here",
"This is the text" + chr(10) + "of the message")
For an additional example of a DLL procedure, see the TabUtil macro
(TABUTIL.S), and the associated DLL source file (ENTAB.C), in the MAC\ editor
subdirectory.
> --
> TSEPro Mailing List
> List Maintenance:
www.semware.com/html/list.htm
>
>