Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long
Private Declare PtrSafe Function EnumWindows Lib "user32" (ByVal lpEnumFunc As LongPtr, ByVal lParam As LongPtr) As Long
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
#Else
Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
#End If
Private Const WM_CLOSE = &H10
Private Const AcrobatWindowClass = "AcrobatSDIWindow"
Public Sub Open_PDF_At_Page(PDFfullName As String, Optional page As String = "1")
Dim PDFexe As String
Dim AdobeCommand As String
If Dir(PDFfullName) <> vbNullString Then
PDFexe = Get_ExePath(PDFfullName)
AdobeCommand = " /a ""page=" & page & """ "
Find_and_Close_Acrobat_Window Mid(PDFfullName, InStrRev(PDFfullName, "\") + 1)
Shell Chr(34) & PDFexe & Chr(34) & AdobeCommand & Chr(34) & PDFfullName & Chr(34), vbNormal
Else
MsgBox PDFfullName & " doesn't exist", vbExclamation
End If
End Sub
Private Function Get_ExePath(lpFile As String) As String
Dim lpDirectory As String, sExePath As String, rc As Long
lpDirectory = "\"
sExePath = Space$(255)
rc = FindExecutable(lpFile, lpDirectory, sExePath)
Get_ExePath = Left$(sExePath, InStr(sExePath, Chr$(0)) - 1)
End Function
'Close the specified Acrobat Pro/Adobe Reader PDF window by enumerating windows.
'Assumes that Acrobat Pro/Adobe Reader is set to display PDF documents in separate windows.
'Edit > Preferences > General category > untick 'Open documents as new tabs in the same window'
Public Sub Find_and_Close_Acrobat_Window(windowTitle As String)
EnumWindows AddressOf EnumWindowsCallback, StrPtr(windowTitle)
End Sub
#If VBA7 Then
Public Function EnumWindowsCallback(ByVal hWnd As LongPtr, ByVal findWindowTitle As String) As Long
#Else
Public Function EnumWindowsCallback(ByVal hWnd As Long, ByVal findWindowTitle As String) As Long
#End If
Dim thisWindowTitle As String, thisWindowClass As String
Dim stringLen As Long
'Continue enumerating windows by default
EnumWindowsCallback = 1
thisWindowTitle = Space$(256)
stringLen = GetWindowText(hWnd, thisWindowTitle, Len(thisWindowTitle))
thisWindowTitle = Left$(thisWindowTitle, stringLen)
thisWindowClass = Space$(256)
stringLen = GetClassName(hWnd, thisWindowClass, Len(thisWindowClass))
thisWindowClass = Left$(thisWindowClass, stringLen)
'Close this window if its title matches the one being sought and stop enumerating windows
If InStr(1, thisWindowTitle, findWindowTitle, vbTextCompare) And thisWindowClass = AcrobatWindowClass Then
PostMessage hWnd, WM_CLOSE, 0, 0
EnumWindowsCallback = 0
End If
End Function