Fax automationFax Automation

How to launch an application to print a document

CapiFax offers a flexible and convenient way to interact even with applications not having a built-in support for bulk faxes: All you need a piece of code to launch the application and print the document by simulating a few key strokes.


Don't ask me for the number...

Many Windows applications can be launched with a document name as a commandline parameter, and an additional parameter "print" if they should output this document to the standard printer and then shut down automatically. This is quite useful for printing any document type without having to deal with the internal file format, such as .doc, .xls, .pdf or .htm. But if you do this, you would still have the problem that the fax printer driver opens a window and asks where to send the fax to.

The CapiFax printer driver supports an easy way to print (and fax) documents without showing the dialogue box for the destination fax number. You simply have to create a file CAPIFAX.NXT in the local user's application data folder. We have set up a sample program in Visual Basic 4.0 which shows the steps involved in printing and sending a document automatically.

So every ten seconds the VB program will check if there is an .htm file in a predefined folder (c:\work, in this case). If so, it creates the capifax.nxt file for CapiFax and then launches the Internet Explorer to print the document using the standard printer. This is a bit tricky since the IE opens his own printer dialogue which needs an Enter keystroke to actually print. The application data path is retrieved from the Windows API.

Sample program: Printing HTML files

Note that the title of the printer dialogue box must be known to the VB program so we can detect it. This title depends on the system language, of course. It is typically "Print" in an English Windows or "Drucken" in German; please check by manually printing a document in the Internet Explorer and then adapt the constant wi$ in the program. The VB form requires a timer element (Timer1).

Of course this is only a very basic sample, designed to show how to automate printing. In a real-world application, you will probably query the fax number from a database, and also create the documents by some program function instead of storing them manually.

'Sends documents automatically as fax
Option Explicit
DefLng A-Z

'Declarations
Const wi$ = "Print" 'Dialogue title, "Drucken" for German Windows!
Const DocPath$ = "C:\Work\" 'Document path including \ at the end
Const DocType$ = "*.HTM" 'Directory mask with file type
Dim nxt$ 'Holds the path of Capifax.nxt

'Special types
Private Type SHITEMID
 cb As Long
 abID As Byte
End Type
Private Type ITEMIDLIST
 mkid As SHITEMID
End Type

'Windows API functions
Private Declare Function SHGetSpecialFolderLocation _
 Lib "shell32.dll" (ByVal hwndOwner As Long, _
 ByVal nFolder As Long, pidl As ITEMIDLIST) As Long
Private Declare Function SHGetPathFromIDList _
 Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
 (ByVal pidl As Long, ByVal pszPath As String) As Long
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 Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
 (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMillisec As Long)
Const SW_SHOWNORMAL = 1, LOCAL_APPDATA = 28

Private Sub Form_Load()
 nxt$ = GetSpecialFolderPath(LOCAL_APPDATA)
 If LenB(nxt$) Then
  nxt$ = nxt$ & "\Shamrock"
  If LenB(Dir$(nxt$, vbDirectory)) = 0 Then
   MkDir nxt$ 'Create Shamrock folder
  End If
  nxt$ = nxt$ & "\CapiFax.nxt"
  Timer1.Interval = 10000 'Start timer
 End If
End Sub

Private Sub Timer1_Timer()
'Checks for a new .htm document every 10 s and prints it
 Dim i&, r&, doc$, nr$
 doc$ = Dir(DocPath$ & DocType$) 'Something to print?
 If doc$ = "" Then Exit Sub 'Not yet
 doc$ = DocPath$ & doc$ 'Yes, add path
 nr$ = "42" 'This is the fax destination number, just as an example!
'Wait up to 60 s for a previous print job (if any) to finish
 For i = 60 To 0 Step -1
  Sleep 1000: If LenB(Dir$(nxt$)) = 0 Then Exit For
 Next
'Write the destination number to capifax.nxt
 Open nxt$ For Output As 1: Print #1, nr$: Close 1
'Now print the document using the registered .htm application
 ShellExecute Me.hwnd,"print",doc$,vbNullString,"c:\",SW_SHOWNORMAL
'Wait until the printer dialogue appears
 For i = 15 To 0 Step -1 'Wait 15 s max.
  Sleep 1000: r = FindWindow(vbNullString, wi$)
  If r Then 'Send keypress <ENTER> to the printer dialogue
   AppActivate App.Title: AppActivate wi$
   Sleep 500: SendKeys "{ENTER}", True: Exit For
  Else 'Not necessary because no dialogue appeared
   If LenB(Dir$(nxt$)) = 0 Then Exit For
  End If
  Sleep 5000: Kill doc$ 'Let it print and then delete the file
 Next
End Sub

Private Function GetSpecialFolderPath$(ByVal FolderID)
 Dim nItemList As ITEMIDLIST, sPath$
 If SHGetSpecialFolderLocation(0, FolderID, nItemList) = 0 Then
  sPath = Space$(256)
  If SHGetPathFromIDList(nItemList.mkid.cb, sPath) Then
   GetSpecialFolderPath = Left$(sPath, InStr(sPath, vbNullChar) - 1)
  End If
 End If
End Function

05/2007 Shamrock Software GmbH