Copy link to clipboard
I'm experiencing crashes and random misbehaviour of Acrobat (both on the latest DC Pro and even back on 8.3) as when launching an embedded PDF from an IBM (Lotus) Notes document AcroAXApp is giving me an AVDoc instance that hasn't finished drawing, so making calls against it (and its associated PDDoc) upsets Acrobat.
I'm basically trying to script extracting OLE Embedded PDFs from an IBM (Lotus) Notes database. When I make COM call to Lotus Notes to activate an embedded PDF it loads the PDF in Acrobat and I get back an AcroAXApp object which has a Document method which returns an instance of AcroAVDoc. From that AVDoc I can get the PDDoc and call Save against it and then Close.
The problem I'm running into is that when I call AcroAXApp.Document it seems it will return the AVDoc before it's finished drawing it on screen, so depending on the timing of my code I can get all sorts of odd errors and total crashes calling methods against AVDoc and its associated PDDoc (sometimes on Save, sometimes on Close, sometimes on the next document).
By chance I found that if my running code displays a modal dialog (including using MessageBox) for a short period of time after activation and prior to making use of AVDoc and PDDoc then Acrobat can complete drawing the loaded PDF and calling methods on both proceeds without issue (on the somewhat slow test environment I'm using, 1 second seems to be reliable).
So is there any way for me, from the COM interface, to detect when Acrobat has finished drawing the AVDoc and its safe to start making calls against it?
Copy link to clipboard
I don’t know anything about IBM/Lotus Notes and how it integrates with Acrobat – but I can tell you that the PDDoc and the AVDoc exist in full before the document is rendered. So while I don’t doubt what you are seeing, I suspect it may be on the IBM side…
Try the same application outside of Notes…
The objects exist and I can access their properties no problem and call methods against them, but for whatever reason (as I noted) unless I put that delay (with a modal dialog - calling sleep is not enough) in before calling Save and then Close I get odd behaviour and crashing of Acrobat and that seems to be correlated with whether it has finished rendering for display the opened PDF or not.
It's impossible for me to test outside Notes with the original embedded data as I can't get at the OLE data blob and stick it anywhere else. I can embed a copy of a sample PDF into a Word document (that will do the embedding via the version of Acrobat I've got installed, which will be more recent than the original for the embed) and have tried that.
If I script opening that test Word document via COM and then get doc.InlineShapes(0).OLEFormat then I can call Activate() against that. Unlike Notes the Activate call in Word doesn't return the OLE handle directly. But I can then access the Object property of the OLEFormat object to get at the OLE handle.
However curiously if Acrobat isn't already running when I run my test code to launch it from a Word document then accessing the OLEFormat.Object property straight after calling Activate results in a "Call was rejected by callee." error. If I add a sleep loop which retries then it will succeed in accessing the Object property after about half a second. So Activate in Word does not wait until the object is ready before returning (for Acrobat PDFs at least) but Object will then become available.
Note that I've had no problems with activating Word, Excel and Powerpoint objects in Notes from my script - they all behave. I agree it is entirely possibly that the problem with activating PDFs lies with Notes rather than Acrobat, but that doesn't really help me work around the issue! As I mentioned Notes gives me an OLE handle after calling Activate and I can access AVDoc from it and PDDoc and they appear fine, but display rendering hasn't completed in Acrobat at that point and calling the Save and Close methods misbehave some of the time and I haven't yet found a way to programmatically detect when it's now save to call Save and Close!
As mentioned, this is outside the bounds of our SDK, as it appears to be related to how Notes uses our SDK to create the OLE object. I would see what their support has to offer..
In your first reply I don't think you said whether or not there was a way to detect if Acrobat had finished fully rendering a loaded PDF from the COM api - that was my question. The other information I just provided for context (and on the off chance anyone had seen similar behaviour) - I'm not asking for the actual problem to be investigated.
I'm unclear whether you now saying "this is outside the bounds of your SDK" is now an answer to my original question - for the avoidance of doubt are you saying it is impossible to detect when Acrobat has finished rendering a loaded PDF to screen?
No, there is not a way.
Ok - thanks for confirming
A side-thought: there are places in Acrobat where you must allow a "message loop" before doing anything. For example to open then close an AVDoc immediately can fail unless Acrobat has a chance to catch up with messages. A modal dialog would be a classic way to enter the message loop. Don't know how this would map to the COM interface.
That's a good point "Test Screen Name" () about the message loop - I'm inexperienced with Windows GUI development, but when trying to figure out why a modal dialog would make a difference I had guessed it was something in that area (and I had messed around with trying pumping waiting messages a little).
When I originally hit the issue I was calling the Activate etc from LotusScript. I then rewrote my script in Python (as Notes exposes itself over COM as well). In both cases I was hitting the same crashing/erroring behaviour from Acrobat, but Python gave me far more access to win32 apis .
Your comment lead to play around a bit more in that area and I've found that if I do a MsgWaitForMultipleObjects/PumpWaitingMessages loop (without passing in an event handle, and listening for all events) with a small timeout and wait for a WAIT_TIMEOUT result to come back from MsgWaitForMultipleObjects then that seems to be a reliable indicator that Acrobat has caught up with messages, as you say, and I've found after that it's safe to start doing stuff with AVDoc and PDDoc without errors/crashing. So that means instead of just coming up with an arbitrary sleep time that's long enough to cope with the largest page render and having to wait the full time, I can shorten that time greatly. Hiding the acrobat app after the activate greatly speeds things up too as it seems to stop the rendering (although there can still be a few messages to pump).
Python defaults to COINIT_APARTMENTTHREADED which is why the rendering was stopping I guess and a plain sleep wouldn't do the job. Under lotusscript I imagine Notes does pump messages, so a straight sleep for long enough probably would have done the job (but been inelegant).
So thanks for the pointer