supermario/bin/MPW-3.2.3/Examples/HyperXExamples/Instructions
2019-06-29 22:17:03 +08:00

159 lines
7.5 KiB
Plaintext

Instructions - The HyperCard XCMD Examples
Copyright Apple Computer, Inc. 1988
All rights reserved.
About the Examples
MPW 3.0 introduces a consistent interface to callback HyperCard
routines from within XCMDs and XFCNs. The HyperCard XCMD Examples
are intended to introduce the use these routines. More importantly,
they are to serve as models for good software development of XCMDs
and XFCNs using MPW 3.0. We provide examples of both an XCMC and
an XFCN written in all three languages provided by Apple Computer,
Inc. as part of the Macintosh Programmer's Workshop: assembler, C
and Pascal.
The files provided with this set of examples is:
LittleDialog.a - sample XCMD to display a dialog box in assembler.
LittleDialog.c - sample XCMD to display a dialog box in C.
LittleDialog.p - sample XCMD to display a dialog box in Pascal.
LittleDialog.r - resources for assembler, C or Pascal LittleDialog.
Reduce.a - sample XFCN removing tabs and spaces in assembler.
Reduce.c - sample XFCN removing tabs and spaces in C.
Reduce.p - sample XFCN removing tabs and spaces in Pascal.
Make - script to build and install the above XCMDs.
'HyperXExample Stack' - minimal stack to test XCMDs and XFCNs.
They will rely upon the following interfaces and library:
{AIncludes}HyperXCmd.a
{CIncludes}HyperXCmd.h
{PInterfaces}HyperXCmd.p
{Libraries}HyperXLib.o
Note that these files are different from those provided with the original
HyperCard Toolkit released through APDA. The differances are:
HyperXCmd.p:
HyperXCmd.p declares the functions and procedures necessary to
access the code in HyperXLib.o. THESE ROUTINE DECLARATIONS ARE
DIFFERANT FROM THOSE WITH THE SAME NAME RELEASED THROUGH APDA:
In all cases, the XCmdPtr passed by HyperCard to the XCMD must
now be an additional parameter passed on to the library routines.
Additionally, several commands were changed to match the internal
workings of HyperCard itself: All Str31 values are really Str255.
Plus the former functions, BoolToStr, ExtToStr, LongToStr, NumToStr
& NumToHex, are now all procedures that take a VAR parameter. As a
bonus, we have added the call: SendHCMessage. THE HYPERCARD TOOLKIT
FILE XCmdGlue.inc IS NO LONGER USED!
HyperXCmd.h:
HyperXCmd.h also declares the functions necessary to access the
code in HyperXLib.o. Only in some cases are these routine declarations
differant from those with the same name released through APDA:
Parameters that were StringPtr or Str31 values are now specified
as either char * or Str255. THE HYPERCARD TOOLKIT FILE XCmdGlue.inc.c
ALSO IS NO LONGER USED!
Building the Examples
Provided with the HyperCard examples is an MPW script file, Make. In order
to build the examples, you must type "make" followed by the filename and then
press the enter key. The build script knows the build rules for LittleDialog.a,
LittleDialog.c, LittleDialog.p, Reduce.a, Reduce.c, and Reduce.p. It will then
produce command lines to assemble, compile, link, or rez the source code and
install the finished XCMD directly in the test stack. Select these lines and
press enter again to complete the build process.
Because this process uses a script which overrides the Make tool, it should
be located in the current directory with the XCMD source.
Writing Your Own XCMDs
Within a stack, each XCMD must have a resource id that differs from all other
XCMDs in that stack. The same is true for XFCNs. Choose a unique resource id
for your XCMD and add it and the name of your file to the Make script.
HyperCard actually accesses XCMDs by calling GetNamedResource. This requires
the name of the resource to be the same as the command. When the linker creates
the XCMD or XFCN resource, it uses the name of the code segment as its default
resource name. The Make script sets the name of the segment to be the same as
the file name by using the linker's -sg option. Thus the file name should be
the same as you want the command name to be.
The XCMD must be a single code segment. The main procedure has the form:
PROCEDURE EntryPoint(paramPtr: XCmdPtr);
This is a Pascal style procedure, so the XCMD itself is responsible for removing
the parameter from the stack. In C, we accomplish this by defining the routine as:
pascal void EntryPoint(XCmdPtr paramPtr);
HyperCard executes the XCMD by jumping to the beginning of it so the entry point
to the code must be the first thing. This is no problem for assembler and C,
where the main segment can simply be placed first. In Pascal, however, this may
not be sufficient. If the main procedure has nested functions, they will be
compiled before the main code. We get around this by having a dummy first
procedure with no nested routines, which then calls the real XCMD code:
PROCEDURE RealXCMD(paramPtr: XCmdPtr); FORWARD;
PROCEDURE EntryPoint(paramPtr: XCmdPtr);
BEGIN
RealXCMD(paramPtr);
END;
PROCEDURE RealXCMD(paramPtr: XCmdPtr);
BEGIN
...
END;
The initial FORWARD declaration of RealXCMD allows us to call the real XCMD
procedure from EntryPoint, but does not generate any code. The advantage of
allowing nested procedures is the ability to share variables between routines
without passing them as arguments. This is because NO GLOBAL VARIABLES are
allowed for an XCMD. Since the default storage for strings in MPW C is along
with the globals, it is necessary to use the -b option introduced with MPW
3.0 C in order to include the string data with the code resource.
Having mentioned placement of string data within the code resource, it is
necessary to emphasize that it is recommended that strings be placed as
resources. This allows easy addaptation of stacks with XCMCs to international
locations.
Unfortunately, at this time,HyperCard does not have a convention for resources
belonging to XCMDs or XFCNs. Currently using a resource mover to copy the
XCMD or XFCN to another stack can leave needed resources behind. There are
two things that can be done to help prevent such errors:
1. To indicate that a resource may belong to an XCMD, the example LittleDialog
uses resources having the same id number as the XCMD itself. This is not a
complete solution since it will not work for an XCMD which has more than one
resource of a given type. This is therefor only a suggestion until a better
means of bundling XCMDs with other resources is developed.
2. Within the code of the XCMD, always check for the availability of of the
resource before it is to be used. Then, if the resource is missing, report it
as an error that indicates what resource is missing.
The linker must be provided with the name of a main code segment so it can stip
unused code (mostly from the libraries we link with) from our XCMDs. Our Make
script includes the linker option -m ENTRYPOINT. The linker is case sensitive,
but Pascal symbols, C functions cast as "pascal", and the default case for
assembler symbols are not case sensitive, i.e. converted to all upper-case,
our main entry point for the linker should be in all upper-case also. XCMDs
do not require the main routine to be named EntryPoint. However, since that
was the name invented for the dummy pascal entry procedure, we have used it
as the default name in our script. It was due to this agreeing with the scipt
that all the examples here have main routines named EntryPoint.
In Conclusion
In keeping with HyperCard's efforts to make program development easier on
the Macintosh, we have tried to introduce a more uniform method of creating
XCMDs to expand the utility of HyperCard. Good luck and have fun!