z07924
asked on
ShellExecute
how do I print a document using ShellExecute to a specific printer.(more like drag and drop) I used the following ,
x = ShellExecute(hwnd, "printto", z_file, "'Acrobat Distiller'", z_path, 0)
but this doesn't work. Anyhelp would be highly appreciated. thanks.
waiting....
x = ShellExecute(hwnd, "printto", z_file, "'Acrobat Distiller'", z_path, 0)
but this doesn't work. Anyhelp would be highly appreciated. thanks.
waiting....
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Another way of setting the current printer is if you know its name:
---
Dim P As Printer
For Each P In Printers
If (P.DeviceName = "HP C LaserJet 4500-PS") Then
Set Printer = P
Exit For
End If
Next
---
---
Dim P As Printer
For Each P In Printers
If (P.DeviceName = "HP C LaserJet 4500-PS") Then
Set Printer = P
Exit For
End If
Next
---
The following is a quick and dirty way to print a file:
---
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
ShellExecute Me.hWnd, "Print", "TheFileName", 0&, 0&, vbMinimized
---
---
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
ShellExecute Me.hWnd, "Print", "TheFileName", 0&, 0&, vbMinimized
---
ASKER
Comment accepted as answer
ASKER
My default printer is something else (HP LaserJet 4M Plus). So this prints to that default printer. My objective is to print the file to a specific printer(Acrobat distiller) without changing the default printer.
any ideas to do this...thanks in advance
any ideas to do this...thanks in advance
? But you already accepted an answer. Did it not really answer your question? I'm just confused.
ASKER
This is my first time in this group. SO i didn't know how to respond to his suggestion. Sorry abt that.
Anyways, his approach didn't work because it prints to the default printer. Any ideas to print a file to a
specific printer without changing the default. thanks.
Anyways, his approach didn't work because it prints to the default printer. Any ideas to print a file to a
specific printer without changing the default. thanks.
ASKER
This is my first time in this group. SO i didn't know how to respond to his suggestion. Sorry abt that.
Anyways, his approach didn't work because it prints to the default printer. Any ideas to print a file to a
specific printer without changing the default. thanks.
Anyways, his approach didn't work because it prints to the default printer. Any ideas to print a file to a
specific printer without changing the default. thanks.
z07924 - who's code did you use to enumerate the printers? I would like to give them 1/2 of the points since you used both our code...
thanks
thanks
ASKER
to be frank, my problem is not yet solved with both the approaches.
This is what I am using. But it is always printing to the default printer...
Dim P As Printer
For Each P In Printers
If (P.DeviceName = "Acrobat Distiller") Then
Set Printer = P
Exit For
End If
Next
x = ShellExecute(hwnd, "print", z_file, "'Acrobat Distiller'", z_path, 0)
This is what I am using. But it is always printing to the default printer...
Dim P As Printer
For Each P In Printers
If (P.DeviceName = "Acrobat Distiller") Then
Set Printer = P
Exit For
End If
Next
x = ShellExecute(hwnd, "print", z_file, "'Acrobat Distiller'", z_path, 0)
Use AzraSound's way of doing it. Let the user select a printer to print with.
Or you use the commondialog box's print method, then pass the printer name to the shellSexcute statement
letme know how it goes.. these points are not all mine
Or you use the commondialog box's print method, then pass the printer name to the shellSexcute statement
letme know how it goes.. these points are not all mine
ASKER
Problem is it is a batch process. No user interaction.
The batch process prints some pdf files to the Acrobat distiller and finally merge all of the output files together and print it to the default printer.
The problem comes when multiple instances of this batch process starts to run....That is why I was looking for a way to print to a specific printer, without user interaction & without changing the default printer.
pleaseeeeeeeeeeeeeee help me....I really appreciate that.
The batch process prints some pdf files to the Acrobat distiller and finally merge all of the output files together and print it to the default printer.
The problem comes when multiple instances of this batch process starts to run....That is why I was looking for a way to print to a specific printer, without user interaction & without changing the default printer.
pleaseeeeeeeeeeeeeee help me....I really appreciate that.
well, without user interaction or a printer specified at runtime, the program doesn't kow which printer you want to print to.. Mabye you can popup a dialog box at the beginning of the programs process(if it's not an ActiveX control or DLL) to alert the user that they cannot continue until they select a printer.
Could you limit the program to only run one instance or is that not an option?
Could you limit the program to only run one instance or is that not an option?
ASKER
I know the printer name at runtime. It is always going to be "Acrobat Distiller". The problem is ShellExecute doesn't work when I specify a printer name to print. It always prints to the default printer...
>>Could you limit the program to only >>run one instance or is that not an >>option?
It is an option. This batch process is run by another another application on which I don't have any control.
so how do I do this. thanks.
>>Could you limit the program to only >>run one instance or is that not an >>option?
It is an option. This batch process is run by another another application on which I don't have any control.
so how do I do this. thanks.
For detecting multiple instances:
http://www.mvps.org/vbnet/code/system/appprevinst.htm
It prints to the defuault printer because I am sure the "Acrobat Distiller" is not the name that windows uses to define the printer.
http://www.mvps.org/vbnet/code/system/appprevinst.htm
It prints to the defuault printer because I am sure the "Acrobat Distiller" is not the name that windows uses to define the printer.
ShellExecute will not allow you to change the printer.
What you can do it change the default printer before you print and change it back after you print.
Here's how:
http://www.mvps.org/vbnet/code/system/defprinternt.htm
What you can do it change the default printer before you print and change it back after you print.
Here's how:
http://www.mvps.org/vbnet/code/system/defprinternt.htm
ASKER
This is exactly what I am doing. It works fine as long as you have single instance of the application. When you have multiple instances the application goes crazy and prints to the default printer at that moment...This si the problem I am having and still I don't know how to solve it...
For detecting multiple instances:
http://www.mvps.org/vbnet/code/system/appprevinst.htm
Check this code out and let me know what comes of it. I used it in aprogram I wrote and it works great
http://www.mvps.org/vbnet/code/system/appprevinst.htm
Check this code out and let me know what comes of it. I used it in aprogram I wrote and it works great
ASKER
I don't want to prevent multiple instances instead I want the next instance to wait for the previous instance to be over before it starts runing. Is it possible to implement within the batch process? thanks.
what kind of program is it? ActiveX control, ActiveX Exe??
Does the program automatically shutoff and close itself upon finishing the task?
How does it load?
Does the program automatically shutoff and close itself upon finishing the task?
How does it load?
ASKER
It is a simple VB application. It automatically shuts off upon finishing the task. A separate application loads
this by passing parameters for each report. (that cause multiple instances...) thanks.
this by passing parameters for each report. (that cause multiple instances...) thanks.
In the application that passes the parameters, you can use your shell execte to execute the report with parameters (which you have done) and the wait for that report to close before starting another instance. How does that sound.
-Now, declare these:
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDNEXT = 2
Public Const GW_CHILD = 5
Public Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
-What we can do is get the hwnd from the report's Process/Thread using the function below
Public Function GethWndFromProcessID(hProc essIDToFin d As Long) As Long
Dim hWndDesktop As Long
Dim hWndChild As Long
Dim hWndChildProcessID As Long
On Local Error GoTo GethWndFromProcessID_Error
'get the handle to the desktop
hWndDesktop = GetDesktopWindow()
'get the first child under the desktop
hWndChild = GetWindow(hWndDesktop, GW_CHILD)
'hwndchild will = 0 when no more child windows are found
Do While hWndChild <> 0
'get the ThreadProcessID of the window
Call GetWindowThreadProcessId(h WndChild, hWndChildProcessID)
'if it matches the target, exit returning that value
If hWndChildProcessID = hProcessIDToFind Then
GethWndFromProcessID = hWndChild
Exit Do
End If
'not found, so get the next hwnd
hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)
Loop
Exit Function
-Your shell execute function will look like this
Dim hProcessID As Long
Dim ReportHwnd as Long
hProcessID = ShellExecute(sApplication, vbNormalFocus)
ReportHwnd = GethWndFromProcessID(hProc essID)
'I don't recommend doing this loop function, but it shows you what's going on
Do:DoEvents:Loop Until ReportHwnd = 0
-Now, declare these:
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDNEXT = 2
Public Const GW_CHILD = 5
Public Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
-What we can do is get the hwnd from the report's Process/Thread using the function below
Public Function GethWndFromProcessID(hProc
Dim hWndDesktop As Long
Dim hWndChild As Long
Dim hWndChildProcessID As Long
On Local Error GoTo GethWndFromProcessID_Error
'get the handle to the desktop
hWndDesktop = GetDesktopWindow()
'get the first child under the desktop
hWndChild = GetWindow(hWndDesktop, GW_CHILD)
'hwndchild will = 0 when no more child windows are found
Do While hWndChild <> 0
'get the ThreadProcessID of the window
Call GetWindowThreadProcessId(h
'if it matches the target, exit returning that value
If hWndChildProcessID = hProcessIDToFind Then
GethWndFromProcessID = hWndChild
Exit Do
End If
'not found, so get the next hwnd
hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)
Loop
Exit Function
-Your shell execute function will look like this
Dim hProcessID As Long
Dim ReportHwnd as Long
hProcessID = ShellExecute(sApplication,
ReportHwnd = GethWndFromProcessID(hProc
'I don't recommend doing this loop function, but it shows you what's going on
Do:DoEvents:Loop Until ReportHwnd = 0
ASKER
This idea sounds excellent. But the only bottlenech is I don't have control over the application that calls the report process. It is a third party product developed using developer 2000.
That product is customized to call this report process by passing the report number.
My only option is to play around with this report process to achieve my goal.
Can you please tell me how to detect any running applications?
I am thinking of creating a separate application that would act like a report manager to control all the report process instances. SO when the VERY first instance of the report process starts it will start the report manager. This manager inturn will look for all the instance of the report process to be over before start printing all the reports created by all the report process instances.
to do this I need to know a way to detect all the running report process from report manager application.
thanks in advance.
That product is customized to call this report process by passing the report number.
My only option is to play around with this report process to achieve my goal.
Can you please tell me how to detect any running applications?
I am thinking of creating a separate application that would act like a report manager to control all the report process instances. SO when the VERY first instance of the report process starts it will start the report manager. This manager inturn will look for all the instance of the report process to be over before start printing all the reports created by all the report process instances.
to do this I need to know a way to detect all the running report process from report manager application.
thanks in advance.
ok, I am confused. Can you give me a layout of how the program interacts with your program? Which is Which?
I thought the reson you wanted the ShelLExecute function was to open the report program with parameters. you should be able to send a command to open 1 report at a time right??
I thought the reson you wanted the ShelLExecute function was to open the report program with parameters. you should be able to send a command to open 1 report at a time right??
Dim prnt As Printer
For Each prnt In Printers
List1.AddItem prnt.DeviceName
Next
to set:
Set Printer = Printers(List1.ListIndex)