Macros in ADEP Designer 10.0

Well, here’s a poorly kept secret now made public.  The macro feature that we previewed in the ES2 Designer is now an officially supported feature.

You can find the online documentation here.

The good news is that the macros you wrote for ES2 should continue to work in the new Designer.  The only changes is that we’ve changed the directory name where they’re stored (now under "macros").  As well, each macro is described by a macro.xml file.

There are a couple items I should hightlight:

There is a method: designer.callExternalFunction() that allows you to call an arbitrary method in a .DLL. Here is your escape key for every integration problem you might conceive.

designer.filterNodeTree() is added to enhance performance.  Traversing the entire DOM searching for specific elements can ge slow on large forms.  For example,
designer.filterNodeTree(xfa.template, "className", "font")
will return all the <font> elements in the form. 
designer.filterNodeTree(xfa.template, "name", "price")
will return all the objects named "price".

If you produce .chm help files to document your macro, you can invoke them with designer.showHelp()

And, just to give you an excuse to try this out, I’ve written a new macro.  This one will append a floating field reference for an existing field to a text object.  Here are the macro.xml and javascript files. Usage: select the text and field objects, then invoke the macro.

 

11 Responses to Macros in ADEP Designer 10.0

  1. Scott says:

    I recently heard of the name change to ADEP (surprisingly I haven’t heard more about it), but how is ADEP 10.0 different from liveCycle designer 10.0. (which I have ).

    • Scott:
      I don’t think you have LC Designer 10.0. The previous designer to ship was Designer ES2 (9.0) that went out with Acrobat X. Unless you happen to have a beta version of the ADEP designer that shipped before re-branding?
      John

  2. Scott sheck says:

    Oops, you’re right I only have the livecycle that came with acrobat 10.0. So does that mean there is an upgrade available?

  3. John Brinkman says:

    Scott:
    Yes, there’s a new Designer. Trial download is available at:
    http://www.adobe.com/devnet/enterprise-platform/trial-downloads.html

    enjoy
    John

  4. Bruce says:

    Hi John,

    I’m struggling though my first macro, and have come across a difference in the JavaScript as run in the Reader runtime and as a macro in Designer. Is this possible? Try

    function dbg(msg) {
    designer.println(msg.toString().replace(/[\n]/gm, “\r\n”) + “\r\n”);
    }
    var xmlstring = ‘<?xml version=”1.0″ encoding=”UTF-8″?>\
    <root xmlns:dd=”http://ns.adobe.com/data-description/”>\
    <parentBodySupportAttachment>\
    <attachment status=”” xmlns=”http://test.com/project/Attachments”>\
    <name dd:minOccur=”0″ dd:nullType=”exclude”/>\
    </attachment>\
    </parentBodySupportAttachment>\
    <otherSupportAttachment dd:minOccur=”0″>\
    <attachment status=”” xmlns=”http://test.com/project/Attachments”>\
    <name dd:minOccur=”0″ dd:nullType=”exclude”/>\
    </attachment>\
    </otherSupportAttachment>\
    </root>;
    var e4x = new XML(xmlstring.replace(/^/, “”));
    dbg(“xml=” + xmlstring);
    dbg(“e4x=” + e4x);

    Run in designer the namespace on the second attachment element is removed, so you end up with;

    But if I try the same code in Reader then it works fine.

    I did try not using e4x but was having trouble generating nodes with the appropriate namespace, would you expect the following to work?

    xfa.datasets.createNode(“dataValue”, “nullType”, “http://ns.adobe.com/data-description/”)

    Seems to create a node but not with the correct namespace/prefix.

    • John Brinkman says:

      Bruce:
      Just as a background, Designer does have a different JavaScript processor than Reader.
      Designer uses ExtendScript (more details here: http://blogs.adobe.com/formfeed/2009/06/clientserver_scripting_differe.html )
      I did a quick check, and it does look like there is a bug in the E4X processing in Extendscript, resulting in your namespace getting dropped.
      I wouldn’t expect the createNode method to work for you because that API is not rich enough to specify the namespace prefix.
      I think your best bet is to manipulate the XML as a string and use loadXML/saveXML to read/write it:
      xfa.datasets.dataDescription.loadXML(‘<root …’);
      If you want to continue to use E4X, you could try working with smaller fragments.
      good luck,

      John

  5. Dan says:

    Is there any more documentation for callExternalfunction than what is on the Adobe web site?

    All the documentation states is: “When this function is called, it passes an interface that the DLL file uses to call back into Designer to retrieve the current selection, and to get or set dialog box variables.”

    What is the definition for this interface? How do I ensure a dll is compatible with it?

    • John Brinkman says:

      Dan:
      A sample would help. It’s on my “to do” list.
      I can’t answer the question about the interface (yet).
      But here’s some more detail on the rest:
      When script calls callExternalFunction, the DLL name specified (which must not include path elements, only a filename such as “foo.dll”) is loaded from the directory containing the currently executing script file, and GetProcAddress is used to find the function identified by the sFunctionName parameter.

      A sample call would be:

      designer.callExternalFunction(“DesignerExtension”, “ShowMyDialog”, “user data here”);

      This would load a DLL called DesignerExtension.dll from the same directory that the plugin is installed, look up a function called ShowMyDialog, and call it, passing the “user data here” string as a wide character string (const wchar_t *).

      The function can return a string, which will be returned from the designer.callExternalFunction call. The string is returned as an HGLOBAL containing a wide character string.

      Here’s an example of a function in a DLL which shows the passed-in string in a dialog, and returns “yes” or “no” based on which option the user clicks:
      extern “C” __declspec(dllexport) HGLOBAL _cdecl ShowMyDialog(HWND hwndParent, const wchar_t *pszArgument)
      {
      int nResult = ::MessageBox(hwndParent, pszArgument, L”DLL Function Sample”, MB_YESNO);

      // Allocate some memory for the result string
      HGLOBAL hMem = GlobalAlloc(0, 64);
      if (!hMem)
      return 0;

      wchar_t *pMem = (wchar_t *)GlobalLock(hMem);
      wcscpy_s(pMem, 30, nResult == IDYES ? L”yes” : L”no”);
      ::GlobalUnlock(hMem);
      return hMem;
      }

      Hope this helps
      John

  6. @Dan: Probably it is documented in ExtendScript documentation. You should check Adobe Bridge SDK docs.

  7. I can see some great uses for external extension mechanism, like connecting to source code repository or diffing two source files! Is there some kind of C++ SDK for Designer like there is e.g. for InDesign?

    • John Brinkman says:

      Maciej:

      Unfortunately, there is no published SDK for Designer. The use-cases you’re looking at are probably not yet possible with the current macro capability — but it would be great to hear what enhancement requests you need to build them.

      John