Wait -- I think I misunderstood. One question, are you printing from a file or from code? Second related question, is it already in PostScript?
Main Topics
Browse All TopicsI need to print to a postscript file from a VB app. The printer itself is simple to set up, but when I send the print commands, an input box pops up asking for the file name.
Is there any way I could pass the file name from code, and not have the box appear?
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Hello.
I think GivenRandy is on the right path.
If you already know the file name to print to (can be easily arranged or pre-arranged)
all you need do is "Send keys" to the pop-up window that appears and "OK" it.
(notice that you will hardly notice the pop-up appear and disapper. when you have sent keys to it.
<Send Keys "my file name",False>.
Check the proper syntax of use and arguments. (it's basically easy.)
Here's a link with some code (similar to GivenRandy's) but more extensive-with samples.
http://www.kather.net/Visu
Hello.
I think GivenRandy is on the right path.
If you already know the file name to print to (can be easily arranged or pre-arranged)
all you need do is "Send keys" to the pop-up window that appears and "OK" it.
(notice that you will hardly notice the pop-up appear and disapper. when you have sent keys to it.
<Send Keys "my file name",False>.
Check the proper syntax of use and arguments. (it's basically easy.)
Here's a link with some code (similar to GivenRandy's) but more extensive-with samples.
http://www.kather.net/Visu
[:o)
Have you explored the printer object.?
dialog.show print.
here's a link.http://www.ms-vb.com/
[:o)
I think you guys are missing the essense of the question. He says he is printing postscript. The printer object itself does not produce postscript output. The fact he is getting a messagebox asking for a filename suggests to me that his printer driver is set up to print to a file and it is prompting him for the filename.
If that is the case, sendkeys might work though I have had mixed success with filling in dialog boxes with it.
I am using the printer driver to create the postscript or PDF output from text created in code. The actual postscript or pdf file does not exist until the printer driver creates it. I need to create a report from a database that can be generated from my website, then the resulting PDF file viewed/printed/downloaded.
Sendkeys does not work with the messagebox asking for a file name for the output file. I've tried appactivate with the message box title but that won't select the message box as the sendkeys destination.
Here's one more factor.
I've tried findwindow to get the handle for this dialog box. No go. The dialog box appears as soon as you send any printer commands, in my case the initial scaling command. At that point my code execution stops, waiting for input into the dialog box. Any findwindow or set focus or sendkeys statements placed after the initial printer command, DO NOT get executed until after the dialog box is filled in.
sodakotahusker
And just how did you do that. I've tried using a seperate exe, but obviously I'm doing something wrong. How do you detect the dialog box and send keystrokes to it. Appactivate doesn't find it, findwindow does but how do I set the focus to the box for sendkeys.
A small chunk of code would be appreciated with examples of
1) how to detect the dialog box
2) how to set the focus to that box
Thanks
Hi,
I wonder whether this msgbox (if it really is a msgbox) can be trapped as an error. If u can that would make things easy.
if not perhaps killing it would do:
This is for NT
' process management
'
' type declaration
'
Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Byte
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
'
' Function declaration
Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
'
' Kill a program'
Private Const MAX_PATH = 256
Public Declare Function EnumProcesses Lib "PSAPI.DLL" ( _
lpidProcess As Long, _
ByVal cb As Long, _
cbNeeded As Long _
) As Long
Public Declare Function EnumProcessModules Lib "PSAPI.DLL" _
(ByVal hProcess As Long, _
lphModule As Long, _
ByVal cb As Long, _
lpcbNeeded As Long _
) As Long
Public Declare Function GetModuleBaseName Lib "PSAPI.DLL" Alias "GetModuleBaseNameA" _
(ByVal hProcess As Long, _
ByVal hModule As Long, _
ByVal lpFileName As String, _
ByVal nSize As Long _
) As Long
Public Declare Function GetModuleFileNameEx Lib "PSAPI.DLL" Alias "GetModuleFileNameExA" _
(ByVal hProcess As Long, _
ByVal hModule As Long, _
ByVal lpFileName As String, _
ByVal nSize As Long _
) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Const PROCESS_TERMINATE = &H1
Private Const PROCESS_CREATE_THREAD = &H2
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private Const PROCESS_DUP_HANDLE = &H40
Private Const PROCESS_CREATE_PROCESS = &H80
Private Const PROCESS_SET_QUOTA = &H100
Private Const PROCESS_SET_INFORMATION = &H200
Private Const PROCESS_QUERY_INFORMATION = &H400
Sub KillProcessName(ByVal lProcessID As Long, ByVal Nom_Prog As String)
Dim szProcessName As String
Dim lLen As Long
Dim hProcess As Long
Dim hMod(0 To 1023) As Long
Dim cbNeeded As Long
Dim i As Long
Dim iMax As Long
Dim lR As Long
Dim lngProcMorte As Long
'Dim tPMC As PROCESS_MEMORY_COUNTERS
lLen = MAX_PATH
hProcess = OpenProcess(PROCESS_QUERY_
PROCESS_VM_READ, _
0, lProcessID)
If (lProcessID <> 0 And lProcessID <> 2) Then
'// get the process name and memory usage:
If (hProcess <> 0) Then
If (EnumProcessModules(hProce
szProcessName = String$(lLen, 0)
LSet szProcessName = "unknown"
lR = GetModuleBaseName(hProcess
szProcessName = Left(szProcessName, InStr(szProcessName, Chr(0)) - 1)
If Nom_Prog = szProcessName Then
lngProcMorte = OpenProcess(PROCESS_TERMIN
Call TerminateProcess(lngProcMo
End If
szProcessName = String$(lLen, 0)
LSet szProcessName = "unknown"
lR = GetModuleFileNameEx(hProce
End If
End If
End If
CloseHandle hProcess
End Sub
Sub KillApplication(ByVal Nom_Prog As String)
Dim aProcesses() As Long
Dim cbNeeded As Long
Dim cProcesses As Long
Dim i As Long
' // Get the list of process identifiers.
ReDim aProcesses(0 To 1023) As Long
If (EnumProcesses(aProcesses(
'// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / 4
'// Print the name and process identifier for each process.
For i = 0 To cProcesses - 1
Call KillProcessName(aProcesses
Next i
End If
End Sub
Bye
Rem
This sample takes a command line argument for the name of the dialog window you are looking for and for the keys you wish to pass in. If you just want to close the window - CLOSEONLY is passed for the key strokes. This is comprised of a module and the form which calls the module. The way I use this is to shell out to DOS to run a batch file which invokes this program with the correct arguments - just before that dialog will be displayed. It uses the sleep API to pause.
-------------
module
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long
Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" (ByVal cChar As Byte) As Integer
Declare Function OemKeyScan Lib "user32" (ByVal wOemChar As Long) As Long
Declare Function CharToOem Lib "user32" Alias "CharToOemA" (ByVal lpszSrc As String, ByVal lpszDst As String) As Long
Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
Public Const WM_Close = &H10
Public Const Keyeventf_Keyup = &H2
Declare Function SetForegroundWindow& Lib "user32" (ByVal hwnd As Long)
Declare Function ShowWindow& Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long)
Declare Function SetActiveWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Global vk As Integer
Global oemchar As String
Global thekey As String
Global scan As Integer
Global results As Long
Global sleeptime As Long
Public Function GoToSleep(sleepseconds As Long, endtime As Variant)
Dim sleeptime As Double
Dim calctime As Double
Dim amtime As Double
Dim pmtime As Double
Dim curhour As Integer
Dim curminutes As Integer
If sleepseconds > 0 Then
sleeptime = sleepseconds * 1000
Sleep (sleeptime)
Exit Function
End If
' tweak this to calculate amount of milliseconds
' until a passed in time
' default to morning startup - calculate if pm
pmtime = 0
amtime = 0
pmtime = 0
curhour = Format(Time, "hh")
curminutes = Format(Time, "mm")
sleeptime = calctimedif(curhour, curminutes) ' calculate difference from now to midnight
Sleep (sleeptime)
Exit Function
End Function
--------------------------
form
Option Explicit
Dim args As Variant
Dim windowTitle As String
Dim keystoSend As String
Dim EndOnDiscovery As Boolean
Dim maxPasses As Integer
Dim numPasses As Integer
Dim WindowHandle As Long
Private Sub Form_Load()
'thekey = Chr(69)
Call DetermineParameters
numPasses = 0
startover:
numPasses = numPasses + 1
If maxPasses > 0 And numPasses > maxPasses Then End
WindowHandle = FindWindow(vbNullString, windowTitle)
If WindowHandle <> 0 Then
If keystoSend = "CLOSEONLY" Then
results = SendMessage(WindowHandle, WM_Close, 0&, 0&)
Else
results = SetForegroundWindow(Window
SendKeys keystoSend
DoEvents
End If
If EndOnDiscovery Then End
End If
' pass a zero in for time if only one pass desired.
If sleeptime = 0 Then End
If Dir$("c:\stopclose.flg") > "" Then
Kill "c:\stopclose.flg"
End
End If
Call GoToSleep(sleeptime, 0)
GoTo startover
End Sub
Private Sub DetermineParameters()
args = Split(Command$, ",")
If args(3) = "" Then
sleeptime = 300 ' default to 5 minutes
Else
sleeptime = Val(args(3))
End If
If args(3) < 0 Then
maxPasses = Abs(args(3))
sleeptime = 2 ' allow 2 seconds for #x number of passes
End If
windowTitle = args(0)
keystoSend = UCase(args(1))
EndOnDiscovery = args(2)
End Sub
You can use Winword to do the trick.
Create or open your document in Word:
Make a reference to the Word library in your project.
Now use Word like this:
On Error Resume Next
Set pWordApplication = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set pWordApplication = CreateObject ("Word.Application")
End If
pWordApplication.Documents
FileName:="DocumentNameHer
ConfirmConversions:=False,
ReadOnly:=True
Set pWordDocument = pWordApplication.ActiveDoc
pWordDocument.PrintOut _ Outputfilename:="DocumentN
PrintToFile:=True, Background:=False
pWordDocument.Close wdDoNotSaveChanges
Set pWordDocument = Nothing
pWordApplication.Quit
Set pWordApplication = Nothing
Paul
Address is;
andrew.allsopp@potashcorp.
I'll be using either Adobe Distiller, or Ghostscript to create the PDF from the postscript file. I'm using a Lexmark 4079 printer driver to file to create the postscript document.
I've set up a printer on a Linux machine that will actually create a PDF file, but I have no way to create a unique name for the file. If more than one user on the website uses the function, I can't guarantee they will get their document.
Any help would be appreciated.
Ok, I think I have an answer.
First set the distiller print driver as the default printer. Then you need to open the distiller and switch off that annoying setting that automatically opens the Acrobat reader after the PDF has been generated.
Your problem is with naming the file. Just before you use the vb printer object, set the App.Title property to the correct filename. The distiller uses the App.Title property to set the filename.
And, even though he isn't, "Bob's you uncle" you have a pdf.
Let me know if it works for your implementation. I still have to implement it on my site. Thanks.
I know this question has been graded, but I found something that may have been a little more helpful.
When using the Adober PDFWriter to generate reports as PDFs, you can set the path/filename in the registry.
You can use the reg setting called PDFFileName under the HKCU\Software\Adobe\Acroba
It is documented with the full version of Adobe Acrobat in the PDF file called Acrobat PDFWriter API Reference.
You will have to set the reg setting right before you start to use the Printer object, and once you do, the PDFWriter will automatically erase the reg setting once the PDF has been created.
Here's a snippet of the text from the PDF.
A number of PDFWriter settings can be read from and written to the Windows
Registry for Windows NT. Windows 95 and 98 use pdfwritr.ini to specify settings.
Table 1.2 lists the registry/INI entries that can be used to control PDFWriter.
For backwards compatibility, the file __pdf.ini in the Windows NT print driver
directory (used in previous releases) is mapped to the Windows Registry. This means
that applications using older functions such as WritePrivateProfileString and
GetPrivateProfileString will still work with this version of PDFWriter.
PDFWriter for Windows NT stores its registry information under the following key:
HKCU\Software\Adobe\Acroba
PDFFilename -
Full path name for PDF file. If
PDFFileName is present, the Print
dialog is suppressed. After a PDF file is
created, the PDFFileName entry is
removed from the registry. You must add
the PDFFileName entry each time you
print.
----
Hope this may help...
Later,
Steve
Business Accounts
Answer for Membership
by: GivenRandyPosted on 2000-07-23 at 11:27:21ID: 3529092
The following is a quick and easy 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
---