Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Close Acrobat After ShellExecute Print 4

Status
Not open for further replies.

Swi

Programmer
Feb 4, 2002
1,963
0
36
US
Does anyone have a suggestion for closing Acrobat after using ShellExecute to print the PDF? Thanks.

Code:
ShellExecute Me.hwnd, "Print", strFile, vbNullString, vbNullString, SW_HIDE

Swi
 
An alternative is to use the Adobe free SDK's and use Adobe how you want to.

Adobe SDK Download

"If I were to wake up with my head sewn to the carpet, I wouldn't be more surprised than I am right now.
 
strongm,

Could you please elaborate? Thanks.

Swi
 
Step 1
Realise that ShellExecute has a return value that the API documentation dismisses as merely an fake hInstance that can only be used as an error code, but in reality is an hProcess (a process handle)...

Step 2
Be aware that there is an API call that allows you to kill off unwanted processes via their process handle, TerminateProcess

Step 3
Get sad, because the above api call requires that the process handle has the PROCESS_TERMINATE access right, and ShellExecute doesn't provide that right in the process handle it returns

Step 4
Cheer up, because we can open a second process handle based on the original handle with any rights we like (well, more-or-less)

Step 5
Write the necessary killer function ...
Code:
[blue]Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Const PROCESS_TERMINATE = &H1

Public Function KillProcess(pid As Long) As Long
    Dim hProcess As Long
    hProcess = OpenProcess(PROCESS_TERMINATE, 0, pid)
    If hProcess Then
        KillProcess = TerminateProcess(hProcess, 1&)
        CloseHandle hProcess
    End If
End Function[/blue]
You just have to pass the return value of your ShellExec command to this function.

However, as ousoonerjoe says, it may be better to use the Adobe SDK for this particlar task as with the technique shown here you'll almost certainly have to build in delays to allow the application to start and for printing to commence.
 
Strongm's right, you'll need to put in a pause that may or may not be long enough before you execute the Kill Process.

By the way. That was nicely written.

"If I were to wake up with my head sewn to the carpet, I wouldn't be more surprised than I am right now.
 
Guys i was wondering if you could help me. I am having the same problem. I have vba code that open a pdf from a drop down and when click opens, prints and closes a file.
I am trying to however not have the open, print and close part visible.

The code below seems to work but only once, when i try the dropdown again it will show the open and print and will not close. I think this is because adobe is still running as a process. I am therefore trying to incorporate the Kill function into this code. I was wondering if someone could have a look at this:

Code:
Private Declare  Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long 
Private Sub UserForm_Initialize() 
     
    Me.Caption = StrConv(strFileType, vbUpperCase) & " file listing within the " & StrConv(strDirectory, vbUpperCase) & " directory" 
     
     
    With Application.FileSearch 
         
        .NewSearch 
        .LookIn = strDirectory 
        .SearchSubFolders = False 
        .Filename = "*." & strFileType 
        .MatchTextExactly = False 
         
        If .Execute() > 0 Then 
            For i = 1 To .FoundFiles.Count 
                Dim strFileName As String 
                If Right(.FoundFiles(i), 3) = strFileType Then 
                    strFileName = Mid(.FoundFiles(i), Len(strDirectory) + 1, Len(.FoundFiles(i)) - (Len(strDirectory) + Len(strFileType) + 1)) 
                    Me.lstDirectoryFiles.AddItem strFileName 
                End If 
            Next i 
             
        End If 
         
    End With 
     
     
     
End Sub 
 
Private Sub cmdPrint_Click() 
     
    Dim strURL As String 
    strURL = strDirectory & lstDirectoryFiles & "." & strFileType 
     
    If strURL = strDirectory & "." & strFileType Then 
         MsgBox "You haven't selected a file to print.", vbExclamation, StrConv(strFileType, vbUpperCase) & " Open Editor" 
    End If 
     
    Application. ScreenUpdating = False 
     
    Call ShellExecute(0&, vbNullString, strURL, vbNullString, vbNullString, 0) 'Change 0 to vbNormalFocus to view.
    PrintURL = ShellExecute(0&, "print", strURL, vbNullString, vbNullString, 0) 'Change 0 to vbNormalFocus to view.
     
    Application.Run "CloseDefinedApp" 
     
    Application.ScreenUpdating = True 
     
End Sub

The function is called

Code:
Sub CloseDefinedApp() 
     
     'UDF from 'ClassNames' module.  Change the  filter string to what
     'appears in the caption bar of the application opening the
     'desired file type (eg "Acrobat" for *.pdf files or "Notepad" for *.txt files).
     'This UDF also sets the Public  Variable 'strClassNameToClose'.
    fEnumWindows ("Adobe Reader") 
     
     'UDF from 'CloseApplications' module.  This UDF uses the 'strClassNameToClose'
     'string (see above) to know which application to close.
    fCloseApp (strClassNameToClose) 
     
End Sub

Code:
Private Const WM_CLOSE = &H10 
Private Const INFINITE = &HFFFFFFFF 
 
Private Declare Function apiPostMessage _ 
Lib "user32" Alias "PostMessageA" _ 
(ByVal hWnd As Long, _ 
ByVal wMsg As Long, _ 
ByVal wParam As Long, _ 
lParam As Any) _ 
As Long 
 
Private Declare Function apiFindWindow _ 
Lib "user32" Alias "FindWindowA" _ 
(ByVal lpClassName As String, _ 
ByVal lpWindowName As String) _ 
As Long 
 
Private Declare Function apiWaitForSingleObject _ 
Lib "kernel32" Alias "WaitForSingleObject" _ 
(ByVal hHandle As Long, _ 
ByVal dwMilliseconds As Long) _ 
As Long 
 
Private Declare Function apiIsWindow _ 
Lib "user32" Alias "IsWindow" _ 
(ByVal hWnd As Long) _ 
As Long 
 
Private Declare Function apiGetWindowThreadProcessId _ 
Lib "user32" Alias "GetWindowThreadProcessId" _ 
(ByVal hWnd As Long, _ 
lpdwProcessID As Long) _ 
As Long 
 
Function fCloseApp(lpClassName As String) As Boolean 
     'Usage Examples:
     '   To close Calculator:
     '       ? fCloseApp("SciCalc")
     '
     
     '
    Dim lngRet As Long, hWnd As Long, pID As Long 
     
    hWnd = apiFindWindow(lpClassName, vbNullString) 
    If (hWnd) Then 
        lngRet = apiPostMessage(hWnd, WM_CLOSE, 0, ByVal 0&) 
        Call apiGetWindowThreadProcessId(hWnd, pID) 
        Call apiWaitForSingleObject(pID, INFINITE) 
        fCloseApp = Not (apiIsWindow(hWnd) = 0) 
    End If 
End Function
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top