Search code examples
vbapdfms-access-2010ddesumatra

send DDE command to pdf document in SUMATRA PDF on subform


I have an MS-Access 2010 application. I use Sumatra PDF as a pdf viewer. To make the viewer fit in with the application, I have loaded the viewer on a subform, using this simple code:

Private Sub Form_Load() 'subform load procedure

    Dim inpFile As String, cmd As String
    
    inpFile = "D:\temp\test.pdf"

    cmd = CurrentProject.Path & "\SumatraPDF-3.5.2-32.exe -plugin " & _
          Me.Hwnd & " """ & inpFile & """"
    runShell cmd

End Sub

Private Function runShell(ByVal cmd As String)

    Dim wsh As Object
    
    Set wsh = VBA.CreateObject("WScript.Shell")
    wsh.Run cmd, vbHide, False 

    Set wsh = Nothing

End Function

This works fine. However, I would like to interact with the PDF document - from my VBA application - using DDE commands (Sumatra PDF supports DDE since version 3.5).

If I run Sumatra as an application, I can use this example code to send a copy selection command:

Private Sub Command1_Click()
    Dim channelNumber As Long
    
    channelNumber = Application.DDEInitiate("SUMATRA", "control")

    Application.DDEExecute channelNumber, "[CmdCopySelection]"
    Application.DDETerminate channelNumber

End Sub

Because Sumatra is loaded on a subform, there is no application Sumatra available, so the DDE initiate fails. However, Sumatra is running as a process...

There is also a complicating factor: my users can have multiple instances of PDF viewers on subforms open and the application has multiple users, which can have PDF viewers open simultaneously.

My question is: is there a way to determine the correct DDE channel for the Sumatra process that is running in my subform? Can I use an API call using the Hwnd of the subform for this? If it is possible, can you give me some sample code?


Solution

  • Initial use of DDE to control SumatraPDF as a "Pre-Viewer" (A misnomer as PDF is always post render viewed) was developed by William Blum for use with LaTeX IDE's (WinEdt) Mainly in 2008. It allows for Server: SUMATRA Topic: control WM_DDE_EXECUTE: Command[s].

    It is now a key means for runtime navigation so opening a document "FileName" via command line with SumatraPDF already "Actively Serving" will use DDE CONTROL to handle many internal commands. If not running with a filename it will self-service once normal running is initiated.

    enter image description here

    One problem is DDE has several restrictions imposed by Windows. For example if a non user session is running, a user command line call to open a file should fail. Similar UAC restrictions can apply if running mixed 32bit and 64bit sessions.

    The plug-in "Pre-viewer" system was primarily designed for Netscape based browsers (Depreciated 2015) and any residual use of explorer PDF "Pre-views" by Office such as "MS Outlook" is a totally unsupported legacy side effect. As a "Sandboxed" framed "Browser" pane, it is restricted in its native abilities by limiting insecure UI functions.

    In Plug-in Mode there should be no external control enter image description here

    So DDE works One Way via one narrow "Control" channel to expose external driven functionality. There is no significant means to expose "Internal" states or data.

    Several requests have been made for DDE Query say for example "Current" Page or Zoom state, but there is no such external feedback design mechanism.

    If you can run VB command on user selection it would be no different to Windows native "Clip" command or WSH sendkeys CTRL + C to copy user selection to Clipboard.