22 Replies Latest reply on Sep 21, 2008 3:22 AM by (Rod_Kiln)

    Using Delphi, and the InDesign automation object ("indesign

      Using Delphi, and the InDesign automation object ("indesign.application"), I need to open a indd file, move to a bookmark and insert text or picture at that exact location. Any examples of such code I could start with?
        • 1. Re: Using Delphi, and the InDesign automation object ("indesign
          Level 1
          Bill,

          I moved your message to start a new topic because you added to an existing topic that had nothing at all to do with yours.

          I'm afraid I can't answer you question, though, being a JavaScripter.

          Dave
          • 2. Re: Using Delphi, and the InDesign automation object ("indesign
            Hi Bill,

            if your still into Delphi InDesign coding, I'm your man.... :)
            Doin it every day!

            What exactly do you want to know?
            What did you reach yet?

            Know how to handle ID with Delphi in general?

            Here's some code to start with:

            ]
            function THelloWorld.ConnectToIndesign():Olevariant;
            var VIdApplication:Olevariant;
            begin
            result := nil;
            VIdApplication := Unassigned;
            try
            VIdApplication := CreateOleObject('InDesign.Application.CS3');
            if not VarIsNull(VIdApplication) then
            result := VIdApplication;
            except
            ShowMessage('InDesign could not be started!');
            exit;
            end;
            end;

            @Dave
            It's a great honor for me to know something you don't (yet)! *grin*
            Especially after learning so much from you and your Blog!

            Marc
            • 3. Re: Using Delphi, and the InDesign automation object ("indesign
              Level 1
              Thanks for the info. I basically just need to open a indd file that has already been constructed by the user. They would have placed bookmarks on the page where they want information from our database to go, and in fact, some pictures also. I've got the whole thing done using the Word object via Delphi and just need to make the changes to accomadate InDesign.

              Can you move to a bookmark and place text autmatically with InDesign?

              With Word, I do this:

              try
              MSWordObj := GetActiveOleObject('Word.Application');
              except
              MSWordObj:=CreateOLEObject('Word.Application');
              end;
              MSWordObj.Documents.Open (sOLETemplate);
              bm:=MSWordObj.ActiveDocument.bookmarks.count;
              tsBM:=TStringlist.create;
              for k:=1 to bm do
              begin
              strField:=MSWordObj.ActiveDocument.bookmarks.item(k).name;
              tsBM.add(lowercase(strField));
              next
              //I need to get a list of bookmarks for other reasons

              //Then move to the different bookmarks
              MSWordObj.Selection.GoTo(-1,0,0,strField);
              //And insert the text
              MSWordObj.Selection.TypeText(s);
              //or picture
              MSWordObj.Selection.InlineShapes.AddPicture(s2);

              //add sometimes I'll force stuff onto the
              //clipboard and then paste it into Word. MSWordObj.Selection.ShapeRange.TextFrame.TextRange.Select;
              MSWordObj.Selection.Paste;

              //sometimes multiple pages are required, so I do this:
              MSWordObj.Selection.EndKey(6);
              MSWordObj.Selection.InsertBreak(7); //page break
              MSWordObj.Selection.InsertFile(sOLETemplate);

              Is there a better way than using bookmarks in InDesign? I really don't want to do the merge with XML's.

              Thanks...
              • 4. Re: Using Delphi, and the InDesign automation object ("indesign
                Level 1
                I don't really understand...

                They have made the documents or they will make them?
                Did they use "bookmarks" or will they use them if you tell them to do so?

                Did you import the InDesign Typelibrary?
                It's very helpful when coding ID in Delphi!

                // declaration
                var vIdApplication1:Olevariant;
                idDoc1:Document;
                idPage1:Page;
                ov1:Olevariant;
                s1:String;

                // to get the application
                vIdApplication1 := CreateOleObject('InDesign.Application.CS3');

                {
                to open a document
                Here you see, how to typecast olevariants
                You have to typecast twice: one the IDispatch, then the real
                ID type from the typelibrary.
                If you typecast them, you will get coding help from BDE.
                }
                idDoc1 := _Application(IDispatch(vIdApplication1)).Open(aDocname, True);

                {
                If you typecasted to a real InDesign type, you'll reget real
                InDesign types (and pointers) from functions.
                }
                idPage1 := idDoc1.pages.firstItem();

                {
                Then you have to get the pointer to an object
                In InDesign you need Textframes to place text, not only selections.
                There are several ways to mark textframes so you can find them for
                text input. The easiest is to get them by their scriptlabel.
                }
                s1 := 'MyTestframelabel';
                vTxt1 := idDoc1.Textframes.Item(s1);

                // and then you can put text into it
                vTxt1.contents := 'Hello world';

                {
                to place images instead of text you can 'place' the file
                }
                ov1:= vTxt1.place('c:\images\myimage.jpg');

                [t.b.c.]

                This should lead you on the right track....
                Don't hesitate to ask further questions....

                Marc
                • 5. Re: Using Delphi, and the InDesign automation object ("indesign
                  Level 1
                  The users will create the docs and put the proper bookmarks in them. But you mention another way, so do you label textframes so they can be referenced by their scriptlabel.

                  What's the name of the type library for InDesign to use with Delphi. With Word its called Word_TLB.pas

                  One more thing, how would you move to the end of the current page and insert a duplicate of the current page, similat to:
                  MSWordObj.Selection.EndKey(6);
                  MSWordObj.Selection.InsertBreak(7); //page break
                  MSWordObj.Selection.InsertFile(sOLETemplate);

                  Thanks again.
                  • 6. Re: Using Delphi, and the InDesign automation object ("indesign
                    Level 1
                    Hi,

                    it's called "Resources for Visual Basic.pas".
                    You can import it via BDS:

                    Menu:Components
                    -> Import component
                    -> Import Type Library
                    ->Adobe InDesign CS3 Type Library

                    In InDesign you just have to duplicate the last page:

                    >idDoc1.pages.lastItem().duplicate(idAtEnd);

                    Marc
                    • 7. Re: Using Delphi, and the InDesign automation object ("indesign
                      Level 1
                      I think bookmarks would work well for what I need to do, so I would like to be able to list all the bookmarks in a doc, change them if necessary, and then goto to them and place text or images.

                      Regarding this:
                      -> Import component
                      -> Import Type Library
                      ->Adobe InDesign CS3 Type Library

                      I'm still using Delphi3 for development so it looks like I have to wing it there. Is there any type of ".pas" file out there like there is for Word.
                      • 8. Re: Using Delphi, and the InDesign automation object ("indesign
                        Level 1
                        Delphi creates the .pas file after you imported the type library.
                        Use your Delphi3 help. There must be a possibility to import "type libraries".

                        Marc
                        • 9. Re: Using Delphi, and the InDesign automation object ("indesign
                          Level 1
                          Marc

                          I can use the Object Browser in VB to view all the methods and parameters, but I still can't figure out how to simply insert text or an image once I move to a bookmark called "Description" using:

                          InDesignDoc.Bookmarks('Description').ShowBookmark;

                          Also, I still can't figure out how to label a textframe so I can access it later via the method you described earlier.
                          • 10. Re: Using Delphi, and the InDesign automation object ("indesign
                            Level 1
                            Hi Bill,

                            Sorry to be so late getting to this thread!

                            If you want to add something to a page, or find an object that's on a page, you need a reference to the page. Simply displaying the page with ShowBookmark won't give you a reference to the page--InDesign scripting, for the most part, doesn't rely on the selection and current view in the way that Word scripting does (this is a good thing, but that's a topic for another day).

                            You had to have a reference to a page to create the HyperlinkPageDestination that you used to create the bookmark--but, if not, you can get a reference to the page using (VBScript form):

                            Rem Given a reference to an instance of InDesign "myInDesign"...
                            myInDesign.Bookmarks.Item("Description").ShowBookMark
                            Set myPage = myInDesign.ActiveWindow.ActivePage

                            In general, though, you probably don't need the bookmark and the whole "ActiveWindow" construct--just use the reference to the page itself.

                            Now that you have a page, you can put things on the page.

                            Rem Create a rectangle
                            Set myRectangle = myPage.Rectangles.Add
                            Rem Size and position the rectangle
                            myRectangle.GeometricBounds = Array("6p", "6p", "24p", "24p")
                            Rem Place a graphic in the rectangle
                            myRectangle.Place "c:\test.tif"

                            If you have a text frame on the page that has the label "myLabel", you can get a reference to the text frame and add text:

                            Set myTextFrames = myPage.TextFrames.Item("myLabel")
                            Rem myTextFrames will return an array--get the first item
                            Set myTextFrame = myTextFrames(0)
                            Rem Replace the text in the text frame:
                            myTextFrame.Contents = "This is some text."
                            Rem Or add text to the end of the text frame:
                            myTextFrame.InsertionPoints.Item(-1).Contents = "This is some additional text."

                            If you know that there is only one text frame with the label "Description" in the entire document, you can even say:

                            Set myTextFrames = myDocument.TextFrames.Item("myLabel")
                            Rem myTextFrames will return an array--get the first item
                            Set myTextFrame = myTextFrames(0)

                            ...to get to it directly. If, at that point, you want to get at the page containing the text frame (and assuming that the text frame is not in a group, pasted inside text, or pasted inside another page item), you can use:

                            Set myPage = myTextFrame.Parent

                            Have you looked through the "Working with Documents" chapter of the InDesign CS3 Scripting Guide: VBScript and the associated scripts archive? I realize that you're using Delphi, but it doesn't look too difficult to convert from one to the other.

                            Thanks,

                            Ole
                            • 11. Re: Using Delphi, and the InDesign automation object ("indesign
                              Level 1
                              In InDesign you need XY-coordinates to place texts or images.
                              This is why bookmarks are not the best choice to place something!

                              *Does your bookmark point to a specific page?
                              *When you've got the page the bookmark points to, do you know where to place your text and images then?
                              *Or does your bookmark point to a specific text?
                              *Do you want to replace this text?

                              You must have a page and a xy-position on that page.
                              THEN you can place an image or a text.

                              If there are frames yet to contain the texts or images, you can place the text or the images THERE. But you will have to identify them to get a pointer.

                              If you would send me your target document as an example, maybe I would be able to tell you some more specific.

                              Marc
                              • 12. Re: Using Delphi, and the InDesign automation object ("indesign
                                Level 1
                                Thanks guys. I'll have my users create simple pages with text frames that I will fill with text and images from my Delphi database application.

                                My only question remains how do I label a text frame while I'm actually creating the document in InDesign? Why am I not seeing something that must be so easy?

                                Bill
                                • 13. Re: Using Delphi, and the InDesign automation object ("indesign
                                  Level 1
                                  Hi Bill,

                                  You can use the Script Label panel (Window>Automation>Script Label) to add a label the the text frame in the user interface. Or, via script (VBScript form again):

                                  Rem Given a reference to a text frame "myTextFrame"...
                                  myTextFrame.Label = "myLabel"

                                  Thanks,

                                  Ole
                                  • 14. Re: Using Delphi, and the InDesign automation object ("indesign
                                    Level 1
                                    You can enter a script label in the script label palette:
                                    InDesign Menu:
                                    -> Window
                                    -> Automation
                                    -> Script Label

                                    When you activate an object in your document you can then enter a label there!

                                    Pay attention:
                                    The label is only stored with the object, if the object is deactivated again. There is no "save"-button!

                                    Marc

                                    P.S.: Ok, now you know it twice..... :)
                                    • 15. Re: Using Delphi, and the InDesign automation object ("indesign
                                      Level 1
                                      Is there a way to have multiple labels per text-frame and access them accordingly via vbscript? For instance, if I assign 3 labels to one text-frame (i.e., Desc1, Desc2, Desc3), only the last entry of the script seems to be recognized and errors on the others:

                                      InDesignDoc.textframes('Desc').contents:='line1';
                                      //errors - requested member of collection does not exist
                                      InDesignDoc.textframes('Desc2').contents:='line2';
                                      //errors - requested member of collection does not exist
                                      InDesignDoc.textframes('Desc3').contents:='line3';
                                      //works fine

                                      Also, I need to be able to set attributes on the text that is assigned as it is added to the text frame. For instance, I need the first line that I assign to be bold.

                                      What I did with Word was move to a bookmark, set the attributes, then used the TypeText method like this:

                                      MSWordObj.Selection.GoTo(-1,0,0,'myBookmark');
                                      MSWordObj.Selection.Font.Bold:=true;
                                      MSWordObj.Selection.TypeText('bold text');
                                      MSWordObj.Selection.Font.Bold:=false;
                                      MSWordObj.Selection.TypeText('more plain text');

                                      There must be something similar with InDesign, yes?

                                      Thanks, Bill
                                      • 16. Re: Using Delphi, and the InDesign automation object ("indesign
                                        Level 1
                                        Hi Bill,

                                        When you say you "assign 3 labels to one text frame," what exactly do you mean? While a text frame can have multiple labels, setting the textFrame.label property to a string only sets one label. The others are set via the textFrame.insertLabel method. Only the textFrame.label property works to identify the text frame in the page.textFrames.item("label") construction. I can't tell, from the above, if you're trying to address one text frame, or three...?

                                        Next, the InDesign way to accomplish the TypeText method is to set the contents of an insertion point object to a string, as in (VBScript form):

                                        Rem Given a reference to a text frame "myTextFrame"...
                                        Rem Enter text at the first insertion point in the text frame:
                                        myTextFrame.InsertionPoints.Item(1).Contents = "Start of the text."
                                        Rem Enter text at the last insertion point in the text frame:
                                        myTextFrame.InsertionPoints.Item(-1).Contents = "End of the text."

                                        (Note that no selection is necessary to do this.)

                                        Thanks,

                                        Ole
                                        • 17. Re: Using Delphi, and the InDesign automation object ("indesign
                                          Level 1
                                          Ole

                                          Bingo on text stuff. Worked great.

                                          If I place an image into a text frame like this:
                                          InDesignFrm:=InDesignDoc.TextFrames('Picture');
                                          InDesignFrm.place('c:\temp\clouds.bmp');

                                          How do I size the picture proportionally to the frame at that point? I know I need to use the Fit method somehow with these settings:
                                          idFitContentToFrame
                                          idProportional

                                          but I don't know how to use them.

                                          Thanks, Bill
                                          • 18. Re: Using Delphi, and the InDesign automation object ("indesign
                                            Level 1
                                            Is there a way to place more than one image into a text frame and size them proportionally?

                                            Bill
                                            • 19. Re: Using Delphi, and the InDesign automation object ("indesign
                                              Level 1
                                              Hi Bill,

                                              Well...two things. First, if you place an image in the text frame the way you're doing it, the image will replace the text content in the frame. Is that what you want?

                                              If, instead, you want to place the graphic in text as an anchored graphic, then you need to return to our friend the insertion point and tell it to place the graphic. If you do that, you get a graphic that moves along with the text as the text is edited and flows from page to page. Is that what you want?

                                              There are good reasons to use either the first method (independent graphics) or the second (anchored graphics)--it all depends on what you want to do.

                                              re: "Is there a way to place more than one image into a text frame and size them proportionally?"

                                              The answer to this question depends entirely on your answer to the above questions. If the former (independent frames), then, no, not without trickery; if the latter, then, yes, but it might not be what you want.

                                              Re: fitting the frame to the graphic or vice versa

                                              Once you place the graphic, InDesign returns an array of references to the graphics (it does this because it's possible to place more than one file at once). Usually, you want the first item of the array. The parent of that object is the frame containing the graphic. That's usually the right place to direct your fitting commands. Something like this (VBScript form):

                                              Rem Given a reference to a graphic "myGraphic"...
                                              myGraphic.Parent.Fit idFitOptions.idContentToFrame

                                              I'm not sure about Delphi--you might have to use the decimal form of the enumeration--1684883046, in this case.

                                              You might also take a look at the ImageCatalog.vbs script that comes with InDesign CS3--it's in the Scripts panel (or in the Scripts Panel folder inside the Scripts folder in your InDesign application folder). It's got quite a lot of image handling code in it.

                                              Thanks,

                                              Ole
                                              • 20. Re: Using Delphi, and the InDesign automation object ("indesign
                                                Level 1
                                                Thanks again.

                                                So I have a one page template that I want to populate with information from a database via Delphi. I open the template, move to the proper textframes and place the text or image in there. That's all fine.

                                                Then I move to the next record and I want to add that same fresh template again at the end of the current document I'm working on. I think I need to remove the textframe labels from the existing document before I insert a new template or else they would be redundant or are the organized by pages? If not, is there another way to access them besides:
                                                InDesignDoc.textframes('myTextFrameLabel')
                                                • 21. Re: Using Delphi, and the InDesign automation object ("indesign
                                                  Level 1
                                                  Hi Bill,<br /><br />re: InDesignDoc.textframes('myTextFrameLabel')<br /><br />Sure. There are many ways to get at objects. You can use a page, a spread, a layer, or any other container. The basic form is:<br /><br />Document.container.pageItems.item(index_or_string)<br /><br />Where <container> can be Spread, Page, Layer<br /><br />That means that there's no conflict, provided that the page items are unique within their container.<br /><br />Thanks,<br /><br />Ole
                                                  • 22. Re: Using Delphi, and the InDesign automation object ("indesign
                                                    Indesign with Delphi
                                                    Dear Delphi-Friends:

                                                    There is a picture image frame in an Adobe Indesign CS3 document INTO which I want to load a picture from a folder (path known).
                                                    As a beginner, I dont know exactly how to access the OLE-container with Indesign. How can I get to the document and then address the image frame?

                                                    With a button in my Delphi Program, I would like to insert the image into an already created Indesign document where the image fame is already placed. So, I know the document, I know the frame. How can I bring my image into this frame.

                                                    Actually there are 5 image frames with text frames underneath. I think if I know how to address the image frames, I could adapt the routine to load text into the text frames in a similar way.

                                                    If somebody has something to start with, I would be very grateful.
                                                    Thanks,
                                                    Rod