Please, try the next way. It launch the Adobe Acrobat Reader DC printing window and then finds its control necessary handlers and change/press them according to the printing need. SendKeys
does mean a reliable method, if you move the mouse and change the focus from the window where it should act:
- Copy the next API declarations on top of a standard module (in the declarations area:
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hwnd1 As LongPtr, _
ByVal hwnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, _
ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As Long
Private Declare PtrSafe Function GetNextWindow Lib "user32.dll" Alias "GetWindow" (ByVal hwnd As LongPtr, _
ByVal wFlag As Long) As LongPtr
Then copy the next code in the same module:
Sub PrintPdfSpecificPage()
Dim strPathAndFilename As String, strPages As String
strPathAndFilename = "your pdf file full name" 'use here the real full name
strPages = "2" 'the page to be printed number
'it may be "1,2" or "2-4"...
'launch the Adobe Acrobat DC printing window:
Shell ("""" & "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" & """/p """ & strPathAndFilename & """")
'wait for the window to expose its handle and continue the process of the necessary controls identification (their handles):
Dim prHwnd As LongPtr, grBoxHw1 As LongPtr, grNext4 As LongPtr, grNext20 As LongPtr
Dim pgHwnd As LongPtr, pgNHwnd As LongPtr, printHwnd As LongPtr, nrPag As String
Const BM_CLICK = &HF5, WM_SETTEXT = &HC
Const WM_LBUTTON_DOWN = &H201, WM_LBUTTON_UP = &H202
Do While prHwnd = 0
prHwnd = FindWindow("#32770", "Print")
DoEvents
Loop
Application.Wait Now + TimeValue("00:00:02") 'wait two seconds for the whole window to expose its controls handles
grBoxHw1 = FindWindowEx(prHwnd, 0, "GroupBox", vbNullString) 'the first child GroupBox window
grNext4 = getNextChildX(grBoxHw1, 3, "GroupBox"): Hex (grNext4) 'find the fourth control handle
pgHwnd = FindWindowEx(grNext4, 0, "Button", "Pa&ges") 'find the radio button accepting pages interval handler
SendMessage pgHwnd, WM_LBUTTON_DOWN, 0&, 0&
SendMessage pgHwnd, BM_CLICK, 0&, ByVal 0& 'check the radio button
pgNHwnd = FindWindowEx(grNext4, 0, "RICHEDIT50W", vbNullString) 'find the window where the page number to be dropped
SendMessage pgNHwnd, WM_LBUTTON_DOWN, ByVal 0&, 0& 'without this lines, the page number is changed, but the changing event is not triggered...
SendMessage pgNHwnd, WM_LBUTTON_UP, ByVal 0&, 0&
SendMessage pgNHwnd, WM_SETTEXT, 0&, ByVal strPages 'place the page to be printed number
SendMessage pgNHwnd, WM_LBUTTON_DOWN, ByVal 0&, 0&
SendMessage pgNHwnd, WM_LBUTTON_UP, ByVal 0&, 0&
grNext20 = getNextChildX(grBoxHw1, 19, "GroupBox"): Debug.Print 'find the GroupBox where the Print button exists
printHwnd = FindWindowEx(grNext20, 0&, "Button", "Print") 'find the Print button handle
SendMessage printHwnd, BM_CLICK, 0&, ByVal 0& 'press/click the Print button:
'close the Acrobat main Window:
Dim acrobatHwnd As LongPtr
Const WM_SYSCOMMAND = &H112, SC_CLOSE = &HF060
'wait for the printing Window to be closed, to let Acrobat expose its main window handle:
Do While acrobatHwnd = 0
acrobatHwnd = FindWindow("AcrobatSDIWindow", "Adobe Acrobat Reader DC (32-bit)")
DoEvents
Loop
SendMessage acrobatHwnd, &H10, 0&, 0& 'close the main Acrobat Reader window
End Sub
Function getNextChildX(parentHwnd As LongPtr, x As Long, strClass As String) As LongPtr
Dim nextChild As LongPtr, i As Long
nextChild = FindWindowEx(parentHwnd, 0&, strClass, vbNullString)
For i = 1 To x
nextChild = GetNextWindow(nextChild, 2)
Next i
getNextChildX = nextChild
End Function
It was a little more complicated than I thought, but worked in my environment...
Please, test it and send some feedback