
Converting to MacApp Release 13
This document describes changes required to compile and run older
MacApp applications using MacApp Release 13. Some changes are
specific to migrating from MacApp 3.3 to R12, and some from R12 to
R13, but a few regressed changes from MacApp 3.1 are also included
because they were previously not required changes for migrating to
MacApp 3.3, but now are required or highly recommended.
The following topics are covered:
Good Reasons for migrating
Here are a just a few of the many Good Reasons for migrating to
Release 13, which many developers have been asking to have in MacApp,
for you to remember as you are migrating:
- Iterator code is more compact
- Constructors are used more effectively which reduces the need
for I methods and lets the compiler optimize the constructors
- Exception handling code is much more compact and easier to
write and maintain, particularly when combined with the use of
CAutoPtr_AC
- Functions return function results instead of modifying
parameters which optimizes code generation, and simplifies your
code
- Multi-level undo/redo is a better user experience
- Classes and methods are named more precisely, so you remember
them more easily
- Member data is protected so you are less likely to trounce on
them or play tricks that trip you up later
- ACS classes let you work with more lightweight dependencies in
your own code; whether it's a shared library or an application,
you no longer need to depend on all of MacApp
- Just as MacApp helps work around limitations in the Mac OS,
ACS helps work around limitations in STL; for example, ACS
containers can delete while iterating
- Of course, there are the new features you can now use, such as
Networking, Threads, and Appearance, all of which require very
little effort to get started, usually a sprinkling of code, a
simple subclass, or a new view in Ad Lib.
- Not to mention scripting, drag manager, QuickTime (in one of
the samples), and other features delivered to you as early as
MacApp 3.3 which have been battle-tested and refined.
- MacApp's automatic use of TidyHeap in your debug builds will
help you watch for problems such as memory leaks and
double-deletes, and it will also help you stress-test your
application more robustly than ever before.
Example & Tools
We have provided an annotated
conversion example which
shows many of the considerations discussed in the following sections.
ConvertToR13
|
This script iterates over all .h, .cp, .cpp, and .cxx
source files in a specified path directory, applying the MPW
Canon tool with the "R13.dict" dictionary file to those
source code files. Running this script will make most class
name and terminology changes. All changes will be reported
in the MPW Shell, so you can examine this output for any
mistakes.
|
R13.dict
|
This is a canon dictionary which can be used with MPW or
ToolServer to translate old MacApp names into the new ACS
names.
|
Free2Delete
|
This script will scan your source code and convert the
old and no longer used Free methods into C++ destructors.
|
UpdateClassInfo
|
This script which will scan your source code and update
your class description and definition macros.
|
Canonize
|
This is a helper script for the ConvertToR13 script,
which calls Canon with the appropriate parameters.
|
RunCanon
|
This is a helper script for the ConvertToR13 script,
which calls Canonize with the appropriate parameters.
|
Note: these scripts and the canon dictionary are not likely to
look very good in your web browser. There are intended to be viewed
using MPW.
Getting Ready to Migrate
The application should be compilable and runnable under a
particular version of MacApp, at least version 3.1.5 or newer, before
following these release notes. If you are using MacApp Release 3.3 or
Release 12, you will encounter correspondingly fewer changes.
- If the application uses MacApp 3.0, you can migrate to MacApp
3.1 by following its Release Notes in close detail. The
application should not be migrated to R13 until it is running
correctly with MacApp 3.1.
- If the application uses MacApp 2.0.1 or MacApp2PPC, it should
be feasible for the application to migrate. However, it should be
translated to C++, upgraded to MacApp 3.1.5, and debugged to an
alpha quality level before migrating to R13. This step may take
more than a month, but the time invested is significantly lower
than attempting to implement all the new features in MacApp
yourself. If you can't justify spending a couple months to perform
this step and you are using MacApp 2.0.1 in Object Pascal,you can
still make your app PowerPC-native using MacApp2PPC (which ships
on CodeWarrior CDs), because it's really easy to do [plug].
- You may optionally choose to follow MacApp 3.3 Release Notes,
or jump right in to migrating to Release 13. Following the 3.3
release notes will save you the effort in interpreting a number of
compile-time errors with a couple dozen routines whose names have
changed, but if you have good deductive skills and also run the
Free2Delete and UpdateClassInfo scripts (mentioned below, in
Migrating to Release 13), you can get by without stopping at
version 3.3.
Migrating to Release 13
Assuming the application is compilable and runnable under MacApp
3.1.5, the following steps should be taken for migrating the
application:
- Use MakeProjectFromTemplate to create a new CodeWarrior
project. Remove the template files, add your existing source code,
and make other application-specific project settings as needed.
This will ensure the project settings, include paths, libraries,
etc. are correct for MacApp and ACS, and it is a lot easier than
applying all the requisite changes to your existing project.
- Run the Free2Delete MPW script (provided with MacApp
3.3, but also provided with Release 13) using MPW or ToolServer.
This converts Free() methods to destructors automatically for you.
- Run the UpdateClassInfo MPW script (provided with
MacApp 3.3, but also provided with Release 13). This cleans up
ClassInfo macros so they use current names and removes
DeclareClassDesc.
- Set the MPW current directory to the directory containing the
ConvertToR13 script. Run the ConvertToR13 script
(provided with Release 13) with a parameter specifying the
directory path containing source files to be converted. This
script iterates over all .h, .cp, .cpp, and .cxx source files
using the MPW Canon tool with the "R13.dict" dictionary file. This
handles most class name and terminology changes automatically,
including a few anachronisms.
- If you choose not to perform the ConvertToR13 step, you may be
able to get by if you add the following define to
AutoSwitches_AC.h
(located in CS:suites:core:headers:):
#define qBackwardCompatible 1
- There are a few things the qBackwardCompatible flag can't do
for you, such as replace all your Boolean, TRUE, and FALSE
references with bool, true, and false, and transmogrify methods
whose parameters have changed or that have become const.
- Change direct accesses to member data with
accessor/manipulator functions. Porting tip: setting the
qBackwardCompatibility flag also lets you continue to get away
with bad programming practices such as directly accessing member
data, so you can delay this cleanup step by temporarily setting
the qBackwardCompatibility flag to 1.
- Convert I methods to constructors. For each occurrence, use
the Constructors examples to convert your code manually.
- Search your code for "FailInfo". For each occurrence, use the
Exception Handling examples to convert your code manually.
- Review the list of methods that have become const or that have
changed parameters and update your source code.
- Review all command objects that implement filtering or that
rely on the Commit method. The new multi-level Undo/Redo will
break filtering, but you can disable multi-level undo by setting
the undo/redo level to 1.
Conversion notes
The notes in this section are not required reading since many of
them are covered by following the steps outlined above, but it
contains useful reference material for converting your code.
The following applications have been migrated to Release 13, and
were used to generate the conversion notes and examples.
- Ad Lib (view editor)
- Analytica (third party visual spreadsheet)
- Mouser (source code browser)
- DrawShapes (unsupported example)
- WEView (unsupported view/command classes)
- Gray Council (third party views)
Changes caught by the build environment
- Path references to the "Interfaces" or "CPlusIncludes" should
be removed from access paths since the MacApp header files now
live inside Includes folders of the Libraries folder.
- Bunches of libraries have been renamed or are new libraries
that are required for linking:
68K
MacOS.lib
ToolLibs.o
CW_memcpy_glue.lib
AEObjectSupportLib.o
MSL Runtime68K.Lib
MathLib68K Fa(4i_8d).Lib
MSL C++.68K Fa(4i_8d).Lib
MSL C.68K Fa(4i_8d).Lib
|
PPC
DragLib
InterfaceLib
MathLib
ObjectSupportLib
AppleScriptLib
PPCToolLibs.o
QuickDrawGXLib
QuickTimeLib
TidyHeapSharedLib
MSL RuntimePPC.Lib
MSL C.PPC.Lib
MSL C++.PPC.Lib
ThreadsLib
Multiprocessing API Library
TranslationLib
|
Changes caught by the compiler
- You must turn on native C++ exceptions, bool support, and
native RTTI support in the C++ compiler settings panel, or else
you will suffer from obscure compile-time errors. ACS
CoreSwitches_AC.h has checks for some options and tells you if
they're not turned on, so you are less likely to go ballistic if
you are including MacApp or ACS source files.
- Many MacApp files that moved to ACS logically have different
header file names. Here are some examples:
#ifndef __PASCALSTRING__
#include <PascalString.h>
#endif
#ifndef __ULIST__
#include <UList.h>
#endif
#ifndef __UDYNAMICARRAY__
#include <UDynamicArray.h>
#endif
becomes:
#ifndef __CPascalString_AC__
#include "CPascalString_AC.h"
#endif
#ifndef __CList_AC__
#include "CList_AC.h"
#endif
#ifndef __CDynamicArray_AC__
#include "CDynamicArray_AC.h"
#endif
- Some stuff is just plain gone, you just don't need it any
more. No more: TObject base class, FreeList, FreeListIfObject,
SetEltType, CDynamicArray_AC::Lock; more.
- Bunches and bunches of classes have been renamed from TBlah to
CBlah_AC or MBlah_AC, to indicate their transference into ACS
following the removal of TObject. You can guess how to rename most
of these, but you may want to consult the R13.dict file or
Compatibility.h
to find out what has been renamed to what.
- Member data is protected so you are less likely to trounce on
them or play tricks that trip you up later. In general you should
be using existing (or new) accessor functions or manipulator
functions. If your application's use of a class requires accessors
or manipulators that aren't defined and you can't work around the
problem, you may specify #define qBackwardCompatible 1 in your
AutoSwitches_AC.h file, to make data members public again. You
should also request the addition of specific accessor or
manipulator functions to the MacApp team for future MacApp
releases. Here are some commonly accessed data members that now
require accessors:
fSize GetSize
fViewPerPage GetViewPerPage
fDeviceRes GetDeviceRes
fPaperRect GetPaperRect
fInkRect GetInkRect
fMarginsRect GetMarginsRect
fInteriorRect GetInteriorRect
fWMgrWindow GetWindowRef // Note the terminology change
- Many functions return a CViewRect, CViewPoint or CStr255_AC
instead of passing the result through a parameter (an explanation
is found in the
Miscellaneous
notes). Turning on Hidden Virtual Functions warning will
detect this change, and calling Inherited will generate a compiler
error. Here are some of the
functions that have changed to return results (others are listed
under coordinate conversions,
where method names have changed). When qBackwardCompatible is
defined as 1 in AutoSwitches_AC.h, the old-style functions are
still provided for most (but not all) cases.
GetFrame
CalcMinFrame
DoCalcViewPerPage
DoGetPrintExtent
GetStandardStateFrame
GetText
GetTitle
ReadString
- TFileHandler is gone; use equivalent TFileBasedDocument
methods directly.
- Objects that are passed to WriteStreamObject() must be changed
to derive from MStreamable_AC as a mixin class if they get the
following compiler error:
Error : Cannot convert
'TMyClass *' to
'MStreamable_AC *'
- In many cases, you may remove MA_DEFINE_CLASS and
MA_DECLARE_CLASS macros for classes that aren't streamable, such
as commands.
- TDocument::Free() and TCommand::Free() were removed; your
Free() implementations should be moved to the destructor. This can
be automated using the Free2Delete MPW script (part of MacApp 3.3
update). You can still define Free methods, but they won't get
called unless you call them. If removing Free methods is a problem
for your code, consider overriding Close or related polymorphic
methods that already exist within MacApp which are called
automatically before deleting. For your own classes, you may
decide to implement your own protocol for closing or freeing
before deleting.
On the MPW command line, pass the name of the file containing
the class declaration(s) and the name of the file containing the
implementation(s); for .cp files that contain both, pass the file
name for both parameters. Examples:
Free2Delete MApp.cp MApp.cp
Free2Delete UApp.h UApp.cp
Free2Delete UDoc.h UDoc.cp
Free2Delete UDoc.cp UDoc.cp
- The iterator method More() was replaced with Current(), but
you may alternatively refer to "iter" alone which will return
whether iteration has completed.
- TStream::ReadStreamObject (and related) have swapped the
return value and parameter:
Boolean wasValid;
aMyClass = dynamic_cast_AC(TMyClass,
aStream->ReadStreamObject(wasValid));
- Min and Max are sensitive to mixing long and int and give an
error including when it is ambiguous; one workaround is to
explicitly coerce the offending parameter using static_cast, e.g.,
short aNumber = Min(0, anotherNumber);
becomes:
short aNumber = Min_AC(static_cast<short> (0), anotherNumber);
- The DescendsFrom method no longer exists; use MA_MEMBER
instead; example:
if (clipView->DescendsFrom(TMyView::GetClassDescStatic()))
becomes:
if (MA_MEMBER(clipView, TMyView))
- The TTracker constructor changes its TObject parameter to
MDependable_AC; client trackers may need to change their
TMyTracker methods to accept an MDependable_AC if they get a
compiler error inside their calls to TTracker.
- In some cases, you may have been relying on not having to
implement a constructor or an I method, calling the base class I
method instead. The simplest way to clean this up is to define a
constructor whose parameters are identical to the base class,
which passes those parameters through to the base class
constructor.
- gConfiguration.has<thing> booleans have been replaced
with Has<thing>_AC function calls. Functions help
encapsulate existence tests, and allow for only testing those
libraries or toolbox managers that your application has interest
in using.
- The HasFPU test has been removed since it would require MacApp
to test for this configuration option before static initialization
of any floating point values has occurred, and initialization
order of static data cannot be uniformly guaranteed by existing
linkers.
- Window globals have become methods because they change at
runtime:
gStandardWindowMoveBounds this->GetDynamicMoveBounds
gStandardWindowResizeBounds this->GetDynamicResizeLimits
gStandardWindowScreenRect this->GetDynamicMoveBounds
- Many functions have become const; here is a partial list:
GetBehindWindowPtr
GetDynamicResizeLimits
GetStandardSignature
IsModal
Clone
GetStandardStateFrame
IsInModalState
Compare
WriteTo
WriteFields
GetCurrentItem
CanSelectItem
CanSelectCell
GetItemText
- In cases where MStreamable_AC isn't the Inherited class
because it's mixed in and descends from more than one base class,
some inherited calls must be changed from Inherited:: to
MStreamable_AC::.
- Changed() and DoUpdate() changed parameters from TObject* to
MDependable_AC* and TObject* to void*:
virtual void DoUpdate(ChangeID theChange,
TObject* changedObject,
TObject* changedBy,
TDependencySpace* dependencySpace); // override
becomes:
virtual void DoUpdate(ChangeID_AC theChange,
MDependable_AC* changedObject,
void* changeData,
CDependencySpace_AC* dependencySpace); // override
- Coordinate conversions and
invalidation use overloaded functions and return values to allow
for smaller code generation and performance optimization:
QDToViewRect(rect, vrect);
QDToViewPt(pt, vpt);
ViewToQDRect(vrect, rect);
InvalidateVRect(vrect);
pt = ViewToQDPt(vpoint);
LocalToWindow(vpoint);
become:
CViewRect vrect(QDToView(rect));
CViewPoint vpt (QDToView(pt));
CRect_AC rect (ViewToQD(vrect));
Invalidate(vrect);
pt = ViewToQD(vpt);
vpoint = LocalToRootView(vpoint); // !!! return value added
- Global functions that operate on VRects are now replaced with
CViewRect methods and operators (many which have been available
since MacApp 3.0; the global functions were provided for Pascal
compatibility):
OffsetVRect(vr, dh, dv);
SetVRect(vr, left, top, right, bottom);
SectVRect(src1VRect, src2VRect);
become:
vr.Offset(dh, dv);
vr.Set(left, top, right, bottom);
destVRect = src1VRect & src2VRect;
- A number of globals are now scoped, and some are static, not
pointers:
gViewServer
gSelectionAdorner
become:
TViewServer::fgViewServer
TAdorner::fgSelectionAdorner
- When calling AddAdorner, this:
AddAdorner(gSelectionAdorner, kDrawView, false);
becomes:
AddAdorner(&TAdorner::fgSelectionAdorner, kDrawView, false);
- Use pre-defined constants where possible, e.g., kTextType_AC
instead of 'TEXT', kStyleType_AC instead of 'styl'. This aids
consistency and portability.
- MacApp no longer uses the
char* coercion
operator.
- Developer feedback to the suggestion of going single-segment
was predominantly positive.
- Here is a summary list of functions whose parameters have
changed, and how they changed (in some cases, explanations for why
changes were made are mentioned elsewhere in this document). Some
functions are listed elsewhere
(function return values and
coordinate conversions ).
DoSave
|
no parameter (use DoSave, DoSaveAs, etc.)
|
Clone
|
TObject* return value -> void. NB, don't declare
this if you also use MA_DECLARE_CLASS.
|
ReadStreamObject
|
swapped argument and return value
|
CanSelectItem
|
short to long; use GridCoordinate for abstraction
|
GetItemText
|
short to long; use GridCoordinate for abstraction
|
CanSelectCell
|
GridCell to const GridCell&
|
DrawCell
|
GridCell to const GridCell&
|
ComputeNewSelection
|
GridCell& to const GridCell&
|
TStdPrintHandler
|
constructor TStdPrintHandler no longer has a
squareDots
parameter
|
TView
|
TView constructor has no first two parameters for
superview & document, need to call AddSubView and
HandlePostCreate separately
|
TTEView
|
no more
isStyledText
parameter
|
TDialogTEView
|
same as TTEView
|
SetMenuItemText
|
if using Menus.h functions, add :: for scoping, or
remove first parameter
|
AddCharacter
|
-> const CStr2_AC&
|
DoMakeTypingCommand
|
-> const CStr2_AC&
|
CellsToPixels
|
first parameter RgnHandle -> const
TGridViewDesignator*
|
SetIconRsrcID
|
new parameter
|
SetSmallIconRsrcID
|
new parameter
|
FileHasBeenSaved
|
CStr255 -> TFile*
|
- A bunch of methods or functions have been renamed or removed:
SetupUndoMenu
|
SetupUndoRedoMenus
|
SetIconRsrcID
|
SetIconSuiteRsrcID
|
GetPosition
|
GetReadPosition or GetWritePosition, depending on
the context in which it's used.
|
SetPosition
|
SetReadPosition or SetWritePosition, depending on
the context in which it's used.
|
Commit
|
use the command's destructor
|
SetEltType
|
use templated lists and iterators
|
FreeList
|
call delete directly
|
Lock
|
no longer needed (an object is no longer a handle)
|
== NULL
|
.IsNULL() or ! Some auto-pointered member data
(e.g., TView::fAdorners) can't be directly compared
with NULL; use IsNULL() or the ! operator
|
o->GetClassID
|
MA_GET_CLASS_ID(o)
|
o->GetClassName
|
MA_GET_CLASS_NAME(o)
|
GetClassDescDynamic
|
Use MA_MEMBER, dynamic_cast, or dynamic_cast_AC
depending on context.
|
MA_DYNAMIC_CAST
|
dynamic_cast
|
ReadRGBColor
|
Add an include for "ImagingStreaming_AC.h", and use
the >> and << operators.
|
- Use TH_new where possible, in place of new, so that TidyHeap
can track your allocations and tell you where you have leaked
memory, whether you have performed a double-delete, and a whole
host of other things. You can use NewDropper (provided with
R13) to convert your code automatically.
Changes caught by Rez
- User can't implicitly use defaults for Rez settings,
particularly SystemSevenOrLater since R13 explicitly requires it
be turned on (and Rez headers turn it off by default), user must
specify CWMacAppRezPPC_d.r as the Rez prefix file (not set in a
3.3 project).
Changes caught by the linker
- Requires (weak) linking against QuickTimeLib in order to find
CustomGetFilePreview.
Changes noticed at Runtime
What seems to have been fixed that wasn't expected to be fixed
- Default command context now behaves in a predictable manner.

© Copyright 1997 by Apple Computer, Inc. -- Last Updated
7/31/97