11

I embedded a PDF viewer in a C# Winform using AxAcroPDFLib. However, the annotation buttons in the toolbar (comments...) are disabled. I searched and found that they are disabled by default, but some reported enabling them using Javascript:

Collab.showAnnotToolsWhenNoCollab = True

Is there a way to do this here?

Edit: Is it possible to use the browser plugin in a WebBrowser Control? If so, how can this be done?

Jerry
  • 4,258
  • 3
  • 31
  • 58

1 Answers1

6

Update - The first section is relevant only to Acrobat Reader. For information on when using full versions of Acrobat, see the second section.

Acrobat Reader

I'll preface all of this by stating this is probably not the answer you're looking for, but I felt this warranted more of an explanation than just a comment.

A similar, self-answered question was asked on SO (here), where the OP came to the conclusion that this behavior is by design and nothing cannot be done about it, which I agree with, almost.

While I'm sure you've seen that Reader itself can add annotations, the only straightforward means of accomplishing this using the Reader Plugin (AcroPDFLib) is for the document being loaded to be "Reader Enabled," at which point annotations become available just as they are in Reader. If you have control of the documents you wish the plugin to load, this may be a solution for you.

To your question about possibly setting Collab.showAnnotToolsWhenNoCollab = True as a workaround, my searches only showed this being a viable workaround for those using a full version of Acrobat, not Reader. More specifically, on an Adobe forum (here), an Adobe staff commented on the use of this property directly:

No, it is not [about allowing commenting in Adobe Reader]. It is about enabling commenting in a browser for Acrobat Standard or Professional. If you wish to enable commenting in Reader, then you need to "Reader Enable" the PDFs themselves using Acrobat professional or Adobe Livecycle Reader Extension Server.

Granted, this comment was in reference to Acrobat 9, it appears to still be valid for Acrobat XI.

One last bit. I don't know the scope of your application, so this may be completely irrelevant, but if this is a commercial application, even if do you find a functional workaround, I'd be hesitant to use it, as it might violation the Adobe Reader license agreement (here); specifically section 4.3.3, Disabled Features. The short version is, as with most companies, they don't want you circumventing their protections.

Full versions of Acrobat

The following code will create a PDF viewer (using the Form's window for drawing), open a PDF, then set collab.showAnnotToolsWhenNoCollab = true to allow annotations on the open PDF. This requires a reference to the Acrobat type library.

void CreatePdfViewerAndOpenFile(string pdfFile)
{
    short AV_DOC_VIEW = 2;
    short PDUseBookmarks = 3;
    short AVZoomFitWidth = 2;

    Type AcroExch_AVDoc = Type.GetTypeFromProgID("AcroExch.AVDoc");
    _acroExchAVDoc = (Acrobat.CAcroAVDoc)Activator.CreateInstance(AcroExch_AVDoc);
    bool ok = _acroExchAVDoc.OpenInWindowEx(pdfFile, this.Handle.ToInt32(), AV_DOC_VIEW, -1, 0, PDUseBookmarks, AVZoomFitWidth, 0, 0, 0);

    if (ok)
    {
        CAcroPDDoc pdDoc = (CAcroPDDoc)_acroExchAVDoc.GetPDDoc();
        object jsObj = pdDoc.GetJSObject();
        Type jsObjType = jsObj.GetType();
        object collab = jsObjType.InvokeMember("collab",
            BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance,
            null, jsObj, null);

        jsObjType.InvokeMember("showAnnotToolsWhenNoCollab",
            BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance,
            null, collab, new object[] { true });
    }
}

Call this method from wherever you want to display the PDF. When finished, be sure to call the Close method or the PDF file will remain open in the Acrobat process in the background.

_acroExchAVDoc.Close(-1);

Bear in mind that a lot of "normal" functionality is left out of this example, like form resize handling, etc., but it should get you started. Because resizing isn't handled by this example, you'll probably want to maximize the form before invoking the method, so the viewer is big enough to be useful. For more information on how to use the viewer in this fashion, download the Acrobat SDK (here) and look at the ActiveViewVB sample project, which is what I used to build some of this example. For reference, I used the Acrobat XI SDK.

Community
  • 1
  • 1
cokeman19
  • 2,405
  • 1
  • 25
  • 40
  • Thanks, but I have the full version of Acrobat, and I'm still not able to get it to work. Maybe it's available only in the web plugin version, but I don't know how to use this. – Jerry May 11 '15 at 09:54
  • Thank you very much. This is very useful. I can use annotations now. But there are still few problems: 1. The save button in the toolbar is disabled, even after adding annotaions. 2. The size of toolbar buttons (and everything else) is a lot bigger than in Adobe Acrobat (looks like a different resolution than the desktop). Both issues are shown in the attached image: http://oi57.tinypic.com/2vxfzvb.jpg . I use Adobe Acrobat DC. – Jerry May 12 '15 at 12:27
  • I tried on another machine which has Adobe acrobat pro 9. The last InvokeMember crashes with error "System.Runtime.InteropServices.COMException (0x80010105): The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))", and event viewer shows faults in annots.api and escript.api modules. – Jerry May 12 '15 at 15:06
  • 1
    I'm can replicate the Save button issue, but not the toolbar button size issue. For the Save button, the ActiveViewVB sample in the SDK has the same issue; it never enables. My initial thought is that it may be a bug on Adobe's part. As "confirmation" of this, actually saving the PDF with annoations does work, if you manually save it. Also, if you call _acroExchAVDoc.GetPDDoc().GetFlags(), the document contains the PDDocIsModified bit. – cokeman19 May 12 '15 at 17:04
  • Great thanks! I fixed the size issue by checking "Disable display scaling on high DPI settings" on the file properties. – Jerry May 12 '15 at 17:11
  • For RPC_E_SERVERFAULT, since I can't replicate it, my best guess is an object model difference between Acrobat 9 and DC (i.e. "collab" is in a different place). You could test this by checking if "collab" is null. If you can get that, then try to *get* the value of "showAnnotToolsWhenNoCollab". If you can get both of these, then it's not an object model issue. My next guess is an interoperability issue with the Acrobat type library. On the Acrobat reference, try toggling "Embed Interop Types" to see if it has any effect on the error. If it does, you *may* need to write version-specific code. – cokeman19 May 12 '15 at 17:19
  • Thanks, but it didn't work. collab wasn't null. And toggling "Embed Interop Types" didn't help. Any other ideas? – Jerry May 12 '15 at 17:40
  • Unfortunately, I think I'm out of useful ideas; RPC_E_SERVERFAULT is just such a generic exception. It is odd though that it will let you get "collab", but not get/set "showAnnotToolsWhenNoCollab". The last idea I have would be to modify that SDK sample app to set "collab.showAnnotToolsWhenNoCollab = true" and run it on the errant machine. Since the sample app is VB, not C#, you'll be able to set the property directly through late binding, as opposed to using reflection like we've be doing thus far. If it works, perhaps this will provide you an avenue for additional troubleshooting. – cokeman19 May 12 '15 at 19:07
  • OK, thank you very much for all your help. You've been so kind and helpful. – Jerry May 12 '15 at 19:25
  • 1
    Glad to be of some help. – cokeman19 May 12 '15 at 20:31
  • @Jerry and cokeman: Personally, I have never been able to use the object returned by GetJSObject() from Acrobat with C# reliably, (I have tried with C# 4 dynamic type and with reflection). I have also seen this RPC_E_SERVERFAULT error (and others) and in my case migrating that part of the code to VB.NET fixed the issue. It seems that VB.NET implements access to IDispatch interfaces somehow different to what C# does. – yms May 15 '15 at 15:53
  • @yms Would you please explain how you did that? – Jerry May 15 '15 at 16:22
  • just use "Dim _acroExchAVDoc = CreateObject("AcroExch.AVDoc")" in VB.NET instead of GetTypeFromProgID + Activator.CreateInstace, and call the methods directly from _acroExchAVDoc instead of using InvokeMember – yms May 15 '15 at 16:34
  • Thanks, but bow can you execute javascript after this point using _acroExchAVDoc in VB.net? – Jerry May 16 '15 at 15:41
  • 1
    Just do "_acroExchAVDoc.GetPDDoc().GetJSObject().collab.showAnnotToolsWhenNoCollab = True" after calling OpenInWindowEx, the code should look very similar to the C# code in this answer, but you can invoke methods and properties directly without using "InvokeMember" from reflection. – yms May 17 '15 at 17:13
  • Thank you very much! I updated Adobe 9 to DC, and now both work fine using C# and VB.NET. Thanks cokeman19 and yms for your help. – Jerry May 18 '15 at 11:18