17 Replies Latest reply on May 15, 2012 8:58 AM by Larry G. Schneider

    [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")

      Hi

      I have a huge problem with the InDesign Duplicate method.

      Previously I have used copy/paste, but everyone advises me to avoid the clipboard, so I decided to switch to the Duplicate method.

      Basically what I want to do is to copy a text frame to the first page of my InDesign document. Theoretically this should be possible with the following code snippet (assuming that InDesign is instantiated):

      InDesign.Document doc = app.ActiveDocument;
      InDesign.TextFrame frame = (InDesign.TextFrame)doc.TextFrames[1];
      InDesign.TextFrame df = (InDesign.TextFrame)frame.Duplicate(doc.Pages.FirstItem(), new double[2] { 0, 0 });

      Everything seems to work just fine - the textframe is copied/duplicated to the first page, but then I get an exception: "Return argument has an invalid type".

      I have tried replacing the third line with any of the following lines, but I always get the return argument error:

      frame.Duplicate(doc.Pages.FirstItem(), new double[2] { 0, 0 });
      InDesign.PageItem df = frame.Duplicate(doc.Pages.FirstItem(), new double[2] { 0, 0 });
      InDesign.PageItem df = (InDesign.PageItem)frame.Duplicate(doc.Pages.FirstItem(), new double[2] { 0, 0 });
      object df = frame.Duplicate(doc.Pages.FirstItem(), new double[2] { 0, 0 }) as object;
      object df = (object)frame.Duplicate(doc.Pages.FirstItem(), new double[2] { 0, 0 });

      What am I doing wrong?

      Pls. help!

      Thanks in advance!

      Best regards,
      Bo
        • 1. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
          Level 1
          Hi Bo,

          It's probably the usual problem with C# and InDesign scripting--the lack of support for optional parameters in C#. The duplicate method has two parameters. Both are marked as optional--and in VBScript, PageItem.Duplicate can be used without providing a parameter (this duplicates the object without moving the duplicate).

          The thing is, when you use one of the parameters in VBScript, you omit the other. As far as I know, there's no way to do this in C#--and the same is true for the PageItem.Move method.

          You can get around this (and other C# problems) by using the Application.DoScript method to send a VBScript (as a string) to InDesign from your C# project.

          Thanks,

          Ole
          • 2. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
            Level 1
            Hi Ole

            Thanks a lot for your good advice.

            I have tried using the Duplicate method in VC++, and it worked just fine without any parameters (as you told me it would using VBScript).

            My further investigation have shown that the Duplicate method always fails in C# with the "Return argument has an invalid type" on any InDesign object that supports the Duplicate method (EPS, TextFrame, Group, PICT etc.).

            I need to get a handle to the duplicated object back from the method, so I can process it further. I have no idea on how to do this with the Application.DoScript method.

            In my opinion any call to the InDesign COM object is unhandled, but DoScript is extremely unhandled, so I would prefer not to use it.

            In your opinion is the "Return argument has an invalid type" error, my fault (wrong parameters etc.), or should I report it as an error to Adobe?

            PS.: My application is > 6000 lines communicating with InDesign CS3 via the COM object. The application is C#, connected with a SQL Server 2005 database and the output is a 60 pages catalog. It works ok using copy/paste, but it is very slow to process the data, so I figured that the Duplicate methods would be faster.

            Best Regards,
            Bo
            • 3. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
              Level 1
              Hi Bo,

              I think that the error message has to do with the extra parameter. That's why the method seems to work--it's just taking the first parameter provided and doing what it's supposed to do. At that point an error gets returned, not the expected object.

              DoScript can return an object--I'll try to create an example for you as soon as I can.

              Thanks,

              Ole
              • 4. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                Level 1
                Hi Ole

                I have testet this, and the method actually uses both parameters. It places the duplicate on the destination specified by the first parameter (page, spread etc) and it offsets the position as specified by the second parameter (array with x and y offset).

                Looking forward to see your DoScript code.

                Thanks,
                Bo
                • 5. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                  Level 1
                  Hi Bo,

                  Sorry, you're right--the second parameter does move the duplicated object to a new location. This has not always been the case, and my recollection was based on an earlier version.

                  Thanks,

                  Ole
                  • 6. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                    Level 1
                    I have an workaround for such C# issues:

                    - Build a very small VB.NET Application that calls the function without the optional parameters.
                    - Disassemble the EXE with Reflector (http://www.aisto.com/roeder/dotnet/) and view the C# code.

                    The resulting code will look like this:

                    object scriptArgs = LateBinding.LateGet( _id, null, "ScriptArgs", new object[0], null, null );

                    LateBinding.LateCall( scriptArgs, null, "Clear", new object[0], null, null );

                    Not very nice, but it works!
                    • 7. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                      Level 1
                      Hi Debilo

                      Tried your approach using VB and got a nice disassembly from Reflector.

                      The resulting code look like this

                      object myFrame = RuntimeHelpers.GetObjectValue(NewLateBinding.LateGet(NewLateBinding.LateGet(myDocument.Sp reads[1], null, "TextFrames", new object[0], null, null, null), null, "Add", new object[0], null, null, null));
                      NewLateBinding.LateCall(myFrame, null, "Duplicate", VBt_arrayS1, null, null, VBt_arrayS2, true);

                      But how do I get C# to recognice the NewLateBinding method

                      According to MSDN NewLateBinding is in the Microsoft.VisualBasic.CompilerServices namespace, but C# can't find this namespace.

                      Do I need a reference to a DLL in order to get it to work?

                      Best regards,
                      Bo
                      • 8. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                        Level 1
                        You need a reference to the "Mircosoft.VisualBasic" DLL !

                        Then include these two namespaces:

                        using Microsoft.VisualBasic;
                        using Microsoft.VisualBasic.CompilerServices;

                        That is what i have done!
                        • 9. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                          Level 1
                          Hi Debilo and Ole

                          Thanks a lot - now it works except that I do not get back the duplicated object.

                          Debugging the C# code revealed that the return type from the InDesign COM object is a TextFrame, but the Interop.InDesign.dll think it is a PageItem (resulting in the "Return argument has an invalid type" error)

                          A colleague of mine discovered how to edit/change the return types directly in Interop.InDesign.dll.

                          After he made the change everything works as expected in C# (with no disassembled C# code and no DoScript needed).

                          Here is his instructions on how to do it:

                          -----------

                          Start a Visual Studio 2005/2008 Command Prompt.

                          In this command box, navigate to the folder where Interop.InDesign.dll resides.

                          Execute the following command to disassemble the DLL:

                          ildasm Interop.indesign.dll.org /out=Interop.InDesign.il

                          Open the indesign.il file in notepad and modify the problematic methods, for example Rectangle::Duplicate.
                          Locate Rectangle::Duplicate

                          .method public hidebysig newslot abstract virtual
                          instance class InDesign.PageItem

                          Change to:

                          .method public hidebysig newslot abstract virtual
                          instance class InDesign.Rectangle

                          or

                          .method public hidebysig newslot abstract virtual
                          instance object

                          Save your changes.

                          Now the Rectangle.Duplicate method will return an InDesign.Rectangle or an object (that you can cast to InDesign.Rectangle) depending on which change you made.

                          In order to regenerate the interop dll (Interop.InDesign.dll), run the following command:

                          ilasm Interop.InDesign.il /DLL /RES=Interop.InDesign.res

                          -----------

                          As I see it the error originates from the "Resources for Visual Basic.tlb" supplied by Adobe (the Interop.InDesign.dll is created when your VS200X project has a reference to this type library)

                          I realize that we have to do the dll-fix every time Adobe releases a new/updated InDesign version, but it is my hope, that Adobe will fix the error directly in the type library (assuming that my previous statement is correct)

                          Thanks a lot for all your help

                          Best regards,
                          Bo
                          • 10. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                            Level 1
                            Hi Bo,

                            For whatever it's worth, here's how to do it using DoScript:

                            //DuplicateTextFrame
                            InDesign.Application myInDesign = new InDesign.ApplicationClass();
                            InDesign.Document myDocument = myInDesign.Documents.Add(true, myInDesign.DocumentPresets[1]);
                            InDesign.Page myPage = (InDesign.Page) myDocument.Pages[1];
                            InDesign.Page myDestinationPage = (InDesign.Page)myDocument.Pages.Add(InDesign.idLocationOptions.idAfter, myPage);
                            InDesign.TextFrame myTextFrame = myPage.TextFrames.Add(myDocument.Layers[1], InDesign.idLocationOptions.idUnknown, myPage);
                            myTextFrame.GeometricBounds = new string [4] {"72pt", "72pt", "288pt", "288pt"};
                            myTextFrame.Contents = "Example text frame.";
                            int myID = myTextFrame.Id;
                            string myJavaScript = "myID = arguments[0];\r";
                            myJavaScript += "var myDestinationPage = arguments[1];\r";
                            myJavaScript += "var myX = arguments[2];\r";
                            myJavaScript += "var myY = arguments[3];\r";
                            myJavaScript += "var myPageItem = app.activeWindow.activePage.pageItems.itemByID(myID);\r";
                            myJavaScript += "var myPage = app.documents.item(0).pages.item(myDestinationPage);\r";
                            myJavaScript += "myPageItem.duplicate(myPage);\r";
                            //Remember that the page index is zero based, so the index of page 2 = 1.
                            Array myArguments = new double[4] {myID, 1, 0, 0};
                            InDesign.TextFrame myDuplicateFrame = (InDesign.TextFrame)myInDesign.DoScript(myJavaScript, InDesign.idScriptLanguage.idJavascript, myArguments);
                            //DoScript returned a text frame on page 2."
                            //To show that this is a valid reference, change the text in the frame."
                            myDuplicateFrame.Contents = "Duplicate text frame on page 2.";

                            I'm not really certain that I consider this an InDesign error. The truth is that C# is an unsupported language. The farther you go from the supported languages--VBScript, AppleScript, and Extenscript--the more problems you'll have.

                            For that matter, I'm not sure that we could change the library to make C# happy without breaking one or more of the supported languages (we don't have separate implementations for the different languages, except in the case of reserved language terms).

                            Thanks,

                            Ole
                            • 11. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                              Level 1
                              Hi Ole

                              I stand corrected!

                              I am fully aware, that C# is an unsupported language, but the advantages of using C# to control InDesign via the COM object, in my opinion, is superior to any of the other supported scripting languages.

                              I have with great success - in the recent year - used the COM object to create spectacular looking catalogue designs, so I really think that Adobe should open and support the COM interface to any programming language that supports COM.

                              My guess is, that the COM object is used internally by Adobe applications (correct me if I am wrong), but why not open it up to other third-party developers.

                              Using C# or any other language against the COM object is (again in my opinion) more closely handled than scripting where it is difficult to determine what has happened, if anything goes wrong.

                              PS.: Thanks a lot for your DoScript sample - it will undoubtedly come in handy in my further development efforts.
                              Best regards,
                              Bo
                              • 12. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                                Level 1
                                Hi Bo,

                                re: "My guess is, that the COM object is used internally by Adobe applications (correct me if I am wrong), but why not open it up to other third-party developers."

                                Not as far as I know. The Creative Suite applications use ExtendScript's Bridgetalk for cross-application automation.

                                We do support COM--what we don't support is strong typing. You can use the COM object without any trouble with VBScript, VBA, and versions of Visual Basic prior to VB.NET (VB5 CCE and VB6 work quite well). The trouble, from the point of view of VB.NET or C#, is that InDesign scripting is loosly typed--this is very much by design.

                                But I'm glad it's working for you, in spite of the philosophical differences between our model and C#!:-)

                                Thanks,

                                Ole
                                • 13. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                                  Hi,

                                  This is bala. iam new for indesign automation. i am using c# for automation the indesign. i need help to automatically indexing the searching word. Please help.

                                  Regards,
                                  Bala K
                                  • 14. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                                    Yuqi Peng Level 1
                                    Not sure if this is still active or not. In Adobe CS3, they might have defacts in pageItem duplicate method as I also try to copy (duplicate) a selectedPageItem with two array as parameters, it always raise exception. It works fine on CS2.

                                    is there any adobe guy?
                                    • 15. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                                      Level 1
                                      Hi Yuqi Peng,

                                      What language are you using? The "defect" is most likely either in the language (especially if it's C#), or in your configuration (if it's Visual Basic). The duplicate method can take parameters of a variety of types--if your language/configuration does not allow this, then you'll get the error.

                                      Here's a VBScript that shows how to use the duplicate method to duplicate and move a rectangle, including duplicating the rectangle to a new page and a new document. Note that the different approaches involve using parameters of multiple types: array and page.

                                      Rem Duplicate.vbs
                                      Rem An InDesign CS4 VBScript
                                      Rem
                                      Rem Shows how to use the duplicate method.
                                      main
                                      Function main()
                                           Set myInDesign = CreateObject("InDesign.Application")
                                           mySetup myInDesign
                                           mySnippet myInDesign
                                           myTeardown myInDesign
                                      End Function
                                      Function mySetup(myInDesign)
                                           Set myDocument = myInDesign.Documents.Add
                                           myDocument.ViewPreferences.HorizontalMeasurementUnits = idMeasurementUnits.idPoints
                                           myDocument.ViewPreferences.VerticalMeasurementUnits = idMeasurementUnits.idPoints
                                           myDocument.ViewPreferences.RulerOrigin = idRulerOrigin.idPageOrigin
                                           Set myPage = myDocument.Pages.Item(1)
                                           Set myRectangle = myPage.Rectangles.Add
                                           myRectangle.GeometricBounds = Array(72, 72, 144, 144)
                                      End Function
                                      Function mySnippet(myInDesign)
                                           Set myRectangle = myInDesign.Documents.Item(1).Pages.Item(1).Rectangles.Item(1)     
                                           Rem
                                           Rem Given a reference to a rectangle "myRectangle"...
                                           Rem Duplicate the rectangle and move the
                                           Rem duplicate to the location (12, 12).
                                           Rem Absolute move:
                                           Set myDuplicate = myRectangle.Duplicate(Array(12, 12))
                                           Rem Duplicate the rectangle and move the duplicate *by* 12
                                           Rem points horizontally, 12 points vertically.
                                           Rem Relative move (note empty first parameter):
                                           Set myDuplicate = myRectangle.Duplicate (, Array(12, 12))
                                           Rem Duplicate the rectangle to another page (rectangle appears at (0,0).
                                           Set myPage = myInDesign.Documents.Item(1).Pages.Add
                                           Set myDuplicate = myRectangle.Duplicate(myPage)
                                           Rem Duplicate the rectangle to another document.
                                           Set myDocument = myInDesign.Documents.Add
                                           Set myDuplicate = myRectangle.Duplicate(myDocument.Pages.Item(1))
                                           Rem

                                      End Function
                                      Function myTeardown(myInDesign)
                                      End Function

                                      Thanks,

                                      Ole
                                      • 16. Re: [CS3 VS2008 C#] Duplicate TextFrame problem - ("Return argument has an invalid type")
                                        Bill joy Level 1

                                        Hi Bo_Peters

                                        I want to ask you that How create Indesign application using vc++ ?

                                        I am able to develop application in C# using COM and generate Interop.Indesign.dll

                                        I am not understand how use COM with vc++ or there is another method to create Indesign instance using vc++.