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