
Form DocuView has always had serious problems when previewing files in the ActiveX HTML viewer control.
For example, if the user has Show file checked, and the file being previewed in the HtmlView WebBrowser control is a PDF file, and the user clicks Delete, the user receives the error "Delete of file .. failed.". The reasons is simple -- the PDF is still being previewed in the HtmlView WebBrowser control, which locks the file, and the DocuRef.delete() method cascades to DocuOpenFile.delete(), which fails to delete the file and presents the error message.
A similar error "Unable to save data to the file .." occurs when the user clicks the Open button while a PDF file is being previewed in the HtmlView WebBrowser control, and the cause is identical. In class DocuActionFile method saveTempFile(), the binData.saveFile(fileName); fails because the file is in use.
I remember all this stuff from as far back as AX 4.0.
Starting somewhat recently (CU10?), while previewing a PDF file and simply changing one of the other fields, such as the description, and hitting ctrl-S to save the changes generates the same "Unable to save data to the file .." error message. The reason here is again simple. When saving changes to a record, the data source method leaveRecord() is called, followed by active() once the changed are saved, and active() calls loadFile(), which tries to save the file again, while it's still in use.
The solution would seem simple, tell the WebBrowser control to .navigate('about:blank') so it releases the file. And this works for the .delete() case, but only when the user is given a confirmation prompt. It seems the WebBrowser control does not process its messages in real time while X++ is running. The UI must be given control, which happens when the user is given a delete confirmation prompt, during which the WebBrowser control completes the navigation, releasing the PDF viewed and the PDF file itself, allowing it to be deleted properly as an open file.
However, this does not work with the Open button, because no messages are processed, apparently. But, if I add a simple Box::info() which forces the user to press OK, then the Open works fine, i.e. the WebBrowser control navigates to the blank URL, releasing the PDF viewer and the PDF file itself, allowing the subsequent save of the same file to overwrite the original previewed file, and then the Open to execute the shell to open Adobe Acrobat Reader.
Are there any tricks to get the WebBrowser control to process its messages without prompting the user directly? In other words, is there an X++ equivalent to DOEVENTS. I tried infolog.yield(), which isn't well documented, and it doesn't get the job done.
I'm open to suggestions. I'm frankly beyond frustrated that these problems are still around in the product 10 years later.
*This post is locked for comments
I have the same question (0)So I found something that appears to work pretty well.
The following code uses the .NET DoEvents() to process windows messages, waits 0.1 seconds, and does it again. This seems let the WebBrowser control process its messages.
System.Windows.Forms.Application::DoEvents(); // process windows messages
sleep(100); // milliseconds
System.Windows.Forms.Application::DoEvents(); // process windows messages