I have PDF documents that are mostly multi page but I only want to print page 1 from each document. The following prints the entire pdf document. I have seen reference to a parameter page=1 but do not seem to get that into the right place in the following:-
Shell ("""" & "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" & """/p /h """ & strPathAndFilename & """")
Can someone please show me how to get the above shell command to just print page 1 of the document. Many thanks.
Using that method it should not in theory be possible, hysterically/historically the Adobe support take on that line is. Unclear if its a breach of EULA to programable aid a Reader user.
...with the free Reader too. Command lines were declared obsolete by Microsoft around 1992...
Thus not a supported Adobe means (just highly popular abuse of Acrobat Reader, including MS commercial printing). There are workarounds.
So to directly answer your question you would need to simply split off page 1 to only send that to Acrobat Reader for blind print the onepage.pdf
There are different methods within Acrobat API via vba to designate only one page is to be converted. but then that's using an expensive method for such a "simple" task.
Thus 3 more common routes to your solution
wscript "pdf_print_sendkeys.vbs" "C:\Users\WDAGUtilityAccount\Desktop\SandBox\apps\PDF\Adobe\Reader\AcroRd32.exe" "C:\test.pdf" "1"
For the easier first 2 options there are many good solutions
Disclaimer I support SumatraPDF which using just one portable exe (kept as binary is FOSS) can command line print page 1 easily, HOWEVER it will only be print as image and if that's acceptable should serve you well.
Thank you for your response. I could do it using Acrobat Pro but will settle for just the /p parameter and let the user restrict the printed output to the first page.
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:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.