Porting Guide - Partner with Adobe

Transcription

Porting Guide - Partner with Adobe
Porting Guide
Technical Note #10075
Version InDesign CS/InCopy CS
10 Mar 2004
ADOBE SYSTEMS INCORPORATED
Corporate Headquarters
345 Park Avenue
San Jose, CA 95110-2704
(408) 536-6000
Copyright 2003 Adobe Systems Incorporated. All rights reserved.
The information in this document is furnished for informational use only, is subject to change without notice, and should not be construed as a
commitment by Adobe Systems Incorporated. Adobe Systems Incorporated assumes no responsibility or liability for any errors or inaccuracies that
may appear in this document. The software described in this document is furnished under license and may only be used or copied in accordance with
the terms of such license.
Adobe, Adobe After Effects, Adobe InDesign, Adobe PhotoDeluxe, Adobe Premiere, Adobe Photoshop, Adobe Illustrator, Adobe Type Manager,
ATM and PostScript are trademarks of Adobe Systems Incorporated that may be registered in certain jurisdictions. Macintosh and Apple are
registered trademarks, and Mac OS is a trademark of Apple Computer, Inc. Microsoft, Windows, Windows 95, Windows 98, and Windows NT are
registered trademarks of Microsoft Corporation. All other products or name brands are trademarks of their respective holders..
Rev #
Date
Author
Comments
0.1
9 Jan 2003
Seoras Ashby
Initial draft.
0.2
14 Jan 2003
Ian Paterson
Integrated content on converting/setting up
projects.
0.3
20 Jan 2003
Ian Paterson
Integrated content on converting Mac projects
and helper tools.
0.4
20 Jan 2003
Seoras Ashby
Integrate content on creating new Mac
projects.
0.5
22 Jan 2003
SeorasAshby/ Ian Paterson
Added the porting checklist stuff as a
troubleshooting section.
0.6
24 Jan 2003
SeorasAshby/ Ian Paterson
Added the review feedback from Jane/Lee
0.7
27 Jan 2003
SeorasAshby/ Ian Paterson
Integrated some porting recipes content.
0.8
29 Jan 2003
Seoras Ashby/ Ian Paterson
Edit for final alpha review.
0.9
31 Jan 2003
Ian Paterson
Added review feedback from Robin, Jane and
Michael
1.0
31 Jan 2003
Seoras Ashby
Add Jane’s Save As XML for backwards
conversion FAQ.
1.1
11 Apr 2003
Ian Paterson
Updated with the content on the UI for
SnowGoose and DollyXs.
1.2
22 Apr 2002
Jane Zhou-Bond/Ian Paterson
Created more porting recipes and refactored
the FAQs to make explicit which are porting
recipe content.
1.3
11 Jul 2003
Ken Sadahiro
Another interim update, including new
screenshots for Visual C++ .NET 2003 and
revised instructions and new recipe content.
1.4
14 Jul 2003
Ian Paterson
Further edits; conversion recipe, subediting,
DollyXs detail.
Rev #
Date
Author
Comments
1.5
14 Jul 2003
Ken Sadahiro
Updated document to use new “InDesign CS”
and “InCopy CS” designation.
1.6
21 Jul 2003
Ken Sadahiro
Corrected $(InputPath) settings for .fr file
specific VC++ .NET 2003 settings.
1.7
14 Aug 2003
Ken Sadahiro
Changed Mac project Creator type from
‘InDn’ to ‘ID30’, based on change by
InDesign/InCopy Engineering.
1.8
26 Aug 2003
Ken Sadahiro
Added info about a new string field in
PluginVersion resource. Changed Creator
back to InDn as per Engineering change.
1.9
03 Sep 2003
Ken Sadahiro
Updated title page image.
2.0
16 Sep 2003
Ken Sadahiro
Added new porting recipes.
2.1
9 Mar 2004
Jane Bond
Update Mac SDK lib location and folder name
change.
Contents
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Before you begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Terminology and definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Key concepts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
New SDK organisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Schematic view of the SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Plug-in development environment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Porting strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Renaming of SampleCode to sdksamples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Flattening within each sample folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Moving content from Utilities folder to sdksamples/common. . . . . . . . . . . . . . . . . . . . . 16
Converting a 2.0 Windows plug-in project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Backing up BasicMenu sample in the SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Copying files from the 2.0 project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Modifying source paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Configuring project settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Configuring file settings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Code changes required to the 2.0 sample code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Converting a 2.0 Mac plug-in project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Backing up BasicMenu sample in the SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Copying files from the 2.0 project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Configuring project settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Code changes required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Creating a Windows plug-in project from scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Creating a new, empty project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Creating source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Configuring project settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Customising file-specific settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Building and testing the debug plug-in on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Building and testing the release plug-in on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Creating a Mac plug-in project from scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Creating a new, empty project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Configuring project settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Creating source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
v
Contents
Adding libraries to the project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Building and testing the debug plug-in on Mac. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Building and testing the release plug-in on Mac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Converting a Windows plug-in for InDesign CS/InCopy CS project made with Visual C++ 6.0 to Visual
C++ .NET 2003. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Getting started with DollyXs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Running DollyXs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Advanced: Running DollyXs with custom options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Getting started with SnowGoose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Running SnowGoose. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Features and limitations of SnowGoose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Frequently asked questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103
How do I set up Visual C++ .NET 2003 to access tools required to build SDK plug-ins? . . . . .103
How do I set up CodeWarrior to access tools required to build SDK plug-ins? . . . . . . . . . . .104
Where do I begin porting my plug-in to the current SDK? . . . . . . . . . . . . . . . . . . . . . . .105
Where can I see an overview of the API changes between 2.0 and InDesign CS/InCopy CS? . .105
Where are the API headers in the current SDK? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
Where are the API libraries in the current SDK? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
Where's the sample code in the current SDK? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
Where's the documentation in the current SDK? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
Where is InDesign CS/InCopy CS preference files folder on Windows now? . . . . . . . . . . . .106
How can I make an object model dump to see boss class information? . . . . . . . . . . . . . . .106
How do I get the application to load my plug-in binary? . . . . . . . . . . . . . . . . . . . . . . . .106
What is TriggerResourceDeps.cpp there for? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
How has the PluginVersion resource changed? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
How do I update the k<whatever>RegisterBoss classes in my plug-in? . . . . . . . . . . . . . . .108
How can I get custom objects and attribues to the InDesign Interchange Format? . . . . . . .108
How do I know if I have a Java Run-Time on Windows, and what version? . . . . . . . . . . . . .108
How do I obtain a Java run-time for Windows? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .108
How do I bring up a Terminal window on Macintosh OS 10.2.x? . . . . . . . . . . . . . . . . . . .109
What are .rsp files for? (@ option in Windows project files) . . . . . . . . . . . . . . . . . . . . . . . 109
What is DebugWindow, and how do I use it?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
Porting recipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
How can I fix my dialog-controller code that doesn’t compile? . . . . . . . . . . . . . . . . . . . .109
How do I use the new ColorDropDownListWidget? . . . . . . . . . . . . . . . . . . . . . . . . . . .110
I get many compiler errors related to PMString, WideString, and other string related APIs. How do
I get my code to compile?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
vi
10 Mar 2004
Porting Guide
Contents
I am trying to port a scriptable plug-in. I see that there are many changes not only to the API, but
also how the platform-specific resources are specified. Where should I start? . . . . . . . . . . .113
How do I get my code that uses IPlaceBehaviour to compile? . . . . . . . . . . . . . . . . . . . . .113
How have the semantics of IDataLinkReference changed? . . . . . . . . . . . . . . . . . . . . . . .113
How can I fix problems compiling ODFRez data statements with iconic buttons? . . . . . . . .114
Can I use PNG artwork with iconic buttons? How do I handle the cross-platform issues? . . . .114
What is Skip By Leading? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
How do I use the minHeightLeadingDiff parameter when getting tiles? . . . . . . . . . . . . . .117
How do I adapt to the meta data API changes? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .118
What is the purpose of IAdornmentShape::WillPrint? . . . . . . . . . . . . . . . . . . . . . . . . . .120
How do I get my FontGroupIteratorCallBack to compile? . . . . . . . . . . . . . . . . . . . . . . . .121
How do I get my IKerningOnTheFly code to compile? . . . . . . . . . . . . . . . . . . . . . . . . . .121
How do I get my IPMFont::GetWindowsLogFont code to compile and run without bugs? . . .122
How has the ToolDef resource changed? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
How has swatch creation changed? Do I still need to create a kSolidMetaDataBoss etc? . . . .123
What has happened to ITableTextSelection? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .124
Should I keep using ISelection and ISelectUtils interfaces? . . . . . . . . . . . . . . . . . . . . . . .125
Which selection type (ISelection::SelectionType) constants should I use? . . . . . . . . . . . . .125
How do I remove dependency on IID_NEED_<whatever>SELECTION? . . . . . . . . . . . . . . .125
What has changed in IHierarchy interface? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .129
IDocumentUtils now on the Utils boss. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
What has changed in IFileList? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
What has changed in ITreeViewController?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
What has changed in IControlView? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
What happened to RedlineID.h?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
What has changed for body and last line text alignment attributes?. . . . . . . . . . . . . . . . .131
What do you need to change for your sub-dialog observer . . . . . . . . . . . . . . . . . . . . . .132
What has happened to IComposeScanner::QueryDataAt()? . . . . . . . . . . . . . . . . . . . . . .133
What has changed in IPageItemAdornmentList? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133
Why has parcel index changed to parcel key (ParcelKey)? . . . . . . . . . . . . . . . . . . . . . . .134
What has changed in IActionManager? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .135
What has changed in ICreateFrameData? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .135
What has changed in the OPI-related methods in IPDFDocPort? . . . . . . . . . . . . . . . . . . .136
What has changed in IPrintDataHelperStrategy? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
What has happened to ITableFrameList? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
Why was the "removed" parameter dropped from ITextAttributeSuite::ApplyAttributes? . . .137
What have happened to the command generator methods in ITextModel, and what should I use
instead? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .138
My selectable dialog doesn’t seem to validate when the user switches. What has changed in
selectable dialogs? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .139
Porting Guide
10 Mar 2004
vii
Contents
How have the CanSplitCell/SplitCell methods in ITableSuite, ITableCommands and ITableModel
changed? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
How has IPhase2Conversion changed? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
I am using an interface and/or class which is not mentioned in this Porting Recipes section. How
can I find out what changed? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Parameters for DollyXs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Parameters for SnowGoose. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
viii
10 Mar 2004
Porting Guide
1
#10075 Porting Guide
Overview
Welcome to the InDesign CS/InCopy CS SDK. This porting guide details the significant
changes that have been made to the SDK (see the Schematic view of the SDK for a roadmap)
and provides essential information to move your InDesign/InCopy plug-ins to the current
SDK. This document is geared towards developers porting code from version 2.x to the
current SDK and assumes a degree of familiarity with InDesign or InCopy programming.
There are sections for converting projects for Macintosh and Windows; see Converting a 2.0
Windows plug-in project and Converting a 2.0 Mac plug-in project. There are also highly detailed
specifications for setting up a project from the ground up; see Creating a Windows plug-in
project from scratch and Creating a Mac plug-in project from scratch. In addition to describing
the configurations required for Windows and Mac plug-in projects, it includes reference
sections on Troubleshooting, Frequently asked questions and Porting recipes to help overcome
problems often encountered when porting code.
Before you begin
Before you begin please take care of the following.
1.
Check your development platform meets the requirements specified by the section Plugin development environment. Building Windows plug-ins now requires Visual C++ .NET
2003 (Visual C++ 7.1), a change from all preceding SDKs.
2.
Install the SDK. Portions of the discussion from this point onwards assumed that you
have installed the SDK into c:\id3sdk on Windows, or into a folder called /mac/id3sdk on
Macintosh; these locations are by no means obligatory and were chosen simply to
condense the descriptions requiring absolute paths.
3.
See Schematic view of the SDK for the overall organisation of the SDK .
4.
Set up Visual C++ .NET 2003 as described in the FAQ How do I set up Visual C++ .NET
2003 to access tools required to build SDK plug-ins?
5.
Set up CodeWarrior as described in the FAQ How do I set up CodeWarrior to access tools
required to build SDK plug-ins?
6.
Decide how you are going to approach the task of porting your plugins to the new
organisation, see Porting strategies for a roadmap.
#10075 Porting Guide
9
#10075 Porting Guide
Notation
Notation
Menu names: for example, Project > Settings
Dialog names: for example, Options dialog
Computer input, such as commands that you would enter or paths to enter in project settings
share a common run-style: for instance,
sh dollyxsgui.sh
Source code uses the same run-style as computer input: for instance,
printf(“Hello world”);
Computer output that is something you would experience rather than enter is represented in
its own run-style: e.g. Cannot find specified file
SDK root folder: C:\id3sdk on Windows, /mac/id3sdk on Mac. In some contexts, <sdk> may
be used where no specific platform is referenced.
Terminology and definitions
This section defines terms used within this document alone.
10
•
IDE; integrated development environment.
•
Visual C++ .NET (2003); refers to the IDE used to develop plug-ins on Windows. This is
required to be Visual C++ 7.1.
•
CodeWarrior; refers to the IDE used to develop plug-ins on Macintosh.
•
DollyXs; a tool for creating plug-in code based on templates defined in XSL. Provides a
more compact way to define the templates than the original Dolly shipped with the 2.0
SDK. See Getting started with DollyXs.
•
ODF; OpenDoc Framework. Originally this was a cross-platform software effort initiated
by Apple and IBM; it defined an object-oriented extension of the Apple Rez language to
specify user interface resources. The API uses ODF to define a type system that specifies a
variety of plug-in resources knows as framework resources.
•
ODFRC; OpenDoc Framework Resource Compiler. The SDK supplied compiler for
framework resource .fr files (Mac and Windows).
•
RC Includer; The SDK supplied CodeWarrior compiler plug-in for .rc files (Mac only).
See /mac/id3sdk/devtools/rcincluder/readme.txt for more information.
•
SAXON; “The SAXON XSLT Processor from Michael Kay", the most advanced XSLT
engine in terms of its conformance to W3C specifications. See its home page, which is at
http://saxon.sourceforge.net. This is the transform engine used in SnowGoose and
DollyXs.
#10075 Porting Guide
Key concepts
•
SnowGoose; a tool for migrating projects from the 2.0 SDK to the current SDK. The name
of the program is ironic given ‘real’ Snow Geese are some of the most hardy and
accomplished migrators in the world. See Getting started with SnowGoose.
•
XMP; eXtensible Metadata Platform. Provides Adobe applications and workflow partners
with a common XML framework that standardizes the creation, processing, and
interchange of document metadata across publishing workflows.
•
XSLT; eXtensible Stylesheet Language: Transformations. A language primary intended for
transforming one XML document into another. See http://www.w3c.org/Style/XSL/. This
is used in both SnowGoose and DollyXs which use “smart” templates.
Key concepts
New SDK organisation
The SDK has undergone some changes, both functional and structural, since the last major
release. This section provides an overview of the changes and explains why they were
necessary.
The most important functional change is the merging of the InDesign and InCopy SDKs. The
same libraries and header files are now used when building projects for both products. This
means that project settings for InDesign and InCopy plug-ins are the same, and can be built
using just one SDK. This radically simplifies development for InDesign CS and InCopy CS, and
some of the SDK plug-ins can be loaded under both InDesign CS and InCopy CS from a single
binary compiled into one location.
The functions of the Diagnostics plug-in are now embedded in the debug build of the
applications. Consequently, the Diagnostics plug-in has been removed from the SDK. To use
the functions the plug-in provides, choose the Test>Diagnostics menu of the debug build. For
example, use this menu to dump the object model at runtime. This will create a reference of all
defined bosses and interfaces in the application. For further information on this plug-in read
tech note #10071 (Diagnostics tech-note).
The types of content in the SDK have not changed, but they have been restructured to bring the
SDK projects more closely in line with the build process of the underlying application. Making
this change will streamline the process of handling cases, analyzing sample code, and improve
Adobe's overall response to questions from 3rd party developers. These structural changes will
require 3rd party developers to modify some project settings as they port existing plug-ins. To
mitigate this impact, this guide describes the necessary changes in detail. In addition, a tool
(Snowgoose: see Getting started with SnowGoose) has been provided to automate porting old
projects to the new format; this was used to convert all the SDK plug-ins from the 2.0
organisation to the current organisation. It is also possible to generate a complete plug-in
project that should compile under the current SDK using DollyXs (see Getting started with
DollyXs). The section Porting strategies explains how these tools and the reference material in
this document can be used to convert plug-ins from 2.0 to the current version.
#10075 Porting Guide
11
#10075 Porting Guide
Key concepts
The table Overview of changes in SDK format describes how the content from the old SDK
format has been rearranged in the new SDK. The former API directory has been separated into
distinct directories for header files and libraries. The header files are now collocated with the
source code for the SDK samples, and the libraries are located in the build folder. The project
files reside within a build folder, rather than being in a Project folder within each sample. The
organisation is shown in a schematic view in the section entitled Schematic view of the SDK.
Other changes have been made to fix defects in the projects in the 2.0 SDK, such as the
CVTRES fatal error, which was fixed by modifying the pre-link and post-build steps; see e.g.
Property Pages > Build Events > Pre-Link Event onwards.
TABLE 1.1 Overview of changes in SDK format
12
Content
2.x SDK
InDesign CS/InCopy CS SDK
API Files
/API
/source/public
Precompiled headers
/API/PreComp
/source/precomp
Debug Libraries (Mac)
/API/LibD
/build/mac/libd
Release Libraries (Mac)
/API/LibR
/build/mac/libr
Debug Libraries (Windows)
/API/LibD
/build/win/objd
Release Libraries (Windows)
/API/LibR
/build/win/objr
Technical Notes
/Documentation/Tech
Notes
/docs/guides
Programming Guides
/Documentation
/docs/guides
API Reference (HTML)
/Documentation/WebD
ocs
/docs/references
SDK Code Samples
/SampleCode
/source/sdksamples
SDK Projects (Mac)
/SampleCode/xxx/yyy/
Project
/build/mac/sdkprj
SDK Projects (Windows)
/SampleCode/xxx/yyy/
Project
/build/win/sdkprj
SDK Tools
/Tools
/devtools/bin (for ODFRC and other compilerrelated executables)
/devtools/sdktools (for DollyXs and other helper
tools)
SDK Utility Files (shared code,
SDK-specific includes etc.)
/Utilities
/source/sdksamples/common
#10075 Porting Guide
Key concepts
Schematic view of the SDK
Below is shown a schematic of the new organisation of the SDK, showing at a high level where
the components required to compile plug-ins can be found.
<sdk>
Folder where you installed
the SDK, i.e. the root of the
SDK tree
Note: source/projects for SDK
samples are highlighted in
yellow
build folder contains projects and binaries needed to
compile plug-ins. It also is the target for intermediate files
and output files.
build
mac
sdkprj
libd
libr
debug
release
This is the build folder for the Macintosh platform. It
contains the projects (MCP files) for Metrowerks
CodeWarrior.
SDK
SDK
Note that the libraries are now in libD (debug) or libR
(release) .
SDK sample plug-ins compile to a folder release/SDK or
debug/SDK in the build/mac folder.
build/mac/sdkprj folder has Mac projects for sdksamples
This is the build folder for the Windows platform. It
contains the projects (DSP files) for Visual Studio.
win
Note that the libraries and the intermediate files for the
sdksamples plug-ins can be found in objd (debug) or objr
(release).
sdkprj
objd
objr
debug
release
The sample plug-ins compile to a folder debug/SDK or
release/SDK in the build/win folder
SDK
SDK
build/win/sdkprj folder has Win projects for sdksamples
docs
docs/guides contains the PortingGuide and other content.
guides
references
docs/references contains a Windows Compiled Help
Module (.chm file) and a tar.gz file for Macintosh OS 10.x
The boost library is described at the Web-site http://
www.boost.org.
external
boost
It is used as the basis of the collection classes in the
InDesign/InCopy API.
The folder source contains samples and header files
(normal and pre-compiled)
source
sdksamples
precomp
source/sdksamples contains the source only for sample
plug-ins.
public
The projects for these sample plug-ins can now be found
in build/win/sdkprj (Windows) and build/mac/sdkprj
(Macintosh)
commands
basicdialog
...
common
The folder source/precomp contains assets relating to precompiled headers
...
includes
interfaces
devtools
bin
#10075 Porting Guide
It also contains implementation classes such as
CDialogObserver.cpp, which are included for reference
only (since the binary is in the Public libraries).
devtools/bin folder contains the compiler tools you need
(like ODFRC). On Windows, be sure that devtools/bin is a
path for executables for Visual Studio.
sdktools
dollyxs
Public contains API header files, in folders source/public/
includes, source/public/interfaces and source/public/
widget/includes.
snowgoose
...
devtools/sdktools contains helper tools like DollyXs (a
plug-in Wizard) and SnowGoose (for converting 2.0 SDK
projects to 3.0 SDK projects)
13
#10075 Porting Guide
Key concepts
Plug-in development environment
The operating systems and IDEs for which plug-in development is supported are tabulated
below.
TABLE 1.2 Supported development platform requirements
14
Platform
Component
Note
Applications
InDesign CS or InCopy CS
It is recommended you
have both debug and
release applications.
The debug application
is instrumented to
detect bugs and is
essential to successful
plug-in development.
Mac
Mac OS X 10.2 or better
Mac
CodeWarrior 8.3
+ ODFRC and RC
Includer compilers
supplied on this SDK.
Windows
Windows 2000
+ Service Pack 2
Windows
Windows XP
Windows
Visual C++ .NET 2003 (also
known as Visual C++ 7.1)
Mac
G3 Processor min
G4 Processor recommended
256MB memory min
512MB memory recommended
Windows
Pentium III min
Pentium 4 recommended
256MB memory min
512MB memory recommended
Mac
Web browser that understands
long Macintosh filenames
+ ODFRC compiler
supplied on this SDK
to view html
documentation in
<sdkdocs>.tar.gz file.
Choices include Apple
Safari, Mozilla
Chimera, OmniWeb.
Note that Navigator
and Internet Explorer
shipping versions don’t
support long Macintosh
filenames in local hrefs.
#10075 Porting Guide
Key concepts
Platform
Component
Note
Windows
Windows Help (standard
component of Windows)
to view compiled help
documentation
(index.chm)
Windows/Mac
Acrobat Reader 5.0 or better
(Acrobat 6.0 is the shipping
version)
to view PDF-based
documentation
Porting strategies
Documentation and tools have been provided to minimise the pain of converting to the
current SDK organisation:
1.
Conversion guides, which specify how to convert an existing 2.0 project to work with the
new SDK organisation. See Converting a 2.0 Windows plug-in project and Converting a 2.0
Mac plug-in project. (If you are converting and existing Visual C++ 6.0 project for an
InDesign CS/InCopy CS plug-in to work with Visual C++ .NET 2003, see Converting a
Windows plug-in for InDesign CS/InCopy CS project made with Visual C++ 6.0 to Visual
C++ .NET 2003.
2.
Guides to creating a project from scratch, which describe the process of creating a new
plug-in project. See Creating a Windows plug-in project from scratch and Creating a Mac
plug-in project from scratch.
3.
SnowGoose, which parses a Visual C++ 6.0 project file (.dsp) or converts a CodeWarrior
.mcp.xml file to convert it to work with the revised SDK organisation. For details see
Getting started with SnowGoose.
4.
DollyXs, which generates an a new plug-in from an XML-based code specification. This
generates an entire plug-in to your specification and is the recommended way to produce
a skeleton plug-in. For details see Getting started with DollyXs.
To port an existing plug-in we recommend you check out the conversion guides first. These
describe the manual steps you need to reorganise source files and projects. If you have several
plug-ins to port check out SnowGoose which can automate some of the manual labour
involved. Use the guides to creating a project from scratch as a reference to verify project
settings. Or if you want to recreate your project manually in full you can follow the recipes
these sections provide as an alternative to converting your 2.0 project. Once you’ve reorganised your code to work within the SDK, use the Troubleshooting, Frequently asked
questions and Porting recipes to fix up the problems you encounter porting the code.
Renaming of SampleCode to sdksamples
This change was brought about to qualify the folder in which the SDK samples were located by
something that made explicit the intention to ship these in the SDK. This was brought about by
the co-location of the SDK codebase with that of the InDesign CS/InCopy CS product.
#10075 Porting Guide
15
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
Flattening within each sample folder
This means that the code for a sample plug-in that was previously within Project, Resources
and Source folder is now located in a single folder for the sample within source/sdksamples.
This flattening simplifies the project settings for individual SDK projects.
Moving content from Utilities folder to sdksamples/common
There are some files included by all SDK plug-ins such as SDKDef.h or
SDKPluginEntrypoint.cpp that used to be located in a folder named Utilities in the 2.0 SDK
codebase. This folder has been removed since its location was inconsistent with the rest of the
codebase and its content moved to a folder <sdk>/source/sdksamples/common.
Converting a 2.0 Windows plug-in project
This section describes the manual steps required to change an existing InDesign 2.0 SDK Visual
C++ 6.0 plug-in project to work with the current SDK. The changes required to be made to the
2.0 project BscMnu.dsp are described, to allow this to work successfully with the SDK. If you
have any questions at all about the required configuration when reading through this section
then you should refer to the section entitled Creating a Windows plug-in project from scratch,
which is a more definitive specification of the project settings required.
In some respects the process described is academic, since the SDK already contains a working
example of the BasicMenu sample. The real intent is that you would adapt this recipe for your
own plug-in. However, if you want to perform this exercise exactly as written here to familiarise
yourself with the new configuration of SDK plug-ins, and be able to enter the data as specified
in this recipe to perform the conversion, you should back up the existing SDK sample
(source/sdksamples/basicmenu) and its corresponding project (BasicMenu.dsp) in the project
folder (build/win/sdkprj) before you begin. Note that you would need to have a 2.x SDK
available and copy some files from that to a location within the current SDK. If you do not have
an SDK and simply want to set up a project from scratch then consult the section Creating a
Windows plug-in project from scratch.
The steps below are described for those who feel comfortable working within the IDE of
Microsoft Developer Studio and using the GUI to modify the project settings. Whilst it is
possible to change project settings by editing the project file directly in a text editor, it is not
recommended here.
Backing up BasicMenu sample in the SDK
Move the contents of the folder c:\id3sdk\source\sdksamples\basicmenu to a backup location,
as you will be recreating its contents from the 2.0 source.
Move the project file c:\id3sdk\build\win\sdkprj\BasicMenu.vcproj to a backup location, as
you will be creating your own version in the course of carrying out this recipe.
16
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
Copying files from the 2.0 project
Copy the source from the folder BasicMenu for the 2.0 SDK to the new folder within
c:\id3sdk\source\sdksamples\basicmenu for the current SDK. You should ensure that the files
from Source and Resources folders in the 2.0 plug-in now all reside at the same level in a folder
called basicmenu. The contents of the folder basicmenu should resemble those shown below.
Copy the project file BscMnu.dsp from the 2.0 SDK to the folder c:\id3sdk\build\win\sdkprj.
Rename this file to be BasicMenu.dsp to respect the current SDK naming convention that
project files have the same name as the plug-in that they generate. (NOTE: The file extension is
still .dsp; Visual C++ .NET 2003 will be used for the transformation.)
Open the project file called BasicMenu.dsp that you have just created by renaming BscMnu.dsp
in c:\id3sdk\build\win\sdkprj. You will see this dialog; just click Yes to perform the conversion.
In the Solution Explorer, delete the DocSource folder, as the content that would previously
have been in this folder is no longer published on the SDK.
Modifying source paths
If you attempt to open individual files in this project file (BasicMenu.dsp) at this point, you
will find that the paths are incorrect and Visual C++ .NET 2003 claims that the file does not
exist. In the 2.0 SDK, since the project file was located in the Project folder, the relative path
from project to an individual .cpp file would be ..\Source (or ..\Resources, and so on.). Visual
C++ 7.1 does not allow you through its user interface to change the relative path associated
with a project item, so the recommended technique is to re-add project items. If you do this by
cutting and pasting the relative paths from the table Relative source paths to add existing item
and add one file at a time, the process is somewhat simpler. It is also somewhat easier if you add
#10075 Porting Guide
17
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
one file at a time to determine which file is the Existing Item, and which the legacy that has an
incorrect Relative Path, than adding all files at once.
You can re-add files using the Project > Add Existing Item... menu.
You should have copied all of your source and resource files into the same folder
(c:\id3sdk\source\sdksamples\basicmenu). Note that the .fr files will not show up if the Files of
Type dropdown list is “Visual C++ Files”; you need to change that to “All Files” to make the .fr
files show up.
To add the correct “existing item” using File > Add Existing Item, you can add each item
individually by cutting and pasting the relative path from the project to the file from the table
below. This avoids having to navigate using the file system to locate each file.
TABLE 1.3 Relative source paths to add existing item
File as it appears in Solution Relative Path (Properties > Relative Path)
Explorer
BscMnuID.cpp
..\..\..\source\sdksamples\basicmenu\BscMnuID.cpp
BscMnuNoStrip.cpp
..\..\..\source\sdksamples\basicmenu\BscMnuNoStrip.cpp
PlugInStatics.cpp
..\..\..\source\public\statics\PlugInStatics.cpp
SDKPlugInEntrypoint.cpp
..\..\..\source\sdksamples\common\SDKPlugInEntrypoint.cpp
SDKUtilities.cpp
..\..\..\source\sdksamples\common\SDKUtilities.cpp
VCPlugInHeaders.cpp
..\..\..\source\precomp\msvc\VCPlugInHeaders.cpp
TriggerResourcesDeps.cpp
..\..\..\source\sdksamples\basicmenu\TriggerResourcesDeps.cpp
BscMnuActionComponent.cpp
..\..\..\source\sdksamples\basicmenu\BscMnuActionComponent.cpp
BscMnuFactoryList.h
..\..\..\source\sdksamples\basicmenu\BscMnuFactoryList.h
BscMnuID.h
..\..\..\source\sdksamples\basicmenu\BscMnuID.h
BscMnu.fr
..\..\..\source\sdksamples\basicmenu\BscMnu.fr
BscMnu.rc
..\..\..\source\sdksamples\basicmenu\BscMnu.rc
At the end of this process, you should be able to verify that the relative paths to the remaining
source files are correct, by double-clicking to open each file (though not recommended for the
18
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
.rc file). Below is shown a screenshot showing how the Relative Path should appear. See the
menu View > Properties (Alt + Enter) to obtain this File Properties dialog when a source file is
selected in the Solution Explorer (not the same as the Properties sheet obtained by right-mouse
click in the Solution Explorer).
Configuring project settings
These settings apply at the level of the project, and are applied for each configuration (Debug
or Release).
Property Pages > General
You should modify the “General” settings for the project by selecting Project > Properties >
General. Note that the correct paths should be objd (all lower case) for debug and objr (all
lower case) for release.
#10075 Porting Guide
19
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
TABLE 1.4 General settings
Tab
Label
Configuration
Setting
General
Intermediate Directory
Debug
..\objd\BasicMenu
General
Output Directory
Debug
..\objd\BasicMenu
General
Intermediate Directory:
Release
..\objr\BasicMenu
General
Output Directory
Release
..\objr\BasicMenu
Property Pages > C/C++
Settings that changed from those at version 2.0 are listed below. See the section Configuring
project settings for a complete specification of the settings.
TABLE 1.5 C/C++ settings
20
Tab > Category
Label
Configuration
Setting
General
Debug
Information
Format
Debug + Release
Program Database (/Zi)
General
Warning as errors
Debug + Release
Yes (/WX)
Optimization
Inline Function
Expansion
Debug
Only __inline (/Ob1)
Code Generation
Exception
handling
Debug + Release
No
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
Tab > Category
Label
Configuration
Setting
Code Generation
Buffer Security
Check
Debug + Release
Yes (/GS)
Code Generation
Treat wchar_t as
Built-In Type
Debug + Release
Yes (/Zc:wchar_t)
Code Generation
Force
Conformance in
For Loop Scope
Debug + Release
Yes (/Zc:forScope)
Precompiled Headers
Precompiled
Header File
Debug
.\..\objd\BasicMenu/BasicMenu.
pch
Precompiled Headers
Precompiled
Header File
Release
.\..\objr\BasicMenu/BasicMenu.
pch
Output Files
ASM List Location
Debug
.\..\objd\BasicMenu/
Output Files
Object File Name
Debug
.\..\objd\BasicMenu/
Output Files
Program Database
File Name
Debug
.\..\objd\BasicMenu/
Output Files
ASM List Location
Release
.\..\objr\BasicMenu/
Output Files
Object File Name
Release
.\..\objr\BasicMenu/
Output Files
Program Database
File Name
Release
.\..\objr\BasicMenu/
Advanced
Command Line
Debug + Release
/vmg @SDKCPPOptions.rsp
NOTE: You should ensure that you modify the path to the RSP file to SDKCPPOptions.rsp (no
relative path to Utilities folder is required, this folder is gone, but the RSP file is now in sdkprj
along with the projects that refer to it). See the Advanced setting in the table above. You will
have to set these individually for some files as well.
If you were not already using references to RSP files, we strongly recommend that you do so,
since it considerably simplifies the project file and can be used both for the .fr file and the .cpp
#10075 Porting Guide
21
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
files. See the FAQ What are .rsp files for? (@ option in Windows project files) for further
information.
Property Pages > Linker
The link settings need to be modified because the path of the libraries relative to the project file
is now a little different than they were in 2.0 SDK. Note that the libraries are now held in objd
or objr, rather than libD/libR as they were in the 2.0 SDK.
22
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
TABLE 1.6 Linker settings
Label under ConfigLinker
uration
Properties
Setting
General >
Output File
Debug
..\debug\SDK\BasicMenu.pln
General >
Output File
Release
..\release\SDK\BasicMenu.pln
General >
Additional
Library
Directories
Debug +
Release
<<Please make sure that this text field is empty and doesn’t contain a reference
to api\libD or api\libR>>
Input >
Additional
Dependencies
Debug
..\objd\PMRuntime.lib ..\objd\Public.lib ..\objd\WidgetBin.lib
Input >
Additional
Dependencies
Release
..\objr\PMRuntime.lib ..\objr\Public.lib ..\objr\WidgetBin.lib
Debugging >
Generate
Debug Info
Debug +
Release
Yes (/DEBUG)
Debugging >
Generate
Program
Database File
Debug
..\debug\SDK\BasicMenu.pdb
Debugging >
Generate
Program
Database File
Release
..\release\SDK\BasicMenu.pdb
Advanced >
Import
Library
Debug
.\..\objd\BasicMenu/BasicMenu.lib
Advanced >
Import
Library
Release
.\..\objr\BasicMenu/BasicMenu.lib
Property Pages > Build Events > Pre-link Event
These new settings for pre-link and post-build fix the error “CVTRES: fatal error CVT1100;
duplicate resource” encountered in 2.0 SDK projects. The only consideration is at the time of
writing that you have to specify the folder devtools/bin for executables otherwise these new
pre-link/post-build steps will not work as intended (some of the dependencies for these scripts
#10075 Porting Guide
23
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
would not be resolved). For more detail see the FAQ entitled How do I set up Visual C++ .NET
2003 to access tools required to build SDK plug-ins? The correct setting for the Build Events >
Pre-link Event > Command Line setting for both Debug and Release configurations is shown
below:
merge_res.cmd $(IntDir)
BscMnu
Property Pages > Build Events > Post-Build Event
The changed setting since 2.0 is the counterpart required to the pre-link step, again to correct
the CVTRes error. The correct setting for the Events > Pre-link Event > Command Line setting
for both Debug and Release configurations is shown below.
restore_res.cmd $(IntDir)
BscMnu
Configuring file settings
This section specifies how to configure settings for individual files. Select the file within the
project’s File View before making each setting.
VCPlugInHeaders.cpp file: Property Pages > C++ Settings > Custom build
Right-click on the file VCPlugInHeaders.cpp in the Solution Explorer and select Properties to
open the Property Page shown below. You should change the setting Precompiled Headers >
Create/Use Precompiled Header to “Create Precompiled Header (/Yc)” for this file and make
the settings listed in the table below.
24
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
TABLE 1.7 Custom build settings for VCPlugInHeaders.cpp file
Tab > Label
Configuration
Setting
C/C++ >
Precompiled
Headers >
Create/Use
Precompiled
Header
Debug +
Release
Create Precompiled Header (/Yc)
.fr file: Project Settings > Custom build
Right-click on the file BscMnu.fr in the Solution Explorer and select Properties to open the
Property Page. Make the settings listed in the table below.
TABLE 1.8 Custom Build Step settings for BscMnu.fr file
Tab > Label
Configuration
Setting
General >
Description
Debug +
Release
Performing Custom Build Step on $(InputPath)
General >
Command Line
Debug
odfrc “$(InputPath)” -o “$(IntDir)\$(InputName).fres” -d DEBUG -i
..\..\..\source\sdksamples\basicmenu @SDKODFRCOptions.rsp
General >
Command LIne
Release
odfrc “$(InputPath)” -o “$(IntDir)\$(InputName).fres” -i
..\..\..\source\sdksamples\basicmenu @SDKODFRCOptions.rsp
General > Outputs
Debug +
Release
$(IntDir)\$(InputName).fres
General >
Additional
Dependencies
Debug +
Release
$(IntDir)\TriggerResourceDeps.obj
#10075 Porting Guide
25
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
This shows what the Custom Build tab should look like for BscMnu.fr for the Debug
configuration.
Click on the “...” button in the Additional Dependencies setting. There should be an explicit
dependency on: $(IntDir)\TriggerResourceDeps.obj
.rc file: Project Settings > Resources
You should change the setting associated with the project .rc file (Windows-specific resource
file), to take the modified include paths shown below. This is the same for Debug and Release
configurations. This should enable the resource compiler to locate the include files, as it cannot
apparently make use of an RSP file and so we have to partially duplicate some of the access
paths for headers in a custom setting for the resource file. The source include paths for the .rc
file should be those shown below (ignore the absolute path which may appear in the project
file, this is a Visual C++ quirk):
..\..\..\source\sdksamples\common;..\..\..\source\precomp\msvc;..\..\..\source\publ
ic\includes
26
#10075 Porting Guide
Converting a 2.0 Windows plug-in project
This shows what the IDE should show when making this setting:
Code changes required to the 2.0 sample code
1.
You should find that you have to modify the ODFRez PluginVersion resource in the
BscMnu.fr file by adding target product { kInDesignProduct, kInCopyProduct} to have
the plug-in compile. This means that the plug-in would load under both InDesign CS
and InCopy CS. See the FAQ How has the PluginVersion resource changed? for more detail
on this topic. The resource should then look like this:
resource PluginVersion (kSDKDefPluginVersionResourceID)
{
kTargetVersion,
kBscMnuPluginID,
kSDKDefPlugInMajorVersionNumber, kSDKDefPlugInMinorVersionNumber,
kSDKDefHostMajorVersionNumber, kSDKDefHostMinorVersionNumber,
kSDKDefPersistMajorVersionNumber, kSDKDefPersistMinorVersionNumber,
{ kInDesignProduct, kInCopyProduct},
{ kWildFS },
SDK_DEF_MAKE_VERSIONSTRING(
kSDKDefPlugInMajorVersionNumberForResource,
kSDKDefPlugInMinorVersionNumberForResource,
kSDKDefPlugInStepVersionNumberForResource,
kBuildNumber)
};
2.
You should remove any Class resources from the ClassDescriptionTable in BscMnu.fr that
mention AutoRegister. The need for a plug-in to deliver these boss classes has been
eliminated with version 3 of the application.
3.
In BscMnu.fr, the IID_NEED_LAYOUTSELECTION needs to be changed. In the
actually shipping SDK sample plug-in, this has been replaced with
IID_IBSCMNU_ISUITE, however, you would need to define a specific IID (and a
#10075 Porting Guide
27
#10075 Porting Guide
Converting a 2.0 Mac plug-in project
corresponding implementation) to make this work. (Refer to How do I remove
dependency on IID_NEED_<whatever>SELECTION? for a details on why this change was
made.) For now, just change this to
kInvalidInterfaceID,
and the previous line (kDisableIfSelectionDoesNotSupportIID,) should
be changed to:
kDisableIfLowMem,
We recommend that you remove dependency on code in SDKUtilities.cpp, which is now
deprecated.
Converting a 2.0 Mac plug-in project
This section describes the manual steps required to migrate an existing InDesign 2.0 SDK
CodeWarrior plug-in project to work with the current SDK. The changes required to be made
to the 2.0 project BscMnu.mcp are described, to allow this to work successfully with the
current SDK. It assumes that you have installed the SDK to the path /mac/id3sdk. It is more
straightforward to convert a Macintosh project than a Windows project and only a handful of
steps are required on Macintosh, with the majority of effort in changing access paths to respect
the new organisation. If you have any questions at all in this process you should refer to the
section Creating a Mac plug-in project from scratch which should be considered a more
definitive specification of the required project settings for a plug-in project.
In some respects the process described is academic, since the SDK already contains a working
example of the BasicMenu sample. The real intent is that you would adapt this recipe for your
own plug-in. However, if you want to perform this exercise exactly as written here to familiarise
yourself with the new configuration of SDK plug-ins, and be able to enter the data as specified
in this recipe to perform the conversion, you should back up the existing SDK sample before
you begin. Note that you would need to have a 2.0 SDK available and copy some files from that
to a location within the current SDK.
Backing up BasicMenu sample in the SDK
Move the contents of the folder /mac/id3sdk/source/sdksamples/basicmenu to a backup
location, as you will be recreating its contents from the 2.0 source.
Move the project file /mac/id3sdk/build/mac/sdkprj/BasicMenu.mcp to a backup location, as
you will be creating your own version in the course of carrying out this recipe.
Copying files from the 2.0 project
Copy the source from the folder BasicMenu for the 2.0 SDK to the new folder within
/mac/id3sdk/source/sdksamples/basicmenu for the current SDK. You should ensure that the
28
#10075 Porting Guide
Converting a 2.0 Mac plug-in project
files from Source and Resources all reside at the same level in a folder called basicmenu. The
contents of the folder basicmenu should resemble those shown below.
Copy the project file BscMnu.mcp from the 2.0 SDK to the folder
/mac/id3sdk/build/mac/sdkprj. Rename this file to be BasicMenu.mcp to respect the current
SDK convention that project files have the same name as the plug-in that they generate.
Open the project file called BasicMenu.mcp that you have just created by renaming
BscMnu.mcp in /mac/id3sdk/build/mac/sdkprj. Delete the DocSource group in this project, as
the content that would previously have been in this folder is no longer published on the SDK.
Configuring project settings
Target > Target Settings
Change the output directory to {Project}../debug/SDK for the Debug target. To do this,
navigate to /mac/id3sdk/build/mac/debug via the file selection dialog. If the folder named SDK
does not exist, then you should create one with the New Folder button. The equivalent setting
#10075 Porting Guide
29
#10075 Porting Guide
Converting a 2.0 Mac plug-in project
for the Release target is {Project}../release/SDK. If at this point you have already compiled SDK
plug-ins, then these folders would have been created for you.
Uncheck the setting “Save project entries using relative paths”. The effect of unsetting this
option is to simplify the project. Rather than using absolute paths, as one’s intuition might
suggest, when this option is unset, it means that CodeWarrior persists source files using just the
name of the file (minus the path) and relies on the access paths to locate the file rather than
persisting this as if it were part of the filename.
Target > Access Paths
The screenshot below shows typical settings for an SDK plug-in. The main point to note is that
the references to header files all contain ‘source’ rather than ‘API’ as they used to, although
there are some other subtle differences. For instance, widget/includes replaces the old
WidgetIncludes. These differences between the application and SDK plug-ins made it tedious
and difficult to transmit problems from third party developers directly to product engineering.
30
#10075 Porting Guide
Converting a 2.0 Mac plug-in project
You should set the Access paths for the User paths for the Debug target to be as follows:
{Project}../../../source/precomp/codewarrior/(debug)
{Project}../../../source/precomp
{Project}../../../source/public/interfaces
{Project}../../../source/public/includes
{Project}../../../source/public/widgets/includes
{Project}../../../source/sdksamples/common
{Project}../../../source/sdksamples/basicmenu
{Project}..
Interpret DOS and Unix paths should be checked. The access path {Project}.. means search the
folder that is the parent of build/mac/sdkprj, ie. that the build/mac folder will be searched; this
is how CodeWarrior finds the SDK libraries it requires. Release target requires only the
(release) folder be added rather than the (debug) one.
The recommended System paths for both Debug and Release targets are:
{Compiler}MacOSSupport
{Compiler}MSL
{Project}../../../external/boost
At the time of writing you will find that the access paths for the SDK plug-ins do not
necessarily have this qualification of the {Compiler} access path to search only the folders
needed. The typical SDK plug-ins have the following system access paths which can be used if
you do not install the Java support feature of CodeWarrior:
If you did install the Java support for CodeWarrior but don’t plan on using it, then you can
rename the Java_Support folder to be (Java_Support), adding the parentheses to tell
CodeWarrior not to recurse into this folder unless explicitly instructed.
If you specify only the default System access path of {Compiler}, and if you have installed Java
support you will see problems when you try to compile SDK plug-ins, which seem to relate to
Windows header files that are detected by the compiler that conflict with SDK headers. You can
avoid this problem by adding a () around the folder for Java support. However if you want to
#10075 Porting Guide
31
#10075 Porting Guide
Converting a 2.0 Mac plug-in project
use CodeWarrior for both C++ and Java development on the same platform, then you would
need to use the specialised access paths ({Compiler}MacOSSupport and {Compiler}MSL).
When adding the boost path, make the explicit choice to persist the path relative to the project
and not the Compiler, which is the default unless you explicitly specify project-relative in this
setting.
Linker > PPC PEF
You should set the Fragment Name to be BasicMenu.pln. This corrects a defect in the 2.0 SDK
projects where the fragment names were all AdobeCommandsSample, preventing debugging
under Mac OS 10.2.x.
Language Settings > C/C++ Language
ISO C++ Template Parser is a setting that is new for CodeWarrior 8.x, and should be checked.
32
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Code changes required
These are identical to those described in the section Code changes required to the 2.0 sample code
already described for Windows.
Creating a Windows plug-in project from scratch
This section describes the raw manual steps required to set up a new Visual C++ .NET 2003
plug-in project for the Windows platform. This involves:
•
Configuring Visual C++ .NET 2003 if you have not already done so. See the FAQ How do
I set up Visual C++ .NET 2003 to access tools required to build SDK plug-ins?
•
Creating a new, empty plug-in project.
•
Creating source files for the plug-in and adding them to the project.
•
Configuring overall project settings in the debug and release configurations.
•
Customising project settings for special files in the debug and release configurations.
•
Building the debug plug-in and testing that it works under the debug application.
•
Building the release plug-in and testing that it works under the release application.
The settings and files presented in this section will create a plug-in called Acorn. The Acorn
plug-in represents the minimal plug-in that can be made. It provides no functionality but has
sufficient code to allow it to be loaded by the application. If you follow the instructions below
you will generate a plug-in that will show up in the application’s Configure Plug-ins dialog.
If you want to create a plug-in with a name of your choice, e.g. MightyOak, you will need to to
adapt the instructions accordingly. The following heuristics will help if you want to do this.
•
Where you see the name Acorn use your desired name instead, e.g. MightyOak.
•
Where you see the name acorn use your desired name in lower case instead, e.g.
mightyoak.
•
The convention with SDK plug-ins is to use the capitalised form of the name for the
name of the plug-in project, the plug-in binary and in the plug-in’s user interface. The
lower case form of the name is used for the file system folder where the plug-in’s source
code is kept.
Creating a new, empty project
The steps below create an empty project called Acorn.vcproj in the SDK’s Windows project
folder, C:\id3sdk\build\win\sdkprj.
1.
#10075 Porting Guide
Use File/New/Project... to create a new Visual C++. NET 2003 project choosing Win32
Project (under Visual C++ Projects/Win32) as the project template. Name the
project Acorn, make the location a temporary one, e.g. C:\TEMP\, and uncheck the
33
#10075 Porting Guide
Creating a Windows plug-in project from scratch
"Create directory for solution" checkbox. Click OK to continue. Note that the project will
be created in the C:\TEMP\Acorn\ folder.
2.
When the Win32 Application Wizard dialog appears, click on the Application Settings tab
on the left to specify that you want a project with Application Type "DLL" and that you
want it to be an empty project.
Click Finish to generate the project.
34
3.
Use File/Close Solution to close the newly created workspace in Visual C++ .NET.
4.
Copy Acorn.vcproj from the temporary location, C:\TEMP\Acorn\Acorn.vcproj,
into the SDK’s project folder, C:\id3sdk\build\win\sdkprj\Acorn.vcproj.
Just copy this one file, you don’t need the other files the Win32 Application Wizard
created for you.
5.
That completes the creation of the empty project.
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Creating source files
The steps below create the source files for the plug-in in file system folder
C:\id3sdk\source\sdksamples\acorn and add these files to the project’s folders.
1.
Create a file system folder for the plug-in’s code, C:\id3sdk\source\sdksamples\acorn.
2.
Use Visual C++ .NET 2003 File/Open/Project... to open the copied project
C:\id3sdk\build\win\sdkprj\Acorn.vcproj.
3.
Create a Plugin folder in the project’s Source Files folder, and add these files using
Project/Add Existing Item... (once for each file).
4.
•
C:\id3sdk\source\precomp\msvc\VCPlugInHeaders.cpp
•
C:\id3sdk\source\public\statics\PlugInStatics.cpp
•
C:\id3sdk\source\sdksamples\common\SDKPlugInEntrypoint.cpp
Using Project/Add New Item..., create a new file,
C:\id3sdk\source\sdksamples\acorn\TriggerResourceDeps.cpp, inside the project’s Source
Files folder, enter the code below, and save the file.
#include "VCPlugInHeaders.h"
#include "Acorn.fr"
5.
Using Project/Add New Item..., create a new file,
C:\id3sdk\source\sdksamples\acorn\AcornNoStrip.cpp, inside the project’s Source Files
folder, enter the code below, and save the file.
#include "VCPlugInHeaders.h"
#include "InterfaceFactory.h"
extern bool16 gFalse;
/*
References all implementations to stop the linker dead stripping
them from the executable image.
*/
void DontDeadStrip();
void DontDeadStrip()
{
if (gFalse)
{
#include "AcornFactoryList.h"
}
#10075 Porting Guide
35
#10075 Porting Guide
Creating a Windows plug-in project from scratch
}
6.
Using Project/Add New Item..., create a new file,
C:\id3sdk\source\sdksamples\acorn\AcornID.cpp, inside the project’s Source Files folder,
enter the code below, and save the file.
#include "VCPlugInHeaders.h"
// General includes:
#include "ShuksanID.h"
#include "IDFactory_cpp.h"
#pragma export on
#include "AcornID.h"
#pragma export off
7.
Using Project/Add New Item..., create a new file,
C:\id3sdk\source\sdksamples\acorn\AcornID.h, inside the project’s Header Files folder,
enter the code below, and save the file.
#ifndef __AcornID_h__
#define __AcornID_h__
#include "SDKDef.h"
// Plug-in:
#define kAcornPluginName "Acorn"
#define kAcornPrefixNumber 0x79700 // This number was obtained from Adobe Developer
Support.
#define kAcornPrefix RezLong(kAcornPrefixNumber)
// PluginID:
DECLARE_PMID(kPlugInIDSpace, kAcornPluginID, kAcornPrefix + 0)
#endif // __AcornID_h__
8.
Using Project/Add New Item..., create new file,
C:\id3sdk\source\sdksamples\acorn\AcornFactoryList.h, inside the project’s Header Files
folder, enter the code below, and save the file.
#include "VCPlugInHeaders.h"
/*
Invoke REGISTER_PMINTERFACE for each implementation in the plug-in.
For example to add an IActionComponent implementation add a line
like that below. Note there are no implementations in this plug-in.
*/
//REGISTER_PMINTERFACE(AcornActionComponent, kAcornActionComponentImpl)
9.
Using Project/Add New Item..., create a new file,
C:\id3sdk\source\sdksamples\acorn\Acorn.fr, inside the project’s Resource Files folder,
enter the code below, and save the file.
#include "VCPlugInHeaders.h"
// General includes:
#include "ObjectModelTypes.fh"
#include "ShuksanID.h"
#include "BuildNumber.h"
36
#10075 Porting Guide
Creating a Windows plug-in project from scratch
#include "FeatureSets.h"
// Project includes:
#include "AcornID.h"
#ifdef __ODFRC__
/*
// Plugin version definition.
*/
resource PluginVersion (kSDKDefPluginVersionResourceID)
{
kTargetVersion,
kAcornPluginID,
kSDKDefPlugInMajorVersionNumber, kSDKDefPlugInMinorVersionNumber,
kSDKDefHostMajorVersionNumber, kSDKDefHostMinorVersionNumber,
kSDKDefPersistMajorVersionNumber, kSDKDefPersistMinorVersionNumber,
{ kInDesignProduct, kInCopyProduct },
{ kWildFS },
SDK_DEF_MAKE_VERSIONSTRING(
kSDKDefPlugInMajorVersionNumberForResource,
kSDKDefPlugInMinorVersionNumberForResource,
kSDKDefPlugInStepVersionNumberForResource,
kBuildNumber)
};
/*
// Implementation definition.
*/
resource FactoryList (kSDKDefFactoryListResourceID)
{
kImplementationIDSpace,
{
#include "AcornFactoryList.h"
}
};
#endif // __ODFRC__
10.
#10075 Porting Guide
Using Project/Add New Item..., create a new file,
C:\id3sdk\source\sdksamples\acorn\Acorn.rc, inside the project’s Resource Files folder. If
you use the “Resource File” template in the Add New Item dialog (under Resources),
Visual C++ .NET 2003 will add contents from a standard .rc file template, place the file in
the same path as the project, and also provide a resource.h file. We do not want any of
these to happen. Instead, use the “Text File” template in the Add New Item dialog (under
37
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Utility), drag the Acorn.rc file to the Resource Files folder in the Solution Explorer panel,
enter the code below, and save the file.
To edit the Acorn.rc file using a text editor in the IDE as opposed to a resource editor,
right-click on the Acorn.rc file in the Solution Explorer, select Open With..., select
“Source Code (Text) Editor”, then click Open. (When you reopen this file after adding the
code below, you may get a warning from the IDE telling you that “WinRezFlags.h” cannot
be found. Ignore that warning for now, as we will adjust the include paths in a later step.)
#include "WinRezFlags.h"
#include "BuildNumber.h"
#include "AcornID.h"
1 VERSIONINFO
FILEVERSION kMajorVersionNumberForResource, kMinorVersionNumberForResource, 0,
kBuildNumber
PRODUCTVERSION kMajorVersionNumberForResource, kMinorVersionNumberForResource, 0,
0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Adobe Systems Incorporated\0"
VALUE "FileDescription", "Adobe InDesign SDK Plug-in\0"
VALUE "FileVersion", "1.0", "\0"
VALUE "InternalName", kAcornPluginName, "\0"
38
#10075 Porting Guide
Creating a Windows plug-in project from scratch
VALUE "LegalCopyright", kShortCopyRightStr, "\0"
VALUE
VALUE
VALUE
VALUE
"OriginalFilename", kAcornPluginName ".pln\0"
"ProductName", "Adobe InDesign\0"
"ProductVersion", kVersionNumberStr, "\0"
"Copyright", kVersionCopyRightStr, "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1200
END
END
11.
Verify that the plug-in’s file system folder, C:\id3sdk\source\sdksamples\acorn, contains
the files below and that their contents have been set up as described by the steps above.
•
Acorn.fr
•
Acorn.rc
•
AcornFactoryList.h
•
AcornID.cpp
•
AcornID.h
•
AcornNoStrip.cpp
•
TriggerResourceDeps.cpp
12.
Verify that the files are organised as shown below inside the project’s folders. Drag files
around if necessary to place them in the project folders shown.
13.
That completes the creation of source files for the plug-in. Use File/Close Solution to
close the solution. When asked to save the Solution file (Acorn.sln; solutions are
analogous to workspaces in Visual C++ 6.0), go ahead and save it.
#10075 Porting Guide
39
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Configuring project settings
The steps below configure the overall project settings for the Debug and Release
configurations.
40
1.
Use the Project/Properties... menu to display the settings for the Debug configuration.
2.
Visit each of the tabs given below in turn and make the settings for the Debug
configuration. The changes from the settings in the empty project created above have
been tabulated for your reference. Other settings are illustrated by screenshots only and
are not tabulated. (Screenshots are for the Debug configuration only.) Follow the links
provided to see the changes you need to make.
•
Property Pages > General
•
Property Pages > Debugging
•
Property Pages > C/C++ > General
•
Property Pages > C/C++ > Optimization
•
Property Pages > C/C++ > Preprocessor
•
Property Pages > C/C++ > Code Generation
•
Property Pages > C/C++ > Language
•
Property Pages > C/C++ > Precompiled Headers
•
Property Pages > C/C++ > Output Files
•
Property Pages > C/C++ > Browse Information
•
Property Pages > C/C++ > Advanced
•
Property Pages > C/C++ > Command Line
•
Property Pages > Linker > General
•
Property Pages > Linker > Input
•
Property Pages > Linker > Debugging
•
Property Pages > Linker > System
•
Property Pages > Linker > Optimization
•
Property Pages > Linker > Embedded IDL
•
Property Pages > Linker > Advanced
•
Property Pages > Linker > Command Line
•
Property Pages > Resources > General
•
Property Pages > Resources > Command Line
•
Property Pages > Browse Information > General
•
Property Pages > Browse Information > Command Line
•
Property Pages > Build Events > Pre-Build Event
#10075 Porting Guide
Creating a Windows plug-in project from scratch
•
Property Pages > Build Events > Pre-Link Event
•
Property Pages > Build Events > Post-Build Event
•
Property Pages > Custom Build Step > General
•
Property Pages > Web Deployment > General
3.
That completes the overall project settings for the Debug configuration. Save the settings.
4.
Set up the Release configuration by repeating step 2 and making the settings specified for
the Release configuration. Save the settings.
Property Pages > General
TABLE 1.9 Property Pages > General settings
Label
Setting
Configuration
Intermediate
directory
..\objd\Acorn
Debug
Output directory
..\objd\Acorn
Debug
Intermediate
directory
..\objr\Acorn
Release
Output directory
..\objr\Acorn
Release
#10075 Porting Guide
Note
41
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Debugging
•
For information only.
Property Pages > C/C++ > General
TABLE 1.10 Property Pages > C/C++ > General settings
42
Label
Setting
Configuration
Detect 64-bit
portability issues
No
Debug + Release
Note
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Label
Setting
Configuration
Treat Warnings as
errors
Yes (/WX)
Debug + Release
Debug
Information
Format
Program Database (/Zi)
Debug + Release
Note
Note that the setting is common
between Debug and Release. You
may also use Program Database for
Edit & Continue (/ZI), however this
will conflict with the Optimizaton
setting, Inline Function Expansion=
“Only __inline”.
Property Pages > C/C++ > Optimization
TABLE 1.11 Property Pages > C/C++ > Optimization settings
Label
Setting
Configuration
Optimization
Disabled (/Od)
Debug
Optimization
Minimize Size (/O1)
Release
Inline Function
Expansion
Only __inline (/Ob1)
Debug + Release
#10075 Porting Guide
Note
43
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > C/C++ > Preprocessor
TABLE 1.12 Property Pages > C/C++ > Preprocessor settings
44
Label
Setting
Configuration
Preprocessor
Definitions
DEBUG;NO_STRICT
Debug
Preprocessor
Definitions
NO_STRICT
Release
Note
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > C/C++ > Code Generation
TABLE 1.13 Property Pages > C/C++ > Code Generation settings
Label
Setting
Configuration
Enable Miminal
Rebuild
No
Debug
Basic Runtime
Checks
Default
Debug
Runtime library
Multi-threaded Debug DLL
(/MDd)
Debug
Enable String
Pooling
Yes (/GF)
Release
Runtime library
Multi-threaded DLL (/MD)
Release
Buffer Security
Check
Yes (/GS)
Release
Enable Functionlevel Linking
Yes (/Gy)
Release
#10075 Porting Guide
Note
45
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Label
Setting
Configuration
Note
Enable C++
Exceptions
No
Debug + Release
The recommendation would be not
to use exception handling unless you
ensure that you do not throw the
exception beyond your plug-in
boundary or you will stop the
application. If you use it, you should
also make sure that you use the /GX
switch (which it would be through
the IDE when you check Enable
exception handling). This /GX
option enables synchronous
exception handling, with the
assumption that extern C functions
never throw an exception.
Property Pages > C/C++ > Language
TABLE 1.14 Property Pages> C/C++ > Language settings
46
Label
Setting
Configuration
Force
Conformance in
For Loop Scope
Yes (/Zc:forScope)
Debug + Release
Treat wchar_t as a
Built-in Type
Yes (/Zc:wchar_t)
Debug+Release
Note
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > C/C++ > Precompiled Headers
TABLE 1.15 Property Pages > C/C++ > Precompiled Headers settings
Label
Setting
Configuration
Create/Use
Precompiled
Header
Use Precompiled Header
(/Yu)
Debug + Release
Create/Use PCH
Through File
VCPluginHeaders.h
Debug + Release
Precompiled
Header File
.\..\objd\Acorn/Acorn.pch
Debug
Relative path from project
Precompiled
Header File
.\..\objr\Acorn/Acorn.pch
Release
Relative path from project.
#10075 Porting Guide
Note
47
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > C/C++ > Output Files
TABLE 1.16 Property Pages > C/C++ > Output Files settings
48
Label
Setting
Configuration
ASM List Location
.\..\objD\Acorn/
Debug
Object File Name
.\..\objD\Acorn/
Debug
Program Database
Filename
.\..\objD\Acorn/
Debug
ASM List Location
.\..\objR\Acorn/
Release
Object File Name
.\..\objR\Acorn/
Release
Program Database
Filename
.\..\objR\Acorn/
Release
Note
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > C/C++ > Browse Information
•
For information only.
Property Pages > C/C++ > Advanced
TABLE 1.17 Property Pages > C/C++ > Advanced settings
Label
Setting
Configuration
ASM List Location
.\..\objD\Acorn/
Debug
Object File Name
.\..\objD\Acorn/
Debug
#10075 Porting Guide
Note
49
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Label
Setting
Configuration
Program Database
Filename
.\..\objD\Acorn/
Debug
ASM List Location
.\..\objR\Acorn/
Release
Object File Name
.\..\objR\Acorn/
Release
Program Database
Filename
.\..\objR\Acorn/
Release
Note
Property Pages > C/C++ > Command Line
TABLE 1.18 Property Pages > C/C++ > Command Line settings
50
Label
Setting
Configuration
Note
Additional
Options
/vmg
@"SDKCPPOptions.rsp"
Debug + Release
The “@” sets up the .rsp file, which
contains the include paths for all of
the API headers. You can add more
.rsp files if you want to add other
include paths for the C++ source
files in your project.
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Linker > General
TABLE 1.19 Property Pages > Linker > General settings
Label
Setting
Configuration
Note
Output File
..\debug\SDK\Acorn.pln
Debug
See the FAQ on How do I get the
application to load my plug-in
binary? for instructions on how to
ensure that wherever your plug-in is
output, the application should
attempt to load it.
Enable
Incremental
Linking
Yes (/INCREMENTAL)
Debug
Suppress Startup
Banner
Yes (/NOLOGO)
Debug + Release
Output File
..\release\SDK\Acorn.pln
Release
Enable
Incremental
Linking
No (/INCREMENTAL:NO)
Release
#10075 Porting Guide
See the FAQ on How do I get the
application to load my plug-in
binary? for instructions on how to
ensure that wherever your plug-in is
output, the application should
attempt to load it.
51
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Linker > Input
TABLE 1.20 Property Pages > Linker > Input settings
52
Label
Setting
Configuration
Additional
Dependencies
..\objD\PMRuntime.lib
..\objD\Public.lib
..\objD\WidgetBin.lib
Debug
Additional
Dependencies
..\objR\PMRuntime.lib
..\objR\Public.lib
..\objR\WidgetBin.lib
Release
Note
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Linker > Debugging
TABLE 1.21 Property Pages > Linker > Debugging settings
Label
Setting
Configuration
Note
Generate Debug
Info
Yes (/DEBUG)
Debug + Release
This is differerent from the
“DEBUG” compiler flag. Turning on
this option for the Release
configuration generates a program
database (.pdf), which allows you to
step through the Release build of
your plug-in. You may decide to turn
this off for the Release configuration.
Generate Program
Database File
..\debug\SDK\Acorn.pdb
Debug
Generate Program
Database File
..\release\SDK\Acorn.pdb
Release
#10075 Porting Guide
53
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Linker > System
•
For information only.
Property Pages > Linker > Optimization
•
54
For information only.
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Linker > Embedded IDL
•
For information only.
Property Pages > Linker > Advanced
TABLE 1.22 Property Pages > Linker > Advanced settings
Label
Setting
Configuration
Import Library
.\..\objD\Acorn/Acorn.lib
Debug
Import Library
.\..\objR\Acorn/Acorn.lib
Release
#10075 Porting Guide
Note
55
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Linker > Command Line
•
For information only.
Property Pages > Resources > General
At this point, you may need to specify the language for the project (or at least you should not
copy English (United Kingdom) but probably accept the default offering at this point).
56
#10075 Porting Guide
Creating a Windows plug-in project from scratch
TABLE 1.23 Property Pages > Resources > General settings
Label
Setting
Configuration
Preprocessor
definitions
DEBUG
Debug
Culture
English (United States)
(0x409)
Debug + Release
Preprocessor
definitions
NDEBUG
Release
Note
Property Pages > Resources > Command Line
•
#10075 Porting Guide
For information only.
57
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Browse Information > General
•
For information only.
Property Pages > Browse Information > Command Line
•
58
For information only.
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Build Events > Pre-Build Event
•
For information only.
Property Pages > Build Events > Pre-Link Event
TABLE 1.24 Property Pages > Build Events > Pre-Link Event settings
Label
Setting
Configuration
Note
Command Line
merge_res.cmd $(IntDir) Acorn
Debug + Release
Add the command shown
#10075 Porting Guide
59
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Build Events > Post-Build Event
TABLE 1.25 Property Pages > Build Events > Post-Build Event settings
Label
Setting
Configuration
Note
Command Line
restore_res.cmd $(IntDir) Acorn
Debug + Release
Add the command shown
Property Pages > Custom Build Step > General
•
60
For information only.
#10075 Porting Guide
Creating a Windows plug-in project from scratch
Property Pages > Web Deployment > General
•
For information only.
Customising file-specific settings
The steps below customise settings for special files in the project. It is important that this step
should be performed after you have set up the overall project settings as described above.
1.
Visit the project settings for the files listed below and customise the project settings for
the Debug and Release configurations. To apply file specific settings, open the Solution
Explorer panel, expand the folders and right-click on the file for which you want the file
you want to customise the settings. Follow the links below to see the settings that must be
applied.
•
VCPluginHeaders.cpp, Configuration Properties > C/C++ > Precompiled headers
•
.rc file, Configuration Properties > Resources > General
•
.fr file, Configuration Properties > Custom Build Step > General
2.
That completes the customisation of project settings for individual files.
3.
Use Visual C++ .NET 2003 to save the project and the solution.
#10075 Porting Guide
61
#10075 Porting Guide
Creating a Windows plug-in project from scratch
VCPluginHeaders.cpp, Configuration Properties > C/C++ > Precompiled headers
TABLE 1.26 VCPluginHeaders.cpp, C/C++ > Precompiled headers settings
62
Label
Setting
Configuration
Create/Use
Precompiled Header
Create Precompiled Header (/Yc)
Debug + Release
Precompiled Header
File
.\..\objD\Acorn/Acorn.pch
Debug
Precompiled Header
File
.\..\objR\Acorn/Acorn.pch
Release
Note
#10075 Porting Guide
Creating a Windows plug-in project from scratch
.rc file, Configuration Properties > Resources > General
TABLE 1.27 .rc file, Configuration Properties > Resources > General settings
Label
Setting
Configuration
Note
Preprocessor
Definitions
(blank)
Debug + Release
The DEBUG definition is
not needed for .rc files, as
there isn’t anything
debug-specific. To clear
this field, click on the “...”
button, and remove either
“DEBUG” or “NDEBUG”
from the Preprocessor
Definitions dialog.
Additional Include
Directories
..\..\..\source\sdksamples\acorn;..\..\..\
source\sdksamples\common;..\..\..\so
urce\precomp\msvc;..\..\..\source\pub
lic\includes
Debug + Release
#10075 Porting Guide
63
#10075 Porting Guide
Creating a Windows plug-in project from scratch
.fr file, Configuration Properties > Custom Build Step > General
TABLE 1.28 .fr file, Configuration Properties > Custom Build Step > General settings
Label
Setting
Configuration
Command Line
odfrc “$(InputPath)” -o
“$(IntDir)\$(InputName).fres” -d
DEBUG -i
..\..\..\source\sdksamples\acorn
@SDKODFRCOptions.rsp
Debug
Command Line
odfrc “$(InputPath)” -o
“$(IntDir)\$(InputName).fres” -i
..\..\..\source\sdksamples\acorn
@SDKODFRCOptions.rsp
Release
Outputs
$(IntDir)\$(InputName).fres
Debug + Release
Additional
Dependencies
$(IntDir)\TriggerResourceDeps.obj
Debug + Release
Note
To see an explanation of
why this information is
significant, see What is
TriggerResourceDeps.cpp
there for?.
Building and testing the debug plug-in on Windows
The steps below build the debug binary of the plug-in and test it runs under the debug build of
InDesign CS.
1.
64
Use Visual C++ .NET 2003 Build/Rebuild All to compile and link the plugin. This should
generate the following output.
#10075 Porting Guide
Creating a Windows plug-in project from scratch
------ Build started: Project: Acorn, Configuration: Debug Win32 -----Performing Custom Build Step
Compiling...
VCPlugInHeaders.cpp
Compiling...
TriggerResourceDeps.cpp
SDKPlugInEntrypoint.cpp
PlugInStatics.cpp
AcornNoStrip.cpp
AcornID.cpp
Generating Code...
Compiling Resources...
Performing Pre-Link Event...
merge_res.cmd - calling ConcatRes
1 file(s) copied.
merge_res.cmd done.
Linking...
Creating library ..\objd\Acorn/Acorn.lib and object ..\objd\Acorn/Acorn.exp
1 file(s) copied.
restore_res.cmd done.
Acorn.pln - 0 error(s), 0 warning(s)
---------------------- Done ---------------------Build: 1 succeeded, 0 failed, 0 skipped
2.
Check that the plug-in binary has been generated,
C:\id3sdk\build\win\debug\SDK\Acorn.pln
3.
Edit a PluginConfig.txt file to refer to the folder from which additional plug-ins should be
loaded (see the FAQ on How do I get the application to load my plug-in binary?). This file
should be located in the application’s data folder which will vary from user to user. For
example for the user fred the file is located in C:\Documents and
Settings\%USERNAME%\Application Data\Adobe\InDesign\Version
3.0\PluginConfig.txt (for Roman versions) or C:\Documents and
Settings\%USERNAME%\Application Data\Adobe\InDesign\Version
3.0J\PluginConfig.txt (for the Japanese version). Example contents are shown
below.
;
; InDesign Plugin Configuration File
#10075 Porting Guide
65
#10075 Porting Guide
Creating a Windows plug-in project from scratch
;
=Path
"C:\id3sdk\build\win\debug\SDK"
=Exclude
4.
Start the debug build of InDesign CS.
5.
Click the Help/Configure Plugins... menu.
6.
The Configure Plug-ins dialog should list the Acorn plug-in as shown below.
7.
That completes build and test of the debug plug-in.
Building and testing the release plug-in on Windows
The steps below build the release binary of the plug-in and test it runs under the release build
of InDesign CS.
66
1.
Use Visual C++ .NET 2003 to rebuild the project’s Release configuration .
2.
Check that the plug-in binary has been generated,
C:\id3sdk\build\win\release\SDK\Acorn.pln
#10075 Porting Guide
Creating a Mac plug-in project from scratch
3.
Edit your PluginConfig.txt file to refer to the folder from which additional plug-ins
should be loaded ("C:\id3sdk\build\win\release\SDK").
4.
Repeat steps as described in the previous section but this time run the release build of
InDesign CS.
5.
That completes build and test of the release plug-in.
Creating a Mac plug-in project from scratch
This section describes the raw manual steps required to set up a new CodeWarrior plug-in
project for the Mac platform. This involves:
•
Configuring CodeWarrior . See the FAQ How do I set up CodeWarrior to access tools
required to build SDK plug-ins? if you have not already done so.
•
Creating a new, empty plug-in project.
•
Configuring the project settings for the debug and release target in the project.
•
Creating source files for the plug-in and adding them to the project.
•
Adding libraries to the project.
•
Building the debug plug-in and testing that it works under the debug application.
•
Building the release plug-in and testing that it works under the release application.
The settings and files presented in this section will create a plug-in called Acorn. The Acorn
plug-in represents the minimal plug-in that can be made. It provides no functionality but has
sufficient code to allow it to be loaded by the application. If you follow the instructions below
you will generate a plug-in that will show up in the application’s Configure Plug-ins dialog.
If you want to create a plug-in with a name of your choice, e.g. MightyOak, you will need to
adapt the instructions accordingly. The following heuristics will help if you want to do this.
•
Where you see the name Acorn use your desired name instead, e.g. MightyOak.
•
Where you see the name acorn use your desired name in lower case instead, e.g.
mightyoak.
•
The convention with SDK plug-ins is to use the capitalised form of the name for the
name of the plug-in project, the plug-in binary and in the plug-in’s user interface. The
lower case form of the name is used for the file system folder where the plug-in’s source
code is kept.
Creating a new, empty project
The steps below create an empty project called Acorn.mcp in the SDK’s folder for CodeWarrior
projects, /mac/id3sdk/build/mac/sdkprj.
1.
#10075 Porting Guide
Start CodeWarrior.
67
#10075 Porting Guide
Creating a Mac plug-in project from scratch
2.
Use File>New... to create a new CodeWarrior project choosing Empty Project as the
project stationary. Name the project Acorn.mcp and locate it in the SDK’s project
folder, e.g. /mac/id3sdk/build/mac/sdkprj.
3.
That completes the creation of the empty project.
Configuring project settings
The steps below configure the project settings for Debug and Release targets. The approach
taken is to fully configure the Debug target then clone the Release target from it and make a
couple of changes.
68
1.
Rename the target named Acorn you will find in the empty project created above by
opening the Target>Target Settings and changing the Target Name to Debug. Save the
settings.
2.
Visit each of the Debug Settings panels in turn and make the settings for the Debug
target. The changes from the settings in the empty project have been tabulated for your
reference in the sections below. Other settings are illustrated by screenshots only and are
not tabulated. Follow the links provided to see the changes you need to make.
#10075 Porting Guide
Creating a Mac plug-in project from scratch
•
Target>Target Settings
•
Target>Access Paths
•
Target>Build Extras
•
Target>Runtime Settings
•
Target>File Mappings
•
Target>Source Trees
•
Target>PPC Target
•
Target>Property List panel
•
Language Settings>C/C++ Language
•
Language Settings>C/C++ Warnings
•
Language Settings>PPCAsm
•
Language Settings>Rez
•
Code Generation>PPC Processor
•
Code Generation>PPC Disassembler
•
Code Generation>Global Optimizations
•
Linker>Mac OS Packager
•
Linker>PPC Linker
•
Editor>Custom Keywords
•
Debugger>Other Executables
•
Debugger>Debugger Settings
•
Debugger>Remote Debugging
3.
Create the initial Release target by cloning the Debug target as follows.
4.
Click on the Targets tab in the Acorn.mcp project window
5.
Use Project>Create Target... to open the New Target dialog.
#10075 Porting Guide
69
#10075 Porting Guide
Creating a Mac plug-in project from scratch
6.
Name the new target Release and clone the existing Debug target. Verify the Targets tab
shows two targets as shown below.
7.
Visit the panels tabulated below and make the changes indicated for the Release target.
TABLE 1.29 Release target changes
70
Panel
Label
Setting
Note
Target>Target
Settings
Output Directory
{Project}../release/SDK
You may have to create
both the release and the
SDK folders under folder
/mac/id3sdk/build/mac if
you jave not built any SDK
plug-ins before.
Target>Access
Paths
User Paths
{Project}../../../source/precomp/codewarri
or/(release)
Change the existing debug
precompiled header folder
{Project}../../../source/prec
omp/codewarrior/(debug)
to the release folder.
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Target>Target Settings
TABLE 1.30 Target Settings settings
Label
Setting
Target
Note
Target Name
Debug
Debug
The empty project created above has
a target called Acorn that should be
renamed Debug by making this
setting and clicking the Save button.
Output Directory
{Project}../debug/SDK
Debug
The Output Directory should be set
relative to the project using the
Choose a Folder dialog. If you have
not built any SDK plug-ins the
output directory
/mac/id3sdk/build/mac/debug/SDK
may not yet exist. Use the Choose a
Folder dialog to create it.
Target Name
Release
Release
Output Directory
{Project}../release/SDK
Release
#10075 Porting Guide
71
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Target>Access Paths
TABLE 1.31 Access Paths settings
72
Label
Setting
Target
Note
Interpret DOS
and Unix Paths
checked
Debug + Release
User Paths
{Project}
Debug
Remove...
User Paths
{Project}../../../source/precomp/codewarrior/(debug)
Debug
Add...
User Paths
{Project}../../../source/precomp/codewarrior/(release)
Release
Change...
User Paths
{Project}../../../source/precomp
Debug + Release
Add...
User Paths
{Project}../../../source/public/interfaces
Debug + Release
Add...
User Paths
{Project}../../../source/public/includes
Debug + Release
Add...
User Paths
{Project}../../../source/public/widgets/includes
Debug + Release
Add...
User Paths
{Project}../../../source/sdksamples/common
Debug + Release
Add...
User Paths
{Project}../../../source/sdksamples/acorn
Debug + Release
Add...
At this point the
folder may not
exist, you should
create it to
ensure that you
can add this
access path.
User Paths
{Project}..
Debug + Release
Add...
System Paths
{Project}../../../external/boost
Debug + Release
Add...
#10075 Porting Guide
Creating a Mac plug-in project from scratch
•
The empty project will contain an unnecessary path called {Project} which should be
removed. Don’t confuse this with the path called {Project}.. which should be
added.
•
Paths should be added relative to the project’s folder i.e. using the Relative to Project
option in CodeWarrior’s Choose Folder dialog.
Target>Build Extras
TABLE 1.32 Build Extras settings
Label
Setting
Target
Use modification data caching
unchecked
Debug + Release
#10075 Porting Guide
Note
73
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Target>Runtime Settings
•
For information only.
Target>File Mappings
•
For information only.
•
Verify you can find a mapping for the additional file types that are compiled by the
ODFRC and RC Includer compilers supplied on the SDK. These are tabulated below.
TABLE 1.33 File Type mappings for SDK supplied compilers
74
File Type
Extension
Compiler
TEXT
.fr
ODF Resource Compiler
Note
#10075 Porting Guide
Creating a Mac plug-in project from scratch
File Type
Extension
Compiler
TEXT
.rc
RC Includer
Note
Target>Source Trees
•
For information only.
Target>PPC Target
The table below lists only the settings that have to be checked to conform to the plug-in
configuration model recommended. All the other settings should be unchecked.
#10075 Porting Guide
75
#10075 Porting Guide
Creating a Mac plug-in project from scratch
TABLE 1.34 PPC Target settings
Label
Setting
Target
Project Type
Shared Library
Debug + Release
File Name
Acorn.pln
Debug + Release
Creator
InDn
Debug + Release
Type
InD3
Debug + Release
Target>Property List panel
•
76
For information only.
Note
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Language Settings>C/C++ Language
TABLE 1.35 C/C++ Language settings
Label
Setting
Target
Force C++ compilation
checked
Debug+Release
ISO C++ Template Parser
checked
Debug+Release
Enable C++ Exceptions
unchecked
Debug+Release
Enable RTTI
unchecked
Debug+Release
Inline Depth
7
Debug+Release
Enums Always Int
checked
Debug+Release
Require Function Prototypes
checked
Debug+Release
Prefix File
PluginPrefix.h
Debug+Release
#10075 Porting Guide
Note
77
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Language Settings>C/C++ Warnings
TABLE 1.36 C/C++ Warnings settings
78
Label
Setting
Target
Illegal Pragmas
checked
Debug+Release
Empty Declarations
checked
Debug+Release
Possible Errors
checked
Debug+Release
Unused Variables
checked
Debug+Release
Extra Commas
checked
Debug+Release
Extended Error Checking
checked
Debug+Release
Hidden Virtual Functions
checked
Debug+Release
Note
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Language Settings>PPCAsm
•
For information only.
Language Settings>Rez
TABLE 1.37 Rez settings
Label
Setting
Target
Prefix File
PluginBuildFlags.h
Debug+Release
#10075 Porting Guide
Note
79
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Code Generation>PPC Processor
TABLE 1.38 PPC Processor settings
80
Label
Setting
Target
Struct Alignment
PowerPC
Debug+Release
Traceback Tables
Inline
Debug+Release
Store Static Vector Data in TOC
unchecked
Debug+Release
Note
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Code Generation>PPC Disassembler
TABLE 1.39 PPC Disassembler settings
Label
Setting
Target
Show Source Code
checked
Debug+Release
Disassemble Exception Tables
unchecked
Debug+Release
Note
Code Generation>Global Optimizations
•
#10075 Porting Guide
For information only.
81
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Linker>Mac OS Packager
•
82
For information only.
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Linker>PPC Linker
TABLE 1.40 PPC Linker settings
Label
Setting
Target
Note
Dead-strip Static Initialization Code
unchecked
Debug+Release
Dead stripping of
IPMUnknown
implementations shoud be
prevented by the plug-in’s
NoStrip.cpp source file. So
this setting could be
checked if desired.
Initialization
InitConnection
Debug+Release
Main
main
Debug+Release
Termination
TerminateConnection
Debug+Release
#10075 Porting Guide
83
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Linker>PPC PEF
TABLE 1.41 PPC PEF settings
84
Label
Setting
Target
Export Symbols
Use #pragma
Debug+Release
Fragment Name
Acorn.pln
Debug+Release
Collapse unused TOC reloads
checked
Debug+Release
Note
Make sure the Fragment
Name in this panel is the
same as the File Name in
the PPC Target panel to
ensure the CodeWarrior
debugger works correctly.
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Editor>Custom Keywords
•
Feel free to vary the syntax colouring to meet your needs and taste.
Debugger>Other Executables
•
#10075 Porting Guide
For information only.
85
#10075 Porting Guide
Creating a Mac plug-in project from scratch
Debugger>Debugger Settings
•
For information only.
Debugger>Remote Debugging
•
For information only.
Creating source files
The steps below create the source files for the plug-in in file system folder
/mac/id3sdk/source/sdksamples/acorn and add these files to the project. All of the source files
must be added to both the Debug and Release targets in the project.
1.
86
Create a file system folder for the plug-in’s code, /mac/id3sdk/source/sdksamples/acorn.
#10075 Porting Guide
Creating a Mac plug-in project from scratch
2.
Use CodeWarrior’s File>Open... to open the project
/mac/id3sdk/build/mac/sdkprj/Acorn.mcp
3.
Use Project>Create Group... to create the groups tabulated below
TABLE 1.42 Source and resource project groups
Project group name
Source
Source/Plugin
Resources
4.
Arrange the groups as shown below.
5.
Add the file below to the project’s Source/Plugin group.
•
6.
/mac/id3sdk/source/sdksamples/common/SDKPlugInEntrypoint.cpp
Create a new file, /mac/id3sdk/source/sdksamples/acorn/AcornNoStrip.cpp, enter the
code below and save the file. Add the file to the project’s Source/Plugin group.
#include "VCPlugInHeaders.h"
#include "InterfaceFactory.h"
extern bool16 gFalse;
/*
References all implementations to stop the linker dead stripping
them from the executable image.
*/
void DontDeadStrip();
void DontDeadStrip()
{
if (gFalse)
{
#include "AcornFactoryList.h"
}
}
7.
Create a new file, /mac/id3sdk/source/sdksamples/acorn/AcornID.cpp, enter the code
below and save the file. Add the file to the project’s Source/Plugin group.
#include "VCPlugInHeaders.h"
#10075 Porting Guide
87
#10075 Porting Guide
Creating a Mac plug-in project from scratch
// General includes:
#include "ShuksanID.h"
#include "IDFactory_cpp.h"
#pragma export on
#include "AcornID.h"
#pragma export off
8.
Create a new file, /mac/id3sdk/source/sdksamples/acorn/AcornID.h, enter the code below
and save the file.
#ifndef __AcornID_h__
#define __AcornID_h__
#include "SDKDef.h"
// Plug-in:
#define kAcornPluginName "Acorn"
#define kAcornPrefixNumber 0x79700 // This number was obtained from Adobe Developer
Support.
#define kAcornPrefix RezLong(kAcornPrefixNumber)
// PluginID:
DECLARE_PMID(kPlugInIDSpace, kAcornPluginID, kAcornPrefix + 0)
#endif // __AcornID_h__
9.
Create a new file, /mac/id3sdk/source/sdksamples/acorn/AcornFactoryList.h, enter the
code below and save the file.
#include "VCPlugInHeaders.h"
/*
Invoke REGISTER_PMINTERFACE for each implementation in the plug-in.
For example to add an IActionComponent implementation add a line
like that below. Note there are no implementations in this plug-in.
*/
//REGISTER_PMINTERFACE(AcornActionComponent, kAcornActionComponentImpl)
10.
Create a new file, /mac/id3sdk/source/sdksamples/acorn/Acorn.fr, enter the code below
and save the file. Add the file to the project’s Resources group.
#include "VCPlugInHeaders.h"
// General includes:
#include "ObjectModelTypes.fh"
#include "ShuksanID.h"
#include "BuildNumber.h"
#include "FeatureSets.h"
// Project includes:
#include "AcornID.h"
#ifdef __ODFRC__
/*
// Plugin version definition.
*/
88
#10075 Porting Guide
Creating a Mac plug-in project from scratch
resource PluginVersion (kSDKDefPluginVersionResourceID)
{
kTargetVersion,
kAcornPluginID,
kSDKDefPlugInMajorVersionNumber, kSDKDefPlugInMinorVersionNumber,
kSDKDefHostMajorVersionNumber, kSDKDefHostMinorVersionNumber,
kSDKDefPersistMajorVersionNumber, kSDKDefPersistMinorVersionNumber,
{ kInDesignProduct, kInCopyProduct },
{ kWildFS },
SDK_DEF_MAKE_VERSIONSTRING(
kSDKDefPlugInMajorVersionNumberForResource,
kSDKDefPlugInMinorVersionNumberForResource,
kSDKDefPlugInStepVersionNumberForResource,
kBuildNumber)
};
/*
// Implementation definition.
*/
resource FactoryList (kSDKDefFactoryListResourceID)
{
kImplementationIDSpace,
{
#include "AcornFactoryList.h"
}
};
#endif // __ODFRC__
11.
#10075 Porting Guide
Verify that the plug-in’s file system folder, /mac/id3sdk/source/sdksamples/acorn,
contains the files below and that their contents have been set up as described by the steps
above.
•
Acorn.fr
•
AcornFactoryList.h
•
AcornID.cpp
•
AcornID.h
•
AcornNoStrip.cpp
89
#10075 Porting Guide
Creating a Mac plug-in project from scratch
12.
Verify the files are arranged as shown below inside the project’s groups.
13.
That completes the creation of source files for the plug-in. Use CodeWarrior to save the
workspace and all the files.
Adding libraries to the project
The steps below add the API’s libraries to the project. Separate libraries are provided for Debug
and Release targets and care must be taken to add the appropriate library to the appropriate
target.
1.
Use CodeWarrior File/OpenWorkspace to open the project
/mac/id3sdk/build/mac/sdkprj/Acorn.mcp
2.
Use Project>Create Group... to create the groups tabulated below
TABLE 1.43 Libraries groups
Project group name
Libraries
Libraries/API
Libraries/API/Debug
Libraries/API/Relese
Libraries/Compiler
Libraries/Compiler/Debug
Libraries/Compiler/Release
Libraries/System
90
#10075 Porting Guide
Creating a Mac plug-in project from scratch
3.
Verify that your groups are organised as shown below.
4.
Use Project>Add Files... to add each library tabulated below to the project. Add them
individually in the order given and take care to add the debug libraries to the debug target
and the release libraries to the release target.
TABLE 1.44 Libraries project folder contents
Library
SDK folder location
Project group
Target
PMRuntimeDbgLib
/mac/id3sdk/build/mac/libd
API/Debug
Debug
PublicPlugInDbg.Lib
/mac/id3sdk/build/mac/libd/libs
API/Debug
Debug
WidgetBinDbgLib
/mac/id3sdk/build/mac/libd
API/Debug
Debug
PublicDbgLib
/mac/id3sdk/build/mac/libd
API/Debug
Debug
PMMSLRuntimeDbg.Lib
/mac/id3sdk/build/mac/libd/libs
Compiler/Debug
Debug
PMGlobalChainDbg.Lib
/mac/id3sdk/build/mac/libd/libs
Compiler/Debug
Debug
PMRuntimeLib
/mac/id3sdk/build/mac/libr
API/Release
Release
PublicPlugIn.Lib
/mac/id3sdk/build/mac/libr/ libs
API/Release
Release
WidgetBinLib
/mac/id3sdk/build/mac/libr
API/Release
Release
PublicLib
/mac/id3sdk/build/mac/libr
API/Release
Release
PMMSLRuntime.Lib
/mac/id3sdk/build/mac/libr/ libs
Compiler/Release
Release
PMGlobalChain.Lib
/mac/id3sdk/build/mac/libr/ libs
Compiler/Release
Release
CarbonLib
CodeWarrior’s StubLibraries folder.
System
Debug +
Release
#10075 Porting Guide
91
#10075 Porting Guide
Creating a Mac plug-in project from scratch
5.
Verify that the files are organised and added to the correct targets as shown below.
6.
That completes the addition of libraries to the project. Use CodeWarrior to save the
project and all the files.
Building and testing the debug plug-in on Mac
The steps below build the debug binary of the plug-in and test it runs under the debug build of
InDesign CS.
1.
Use CodeWarrior Project>Make to compile and link the project’s Debug target.
2.
Check that the plug-in binary has been generated,
/mac/id3sdk/build/mac/debug/SDK/Acorn.pln
3.
Edit a PluginConfig.txt file to refer to the folder from which additional plug-ins should be
loaded. This file should be located in your application’s data folder which will vary from
user to user. For example for the user fred the file should be located in
/Users/${user}/Library/Preferences/Adobe InDesign/Version
3.0/PlugInConfig.txt (for Roman versions) or
/Users/${user}/Library/Preferences/Adobe InDesign/Version
3.0J/PlugInConfig.txt (for the Japanese version). Example contents are shown
below.
;
; InDesign Plugin Configuration File
92
#10075 Porting Guide
Creating a Mac plug-in project from scratch
;
=Path
"mac:id3sdk:build:mac:debug:SDK"
=Exclude
4.
Start the debug build of InDesign CS.
5.
Click the Help>Configure Plugins... menu.
6.
The Configure Plug-ins dialog should list the Acorn plug-in as shown below.
7.
That completes build and test of the debug plug-in.
Building and testing the release plug-in on Mac
The steps below build the release binary of the plug-in and test it runs under the release build
of InDesign CS.
1.
#10075 Porting Guide
Use CodeWarrior Project>Make to compile and link the project’s Release target.
93
#10075 Porting Guide
Converting a Windows plug-in for InDesign CS/InCopy CS project made with Visual C++ 6.0 to Visual C++ .NET 2003
2.
Check that the plug-in binary has been generated,
/mac/id3sdk/build/mac/release/SDK/Acorn.pln
3.
Edit your PluginConfig.txt file to refer to the folder from which additional plug-ins
should be loaded ("mac:id3sdk:build:mac:debug:SDK").
4.
Repeat steps as described in the previous section but this time run the release build of
InDesign CS.
5.
That completes build and test of the release plug-in.
Converting a Windows plug-in for InDesign CS/InCopy CS project
made with Visual C++ 6.0 to Visual C++ .NET 2003
The early prerelease versions of the InDesign CS/InCopy CS Combined SDK required the use
of Visual C++ 6.0 for Windows plug-in development. If you have a plug-in project that you
made with one of those SDKs, this section offers tips on how to migrate your projects.
The easiest way to migrate your project files (.dsp) from Visual C++ 6.0 to Visual C++ .NET
2003 is to open them with Visual C++ .NET 2003 and let the Visual C++ .NET 2003 IDE
generate the new project file format (.vcproj). However, when you do this, there are a few extra
steps you must take after the .vcproj file is generated. The following outlines the steps necessary
to migrate your InDesign/InCopy .dsp project files to .vcproj format.
1.
Go to the menu File > Open Project, choose the “VC++ 6.0 Project files” from the drop
down Files of type. Select the .dsp file you want to convert, and say Yes to the pop up
dialog. This converts the .dsp file to a .vcproj file.
2.
Go to Build > Rebuild to rebuild the project. It will pop up a Save File As dialog to ask you
to save a Solution file (with a .sln extension). Save it at the same location as your .vcproj
file. (You can choose to put it anywhere you want to.) Now compile the project.
3.
You may see an error that looks like the following when compiling a .fr file:
c:\dragontailandsdk\dragontailnew\source\sdksamples\basicdragdrop\BscDND.fr(27) : error
R32: # Error: Could not open include file MenuDef.fh
Here is what you need to do. In Solution Explorer, right-click on the .fr file for your plugin project and choose Properties. Then change the Command Line (in Custom Build Step
> General) setting to move the quotation marks to the right place. For example, change:
odfrc "$(InputPath)" -o "$(IntDir)\$(InputName)".fres -d
DEBUG -i ..\..\..\source\sdksamples\basicdragdrop
@SDKODFRCOptions.rsp
to this:
odfrc "$(InputPath)" -o "$(IntDir)\$(InputName).fres" -d
DEBUG -i ..\..\..\source\sdksamples\basicdragdrop
@SDKODFRCOptions.rsp
94
#10075 Porting Guide
Converting a Windows plug-in for InDesign CS/InCopy CS project made with Visual C++ 6.0 to Visual C++ .NET 2003
Don't forget to update both Debug and Release configurations. (Depending on the
Custom Build Step settings in your original .dsp file, you may not encounter this
problem.)
4.
You may see the following warning when you build the Debug configuration:
LINK : warning LNK4075: ignoring '/EDITANDCONTINUE' due to
'/INCREMENTAL:NO' specification
This seems to be a conversion problem, for in our old .dsp files, we indeed set
/INCREMENTAL:YES for all projects. In the .vcproj file (for DollyXs, etc.), this
corresponds to:
LinkIncremental="2"
To fix this, go to Project > Properties and change Linker > General > Enable Incremental
Linking to Yes (/INCREMENTAL) for the Debug configuration only. (For the Release
configuration, this is not a problem.)
5.
Sometimes, if a plug-in includes SDKInfoButton.ico, you will see the following in the
Output window during compiling (not a warning):
c:\sdk\source\sdksamples\customprefs\CstPrf.rc(29): Could
not find the file
c:\sdk\source\sdksamples\customprefs\SDKInfoButton.ico.
Performing Custom Build Step
Somehow during the conversion, Visual C++ .NET 2003 thinks the SDKInfoButton.ico is
in the current project folder, which is not the case. Change the path to point to common
folder by removing the old icon and add the new one from the common folder.
6.
We have seen the following linker warning in the Release configuration after building a
converted .dsp file:
LINK : warning LNK4089: all references to 'MSVCP71.dll'
discarded by /OPT:REF
If you see this benign linker warning, switch to the Release configuration, then go to
Project > Properties > Linker > Command Line. In the Additional Options text box,
enter /IGNORE:4089. This will quiet the warning.
7.
You may see a problem where the Visual C++ .NET 2003 IDE wants to have write access
to the .vcproj file when building. This could be an issue for you if you have a source
control system. To remedy this problem, open the project in the IDE, and save the .vcproj
file when you close it right afterwards. You can verify the fix by opening the .vcproj file
with a text editor. Look towards the top of the .vcproj file for the line starting with
'ProjectGUID'. If you see that line, this problem should go away.
8.
Other project setting changes:
•
#10075 Porting Guide
In Project > Properies > C/C++ > General, choose "Program Database (/Zi)" for
"Debug Information Format" in both Debug and Release configurations. In the
.vcproj file, this corresponds to DebugInformationFormat="3".)
95
#10075 Porting Guide
Getting started with DollyXs
•
In Project > Properies > C/C++ > Optimization, choose "Only__inline (/Ob1)" for
"Inline Function Expansion" in the Debug configuration. The old setting is
"Default". (In the .vcproj file, this corresponds to
InlineFunctionExpansion="1".) If you chose the “Program Database for
Edit & Continue (/ZI)” in the previous setting, this Optimization setting is
incompatible. You will need to choose a different Optimization setting.
•
In Project > Properies > C/C++ > Language, choose "Yes (/Zc:forScope)" for "Force
Conformance In For Loop" in both Debug and Release configurations. The old
setting is "No". (In the .vcproj file, this corresponds to
ForceConformanceInForLoopScope="TRUE".)
•
In Project > Properies > C/C++ > Language, choose "Yes(/Zc:wchar_t)" for "Treat
wchar_t as Built-In Type" in both Debug and Release configurations. The old
setting is "No". (In the .vcproj file, this corresponds to
TreatWchar_tAsBuiltInType="TRUE".)
Getting started with DollyXs
DollyXs is a Java program for generating plug-in code. It is capable of generating code for an
InDesign CS/InCopy CS plug-in, including a .vcproj file for Windows projects, and an
mcp.xml file that can be imported into CodeWarrior. Note that the description following
assumes that you have installed the SDK on Windows into c:\id3sdk, or on Macintosh into the
folder /mac/id3sdk. Adapt the directions as required if you have installed to other locations.
The Java-based Dolly code generator was shipped with the InDesign 2 SDK; this supported a
limited conditional logic. It was costly to maintain the template codebase; the standard Adobe
header, for instance, was replicated several hundred times throughout the template codebase.
DollyXs eliminates this, since there is only one copy of the standard header per locale.
DollyXs tries to maintain the ease of use for a developer, whilst keeping the amount of
boilerplate in the template codebase to a minimum. This is particularly useful in a pre-release
cycle, when changes would have been required across potentially dozens or hundreds of files in
the old Dolly template codebase. Another shortcoming of the original version of Dolly was the
relative inflexibility of templates. To create a template that had a new feature, it was necessary
to clone an existing template and start all over again.
DollyXs provides a more flexible approach to code generation; for instance, rather than having
a single template for generating a Dialog-based plug-in, and another template for generating a
plug-in that is Panel-based, DollyXs enables a menu-based plug-in to be generated, which has
the choice of features such as a dialog and/or a panel being added. Below is shown the user
interface from DollyXs. The main point to note is that it expects to generate both Windows and
96
#10075 Porting Guide
Getting started with DollyXs
Macintosh projects at the same time on one platform, and also needs to have an output folder
set up for the bulk of the generated code.
Prerequisites
DollyXs needs no additional software to be installed on Macintosh OS 10.2.x, which comes
with a Java 2 run-time environment already installed.
On Windows, you need to obtain a Java run-time environment at version 1.3 or later if you do
not already have one installed (see FAQ for details of finding out if one is installed, and where
to download if required).
Running DollyXs
You can run DollyXs by supplying an XML-based code specification file. The components that
you intend to generate in your plug-in, along with parameters like long/short name, output
paths, menu items and so on should be specified in this file.
To run DollyXs on Macintosh OS 10.2.x, you should bring up a Terminal window (see the FAQ
in this document), navigate to the folder /mac/id3sdk/devtools/sdktools/dollyxs and enter the
command line as shown below:
sh dollyxsgui.sh
On Windows, you can simply navigate to the folder c:\id3sdk\devtools\sdktools\dollyxs and
double click on the file dollyxsgui.
#10075 Porting Guide
97
#10075 Porting Guide
Getting started with SnowGoose
Advanced: Running DollyXs with custom options
This section is recommended only if you are familiar and comfortable with running Java
applications from the command line, and have some understanding of XSLT. DollyXs works by
updating XML document just after the “Generate ... code” button is pressed. This document is
named inputmac.xml or inputwin.xml, and you can modify this to your taste. It is
recommended that you configure this through the GUI, as you can use the file/folder selection
widgets to enter the correct locations for output folders. However once you have inputmac.xml
or inputwin.xml correctly configured for your local system, you can then proceed to edit these
files and run DollyXs from the command line. This would let you perform manipulations such
as generating an arbitrary number of menu items; at present the GUI only lets you add one
menu item, but this is a limitation of the GUI, not the underlying program. You can also edit
down the input<platform>xml file to contain only one or two elements, to generate only one
or two source files, rather than generating an entire project.
As you can see in the screen shot above, DollyXs has check boxes only for “Add Panel” and
“Add Dialog”. However, DollyXs has other options you can choose from. In the dollyxs/xs
folder, you will find many .xsl files (eXtensible Stylesheet Language). Among these files are files
like command.xsl. In such files, you can find notations that are not represented on the GUI,
such as <xsl:value-of select="/code/@class-name"/>, which can be specified in the
inputmac.xml (Macintosh) or inputwin.xml (Windows) files in the <code> tag. Also, the
DollyXs templates are highly extensible; you can create your own .xsl files, and within them,
you can even use conditional statements, such as <xsl:if test="/code/generate-command">.
(For more details, refer to the Appendix Parameters for DollyXs.)
These customized options can be utilized by editing the input XML file manually, and running
DollyXs from the command line. If you do this frequently it is worth placing these command
lines in a .BAT or .sh file for Windows/Mac respectively.
To run DollyXs on Macintosh OS 10.2.x from the command line, you should bring up a
Terminal window (see the FAQ in this document), navigate to the folder
/mac/id3sdk/devtools/sdktools/dollyxs and enter the command line exactly as shown below:
java -classpath
../gplib/sgguimac.jar:../gplib/saxon.jar:../gplib/xercesImpl.jar:../gplib/xm
l-apis.jar com.adobe.devtech.mrjdepend.dollyxs.DollyXsMacintoshCore
inputmac.xml
On Windows, open a Command Prompt window, navigate to the folder
c:\id3sdk\devtools\sdktools\dollyxs using the cd command, and enter the command line as
shown below:
java -classpath
../gplib/sgguiwin.jar;../gplib/saxon.jar;../gplib/xercesImpl.jar;../gplib/xm
l-apis.jar com.adobe.devtech.dollyxs.DollyXsCore inputwin.xml
Getting started with SnowGoose
SnowGoose is a Java program for migrating projects from the 2.0 SDK organisation to work
within the current organisation. The description below assumes that you have installed the
98
#10075 Porting Guide
Getting started with SnowGoose
SDK on Windows into c:\id3sdk, or on Macintosh into the folder /mac/id3sdk. Adapt the
directions as required if you have installed to other locations.
This tool is provided as a porting utility that could be of benefit to third party developers if
their plug-in matches the model of the 2.0 SDK plug-ins; if it does not, then you should use
DollyXs to generate the boilerplate for the plug-in, which will give you a skeleton project to
which you can add your own files.
SnowGoose was used internally to convert all the SDK plug-in projects for Macintosh and
Windows to conform to the current SDK organisation. It is written in Java.
Prerequisites
SnowGoose needs no additional software to be installed on Macintosh OS 10.2.x, which comes
with a Java 2 run-time environment already installed.
On Windows, you need to obtain a Java run-time environment at version 1.3 or later if you do
not already have one installed (see FAQ for details of finding out if one is installed, and where
to download if required).
Running SnowGoose
The SnowGoose program assumes that the project matches the 2.0 organisation and has been
used to migrate projects for all the plug-ins on this SDK on both Macintosh and Windows,
starting out with their 2.0 equivalent.
The user interface for SnowGoose is shown below. Note that you should convert the Macintosh
project on a Macintosh platform, and the Windows project on the Windows platform. This is a
little different to DollyXs, which generates both Macintosh and Windows projects on either
platform.
To run SnowGoose on Macintosh OS 10.2.x, follow these steps.
#10075 Porting Guide
99
#10075 Porting Guide
Getting started with SnowGoose
1.
First, you must export your existing 2.0 .mcp project file to a .mcp.xml file.
2.
You should then bring up a Terminal window (see the FAQ in this document) and
navigate to the folder /mac/id3sdk/devtools/sdktools/snowgoose
3.
Enter the command line as shown below, which will bring up the GUI:
sh snowgoosegui.sh
4.
Specify the Macintosh Project path (where your 2.0 .mcp.xml file is located), the Output
folder (the folder where you want the new .mcp.xml project to be generated), the Long
plug-in name, and the Short plug-in name. Then click Convert Project.
5.
The exported .mcp.xml file you created in the first step should be chosen through the user
interface of SnowGoose, which also allows other parameters relevant to the conversion to
be entered such as the output folder for the conversion. If the plug-in converting was not
based on the 2.x SDK model (with a distinct long-name for the plug-in and short-name
prefix for the plug-in source files), then you may have only limited success.
6.
If SnowGoose is successful, it should provide you with a confirmatory dialog. Look in the
output folder for a file called something like:
<longpluginname>SNOWGOOSEOUT.mcp.xml
You can then import this project into CodeWarrior to convert it to a .mcp file. Save the
.mcp in the same folder as the newly generated .mcp.xml file, so all of the source file paths
would be correct.
To run SnowGoose on Windows, follow these steps.
1.
Navigate to the folder c:\id3sdk\devtools\sdktools\snowgoose using Explorer, and
double-click on the batch file named snowgoosegui.bat. This will bring up the
GUI.
2.
Specify the Windows Project path (where your 2.0 .dsp file is located), the Output folder
(the folder where you want the new .vcproj project to be generated), the Long plug-in
name, and the Short plug-in name. Then click Convert Project.
3.
If SnowGoose is successful, you should see the generated project file provide you with a
confirmatory dialog. Look in the output folder for a file called something like:
<longpluginname>.vcproj
You can then open this project in Visual C++ .NET 2003.
Features and limitations of SnowGoose
Note that deprecated files such as SDKUtilities.cpp will be stripped out on the conversion. This
was a deliberate policy during the SDK porting process to minimise dependency on code that
was deprecated. SnowGoose parses the old project file (.dsp) on Windows, extracts the source
groups and injects this source tree into a new project file (.vcproj).
If your project does not conform neatly to the 2.0 SDK organisation, then you may find that
the source files have not been correctly represented in the output project, as SnowGoose was
only intended to assist in converting 2.0 SDK projects and has only been tested on converting
100
#10075 Porting Guide
Troubleshooting
these project types. You will also find that the library input path is the standard set of libraries
for SDK plug-ins and if you have included libraries outwith the default set that these are not
represented in the output. If your project falls into this category, please refer to the sections
Converting a 2.0 Mac plug-in project or Converting a 2.0 Windows plug-in project for more
details on how to set your project settings.
Troubleshooting
The table below lists some compile-related issues that were encountered when migrating some
of the SDK plug-ins from the InDesign/InCopy 2.0 SDKs to the InDesign CS/InCopy CS
codebase. In some cases the associated compiler error from Visual C++ .NET 2003 has been
included; for instance, Win C2039.
TABLE 1.45 List of issues encountered when converting the SDK sample plug-ins
Issue
Cause
Resolution
Windows:
Performing Custom
Build Step on
..\..\..\source\sdksample
s\basicmenu\BscMnu.fr
'odfrc' is not recognized
as an internal or
external command,
operable program or
batch file.
Your IDE has not been set up to
access the ODFRC compiler.
Windows:
See the FAQ How do I set up Visual C++ .NET 2003
to access tools required to build SDK plug-ins?
Mac:
See the FAQ How do I set up CodeWarrior to access
tools required to build SDK plug-ins?
Macintosh:
Couldn't find compiler
"ODFRC"
(Win R32761) Error:
Expected '{'
Plug-ins need to specify the
products that they are targeting.
Add {kInDesignProduct} before {kWildFS} for
InDesign CS only, {kInCopyProduct} for InCopy
only, or {kInDesignProduct, kInCopyProduct} for
both. See the FAQ How has the PluginVersion
resource changed?.
(Win R32725)
Compiler errors related
to auto-register
implementation IDs
Auto-register boss classes are no
longer required in your plug-in
Comment out any boss classes that use
kAuto<whatever>RegisterImpl. See the FAQ
entitled How do I update the
k<whatever>RegisterBoss classes in my plug-in?
undefined identifier
'make_functor_void'
API has been simplified.
Functor.tpp does not define
make_functor_void anymore.
Use make_functor for both functions that return a
type or void. Affects code that implements
selection suites.
#10075 Porting Guide
101
#10075 Porting Guide
Troubleshooting
Issue
Cause
Resolution
(Win RC1015) cannot
open include file
'SDKDef.h'.
SDKDef has moved into
sdksamples/common folder.
Check your project settings for your .rc file and
make sure you have an include path for
..\..\..\source\sdksamples\common. Please see the
section on converting a Windows project or setting
up a Windows project from scratch for guidance.
(Win C2039)
'DeleteCmd' : is not a
member of
'ITextModel'
Text model command generation
methods have been factored out
of ITextModel into a new
interface ITextModelCmds.
Use ITextModelCmds methods instead. This
interface is on kTextStoryBoss along with
ITextModel.
Error compiling plugins that use
ADBEIconSuiteButton
Widget
ADBEIconSuiteButtonWidget is
gone.
Use RollOverIconButtonWidget instead. Note that
this RollOverIconButtonWidget needs an extra
kADBEIconSuiteButtonType at the end of the
resource definition. If you forget to add that field
then Mac ODFRC compiler will crash silently when
you do the project build, it will not give you any
compiler error warning or anything, it simply crash
when it compiles the .fr file. Make sure you append
this constant to the end. See BasicDialog and others
in alpha SDK for examples of using this widget
type.
Code that uses
ISelection/ISelectUtils
These interfaces are going away.
Move to the new selection architecture. See FAQ
Should I keep using ISelection and ISelectUtils
interfaces?
(Win C2039) Error
compiling code using
IParcelList
The
IParcelList::QueryNthFrame()
method is gone and so are the
parcel index based methods.
We are adopting the concept of ParcelKey, you use
it to gain access to things like associated
ITextFrame on the parcel list. The following is the
new way of getting a list of ITextFrame given a
selected text range:
1.
Get the index (TextIndex) of first and last
characters of the selected text,
2.
Use ITextModel::QueryTextParcelList to get
the associated ITextParcelList, then use
ITextParcelList to get to IParcelList.
3.
Use IParcelList::GetParcelContaining() to get
to the ParcelKey that contains the first
character. Do the same for the last character.
Then use the IParcelList iterator to go through all
parcels between the start and end parcel, call
IParcelList::QueryParcelFrame to get to the text
frame.
See TinMutSuiteTextCSB::GetItemList for actual
code for above steps
102
#10075 Porting Guide
Frequently asked questions
Issue
Cause
Resolution
(Win C2039) Error
compiling code using
ITableTextSelection
ITableTextSelection::GetTableMo
del is gone
Change to ITableTarget::GetModel.
Selection suite code
fails to compile that
uses
kIntegratorISuiteBoss,
etc.
The boss class hierarchy has been
simplified.
Change kIntegratorISuiteBoss =>
kIntegratorSuiteBoss , kTextISuiteBoss =>
kTextSuiteBoss , kLayoutISuiteBoss =>
kLayoutSuiteBoss etc. See FAQ Suite boss classes
and selection targets.
<whatever>DialogCont
roller.cpp fails to
compile
CDialogController protocol has
changed
See the FAQ How can I fix my dialog-controller code
that doesn’t compile?
Code for menu items
enabled on layout or
text selection fails to
compile
IID_NEED_LAYOUTSELECTIO
N is going away and
IID_NEED_TEXTSELECTION
will be going too.
See the FAQ How do I remove dependency on
IID_NEED_<whatever>SELECTION?
Error on starting up in
debug build: “Plug-in
has no load method”
SDKPluginEntrypoint.cpp is
missing from your plug-in
Locate the file in source/sdksamples/common and
add.
LineWtMeasureCombo
BoxWidget, asserts
when starting up
You don't need to fill in those strings for items
anymore, it will be filled automatically, since the
application knows what line-weights are valid to
apply.
(Mac only)
Can’t debug the plug-in
on OS 10.x
Make sure that the fragment name for the project is
exactly the same as the output filename (i.e. the
filename in PPC Target pane needs to match the
fragment name in PPC PEF pane), or you will have
hard time to debug under OS 10.x. See sections
Converting a 2.0 Mac plug-in project and Creating a
Mac plug-in project from scratch for guidance.
Frequently asked questions
Before reading this section, you should check the Troubleshooting section to see if you can find
a resolution for the problem there.
How do I set up Visual C++ .NET 2003 to access tools required to build SDK plug-ins?
The steps below configure Visual C++ .NET 2003 to be able to access tools required to build
SDK plug-ins. Compilers such as ODFRC.exe and other build tools are kept in folder
C:\id3sdk\devtools\bin.
#10075 Porting Guide
103
#10075 Porting Guide
Frequently asked questions
1.
Start Visual C++ .NET 2003.
2.
Open the Tools > Options dialog, and select the Projects > VC++ Directories property.
3.
Add path: C:\id3sdk\devtools\bin.
4.
That completes the configuration of Visual C++ .NET 2003 to be able to access SDK
build tools.
How do I set up CodeWarrior to access tools required to build SDK plug-ins?
The steps below configure CodeWarrior to be able to access tools required to build SDK plugins.
1.
Quit CodeWarrior if you have it running
2.
Copy the compilers listed below from the SDK into your CodeWarrior compiler plug-in’s
folder.
TABLE 1.46 SDK supplied compilers
104
Compiler
Source SDK folder path
Target folder path
ODFRC
/mac/id3sdk/devtools/bin
/Applications/CodeWarrior 8.3/Metrowerks
CodeWarrior/CodeWarrior Plugins/Compilers
RC Includer
/mac/id3sdk/rcincluder
/Applications/CodeWarrior 8.3/Metrowerks
CodeWarrior/CodeWarrior Plugins/Compilers
3.
The path will vary depending on where you have CodeWarrior installed. For further
information on ODFRC and RC Includer see Plug-in development environment.
4.
That completes the configuration of CodeWarrior to be able to access SDK build tools.
#10075 Porting Guide
Frequently asked questions
Where do I begin porting my plug-in to the current SDK?
You should consult the section entitled Before you begin for a roadmap.
Where can I see an overview of the API changes between 2.0 and InDesign CS/InCopy CS?
You should consult the excellent document produced by the tool APIAdvisor at
<sdk>/docs/references/APIAdvisorID2_vs_ID3.html. This provides a concise statement of the
API changes; it represents a very convenient visualisation of the differences in interfaces and
methods between InDesign/InCopy versions 2.x and InDesign CS/InCopy CS. The rationale
for the changes and semantics of the more significant changes we’ve tried to document in the
Troubleshooting section and this section.
Where are the API headers in the current SDK?
These can now be found in <sdk>/source/public (for instance, the folder interfaces and
includes are there). One small change is that the old 2.0 folder WidgetIncludes is replaced by
widget/includes. Note that the old folder API has been renamed to public to coincide with the
application codebase naming to minimise the disparity between application and SDK plug-ins.
Please refer to Schematic view of the SDK and Overview of changes in SDK format for more
information.
Where are the API libraries in the current SDK?
You should consult sections Schematic view of the SDK and Overview of changes in SDK format.
For information on how to use them in your projects see Property Pages > Linker > Embedded
IDL for Windows and Adding libraries to the project for Mac.
Where's the sample code in the current SDK?
This can be found in <sdk>/source/sdksamples. The projects can be found in
<sdk>/build/win/sdkprj for Windows, and <sdk>/build/mac/sdkprj for Macintosh. Please
refer to Schematic view of the SDK and Overview of changes in SDK format for more
information.
Where's the documentation in the current SDK?
You should see the folder <sdk>/docs/guides for tech-notes and <sdk>/docs/references for API
documentation. There are two formats, CHM (Compiled Help Module) for Window, and a
gzip’d TAR archive for Mac OS 10.x. You can unzip the tar.gz file by executing tar xzf
sdkdocs.tar.gz from a terminal window. Please refer to Schematic view of the SDK and Overview
of changes in SDK format for more information.
#10075 Porting Guide
105
#10075 Porting Guide
Frequently asked questions
Where is InDesign CS/InCopy CS preference files folder on Windows now?
The location of preferences for InDesign CS and InCopy CS was moved. The old preference
location is:
C:\Documents and Settings\%USERNAME%\Local Settings\Application Data\Adobe\...
The new preference location is now at:
C:\Documents and Settings\%USERNAME%\Application Data\Adobe\...
How can I make an object model dump to see boss class information?
The HTML based documentation (index.chm for Windows) provides a representation of the
object model which should become increasingly accurate through through the beta cycle. If for
instance, you wanted to find text attribute boss classes, you could search in the index.chm file
for IID_IATTRREPORT, and find the boss classes that aggregate this interface in the hit-list.
Alternatively, visit the page on IAttrReport and see the boss classes that aggregate this interface
at the foot. You can also create your own based on the dynamic object model using the
Diagnostics plug-in; see the tech-note in <sdk>/docs/guides which details how to do this.
How do I get the application to load my plug-in binary?
The recommended approach is to create a PluginConfig.txt file that refers to a folder you want
the application to examine for plug-ins when it starts up. Please refer to section Building and
testing the debug plug-in on Windows for instructions on how set this up on Windows or section
Building and testing the debug plug-in on Mac for Mac. An alternative is to copy your plug-in
binary into the application’s plug-ins folder.
What is TriggerResourceDeps.cpp there for?
Recall when setting up the Windows projects from scratch, we make the .fr file dependent on
TriggerResourceDeps.obj. If you want to understand why we make these settings the
information given here should help. Visual C++ .NET 2003 lets you specify custom build rules,
which is how we use ODFRC to build our core resources. But we have to do the pre-link step
and the post-build step to avoid clobbering the regular resources, since Visual C++ .NET 2003
isn't smart enough to know that we're building a resource to be combined with the platform .rc
resource. The TriggerResourceDeps file is used for dependency tracking. Since it is a .cpp file
Visual C++ .NET 2003 knows how to manage dependencies for it(Visual C++ .NET 2003 tries
for a .cpp file but it won't try for a .fr file) so we make the TriggerResourceDeps.cpp file
#include the plug-in’s .fr file, and then make the dependency for this .fr file on the object file
TriggerResourceDeps.obj. Hence if the .fr file is changed the TriggerResourceDeps.cpp file will
rebuild and the plug-in will relink with the updated resources. Also if a header used by the .fr is
changed, TriggerResourceDeps.cpp file will rebuild causing the .fr file to rebuild. This gets
broken if the #ifdef __ODFRC__ comes before #includes in .fr file though since those headers
aren't seen by the TriggerResourceDeps.cpp file (which is doing the dependencies for us.)
106
#10075 Porting Guide
Frequently asked questions
•
You might want to examine the files and project settings you made that allow the project
to build its ODFRC resources..
•
Verify that the Pre-link tab set up earlier contains the requisite merge_res.cmd
•
Verify that the Post-build tab set up earlier contains the requisite restore_res.cmd
•
Verify all the .fr files in the plug-in are included by the Acorn.fr file.
•
Verify the #ifdef __ODFRC__ directive in the .fr file occurs after the header files
#includes.
How has the PluginVersion resource changed?
There is a new field that specifies the products you are targeting. You need to add something
like:
{ kInDesignProduct, kInCopyProduct },
to the PluginVersion, just before {kWildFS}.
There is also a new field that specifies a version string for the Adobe Update Manager. This
string will show up as the version string on the About Plug-ins dialog for your plug-in. You can
specify any string you want, however, for convenience, the SDK includes a macro to create a
string out of 4 numbers:
SDK_DEF_MAKE_VERSIONSTRING(kSDKDefPlugInMajorVersionNumberForResource,
kSDKDefPlugInMinorVersionNumberForResource,
kSDKDefPlugInStepVersionNumberForResource,
kBuildNumber)
If you try to compile a plug-in with the old format for the ODFRez PluginVersion resource,
you will see an error message similar to that below:
Performing Custom Build Step on
..\..\..\source\sdksamples\basicmenu\BscMnu.fr
..\..\..\source\sdksamples\basicmenu\BscMnu.fr(55) :
error R32761: # Error: Expected '{'.
# Fatal error:
odfrc - Execution terminated!
You need to update the ODFRez type PluginVersion (see objectmodeltypes.fh) in the
<plugin>.fr file to indicate product IDs your plug-in targets. For example a plug-in that targets
both InDesign CS and InCopy CS would have a statement like this:
resource PluginVersion (kSDKDefPluginVersionResourceID)
{
kTargetVersion,
kTblBscPluginID,
kSDKDefPlugInMajorVersionNumber, kSDKDefPlugInMinorVersionNumber,
kSDKDefHostMajorVersionNumber, kSDKDefHostMinorVersionNumber,
kSDKDefPersistMajorVersionNumber, kSDKDefPersistMinorVersionNumber,
{ kInDesignProduct, kInCopyProduct },
{ kWildFS },
SDK_DEF_MAKE_VERSIONSTRING(kSDKDefPlugInMajorVersionNumberForResource,
kSDKDefPlugInMinorVersionNumberForResource,
#10075 Porting Guide
107
#10075 Porting Guide
Frequently asked questions
kSDKDefPlugInStepVersionNumberForResource,
kBuildNumber)
};
How do I update the k<whatever>RegisterBoss classes in my plug-in?
2.0 required plugins to have register bosses for strings, menus, actions, panels, tips, etc. Most of
these bosses used a standard implementation (usually named kAuto<whatever>RegisterImpl)
which read the info from a resource. These boss classes are no longer needed, so you can just
delete the boss class definitions from your top-level .fr file, and the Boss ClassID from your
ID.h file.
How can I get custom objects and attribues to the InDesign Interchange Format?
InDesign CS has an InDesign Interchange Format feature to export an InDesign CS document
in a format that can be imported into InDesign 2.x for the purposes of backward conversion.
The feature uses the object model that scripting exposes, the only objects and properties it sees
are the ones exposed to scripting. So in order for custom objects and attributes to be included
in the exported XML stream they must be scriptable.
How do I know if I have a Java Run-Time on Windows, and what version?
You need a Java run-time for the helper tools like DollyXs and SnowGoose on Windows only,
since it is pre-installed on Macintosh OS 10.2.x. Bring up a DOS prompt and type the
following:
java -version
If there is no output (other than “java is not recognised...”) then you do not have a correctly
installed Windows Java run-time. When run on a computer with a recent Java run-time
environment (JRE), the above command produces the following output:
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)
How do I obtain a Java run-time for Windows?
If you have verified that you require a Java run-time environment on your Windows machine
to run the helper tools like DollyXs and SnowGoose, you should install a Java run-time
environment. The most recent version at the time of writing is 1.4.1.
This should be an executable file named something like j2re-1_4_1_01-windows-i586.exe; note
that you only require the version with JRE in the name and not a full SDK unless you intend to
develop your own Java applications. You can obtain a Java run-time environment for Windows
by visiting the Sun Web-site. See Java Standard Edition downloads at the URL
http://java.sun.com/j2se/1.4/index.html.
108
#10075 Porting Guide
Porting recipes
How do I bring up a Terminal window on Macintosh OS 10.2.x?
You need this for helper tools such as DollyXs and SnowGoose. If you inspect the folder
/Applications/Utilities, you should see a program named ‘Terminal’. Once you invoke this then
you have a Unix-type terminal window through which you can enter commands.
What are .rsp files for? (@ option in Windows project files)
The @ compiler option is termed “Specify Response File” in the compiler documentation for
Visual C++ .NET 2003. The @ option lets you specify a file that contains compiler options and
source code files to compile. These compiler options and source code files will be processed by
the compiler just as if they had been specified on the command line.
It provides a good place to persist complicated include paths, such as the pattern of includes for
the .cpp files or the .fr files, and avoids having to repeat these shared settings across multiple
projects.See SDKCPPOptions.rsp and SDKODFRCOptions.rsp in the folder
<SDK>/build/win/sdkprj.
What is DebugWindow, and how do I use it?
DebugWindow, a Mac OS X application, is a tool you can use to view TRACE and
TRACEFLOW statements from your plug-in code running in InDesign CS/InCopy CS Debug
builds on the Macintosh OS X platform. To use it, simply launch the application, which resides
in the <SDK>/devtools/debugwin folder, before starting the InDesign CS or InCopy CS Debug
build. You then need to enable the debug output so that TRACE/TRACEFLOW statements are
displayed. To do that, select the Test > TRACE > Echo to Debug Window menu item under the
debug build, and then enable the desired TRACEFLOW category, listed under Echo to Debug
Window. (On the Windows platform, you canoutput TRACE messages to the Notepad applet,
a console window, or the Visual Studio .NET debug window.)
Porting recipes
This section listed some of the API changes from InDesign/InCopy 2.0 to InDesign CS/InCopy
CS. You would need to make changes accordingly in your code.
How can I fix my dialog-controller code that doesn’t compile?
CDialogController class has been changed to provide IActiveContext access during
initialization, validation, and application. Basically, all the 2.0 based methods that were used to
use to initialize and apply the widget are disabled; this was because use of these methods led to
many bugs that were hard to track down- if these methods had been deprecated but still
available, it would have left the door open for bugs to this type to continue being generated by
developers. Instead, you should use xxxDialogFields() methods to do the usual things. See
#10075 Porting Guide
109
#10075 Porting Guide
Porting recipes
BasicDialog for a more complete example and see its design document for more detail on why
this change was made.
Warning : 'BPIDlgController::ApplyFields(const IDType<WidgetID_tag> &)'
hides inherited virtual function
'CDialogController::ApplyFields(const IDType<WidgetID_tag> &) const'
BPIDlgController.cpp line 57
};
Warning : 'BPIDlgController::InitializeFields()'
hides inherited virtual function
'CDialogController::InitializeFields() const'
BPIDlgController.cpp line 57
};
Error
: illegal access from 'CDialogController' to protected/private member
'CDialogController::InitializeFields() const'
BPIDlgController.cpp line 77
CDialogController::InitializeFields();
Note that each of these functions (InitializeDialogFields,
ValidateDialogFields, ApplyDialogFields, and ResetDialogFields) is
passed an IActiveContext parameter. This context provides access to the document, workspace,
view, and selection that your dialog should be inspecting or acting upon. You should use this
context parameter rather than seek these resources globally. For example, rather than call
GetFrontDocument() or QueryActiveSelection(), use context>GetContextDocument() or context->GetContextSelection().
How do I use the new ColorDropDownListWidget?
The UI Color Drop Down list has been replaced by the ColorListDropDownWidget. While you
can still use the original drop down an color picker combination it is recommended that you
switch to the new widget because there are many advantages over the old widget pair. It was
relatively cumbersome to use the old UIColorDropDownListWidget and wasn’t documented
how to use this. Below is shown an example of the new ColorDropDownListWidget (its
ODFRez type-name) that can be seen on the Layer Options dialog.
110
#10075 Porting Guide
Porting recipes
1.
It displays a color swatch along with the color name
2.
It doesn't require a group of widgets
3.
It doesn't require as much client code to get and set colors
4.
It works with UI colors and InDesign CS swatches
5.
You can still link the drop down to a swatch (to display more color than the drop down
allows)
6.
You must change three general areas in order to switch to the new widget.
Defining ODFRez data statements for the widgets
To use the obsoleted UIColorDropDownListWidget for InDesign 2.0, it used to be necessary to
define two widgets in a group like this:
... // This was how it was done in InDesign 2.0
GenericPanelWidget
(
kHyperlinksGenericWidgetId,
// WidgetId
kPMRsrcID_None,
// RsrcId
kBindNone,
// Frame binding
Frame(150,65,285,88)
// Frame
kTrue,
// Visible
kTrue,
// Enabled
"",
// Panel name
{
UIColorDropDownListWidget
(
kHyperlinkColorDropDownWidgetID,// WidgetId
kSysDropDownPMRsrcId,
// RsrcId
kBindNone,
// Frame binding
Frame(0,1,100,21)
// Frame
kTrue,
// Visible
kTrue,
// Enabled
{{}}
),
UIColorPickerWidget
(
kChangeHyperlinkColorSwatchWidgetID,
// WidgetId
kPMRsrcID_None,
// RsrcId
kBindNone,
// Frame binding
Frame(110,-1,133,22)
// Frame
kTrue,
// Visible
kTrue
// Enabled
),
}
),
...
Now, only a single widget is required instead of the group. It would defined in your plug-in .fr
file as follows:
ColorListDropDownWidget
(
kHyperlinkColorDropDownWidgetID,
#10075 Porting Guide
// WidgetId
111
#10075 Porting Guide
Porting recipes
kSysDropDownPMRsrcId,
// RsrcId
kBindNone,
Frame(150,65,285,85)
// Frame
kTrue,
// Visible
kTrue,
// Enabled
0,
// Associated Widget
),
...
Setting up the widgets from C++ code
The code to set up the widgets (e.g. in a dialog controller InitializeDialogFields
implementation) has become much more compact. The code fragment below has error
checking omitted in interests of brevity.
// Fill in color popup menu with the color names installed.
// Assume this code is for an implementation aggregated on boss object
// that is a kDialogBoss subclass.
// Assume that doc is of type IDocument*, and myColorUID is known (and
// corresponds to the element in the drop down list to select)
InterfacePtr<IPanelControlData> panelData(this, UseDefaultIID());
IControlView* panelControlView = panelData->FindWidget(colDropDownWidgetID);
InterfacePtr<IColorListControlData> colorListControlData(panelControlView,
UseDefaultIID());
colorListControlData->Setup(doc->GetDocWorkSpace(),
IID_IUICOLORLIST,
IColorListControlData::kIncludeCustom,
myColorUID);
...
Writing the Get/Create Color code
The amount code required to get and/or create the color has become a lot shorter. You no
longer have to create the custom color if it doesn't exist. Typically this code would be found in
a file named <whatever>Controller.cpp. Most of the error checking in the code is omitted in
interests of clarity.
// Assume doc (IDocument*) available, and that the implementation is
// aggregated on a kDialogBoss subclass
InterfacePtr<IPanelControlData> panelData(this, UseDefaultIID());
IControlView* panelControlView = panelData->FindWidget(colDropDownWidgetID);
InterfacePtr<IColorListControlData> colorListControlData(panelControlView,
UseDefaultIID());
if (colorListControlData && colorListControlData->IsSetup(doc->GetDocWorkSpace()))
{
retVal = UIDRef(::GetDataBase(doc), colorListControlData->GetSelection());
}
...
You can compile using the old obsoleted widgets by simply adding a zero at the end of the
resource for the color picker (ODFRez type UIColorPicketWidget) and the dropdown
(ODFRez type UIColorDropDownListWidget). In order to use the existing widgets you will
need to replace the zero with the WidgetID of the corresponding widget. The dropdown
should have the color picker as its associated widget and the color picker should have the drop
down as its associated widget. You can also use the new drop down widget with the color picker
by doing the same thing.
112
#10075 Porting Guide
Porting recipes
I get many compiler errors related to PMString, WideString, and other string related
APIs. How do I get my code to compile?
There were many changes to the string-related APIs to support the Unicode(TM) 3.2
specification, which extends to a 32-bit character code range. Please refer to the Technote titled
“Unicode 3.x and String-related APIs” (/docs/guides/unicodeandstrings.pdf) for more details.
(Windows only) If you get compiler errors only on PMString::GrabTString() and/or
PMString::SetTString(), you may not have the “Treat wchar_t as Built-In Type” setting correct
on your project. See section Creating a Windows plug-in project from scratch for details.
I am trying to port a scriptable plug-in. I see that there are many changes not only to the
API, but also how the platform-specific resources are specified. Where should I
start?
The scripting architecture of InDesign CS/InCopy CS is not only the foundation for scripting
library support, but also for several other application features. As a result, the architecture has
been refactored, and there are many changes you have to make to your plug-in projects. Please
refer to the Technote titled “Making Your Plug-in Scriptable”
(/docs/guides/scriptableplugin.pdf) for more details.
How do I get my code that uses IPlaceBehaviour to compile?
You need to add a parameter "IPlaceBehavior::eAfterPlace afterPlace" to
IPlaceBehavior::ProcessPlace to communicate what to do with the place gun after creating the
page item. You need to add the new parameter to all classes that inherit from IPlaceBehavior.
Most of the time you just add the parameter and pass it through. If you need to set afterPlace,
you can use kOldBehavior to get the old behavior before this change. The change propagated to
the helper classes CGraphicPlaceBehavior and CPathCreationTracker. Two new methods have
been added to IPlaceBehavior. These methods are:
virtual bool16 CanConvertTo(eFrameKind newPageItemKind) const = 0;
virtual bool16 CanPlaceInto(eFrameKind newPageItemKind) const = 0;
The purpose of these methods is to better control the "conversion" and "place into" behavior of
the new ebook movie, sound, and button page items. The implementation of
CanConvertTo(eFrameKind newPageItemKind) that is provided in CGraphicPlaceBehavior
returns kTrue if the newPageItemKind is kGraphicFrameKind or kTextFrameKind, and kFalse
otherwise. The implementation of CanPlaceInto(eFrameKind newPageItemKind) that is
provided in CGraphicPlaceBehavior always returns kFalse. You will need to override these
methods in your own derived classes if you want different behavior.
How have the semantics of IDataLinkReference changed?
In 2.0, you used the interface IDataLinkReference on kDataLinkBoss to access the linked page
item. The interface stores the UID of the page item. In the current SDK, this interface is
replaced by ILinkObjectReference. You should use the method
#10075 Porting Guide
113
#10075 Porting Guide
Porting recipes
ILinkObjectReference::QueryLinkedObject() to get a data link's linked object, which may not
be a page item (an example is XML data link).
On the other hand, objects with associated links such as kTextStoryBoss still use
IDataLinkReference to point to the data link.
How can I fix problems compiling ODFRez data statements with iconic buttons?
If you have problems in compiling ODFRez data statements that use iconic widgets, it may be
that you are using widgets that are now obsolete. See Troubleshooting errors below for specifics
of errors you might encounter.
Since 2.0, the icon widget control view hierarchy has been re-factored to simplify and remove
redundant widgets. The base functionality for the icon widget resides in the implementation
with identifier kIconSuiteButtonViewImpl . This control view provides all the functionality to
draw a basic icon widget and provides basic support for rollover buttons, ie buttons which
change when the cursor moves over them. See the widget boss class kRollOverIconButtonBoss
which provides the behaviour for a basic rollover button.
Under the old widget scheme there were many custom widgets that were just small variations
of each other. To simplify the icon widgets all icon resources contain a PNGIconAttributes
interface (see widgets.fh). This interface allows the centering, look, and well drawing attributes
of any icon to be specified. The #defines in IconStyleDefs.h should be used when specifying
these values in an icon’s resource.
Can I use PNG artwork with iconic buttons? How do I handle the cross-platform issues?
Many third-party developers have requested a more flexible scheme to allow artwork in image
file formats other than platform-native icon formats to be used in iconic buttons; in particular,
a large request was for an image format that supported transparency. This is now possible with
the advent of widgets where graphics can be supplied in PNG (Portable Network Graphic)
format with support for transparency. See http://www.w3.org/Graphics/PNG/ for a description
of this format. PNG images can be used with the new iconic buttons, e.g
RollOverIconButtonWidget.
Including PNG resources on Windows side is very straightforward, less so on Macintosh. There
is an Adobe-developed CodeWarrior plug-in RC Includer supplied in the SDK folder devtools
that enables resources referenced in Windows RC format to be included in a Macintosh plugin. This means that you can have a cross-platform resource format for including plug-in
resources that are 24-bit images with transparency (PNG).
RC Includer comes with its own documentation at <sdk>/devtools/rcincluder/readme.txt. The
contents of that document are not repeated here in the interests of maintaining the conciseness
of this description and you are encouraged to refer to the RC Includer’s own documentation
for detail on using this tool with Metrowerks CodeWarrior. At the time of writing there isn’t a
published sample that uses RC Includer, although we hope to correct this come the beta
timeframe. Note that you can still use PNG resources without using RC Includer; the RC
Includer just makes it easier since you can have a single .rc file that defines the resources, which
should be written to conform to the recipe below.
114
#10075 Porting Guide
Porting recipes
All icons with control views descended from the implementation with identifier
kIconSuiteButtonViewImpl now support drawing PNG images in addition to the older
platform images. If both a PNG image and an older platform image resource are available the
icon will choose the PNG art. Icons with PNG art support three methods of drawing their art:
disabled, enabled, and rolled-over. When displayed in the enabled mode the base art will be
drawn (PNGA), in disabled mode the base art will be drawn (PNGA) with a 50% transparency.
If the icon has a base image (PNGA) and a roll-over image (PNGR) and the icon is in a mouse
roll-over state, then the roll-over image (PNGR) will be drawn, otherwise the base image is
drawn (PNGA).
You’ll find examples in the SDK samples that use the ODFRez type RollOverIconButtonWidget
such as TextInsetMutator (although these don’t use PNG graphics at the time of writing). A
typical data statement for one of these buttons would look like this:
// Revised code
RollOverIconButtonWidget
(
kTestButtonOneWidgetID,
kIconResourceID,
kButtonTestPluginID,
kBindNone,
Frame (15.0,15.0,75.0,75.0)
kTrue, kTrue,
kADBEIconSuiteButtonType,
),
Another major change since version 2.0 is the support for using PNG graphics as an icon’s
image resource. The older platform formats are still all supported and work seamlessly with the
new PNG graphics. Unlike the older formats, PNG icons can contain transparency and the
same PNG resource can be included without modification on both Mac and PC platforms.
When an IconSuiteButtonView attempts to load an icon it will first attempt to load the icon
using a PNG resource. Remember that Icon resources are not localized and thus placing them
in a local index will have no effect. If a PNG resource cannot be found then the
IconSuiteButtonView will fall back and attempt to load the icon using the older platform
resource. By using this loading scheme the addition of the PNG type causes no additional
change to widget resource specifications and further all widgets currently descended from
IconSuiteButtonView can now use PNG art by simply adding new PNG art. If an icon
successfully loads a PNG it will then attempt to load an optional roll over icon image resource.
If this resource is present, it will be used when the icon has the mouse over it. Note, icons
without a IID_IRollover interface will only draw the rollover PNG in the buttons highlighted
state.
Adding PNG resources on Windows
To add a PNG resource to a Windows plugin its as simple as adding a resource declaration for
the PNG to the plugin’s .rc file. An example of this is shown below; it is taken from application
code, which is not in the SDK (however, hopefully this can be correct come beta-timeframe).
The basic syntax for the Windows resource format is, resource number, resource type, file to
include as resource. In the example below, kIconEyeDropper, and kIconEyeDropperRollOver
have been defined in the include file.
#include "xxxResourceDefs.h"
#10075 Porting Guide
115
#10075 Porting Guide
Porting recipes
kIconEyeDropper 578 "P_Sampler_Lg_N.PNG"
kIconEyeDropperRollOver 579 "P_Sampler_Lg_R.PNG"
Adding PNG resources on Macintosh
Including PNG resources on the MAC is a little more difficult. A plugin “RC Includer” has
been developed to enable CodeWarrior to compile Windows .rc files to MAC resources. The
basic steps to include a PNG resource on the MAC are to configure the “RC Includer” plugin
(found in the devtools folder) and then include the .rc file into the CodeWarrior project your
building. Below is shown a quick recipe for defining the necessary resource statements.
How to include PNG resources the cross-platform way
There should be a resource file called something like xxxPNG.rc; it would contain lines like
this:
#include "xxxResourceDefs.h"
kIconEyeDropper PNGA "P_Sampler_Lg_N.PNG"
kIconEyeDropperRollOver PNGR “P_Sampler_Lg_R.PNG"
The reason for this is that the PNGA and PNGR resource types are the MAC resource types and
the resource file is included directly in a CodeWarrior project so it must be correct for the
MAC. On the PC side xxxPNG.rc wouldn’t actually be found in the Visual Studio project view,
but instead included through xxx.rc. The file xxx.rc (as text) should have the following wrapper
around the xxxPNG.rc include (defining the constants for Windows that are already defined
resource types on the Macintosh):
#define PNGA 578
#define PNGR 579
#include “xxxPNG.rc”
#undef PNGA
#undef PNGR
By defining PNGA and PNGR we can use the same resource file to include the PNG resources
and keep our resource definitions in one place. The basic message is that you should wrap .rc
files that reference .png files when in the above #define/#undef block for the Windows side.
However, there is a single .rc file (xxxPNG.rc) for both Macintosh and Windows that is used to
define the image resources.
Style issues
When defining resources it is syntactically correct to define a resource by number directly but
this is poor programming style, for it gives no indication as to where the resource is used or if
its used at all. The resource should be instead defined using a #define as seen above and then
this same #define can be used in the resources widget declaration.
1234 PNGA “my resource.png” // Poor
kMyResource PNGA “my resource.png” // Good
Troubleshooting errors
These is an important point to note about PNG resources. If after adding a PNG resource the
PNG doesn't display and nothing draws or the old Icon still draws, the problem could be that
the icon drawing code you are using doesn't use the implementation with identifier
kIconSuiteButtonViewImpl to draw the icon and instead defers to a more primitive controlview implementation that knows nothing about how to render PNG artwork for buttons.
116
#10075 Porting Guide
Porting recipes
Suppose that you are re-compiling your existing plug-ins and you see the following error;
Error Number: R32653 Error Message: Undefined name <whatever>.
The problem is the boss ClassID specified in the icon resource definition is no longer valid. For
instance, if this error occurred when compiling the code below, then it would mean that
kIconFieldWidgetBoss was no longer valid.
type IconFieldWidget (kViewRsrcType) : RollOverIconButtonWidget (ClassID =
kIconFieldWidgetBoss)
The solution is to locate a new boss class that will provide the correct behaviour for your
widget.
Suppose that you are re-compiling your existing plug-ins and you see the following error;
Error Number: R32691
Error Message: Custom type name expected, but <whatever> found.
The problem here is the widget name specified in the icon resource definition is no longer
valid. If this error occurred when compiling one of the two code snippets below, then
RollOverIconButtonWidget would be no longer valid.
type SimpleIconSuiteButtonWidget (kViewRsrcType) : RollOverIconButtonWidget
(ClassID = kSimpleIconSuiteButtonWidgetBoss);
Find the new widget that implements the functionality of old widget.
What is Skip By Leading?
See How do I use the minHeightLeadingDiff parameter when getting tiles?
How do I use the minHeightLeadingDiff parameter when getting tiles?
The methods for getting tiles from the spread overlap manager have changed to support the
new Skip By Leading composition preference.
In 2.0 text wrap always tries to find the best next y position for a text line even though it may
not fall on a y position within the leading increments. That is, if a text wrap obstruction is
encountered when trying to flow a line of text, the line of text is likely to drawn directly beneath
the obstruction regardless of the height of the obstruction. This approach is fairly expensive
with respect to time.
InDesign CS/InCopy CS introduces an alternative controlled by the checkbox titled Skip By
Leading within the text wrap group in the composition preferences. The default setting for old
documents is off (unchecked) and for new documents is on (checked). When a text wrap
obstruction is encountered, we would skip down by leading height increments until the line of
text no longer hits the obstruction. The resulting text flow may contain white space between
the bottom of the obstruction and the next line of text. However, this approach is faster. Also,
the resulting lines of text are more likely to line up with text in adjacent text frames or columns
of text (in a multi-column text frame).
The new parameter, minHeightLeadingDiff, is the difference between the minimum height
requested for the tile and the leading amount to be used by the Skip By Leading preference.
#10075 Porting Guide
117
#10075 Porting Guide
Porting recipes
So, if the tile height is usually equal to the leading amount, the minHeightLeadingDiff would
be zero. If, on the other hand, the tile height is usually equal to some other height such as the
ideographic embox height of the line, then the minHeightLeadingDiff would be a positive
number equal to the line height subtracted from the leading height.
TABLE 1.47 Skip By Leading preference/minHeightLeadingDiff API changes
API
Member
Change
ITiler
GetTiles
New parameter minHeightLeadingDiff
ITextTiler
GetLocalTiles
New parameter heightLeadingDiff
TextTilesInfo
See IStandOff.h
fMinHeightLeadingDiff
New member
How do I adapt to the meta data API changes?
Under 2.x, implementation of ILoadMetaData/IMergeMetaData only changes standard
properties. A service provider mechanism is used so that you can implement your own
ILoadMetaData/IMergeMetaData and change user-defined XMP data.
Under the current version, loading/merging of XMP data is handled a little differently. You can
implement the new IRestoreInternalMetaData interface to restore critical user defined XMP
data after loading/merging.
In the current XMP user interface, the load/merge metadata is changed to replace/append. The
related command names are changed to match the user interface changes.
TABLE 1.48 Meta data API changes
API
Change
ILoadMetaData
Obsolete.
Removed from kMetaDataOpsBoss .
IMergeMetaData
Obsolete.
Removed from kMetaDataOpsBoss .
IRestoreInternalMetaData
New interface.
Contains a single method,
RestoreInternalProperties, which was originally
in ILoadMetaData.
IMetaDataAccess
118
Member
AppendFromStream
Signature changed.
kLoadMetaDataCmdBoss
Obsolete.
Use kReplaceMetaDataCmdBoss instead.
kMergeMetaDataCmdBoss
Obsolete.
Use kAppendMetaDataCmdBoss instead
kReplaceMetaDataCmdBoss
New.
#10075 Porting Guide
Porting recipes
API
Member
Change
kAppendMetaDataCmdBoss
New .
ILoadMetaDataCmdData
Obsolete.
Use IReplaceMetaDataCmdData instead.
IMergeMetaDataCmdData
Obsolete.
Use IAppendMetaDataCmdData instead.
IReplaceMetaDataCmdData
New.
IAppendMetaDataCmdData
New.
How to port a 2.x custom metadata service (ServiceID=kMetaDataOpsService). Migrate the
body of your ILoadMetaData::RestoreInternalProperties method into your implementation of
the new method IRestoreInternalMetaData::RestoreInternalProperties. Your
ILoadMetaData::LoadProperties and IMergeMetaData::MergeProperties implementations are
no longer needed and you should remove these interfaces from your service provider boss
class.
// 2.x custom metadata service boss class
resource ClassDescription (...)
{
kMyMetaDataOpsBoss,
kInvalidClass,
{
IID_ICALCULATEMETADATA, kCalculateMetaDataImpl,
IID_IMERGEMETADATA, kMyMergeMetaDataImpl,
IID_ILOADMETADATA, kMyLoadMetaDataImpl,
IID_IK2SERVICEPROVIDER, kMetaDataOpsProviderImpl,
}
};
// 3.x custom metadata service boss class
resource ClassDescription (...)
{
kMyMetaDataOpsBoss,
kInvalidClass,
{
IID_ICALCULATEMETADATA, kCalculateMetaDataImpl,
IID_IRESTOREINTERNALMETADATA,kMyRestoreInternalMetaDataImpl,
IID_IK2SERVICEPROVIDER, kMetaDataOpsProviderImpl,
}
};
How to port 2.x ILoadMetaData client code.
// 2.x code:
InterfacePtr<ILoadMetaData> loadMetaData(...);
loadMetaData->LoadProperties(documentMetaData, externalMetaData);
// 3.x code:
InterfacePtr<IMetaDataAccess> externalMetaDataAccess(externalMetaData,
UseDefaultIID());
InterfacePtr<IPMStream> stream(StreamUtil::CreateFileStreamWrite(...));
#10075 Porting Guide
119
#10075 Porting Guide
Porting recipes
if (externalMetaDataAccess->SaveToStream(stream, kFalse/*package*/,
kFalse/*allowInPlaceModification*/, kFalse/*expandable*/))
{
stream->Seek(0, kSeekFromStart);
InterfacePtr<IMetaDataAccess> docMetaDataAccess(documentMetaData,
UseDefaultIID());
docMetaDataAccess->AppendFromStream(stream, kTrue);
}
How to port 2.x IMergeMetaData client code.
// 2.x code
InterfacePtr<IMergeMetaData> mergeMetaData(...);
mergeMetaData->MergeProperties(documentMetaData, externalMetaData);
// 3.x code:
InterfacePtr<IMetaDataAccess> externalMetaDataAccess(externalMetaData,
UseDefaultIID());
InterfacePtr<IPMStream> stream(StreamUtil::CreateFileStreamWrite(...));
if (externalMetaDataAccess->SaveToStream(stream, kFalse/*package*/,
kFalse/*allowInPlaceModification*/, kFalse/*expandable*/))
{
stream->Seek(0, kSeekFromStart);
InterfacePtr<IMetaDataAccess> docMetaDataAccess(documentMetaData,
UseDefaultIID());
docMetaDataAccess->AppendFromStream(stream, kFalse/*replaceOld*/);
}
What is the purpose of IAdornmentShape::WillPrint?
The new method described below has been added to IAdornmentShape. Override it if your
adornment draws when the application is printing.
120
#10075 Porting Guide
Porting recipes
TABLE 1.49 IAdornmentShape::WillPrint API change
API
Member
Change
IAdornmentShape
WillPrint
New method.
Return kTrue if the adornment is one that will
print (e.g. drop shadow), or kFalse otherwise (e.g.
selection handles).
A new bounding box method,
CShape::GetPrintedBoundingBox, has been
added which includes the PaintedBoundingBox
plus any adornments that report that they will
print. This method is now used by the draw
manager to filter out items that shouldn't draw.
Previous implementation used
GetPaintedBoundingBox which was too big and
included things that shouldn't draw. Check out
file CShape.cpp on the SDK if you are interested
in the details.
Returning kFalse will result in the same behavior
as under the 2.x application.
How do I get my FontGroupIteratorCallBack to compile?
Implement the new method FontGroupIteratorCallBack::GetNamesFlag.
TABLE 1.50 FontGroupIteratorBallBack change
API
Member
Change
FontGroupIteratorCallBack
(see IFontMgr.h)
GetNamesFlag
New method.
Determines how OnFont will return family and
style name.
How do I get my IKerningOnTheFly code to compile?
Make the changes described below.
TABLE 1.51 IKerningOnTheFly change
API
Member
Change
IKerningOnTheFly
LeftSideKerning
RightSideKerning
Signature change.
Parameter bodySize type has changed from type
Fixed to PMReal. Internally the code uses a
double so you must now pass a PMReal.
#10075 Porting Guide
121
#10075 Porting Guide
Porting recipes
How do I get my IPMFont::GetWindowsLogFont code to compile and run without bugs?
Change parameter logfont from type LOGFONT to LOGFONTA.
TABLE 1.52 IPMFont::GetWindowsLogFont API change
API
Member
Change
IPMFont
GetWindowsLogFont
Signature change.
Parameter logfont changed from type LOGFONT
to LOGFONTA. The UNICODE flag has been
turned on for the Win32 API (see tech note
#10078 for further information on Unicode
changes) so it changed the lfFaceName in
parameter logfont to a unicode string. However
the application calls CoolType to fill out the
logfont and CoolType does not have the
UNICODE flag on so it returns a C string. By
using LOGFONTA instead the state of the
UNICODE flag does not matter and this call will
always return a C string in the logfont parameter.
Without this change a plugin with the UNICODE
flag on may have a bug. Note: there may be a
further change post-alpha in this area of
CoolType interaction.
//2.x code:
LOGFONT logFont;
if (pmfont->GetWindowsLogFont(&logFont)) {
PMString logFontName;
logFontName.SetCString(logFont.lfFaceName);
}
// Revised code
LOGFONTA logFont;
if (pmfont->GetWindowsLogFont(&logFont)) {
PMString logFontName;
logFontName.SetCString(logFont.lfFaceName);
}
How has the ToolDef resource changed?
As part of the icon refactoring (described in FAQ about iconic buttons) the tooldef resource
was changed to include a PNGIconAttributes resource. This is the same resource used in
regular icon widgets. For a complete, worked example of this you should see the SDK sample
plug-in WaveTool.
The old, obsolete format is shown below:
// 2.x code
resource ToolDef (128)
{
122
#10075 Porting Guide
Porting recipes
kZoomToolBoss, // classID for tool boss
kPointerToolBoss, // classID for tool type
kDoesNotApply, // classID for parent tool boss
kFifthAdobeToolsGroup, // group number
kSecondAdobeTool, // tool number
kDoesNotApply, // subtool number
kZoomToolActionID, // actionID for tool shortcut
kIconZoom, kZoomToolPluginID, // iconID
};
An example of the new format is shown below with an extra field at the end of the field-list to
specify the type of button:
// Revised code
resource ToolDef (kIconSineWave)
{
kSineWaveToolBoss,
kPointerToolBoss,
kSawWaveToolBoss,
kDoesNotApply,
kDoesNotApply,
kFirstAdobeTool,
kSineWaveToolActionID,
kIconSineWave,
kWavTlPluginID,
kADBEIconSuiteButtonType
};
// The last line is all that is new;
// the constant kADBEIconSuiteButtonType is defined in "IconStyleDefs.h"
};
Remember to declare your includes for ODFRC files outside of the block #ifndef __ODFRC__.
This is necessary to insure that Visual C++ .NET 2003 finds the correct dependencies. An
example is shown below that makes this explicit.
#include "IconStyleDefs.h"
#ifdef __ODFRC__
resource ToolDef (128)
{
---- Tool Def Here --}
#endif
How has swatch creation changed? Do I still need to create a kSolidMetaDataBoss etc?
There have been some simplifications and improvements in the area of swatch creation.In
particular, IGraphicMetaDataUtils and associated implementations had been removed. In the
InDesign 2.0 code base graphics metadata objects were needed frequently. One example of
where a metadata object was used was in the context of creating a new swatch. For reference,
see the tech-note #10032 on Colour Fundamentals.
// 2.x code
Interface<IPMUnknown>
colorMetaDataObject(CreateObject(kSolidMetaDataBoss));
#10075 Porting Guide
123
#10075 Porting Guide
Porting recipes
InterfacePtr<IColorData> colorData (colorMetaDataObject,
IID_ICOLORMETADATA);
colorData->SetColorData (colorspace, colorarray);
UID newUID = Utils<ISwatchUtils>()->CreateNewSwatch (
kPMColorBoss, colorMetaDataObject, workspace, updateGraphicState);
The new code is simpler and there’s no reference to metadata objects, which were obscure and
relatively difficult for third party developers to grasp. The code example below shows how you
would create a new swatch in the new model.
// Revised code
// Note how there’s not a need to create an instance of a
// kSolidMetaDataBoss object
InterfacePtr<IRenderingObject> colorRenderObject(
Utils<IGraphicStateUtils>()->CreateTemporaryRenderObject(kPMColorBoss));
InterfacePtr<IColorData> colorData (colorRenderObject, UseDefaultIID ());
colorData->SetColorData (colorspace, colorarray);
UID newUID = Utils<ISwatchUtils>()->CreateNewSwatch (kPMColorBoss,
colorRenderObject, workspace, updateGraphicState);
What has happened to ITableTextSelection?
In InDesign 2.0, the interface ITableTextSelection incorrectly exposed access to the active text
selection's ITableModel. ITableTextSelection is meant to be used as a utility class for the Suites
on the kTextSuiteBoss which answers questions about the existing text selection.
ITableTextSelection has been moved from the kTextSuiteBoss to the kTextSelectionBoss. This
means that ITableTextSelection is no longer accessible to client code, it is only accessible to
suites on the kTextSuiteBoss.
If you have previously used ITableTextSelection from your client code, what you need to do is:
1.
move the code which was accessing ITableTextSelection to a suite,
2.
add-in your suite to the kTextSuiteBoss class
You will then be able to access ITableTextSelection from the suite implementation (e.g
<whatever>CSB.cpp) simply by writing code like this:
// Revised code
InterfacePtr<ITableTextSelection> tableTextSelection(this, UseDefaultIID());
If you need to get to the ITableModel from the Suite do the following:
// Revised code
InterfacePtr<ITableTarget> tableTarget(this, UseDefaultIID());
InterfacePtr<ITableModel> tableModel(tableTarget->QueryModel());
Remember writing a suite which returns the ITableModel would violate the encapsulation rules
of the new selection architecture. Any code to modify or get information from the selection's
ITableModel needs to be in a Suite.
124
#10075 Porting Guide
Porting recipes
Should I keep using ISelection and ISelectUtils interfaces?
No, these are almost completely removed from the InDesign CS/InCopy CS application
codebase. You should plan on porting any selection code to the new selection architecture that
will be more comprehensively documented in the beta SDK. There are several examples of
new-selection architecture compliant plug-ins in the alpha SDK (BasicMenu,
BasicPersistInterface, TableBasics and TextInsetMutator). The new selection architecture was
first introduced with InDesign 2.0 and was described in detail in the technote #10006
(NewSelection.pdf); see the section References.
Which selection type (ISelection::SelectionType) constants should I use?
These have been re-factored to simplify redundant and confusing definitions. InDesign 2.0, the
header file ISelection.h (also containing the deprecated interface ISelection) had the following
enum for describing the type of actions to take when modifying the current selection:
// from 2.x interface header file
// Selection/Deselection
enum SelectionType { kReplace, kAddTo };
At the same time, ISelectionMessages.h had the following which replicated the constants from
ISelection.h and added another:
// from 2.x interface header file
namespace Selection
{
enum Action { kReplace, kAddTo, kRemoveFrom };
}
For InDesign CS/InCopy CS, the enumeration in ISelection.h has been removed. Please
convert to using the enum from ISelectionMessages.h, as follows:
TABLE 1.53 Moving from version 2.0 constants to InDesign CS/InCopy CS equivalents
2.x code
InDesign CS/InCopy CS code
ISelection::kReplace
Selection::kReplace
ISelection::kAddTo
Selection::kAddTo
ISelection::SelectionType
Selection::Action
How do I remove dependency on IID_NEED_<whatever>SELECTION?
These constants, such as IID_NEED_LAYOUTSELECTION and
IID_NEED_TEXTSELECTION, defined in ActionID.h, are going away and should be
considered obsolete. They were stop-gaps until more of the codebase became new-selection
architecture compliant. If you have menu items that are conditionally enabled on a text or
layout selection in your 2.x code, you should strictly speaking use your own custom suite. Note
that you are free to use the suites provided by the API such as IGraphicAttributeSuite or
ITextAttributeSuite. However the recommended method is to implement your own custom
#10075 Porting Guide
125
#10075 Porting Guide
Porting recipes
suite and add-in to the appropriate suite boss classes- that is, the integrator suite boss class
named kIntegratorSuiteBoss and appropriate concrete suite boss classes for selection formats
you care about; see below.
TABLE 1.54 Suite boss classes and selection targets
2.x boss for add-in
InDesign CS/InCopy CS Selection target
boss for add-in
Example
kIntegratorISuiteBoss
kIntegratorSuiteBoss
abstract
kLayoutISuiteBoss
kLayoutSuiteBoss
layout (i.e. page
items), see
ILayoutTarget
When the pointer
tool is active and
end-user clicks on
a page item, they’re
making a layout
selection
kTextISuiteBoss
kTextSuiteBoss
text e.g. within a
text frame or
selected text within
a table cell. See
ITextTarget
When text tool is
active and there is a
text selection or an
insertion position
kTableISuiteBoss
kTableSuiteBoss
table component.
See ITableTarget
Selected cells in a
table
kXMLStructureISuiteBoss
kXMLStructureSuiteBoss
Nodes in structure
tree. See
IXMLNodeTarget.
Selecting elements
in the structureview
kApplicationDefaultISuiteBoss
kApplicationDefaultSuiteBoss
Application
defaults
kDocumentDefaultISuiteBoss
kDocumentDefaultSuiteBoss
Document defaults
kNoteTextSuiteBoss
InCopy notes.
Selections within
InCopy notes
Please bear in mind though that randomly-selected API suites may target different types of
selection and may change data your 2.0 plug-in did not intend to change. For example
ITextAttributeSuite can target a table selection and apply a text attribute override to the range
of text displayed in each table cell. Also if there's no visible selection API suites often target the
defaults. If you only want to update a layout selection add a custom suite that targets it
exclusivley as described below. This means that you should do the following (adapting from
BscMnu to your own requirements, modifying the IDs as needed as well):
1.
Define a custom suite interface of your own and add this to the k<whatever>SuiteBoss in
which you are interested. The first step in doing this would be to define the identifiers
that you need in your <plugin>ID.h file.
// Define the IDs in the <whatever>ID.h file
126
#10075 Porting Guide
Porting recipes
DECLARE_PMID(kInterfaceIDSpace, IID_IBSCMNU_ISUITE, kBscMnuPrefix + 1)
DECLARE_PMID(kImplementationIDSpace, kBscMnuSuiteASBImpl,kBscMnuPrefix + 1)
DECLARE_PMID(kImplementationIDSpace, kBscMnuSuiteLayoutCSBImpl,kBscMnuPrefix + 2)
2.
Make sure that these are referenced from the <plugin>FactoryList.h file
// Add to <whatever>FactoryList.h
REGISTER_PMINTERFACE(BscMnuSuiteASB, kBscMnuSuiteASBImpl)
REGISTER_PMINTERFACE(BscMnuSuiteLayoutCSB, kBscMnuSuiteLayoutCSBImpl)
3.
Define the add-ins to the integrator (kIntegratorSuiteBoss) and concrete suite boss
classes (e.g., kLayoutSuiteBoss; for the others that may be relevant to your plug-in, see
Suite boss classes and selection targets) in your <plug-in>.fr file. Note that this is simplified
since 2.x, since the potentially confusing xxxISuiteBoss classes have gone away.
AddIn
{
kIntegratorSuiteBoss,
kInvalidClass,
{
IID_IBSCMNU_ISUITE, kBscMnuSuiteASBImpl,
}
},
AddIn
{
kLayoutSuiteBoss,
kInvalidClass,
{
IID_IBSCMNU_ISUITE, kBscMnuSuiteLayoutCSBImpl,
}
},
4.
Decide on the methods on your custom interface and write its API specification.
#ifndef _IBscMnuSuite_
#define _IBscMnuSuite_
#include "BscMnuID.h"
class IPMUnknown;
class IBscMnuSuite : public IPMUnknown
{
public:
enum { kDefaultIID = IID_IBSCMNU_ISUITE };
public:
virtual bool16CanApplyBscMnu(void) = 0;
};
#endif
5.
Provide implementation for your add-in to the integrator suite boss (typically,
<whatever>ASB.cpp; you can base this on the API templates.
// Write
#include
#include
#include
the implementation for the integrator suite
"VCPlugInHeaders.h"
"IBscMnuSuite.h"
"SelectionASBTemplates.tpp"
class BscMnuSuiteASB : public CPMUnknown<IBscMnuSuite>
{
#10075 Porting Guide
127
#10075 Porting Guide
Porting recipes
public:
BscMnuSuiteASB (IPMUnknown* iBoss);
virtual ~BscMnuSuiteASB (void);
virtual bool16CanApplyBscMnu(void);
};
CREATE_PMINTERFACE (BscMnuSuiteASB, kBscMnuSuiteASBImpl)
BscMnuSuiteASB::BscMnuSuiteASB(IPMUnknown* iBoss) :
CPMUnknown<IBscMnuSuite>(iBoss)
{
}
BscMnuSuiteASB::~BscMnuSuiteASB(void)
{
}
bool16 BscMnuSuiteASB::CanApplyBscMnu(void)
{
return (AnyCSBSupports (make_functor(&IBscMnuSuite::CanApplyBscMnu), this));
}
6.
Provide implementations for add-ins on concrete suite boss classes of interest, e.g. to
kLayoutSuiteBoss for custom suite enabled on a layout selection.
// Provide implementation for layout suite
#include "VCPlugInHeaders.h "
#include "ILayoutTarget.h"
#include "IBscMnuSuite.h"
class BscMnuSuiteLayoutCSB : public CPMUnknown<IBscMnuSuite>
{
public:
BscMnuSuiteLayoutCSB (IPMUnknown *iBoss);
virtual~BscMnuSuiteLayoutCSB (void);
public:
virtual bool16CanApplyBscMnu(void);
};
CREATE_PMINTERFACE (BscMnuSuiteLayoutCSB, kBscMnuSuiteLayoutCSBImpl)
BscMnuSuiteLayoutCSB::BscMnuSuiteLayoutCSB(IPMUnknown* iBoss) :
CPMUnknown<IBscMnuSuite>(iBoss)
{
}
BscMnuSuiteLayoutCSB::~BscMnuSuiteLayoutCSB(void)
{
}
bool16 BscMnuSuiteLayoutCSB::CanApplyBscMnu(void)
{
InterfacePtr<ILayoutTarget> iLayoutTarget (this, UseDefaultIID ());
128
#10075 Porting Guide
Porting recipes
const UIDList selectedItems
(iLayoutTarget->GetUIDList (kStripStandoffs));
// if the current selection has at least one drawable page item
// then we will return true so the client code can apply the data
if (selectedItems.Length() > 0)
{
return (kTrue);
}
else
{
return (kFalse);
}
}
7.
You can then custom-enable your menu items based on the presence of your custom suite
interface on the abstract selection. For instance, the menu item that used to be
conditionally enabled with IID_NEED_LAYOUTSELECTION in BasicMenu has been
replaced by one that is conditionally enabled on IID_IBSCMNU_ISUITE being present
on the selection. You would do the same thing, replacing IID_IBSCMNU_ISUITE with
the custom suite interface of your own devising.
kBscMnuActionComponentBoss,
kBscMnuNeedsSelectionActionID,
kBscMnuNeedsSelectionMenuItemKey,
kOtherActionArea,
kNormalAction,
kDisableIfSelectionDoesNotSupportIID|kCustomEnabling,
IID_IBSCMNU_ISUITE,
kSDKDefInvisibleInKBSCEditorFlag,
What has changed in IHierarchy interface?
InDesign CS introduced a push button page item which can have multiple visual states, only
one of which can be active at any one time. This means that push buttons can have "hidden"
children that are in these inactive states. The IHierarchy interface on a push button page item
normally affects only the current visible state of the button and its children. (See the
IAppearanceList interface for information on how to change the active state.) There are some
cases where its very convienent to be able to retrieve all the children, both visible and invisible,
that have a certain interface ID. Hence we added an additional parameter to the IHierarchy
method GetDescendents().
This new parameter is a flag to control the search for the descendents matching the given
interface ID. In InDesign CS, only one flag is currently defined, which is kIncludeHidden. This
flag instructs GetDescendents() to include all hidden children in the search for children with
the given interface ID. This flag can be used to do a search of all the children. Callers should be
very careful when manipulating hidden children returned from this method because they will
not appear to exist in the hierarchy. This new parameter defaults to 0, meaning no special flags
are set. When no special flags are set, GetDescendents() works as it has by returning children in
the visible state.
If you have derived a subclass from CHierarchyNode, the public implementation of IHierarchy,
you will need to add this parameter to your subclass if you override GetDescendents(). In most
#10075 Porting Guide
129
#10075 Porting Guide
Porting recipes
cases, you can simply pass this flag through to the recursive call made to GetDescendents() for
each child.
IDocumentUtils now on the Utils boss
Historically, IDocumentUtils is on the session boss. Now in InDesign CS, it has been added to
the utils boss where it is more logically placed and easier to find.
As such, the version of IDocumentUtils on the session is being deprecated. It will still be on the
session for at least InDesign CS, but the preferred way of accessing it will now be off of the utils
boss.
For example, code that previously did this:
InterfacePtr<IDocumentUtils> docUtils(gSession, IID_IDOCUMENTUTILS);
docUtils->SomeFunction(x);
can now be rewritten as:
Utils<IDocumentUtils>()->SomeFunction(x);
What has changed in IFileList?
In order to remove a file form the "Open Recent" list that is managed by IFileList, we added the
following new method to this interface:
virtual void RemoveFile(const SysFile *removeThis) = 0;
What has changed in ITreeViewController?
In order to determine whether or not the tree can get keyboard focus, we added the following
new method to this interface:
virtual bool16 AllowsSelection( ) const = 0;
This returns whether or not the tree view supports selecting it's nodes. Most Tree views will use
the default CTreeViewController, which will now have a default implementation that does
determines the answer based on the type of selection the controller was initialized within it's
ReadWrite method. If your class derives straight from ITreeViewController, you will need to
decide on returning the appropriate answer.
What has changed in IControlView?
We added two new methods to IControlView. Both will have its default implementation in
CControlView. If you subclass from CControlView, you don't need to do anything unless you
would like to overwrite them.
virtual void DeleteDrawRegion() = 0;
virtual bool16 DrawRegionEncompassesChildRegions() const = 0;
Historically, CControlView has a DeleteDrawRegion() which will delete the cached draw
region when the widget moves. When the parent moves, however, the child draw region is not
130
#10075 Porting Guide
Porting recipes
deleted, although it should be since draw region is based on location in window and that will
change if the parent moves. By putting DeleteDrawRegion() into the IControlView interface,
PanelView can call DeleteDrawRegion() on it's children.
The second method added in is to have the draw region really reflect the region that a widget
will draw into. Currently, the Draw Region returned from GetDrawRegion() does not
incorporate clipping it would get from the parent, even though it will be clipped when it draws.
Therefore, it's DrawRegion() isn't really accurate. Part of this change will be to have the child's
own region to be intersected with the parent's draw region to determine the DrawRegion for
the child. There are some cases, like ownerdraw dropdowns, that aren't clipped by their parents
when drawing. For these few widgets, we need a way to specify that their DrawRegion() should
not be intersected with their parent's DrawRegion(). To do this, you can override this method
to return kFalse. The default is to return kTrue.
However, if you have created a widget that will be a child of another widget and not clipped by
that widget, since our default behavior is to clip, so you would've had to already do some
special things to avoid that. If that is the case, you need to override
DrawRegionEncompassesChildRegions() to return kFalse.
What happened to RedlineID.h?
The public header file RedlineID.h has been deprecated. All of the IDs defined in RedlineID.h
have been moved to InCopySharedID.h. Any references to RedlineID.h should be changed to
InCopySharedID.h. But no IDs were changed as a result of this. In the past, RedlineID was
using a subset of InCopyShared IDs. They are now all in one place for simplicity and
consistency.
What has changed for body and last line text alignment attributes?
Since InDesign 1.0 we have had 2 text attributes that worked together to specify the alignment
of a paragraph. We only support 7 types of paragraph alignment:
•
left, right, center,
•
justify with last line left, last line right, or last line centered,
•
full justified
However, it was possible using text style editing to create other combinations, since the
attribute pair actually supports 16 (4 x 4) alignments. Bad alignments are things like:
•
body left, last line justified (the most common)
•
body left, last line right aligned
To eliminate this odd behavior, we made the following changes in InDesign CS:
•
ICompositionStyle::TextAlignment enum will specify the 7 legal alignments listed above;
•
kTextAttrAlignLastBoss and kTextAttrAlignBodyBoss were replaced by
kTextAttrAlignmentBoss;
#10075 Porting Guide
131
#10075 Porting Guide
Porting recipes
•
ICompositionStyle::[Get|Set]LastLineAlign() were removed;
•
ICompositionStyle::[Get|Set]BodyAlign() were removed;
•
ICompositionStyle::[Get|Set]ParagraphAlignment() were added as the replacement;
•
ICJKFrameGridDefaults::[Get|Set]TextAlignBody() were removed;
•
ICJKFrameGridDefaults::[Get|Set]TextAlignLast() were removed;
•
ICJKFrameGridDefaults::[Get|Set]TextAlignment() were added as the replacement;
•
ICJKFrameData::[Get|Set]TextAlignBody() were removed;
•
ICJKFrameData::[Get|Set]TextAlignLast() were removed;
•
ICJKFrameData::[Get|Set]TextAlignment() were added as the replacement;
•
ICJKLayoutGridDefaults::[Get|Set]TextAlignBody() were removed;
•
ICJKLayoutGridDefaults::[Get|Set]TextAlignLast() were removed;
•
ICJKLayoutGridDefaults::[Get|Set]TextAlignment() were added as the replacement;
•
IFilteredCJKGridCmdData::kTextAlign[Body|Last]Valid enum values were removed;
•
IFilteredCJKGridCmdData::kTextAlignmentValid was added as the replacement.
What do you need to change for your sub-dialog observer
CDialogObserver is intended as the base class for dialogs with OK, Cancel buttons. This base
class takes care of some common operations such as hit OK, Cancel button or preview
checkbox.
For selectable dialogs which contain multiple panels, each panel is kind of treated as dialog,
let's call it a sub-dialog. Often times, the observer on sub-dialog also inherit from
CDialogObserver, which some time is not the right thing to do. In order to prevent this from
happening, we made some changes in CDialogObserver which will not affect your code if your
observer inherits from CDialogObserver on a normal dialog, not a sub-dialog in a selectable
dialog. But if you inherits your observer from CDialogObserver on a sub-dialog, in the debug
build, you will see an assert to remind you that you need to inherit your observer from
AbstractDialogObserver: "This is not main dialog panel (the one with OK, Cancel buttons).
Please inherit from AbstractDialogObserver". This assert has been added to detect observers on a
selectable dialog sub-panel that inherit from the wrong super-class. If you see this assert, it is
likely your observer is using CDialogObserver or CSelectableDialogObserver as its super-class.
Change your implementation use AbstractDialogObserver a the super-class instead. For
example, say you added an observer to a selectable dialog sub-panel in the SDK's
BasicSelectableDialog sample, as shown by the boss class below:
Class
{
kYinPanelBoss,
kPrimaryResourcePanelWidgetBoss,
{
IID_IOBSERVER, kYinPanelObserverImpl,
132
#10075 Porting Guide
Porting recipes
IID_IDIALOGCONTROLLER, kYinPanelControllerImpl,
IID_IPANELCREATOR, kYinPanelCreatorImpl,
IID_IK2SERVICEPROVIDER, kDialogPanelServiceImpl,
}
},
•
The observer implementation (YinPanelObserver) should use AbstractDialogObserver as
its super-class.
•
It should not use CDialogObserver as its super-class. CDialogObserver responsibilities
include OK, cancel and preview dialog widget handling. It should only be used by
observers on sub-boss-classes of kDialogBoss .
•
It should also not use CSelectableDialogObserver as its super-class.
CSelectableDialogObserver extends CDialogObserver to handle the list of selectable
dialog sub-panels. It should only be used by observers on sub-boss-classes of
kSelectableDialogBoss or kTabSelectableDialogBoss.
What has happened to IComposeScanner::QueryDataAt()?
Prior to InDesign CS, IComposeScanner::QueryDataAt() returns a const textChar*. To further
improve its stability and make it 32-bit Unicode savvy, we modified this method to return a
TextIterator object. TextIterator has its own refcount on the chunk in the text model, and thus
makes the TextModel life cycle independent of the compose scanner cache. Clients can hold
onto the TextIterator and be guaranteed that the WideString it points to will not go away from
under them. Client code can iterate over the entire text story using the returned TextIterator,
without worring about lengths of text chunks in the model. Also dereferencing the TextIterator
returns a UTF32TextChar, which fully supports characters beyond the Unicode Basic
Multilingual Plane (BMP).
The numChars parameter previously was guaranteed only to return the number of characters
left in a single chunk (WideString object) in the text story from the requested position. So, as
long as QueryDataAt was not called again, the pointer returned could be used as a direct
accessor to the buffer of data in a single WideString object in the model. Now, however, the
numChars parameter will return up to the length of the text story, which crosses multiple
chunk boundaries. This means that if you want to do buffer-type operations on the data, you
must use TextIterator::AppendToStringAndIncrement() to first copy the data
(which may occupy more than one WideString) into a new WideString and operate on that.
What has changed in IPageItemAdornmentList?
Page item adornment list is a list of adornments that hangs off a page item. Prior to InDesign
CS, IPageItemAdornmentList interface has an integrated iterator interface with the following
methods:
virtual
virtual
virtual
virtual
#10075 Porting Guide
void ResetIterator( IAdornmentShape::AdornmentDrawOrder ) = 0;
IAdornmentShape* QueryNextAdornment() = 0;
void ResetHandleIterator(IAdornmentHandleShape::AdornmentDrawOrder ) = 0;
IAdornmentHandleShape* QueryNextHandleAdornment() = 0;
133
#10075 Porting Guide
Porting recipes
Using the iteration mechanism that is global to the list, it is possible that a high level iteration
could be unexpectedly reset by a lower level iteration. You could fix it locally by storing the
results of the high level iteration off in a local array prior to calling the low level iteration. But
the integrated iterator paradigm seems error prone.
We modified this interface by adding a new iterator interface which makes a copy of the list of
adornments. The new iterator interface is IAdornmentIterator. See IPageItemAdornmentList.h
for more details.
We deprecated the above old methods and added two new methods to
IPageItemAdornmentList:
virtual IAdornmentIterator* CreateIterator(IAdornmentShape::AdornmentDrawOrder
order ) = 0;
virtual IAdornmentIterator*
CreateIterator(IAdornmentHandleShape::AdornmentDrawOrder order ) = 0;
When CreateIterator is called, we make a copy of the iteration. Consequently, it remains
consistent.
Why has parcel index changed to parcel key (ParcelKey)?
In InDesign 2.0, the IParcelList interface used indexes within its list of Parcels to identify
individual Parcels. This scheme had a weakness in that it was not able to uniquely identify
Parcels because the addition and deletion of Parcels in the ParcelList would change the index of
other Parcels. Further, various clients which needed to maintain references to Parcels also
needed notification schemes when the Parcels become renumbered and these schemes were
inadequate.
Prior to the implementation of Parcels in InDesign 2.0, TextFrames were used to contain text
content and the UID of the TextFrame was available as a unique identifier. This uniqueness was
lost with the creation of Parcels to contain text content.
For InDesign CS, we have re-written the IParcelList API to accept a new identifier named a
ParcelKey instead of the simple index into the ParcelList. In this way we are trying to get back
some of the properties that we lost when we abandoned FrameUIDs as identifiers. All
ParcelKey are the same size - 32bits, and are guaranteed to be unique within the creating
ParcelList for the lifetime of the Parcel. However, unlike a FrameUID, there is no guarantee of
uniqueness between Parcels in different ParcelLists - only within the ParcelList that created the
ParcelKey.
A ParcelKey is considered valid when its underlying value is non-zero. Only the creator of the
ParcelKey knows what the meaning of the underlying value is. Only zero has a pre-defined
meaning. See the declaration of the ParcelKey class for more information. Along with the
IParcelList API, various other Text APIs such as ITextParcelList, IParagraphComposer and
ITiler, have been changed to accept ParcelKeys instead of indexes.
To assist in the conversion of InDesign 2.0 code, additional methods have been added to the
IParcelList API to convert between indexes and ParcelKeys. For example:
UID foo(IParcelList* pl, int32 parcelIndex)
{
134
#10075 Porting Guide
Porting recipes
ParcelKey key = pl->GetNthParcelKey(parcelIndex);
return pl->GetFrameUID(key);
}
In addition, an iterator has been added to simplify the implementation of looping operations
across all or some Parcels in the ParcelList.
For example:
InterfacePtr<IParcelList> pl(somePMUnknown,
UseDefaultIID());
IParcelList::const_iterator iter = pl->begin();
IParcelList::const_iterator end = pl->end();
for (; iter != end; ++iter)
{
InterfacePtr<IParcel> parcel(pl->QueryParcel(*iter));
}
What has changed in IActionManager?
There are new versions of DoAction() and UpdateActionStates() in CActionComponent in
InDesign CS. The old methods are still in place for backwards compatibility. But we strongly
recommend you to use the new methods in your action component implementation, as they
give more infomation about how the action was invoked.
The rational behind the changes we made to IActionManager interface was for action
components that operate on panels. There was no foolproof way to know when an action
component was called with the panel it was associated. Normally this does not matter much
because there is only one of each type of panel. However, for the Library panel, there can be
multiple library panels open. So, which library panel do you operate on when an action ID
happens? Especially if the action is invoked via a keyborad shortcut? So we made the following
changes in this interface:
virtual void UpdateActionStates(IActiveContext* ac, IActionStateList *listToUpdate,
GSysPoint mousePoint = kInvalidMousePoint, IPMUnknown* widget = nil) = 0;
virtual void PerformAction(IActiveContext* ac, ActionID id, GSysPoint mousePoint =
kInvalidMousePoint, IPMUnknown* widget = nil) const = 0;
With those new changes, we can distinguish if the action was initially generated via a keyboard
shortcut or via the menu manager, thus can make decisions about which panel to operate on.
What has changed in ICreateFrameData?
ICreateFrameData is a data interface for the kCreateMultiColumnItemCmdBoss. It had a
method called SetActivateTextEditor(bool16 kTrue or kFalse). This setting was used within the
kCreateMultiColumnItemCmdBoss to issue to SelectTextCommand when it is true, thereby
activating the text editor at the end of the command. Primarily, this was used when drag
creating a text frame with the I-Beam tool, but there were also some cases when converting
between frame/frame grid types.
#10075 Porting Guide
135
#10075 Porting Guide
Porting recipes
We changed:
virtual void SetActivateTextEditor(bool16) = 0;
virtual bool16 WillActivateTextEditor() = 0;
to the following new methods:
virtual void SetActivateTextEditor(IControlView* view) = 0;
virtual IControlView* GetActivateTextEditorView() const = 0;
After this change, if the view is nil, text editor will not be activated. This is a small change, but
it eliminates the command’s dependency on the front view, which is not always the layout view.
Many current users of this command don’t set this value for the command, if so, you will be
able to compile with no changes.
What has changed in the OPI-related methods in IPDFDocPort?
The following methods have been updated to take an additional parameter, a const reference to
a PMMatrix: CreateOPIContent, AddOPIToContent, CreateOPIObject and
AddOPIContentToObjectRes.
In all cases, the matrix passed in is required to correctly calculate the object's oriented
bounding box as used in the ALDImagePosition DSC comment.
For CreateOPIObject and CreateOPIContent (which calls CreateOPIObject internally), the
matrix passed in should map the unit square [(0, 0) - (1, 1)] to default coordinates. These
methods are used to associate OPI dictionaries with images and therefore follow the behavior
of images in PDF, where images are drawn in a unit square (the CTM is used to map the square
to device space).
For AddOPIToContent and AddOPIToContentRes (which call AddOPIToContent internally),
the matrix passed in should map the passed-in bounds to default coordinates. These methods
are used to associate OPI dictionaries with placed PDF and EPS files.
There are no default values for these matrices as they are instance specific. An easy way to verify
their correctness is to export a test document to both PDF and EPS using the same omit for
OPI settings. Then compare the values in the PDF's OPI 1.3 dictionary (in the Position array)
with the corresponding ALDImagePosition comments in the equivalent EPS.
What has changed in IPrintDataHelperStrategy?
An IPrintDatahelperStrategy service allows a plug-in to influence controls on the Print dialog.
For instance, it can be used to hide or disable the control for a particular print property. The
method names on this interface have been changed to make their function clearer.
virtual bool16 IsAlwaysLocked(const IPrintData* printData,
IPrintData::Id id) const = 0;
changed to:
virtual bool16 IsLocked(const IPrintData* printData,
IPrintData::Id id) const = 0;
and:
136
#10075 Porting Guide
Porting recipes
virtual bool16 IsNeverRelevant(const IPrintData* printData,
IPrintData::Id id) const = 0;
changed to:
virtual bool16 IsRelevant(const IPrintData* printData,
IPrintData::Id id) const = 0;
NOTE: the logic for IsRelevant() has been reversed. If previously you returned kTrue for
IsNeverRelevant(), you would now return kFalse for IsRelevant().
What has happened to ITableFrameList?
The table support interface ITableFrameList (formerly aggregated on kTableModelBoss) has
been removed. We believe that this will have little impact because their implementation was so
primitive and most callers used and will continue to use ITableFrame to get information about
the layout of the table.
In InDesign 2.0, the combination of kTableFrameBoss and kRowAttrHeightBoss was sufficient
to describe the layout of the table, but this is no longer adequate to support headers and
footers. In particular the assumption that there was a one-to-one correspondence between
model rows and layout rows is no longer true.
To support this, we completely rewrote the way in which we describe the composed state of the
table. The new interface, named ITableLayout, also on the kTableModelBoss, provides
extremely detailed information about the layout of the table.
The information that used to be available via ITableFrameList is now available via
ITableLayout. Also, the kTableFrameBoss now simply represents a way to anchor the table into
the text flow and no longer contains any persistent layout data. The underlying
implementation of ITableFrame on this boss simply calls ITableLayout to get the desired
information.
Why was the "removed" parameter dropped from ITextAttributeSuite::ApplyAttributes?
This was changed because there is no concept of removing attributes in this manner. The
implementation couldn't have achieved what the caller might expect, and that parameter was
never used.
If you are trying to use the "removed" parameter, either look at applying the correct attribute,
or use ITextModelCmds::ClearOverridesCmd() to get a command that will remove an
override.
In class ITextAttributeSuite:
virtual ErrorCode ApplyAttributes(AttributeBossList* applied,
AttributeBossList* removed, const ClassID& strandID) = 0;
changed to:
virtual ErrorCode ApplyAttributes(const AttributeBossList*
applied, ClassID strandID) = 0;
#10075 Porting Guide
137
#10075 Porting Guide
Porting recipes
What have happened to the command generator methods in ITextModel, and what
should I use instead?
The functions on the ITextModel interface which allowed constructing text edit commands
have been moved to a new interface called ITextModelCmds. These functions are PasteCmd,
InsertCmd, DeleteCmd, ReplaceCmd, TypeTextCmd, ApplyCmd, ApplyStyleCmd,
UnapplyStyleCmd, ClearOverridesCmd, and UserApplyCmd.
Further to moving these functions from one interface to a new one, we changed the types that
used to pass WideString and AttributeBossList objects from using pointers to using
K2::shared_ptr. The reason we've introduced K2::shared_ptr is to allow the command and its
clients to share WideString/AttributeBossList objects. This facilitates using these commands, as
the client no longer has to worry about being responsible for deleting these objects.
When you recompile your plug-in code with the updated ITextModel interface, you will get
compiler errors if you use one of the functions mentioned above. To fix the compile errors,
there are three things to do:
1.
Define an ITextModelCmds interface and move all the calls to command constructor
functions to the ITextModelCmds interface.
2.
Where you were passing a pointer to AttributeBossList to a command constructor
function, switch to using a K2::shared_ptr.
3.
Where you were passing a pointer to WideString to a command constructor function,
switch to using a K2::shared_ptr.
The following example shows how the usage of ITextModel::InsertCmd is changed. Suppose
your code looked like this:
InterfacePtr<ITextModel>model(textStoryUIDRef,
UseDefaultIID());
TextIndex start = model->TotalLength()/2;
WideString myString ("My string");
InterfacePtr<ICommand> iCmd(model->InsertCmd(start, myString,
kTrue/*copy data*/));
CmdUtils::ProcessCommand(iCmd);
You will get a compiler error about InsertCmd not being defined for class ITextModel. The
ported code looks as follows:
#include "K2SmartPtr.h"
#include "ITextModelCmds.h"
...
InterfacePtr<ITextModel>model(textStoryUIDRef,
UseDefaultIID());
InterfacePtr<ITextModelCmds>modelCmds(model, UseDefaultIID());
TextIndex start = model->TotalLength()/2;
K2::shared_ptr<WideString> myString(
new WideString("My string"));
InterfacePtr<ICommand> iCmd(modelCmds->InsertCmd(start,
138
#10075 Porting Guide
Porting recipes
myString));
CmdUtils::ProcessCommand(iCmd);
Notice how the usage of K2::shared_ptr made it not necessary to have to remember that
the command had to copy the WideString object because the latter is a stack-based object.
My selectable dialog doesn’t seem to validate when the user switches. What has changed
in selectable dialogs?
Unlike InDesign 2.0, InDesign CS does not call IDialogController::
ValidateDialogFields for the individual selectable dialog panels when the user
switches panels using the panel selection list. You can see this behavior change using the
paragraph style's justification panel using the steps below:
1.
Start InDesign.
2.
Paragraph Styles Panel>New Paragraph Style...
3.
Switch to Justification panel using panel list.
4.
Enter 133% for Minimum word spacing 80% for Maximum word spacing.
5.
Switch to Hyphenation panel using panel list.
Under InDesign 2.x an invalid word spacing alert in popped at this point. Under InDesign CS
no alert is popped, the validation runs and the alert gets popped when you click the OK button.
If you need to have dialogs validate when the user switches panels adapt the recipe below to
your plug-in. The recipe adds dialog controllers to the panels in the BasicSelectableDialog
plug-in then extends the sample to run dialog validation when the user switches panels:
1.
Add dialog controllers to the selectable dialog's panels. Implement the
YinPanelController and YangPanelController C++ classes based on
CDialogController.(you will likely already have these in your own plug-in and can skip
this step, otherwise see BasicDialog for sample CDialogController implementation).
Class
{
kYinPanelBoss,
kPrimaryResourcePanelWidgetBoss,
{
/** Creates the Yin panel by informing the
DialogPanelService of the service IDs and panel view
resource IDs used by this boss. */
IID_IPANELCREATOR, kYinPanelCreatorImpl,
/** Registers panel as member of the DialogPanelService. */
IID_IK2SERVICEPROVIDER, kDialogPanelServiceImpl,
/** Controls the panel's dialog. */
#10075 Porting Guide
139
#10075 Porting Guide
Porting recipes
IID_IDIALOGCONTROLLER, kYinPanelControllerImpl,
}
},
Class
{
kYangPanelBoss,
kPrimaryResourcePanelWidgetBoss,
{
/** Creates the Yin panel by informing the
DialogPanelService of the service IDs and panel view
resource IDs used by this boss. */
IID_IPANELCREATOR, kYangPanelCreatorImpl,
/** Registers panel as member of the DialogPanelService. */
IID_IK2SERVICEPROVIDER, kDialogPanelServiceImpl,
/** Controls the panel's dialog. */
IID_IDIALOGCONTROLLER, kYangPanelControllerImpl,
}
},
2.
Extend your selectable dialog's observer (your CSelectableDialogObserver
implementation your kSelectableDialogBoss or kTabSelectableDialogBoss boss class) so
that it calls validation.
void BscSlDlgDialogObserver::Update(
const ClassID& theChange,
ISubject* theSubject,
const PMIID& protocol,
void* changedBy)
{
bool16 handledMessage = kFalse;
if (theChange == kListSelectionChangedByUserMessage &&
protocol == IID_ILISTCONTROLDATA)
{
/* Unlike InDesign 2.0, InDesign CS does not call
ValidateDialogFields for the individual panel dialogs when
the user switches panels using the panel selection list. If
your plug-in depends on this you can call validation
yourself using this workaround. Look for a dialog
controller on the panel that is currently selected. */
140
#10075 Porting Guide
Porting recipes
InterfacePtr<ISelectableDialogSwitcher>
selectableDialogSwitcher(this,
IID_ISELECTABLEDIALOGSWITCHER);
WidgetID currentPanelWidgetID =
selectableDialogSwitcher->GetPanelWidgetID(
selectableDialogSwitcher->GetCurrentPanelIndex());
IControlView* currentPanelControlView =
selectableDialogSwitcher->
GetDialogPanel(currentPanelWidgetID);
InterfacePtr<IDialogController>
currentPanelDialogController(currentPanelControlView,
UseDefaultIID());
if (currentPanelDialogController)
{
/* Run dialog validation. */
WidgetID invalidWidgetID =
currentPanelDialogController->ValidateDialog();
if (invalidWidgetID != kDefaultWidgetId)
{
/* Validation failed. Force the user to stay on this
panel. */
selectableDialogSwitcher->
SwitchDialogPanelByID(currentPanelWidgetID);
/* Focus on the invalid widget. */
currentPanelDialogController->
SelectDialogWidget(invalidWidgetID);
/* We've handled this message so don't pass it on to
the base class.*/
handledMessage = kTrue;
}
}
}
if (!handledMessage)
{
/* Call base class Update function so that default behavior
will still occur (selectable dialog listbox, OK and Cancel
buttons, etc.). */
#10075 Porting Guide
141
#10075 Porting Guide
Porting recipes
CSelectableDialogObserver::Update(theChange, theSubject,
protocol, changedBy);
}
/* Handle other widget's that are common to your selectable
dialog panels here... */
}
How have the CanSplitCell/SplitCell methods in ITableSuite, ITableCommands and
ITableModel changed?
In InDesign 2.0, ITableCommands and ITableModel had CanSplitCell/SplitCell methods to
split a cell given an anchor. For vertical splits, ITableSuite iterated over the anchors in the
current selection and called ITableCommands' respective methods; for horizontal splits,
ITableSuite called those methods to split only the top left cell in the selection.
In InDesign CS, we have replaced these methods with CanSplitCells/SplitCells. These methods
take a GridArea of cells instead of a GridAddress anchor.
CanSplitCell(GridAddress) was changed to CanSplitCells(GridArea).
SplitCell(GridAddress) was changed to SplitCells(GridArea).
To convert, simply pass in a GridArea containing only that anchor. For instance
GridAddress(row, col) becomes GridArea(row, col, row + 1, col +
1).
How has IPhase2Conversion changed?
In InDesign 2.x, the way to obtain the database root in a phase 2 data converter was to call
IPhase2Conversion::GetDataBase, and then to call db->GetRootUID() to get
the document or workspace. However, when you are converting a library asset, the root of the
asset is not the root of the database, so this approach fails. To address this issue, a new method
GetRootObject has been added to the IPhase2Conversion interface to allow phase 2
converters to convert assets in libraries. Also, GetRootObject returns a UIDRef, so the
IPhase2Conversion::GetDataBase method has been removed, requiring clients to
use the new GetRootObject method and to retest their phase 2 converters.
Where the phase2 converter used to do this:
IDataBase* db = iPhase2Conversion->GetDataBase();
InterfacePtr<IDocument> doc(db, db->GetRootUID(),
UseDefaultIID());
if (doc == nil)
{
// we only convert documents
142
#10075 Porting Guide
Summary
return;
}
// example conversion follows
InterfacePtr<IStoryList> storyList(doc, UseDefaultIID());
for(int32 i = storyList->GetAllTextModelCount() - 1;
i >= 0;
i--)
//...
The phase 2 converter should now do something like this:
UIDRef rootObj = iPhase2Conversion->GetRootObject();
InterfacePtr<IStoryList> storyList(rootObj, UseDefaultIID());
if (storyList == nil)
{
return;
}
// we could be converting either a document or an asset...
for (int32 i = storyList->GetAllTextModelCount() - 1;
i >= 0;
i--)
//...
For more information on data converters, refer to the Data Conversion technote
(dataconversion.pdf).
I am using an interface and/or class which is not mentioned in this Porting Recipes
section. How can I find out what changed?
Refer to the InDesign/InCopy 2.x -> InDesign CS/InCopy CS API Advisor reports in the SDK
(/docs/references/ APIAdvisorID2_vs_ID3.html) for details.
Summary
This document presented information that helps port plug-in code from the InDesign 2.x and
InCopy 2.x SDKs to the combined current SDK. The main emphasis has been on providing
detailed specifications that can be used as the basis of converting plug-ins from the 2.x SDK to
the current SDK, and on building plug-ins from scratch that will compile with the current SDK
and execute within InDesign CS/InCopy CS. The project settings detailed in this document
conform to the settings of projects in the InDesign CS/InCopy CS application plug-ins and
third-party developers should take heart from these being made fully explicit for their use.
#10075 Porting Guide
143
#10075 Porting Guide
References
There has also been an attempt to catalogue the most common code-related issues that you
might encounter when converting code from the 2.x to the current version and resolutions
have been suggested for these. In the majority of cases these are the results of simplifying refactorings in the public API. In addition some new features of the API have been described (in
sufficient depth to create working implementations) that deliver benefits for third-party
developers.
References
Tech note #10006; Selection.
Tech note #10071; Diagnostics.
Tech note #10078; Unicode 3.x and String-related APIs.
Tech note #10082; Making Your Plug-In Scriptable.
http://saxon.sourceforge.net
http://www.w3c.org/Style/XSL
http://www.w3.org/Graphics/PNG
http://java.sun.com/j2se/1.4/index.html
Appendix
Parameters for DollyXs
This information is provided for reference only. The user interface hides the detail of the
parameters within the XML configuration file that DollyXs transforms via its stylesheets into
code. The DollyXS GUI code reads and writes this specification (contained in inputwin.xml or
inputmac.xml) at start-up and shutdown of DollyXS respectively. The XML-based
specification for a plg-in contains the following:
1.
global attributes of the code to be generated, such as the plug-in long name, short-name
and so on. These are shown in the table <code> attributes for DollyXs.
2.
Elements that control what is generated in the output. These are shown in the table Valid
elements for a DollyXs code specification.
TABLE 1.55 <code> attributes for DollyXs
144
Attribute name
Description
long-name
This is a mixed case name for the plug-in. For instance, BasicMenu is
an example of a long-name attribute.
#10075 Porting Guide
Appendix
Attribute name
Description
folder-name
This is typically just the lower case form of the plug-in long-name for
SDK plug-ins.
short-name
An abbreviated variant of the long-name that results in more
compact names for generated files. For instance, BscMnu is the shortname attribute for the BasicMenu sample plug-in.
prefix-number
This is something like 0x57200, the prefix ID for the BasicMenu
sample. You should obtain a prefix ID range from Adobe Developer
Support to guarantee that your prefix ID won’t clash with application
or other third-party plug-ins.
output-dir
This is the directory to which the plug-in sample code would be
generated. This could be something like c:\id3sdk\source\sdksamples
when running on Windows, or /mac/id3sdk/source/sdksamples when
running on Macintosh.
owner-name
This is something to personalise your plug-in code, e.g. the lead
developer’s name.
win-project-output-dir
This is where the generated project file is written, if one is desired.
This attribute is required if you have specified <vcproj-file/> in the
element list. A typical setting on Windows would be
c:\id3sdk\build\win\sdkprj, and on Macintosh
/mac/id3sdk/build/mac/sdkprj.
mac-project-output-dir
This is the path to which the generated mcp.xml would be written, if
one is desired. It is required if you have specified <mcp-xml-file/> in
the element list.
Below are shown elements that can occur in a DollyXs code specification which control the
generated code.
TABLE 1.56 Valid elements for a DollyXs code specification
Element
Description
<menu-item name="ItemOne"/>
Optional but useful. Include one of these for each
menu item that you would like in your plug-in. The
‘name’ attribute should be unique for each menu
item to generate valid code.
<generate-panel/>
Optional. If you include this element, then the
generated plug-in will support a panel. If you
comment it out with <!-- and --> then you will
find that it doesn’t generate the code supporting a
panel.
#10075 Porting Guide
145
#10075 Porting Guide
Appendix
146
Element
Description
<generate-dialog/>
Optional. If you include this element, then the
generated plug-in will support a dialog. If you
comment out this element from your specification
with <!-- and --> (you should also comment out
the dialog controller/observer bits) then it won’t
generate support for a dialog.
<dialogcontroller-file namepostfix="DialogController"/>
Required if you have <generate-dialog/>
<dialogobserver-file namepostfix="DialogObserver"/>
Required if you have <generate-dialog/>
<generate-menu/>
Required. You should not omit this at the time of
writing if you want a plug-in that is sensible. If you
have a <generate-panel/> element, then the menu
items will be on the panel popout menu. If you
have <generate-dialog/> but no panel, then the
menu items will be descendants of the Plug-ins
menu of the application itself.
<actioncomponent-file namepostfix="ActionComponent"/>
Required. You should not at the time of writing
need to change the name-postfix attribute since
DollyXs does not yet support multiple action
components.
<id-h-file/>
Required. This is responsible for generating a file
that takes on the short-name and postfixes ID.h.
For instance, if the short name is BscMnu, then the
generated file would be named BscMnuID.h.
<id-cpp-file/>
Required. Generates <short-name>ID.cpp
<nostrip-file/>
Required. Generates <short-name>NoStrip.cpp
<triggerresourcedeps-file/>
Required. Generates TriggerResourceDeps.cpp
<factorylist-file/>
Required. Generates <short-name>FactoryList.h
<rc-file/>
Required. Generates <short-name>.rc
<fr-file/>
Required. Generates <short-name>.fr, the toplevel framework resource file (ODFRez).
<enus-fr-file/>
Required. Generates English-US locale-specific
string table.
<jajp-fr-file/>
Required. Generates Japanese locale strings.
#10075 Porting Guide
Appendix
Element
Description
<vcproj-file/>
Required if you want a Windows project. If you
include this you will generate a project file to the
path given by the <code> attribute named winproject-output-dir. The project file takes on the
long-name <code> attribute. For instance, if the
long-name is BasicMenu, then the generated
project file would be BasicMenu.vcproj.
<mcp-xml-file/>
Required if you want a Macintosh project in XML
format that CodeWarrior can import. If you
include this you will generate a mcp.xml file to the
path given by the <code> attribute mac-projectoutput-dir. Again this is named after the longname <code> attribute.
Parameters for SnowGoose
This information is provided for reference only. The user interface hides the detail of the
parameters within the XML configuration file that SnowGoose transforms via its stylesheets
into code. The SnowGoose GUI code reads and writes this specification (contained in
inputwin.xml or inputmac.xml) at start-up and shutdown of SnowGoose respectively. The
XML-based specification for converting a plug-in projects contains the following elements:
TABLE 1.57 <code> attributes for SnowGoose
Attribute
Description
long-name
Required. Specifies the long-name of the plug-in. This is used to
generate the project file. For instance, BasicMenu is the long name
associated with the plug-in BasicMenu.pln. If you were converting a
Windows project, then SnowGoose would generate its output to
something like c:\id3sdk\build\mac\sdkprj\BasicMenu.vcproj.
folder-name
Required. This is typically the lower-case form of the plug-in long
name, for the SDK plug-ins. For instance, the folder name basicmenu
is associated with BasicMenu.pln.
short-name
Required. This is an abbreviated form of the long-name. For instance,
BscMnu is the short-name for BasicMenu.pln.
input-win-project
Required if you’re generating a Windows project. This is the project
file (.dsp) that you are attempting to convert to the current SDK
organisation.
#10075 Porting Guide
147
#10075 Porting Guide
Appendix
148
Attribute
Description
win-project-output-dir
Required if input-win-project is defined. This folder ideally should
exist before running SnowGoose. The <long-name>.vcproj that
SnowGoose creates will be generated into this folder. It will overwrite
an existing <long-name>.vcproj without prompting, so be aware of
this.
input-mac-project
Required if you’re generating a Windows project. This should be an
mcp.xml file that you have already exported from CodeWarrior from
your existing 2.0 project.
mac-project-output-dir
Required if input-mac-project is defined. This folder ideally should
exist before running SnowGoose. The generated file that would be
named <long-name>_SNOWGOOSEOUT.mcp.xml file is created in
this folder.
#10075 Porting Guide
Appendix
#10075 Porting Guide
149
#10075 Porting Guide
Appendix
150