|
|
[Home] [What's New] [Download] [Pricing & BuyNow] [Tips] [Developer] [FAQ] [Manual] [Screenshots] [Contacts]
Print to image file - TIFF, GIF, JPEG, JPEG 2000, PDF, BMP, PNG
|
Developer>> |
|
Developer |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Printer friendly version of this page This document contains information about Zan Image Printer's configuration options including how to modify options from your application. It also discusses how to print a document to Zan Image Printer from your application. Zan Image Printer uses INI files to store the printer settings. When you alter your preferences within Zan Image Printer user interface, the INI files are automatically modified and saved. The sections, keywords, and values in each of the INI files used by Zan Image Printer are explained in detail in this document. Two programming models are available to developers. You can directly access and modify the INI setting files (using the Win32 APIs or with INI components) or you can call the provided command line utilities directly from your application. This document includes numerous VBScript, VB, Delphi, C/C++, VC.NET/CLI, VB.NET, and C# code samples to help you get started quickly. Many users have asked us how to print documents to Zan Image Printer within their applications. Therefore, we have also included many VB, Delphi, C/C++, VC.NET/CLI, VB.NET, and C# code examples, demonstrating how to automate printing Word documents, Excel spreadsheets, HTML files, and other shell printable documents from your application. The provided command line utilities zvprtcfg and zvprtcfg_win32 also support some batch/script printing commands so you can automatically print your files (Excel, Word, HTML, PDF, and other shell printable documents). There are also examples of how to print entire subfolders of documents, which turns Zan Image Printer into a powerful batch document converter.
Zan Image Printer adds an uninstall registry entry under HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50 after it is installed. Query this uninstall registry entry (e.g., value data is C:\Program Files\zvprt50\uninstall.exe) to determine directory where Zan Image Printer was installed. The function GetZanInstallDir in the "change save.ini and image.ini settings" code samples demonstrates how to query Zan Image Printer's installation folder. Tip: The easiest way to see where the program files are located on your computer is to go to the Program Information page and check the value of the Installation Directory item in the list. If Zan Image Printer was installed with the "all users share the same settings" option disabled, all Zan Image Printer specific settings are saved in INI setting files stored in CSIDL_APPDATA\zvprt50\[printername], where CSIDL_APPDATA(0x001a) identifies the file system directory that serves as a common repository for the current user's application-specific data. To access the INI file path for the specified printer independently of the operating system, applications should call the SHGetFolderPath Win32 API with CSIDL_APPDATA and then append zvprt50\[printername] to the returned path. For example, if the current user is administrator, and the printer name is Zan Image Printer(bw), a typical path to the INI setting files for this printer is C:\Documents and Settings\Administrator\Application Data\zvprt50\Zan Image Printer(bw). If Zan Image Printer was installed with the "all users share the same settings" option enabled, the policy property (integer) in the configure.ini file determines where the common application data that can be read and written by all users is located: C:\Documents and Settings\All Users\Application Data\zvprt50\Zan Image Printer(bw) C:\Documents and Settings\All Users\Documents\zvprt50\Zan Image Printer(bw) The function GetZanConfigurationDir in the "change save.ini and image.ini settings" code samples demonstrates how to determine Zan Image Printer's configuration directory programmatically. Tips: "All users share the same settings" = 0 (users have their own settings with the printer): C:\Program Files\zvprt50>zvprtcfg zan image printer(bw) configuration.allusers=0 "All users share the same settings" = 1: C:\Program Files\zvprt50>zvprtcfg zan image printer(bw) configuration.allusers=1 Running the command line utility zvprtcfg with -show switch also displays the current INI setting files folder (Configuration Directory): C:\Program Files\zvprt50>zvprtcfg zan image printer(bw) -show Build Datetime=Nov 28 2009, 12:16:28 File Version=5, 0, 9, 1 OS Name=Microsoft Windows XP Professional x64 Edition OS Version=5.02.3790 Service Pack 1 Windows Directory=C:\WINDOWS System Directory=C:\WINDOWS\system32 Session ID=0 Printer Driver Directory=C:\WINDOWS\system32\spool\DRIVERS\x64 Configuration Directory=C:\Documents and Settings\Administrator\Application Data \zvprt50\zan image printer(bw) Printer GPD File=C:\WINDOWS\system32\spool\DRIVERS\x64\3\zvprt1.gpd Debug Logging=Disabled Windows environment variables: [%ALLUSERSPROFILE]=C:\Documents and Settings\All Users [%APPDATA]=C:\Documents and Settings\Administrator\Application Data [%TEMP]=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp [%TMP]=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp [%USERDOMAIN]=ZAN-PMLGRLABUJT [%USERNAME]=Administrator [%USERPROFILE]=C:\Documents and Settings\Administrator [%windir]=C:\WINDOWS Parameters(keyword-value pairs) for zan image printer(bw): save.folder=E:\test\ save.basefilename=[%DocName] save.filenameindex=1 save.filexistact=1 save.popupdialog=2 Debug Logging for troubleshooting Zan Image Printer offers the capability to create a detailed log file for troubleshooting purposes. For more details, see the Program Information page. Furthermore, Zan Image Printer has been built in with extra debug information, which allows us to quickly analyze and solve program crashes if the Windows memory dump or minidump file is provided to us. multi-threaded printing To achieve multi-threaded printing, you can load balance the print jobs across multiple Zan Image Printer instances (e.g., submit the print job to the printer with the least amount of pending documents). This is because we want to have every Windows Spooler queue printing actively and independently, if all the print jobs went to the same Zan Image Printer, only one job at a time would actually be printed before moving to the next print job in the printer queue. default ini setting files The installation program copies the ini setting files of the first selected printer to your hard disk (the default location is C:\Program Files\zvprt50\default). When a user accesses Zan Image Printer for the first time, Zan Image Printer copies an initial profile for this user from C:\Program Files\zvprt50\default. combine/merge multiple document types into a single TIFF/PDF file Zan Image Printer can combine or merge multiple document types into a single TIFF/PDF file. Use the following steps to accomplish this: 1. On the Save page, specify a permanently fixed file name if you want to always append to the same file. Alternatively, you can specify a variable file name using macros. For example, if you specify a relatively fixed file name like "document[%date]", you can append to a different file each day. The images will append to the same file as long as you have not passed midnight. Only after midnight will a new file be created and the images for that day will be appended to the new file.
create faxable TIFF files A faxable file is a monochrome image file in TIFF format. Zan Image Printer can be set up to create faxable TIFF files. With this capability, anything you can print can be converted into a fax compatible file. Use the following steps to create faxable TIFF: 1. Review your faxing hardware and software's specification to determine the required TIFF parameters so that you can configure Zan Image Printer to match. If you have a sample TIFF file and wish to determine the values of the tags in the header, you can download AsTiffTagViewer, it is a free TIFF Tag Viewer for Windows. 2. During the setup, configure the selected printer to only support 204 x 196 (204 x 98) DPI and A4 (or Letter) paper size, set the default Color to Black & White mode. The TIFF Class F suggests that the <98, 100>, <196, 200>, <200, 204> DPI resolution values may be treated as being equivalent, so you can also set the supported DPI to 200 x 200 (200 x 100) depending on your requirements. 3. After Zan Image Printer is installed, on the Image->TIFF tab, set the "RowsPerStrip" to "Each page as a single strip". If your fax application requires LSB-to-MSB(FillOrder=2) bit order, check the "Reverse bit order" option. The vast majority of facsimile products store data LSB first (FillOrder=2, LSB-to-MSB). Use CCITT Group 4 compression whenever permitted by your faxing hardware and software, since CCITT Group 4 compression will usually offer a better compression ratio than CCITT Group 3.
4. On the Advanced TIFF options dialog, specify the options to make a faxable TIFF with a preset width and height. Faxable TIFFs must have a 1728 pixel width. Some fax applications also require a specific height based on a specific number of lines such as 2200. Consult your fax application's documentation to determine what restrictions it has. Check the "Place Image File Directory (IFD) in front of image data" option if your fax application requires that the TIFF image file descriptor (IFD) header precede the actual TIFF data (e.g., Cisco fax-enabled routers).
All of the Zan Image Printer specific options are grouped in several INI files, you can edit INI files manually with any plain text editor (e.g., Notepad), developers can also call Win32 APIs (GetPrivateProfileString, GetPrivateProfileInt, WritePrivateProfileString) to read or write these INI files directly to control the printer's behavior programmatically. ini files:
Settings in save.ini The AppName specifies the name of the section containing the key name, AppName is the first parameter to be passed when calling the GetPrivateProfileString, GetPrivateProfileInt and WritePrivateProfileString Win32 APIs. KeyName specifies the name of the key whose associated string is to be retrieved. KeyName is the second parameter to be passed when calling the GetPrivateProfileString, GetPrivateProfileInt and WritePrivateProfileString Win32 APIs. All the data is stored either as a string or as a DWORD (32-bit integer). The fourth column "Command Line Utility KeyName" specifies the keyname used by the command line utilities zvprtcfg and zvprtcfg_win32. The table below lists all of the supported settings in save.ini.
The following code samples explain how to retrieve the save folder and popup dialog option, as well as how to change the file name and when file exists option. The code samples also show how to set the file format to 2 (JPEG), the color type to 3 (true color), and then obtain the current compression method. VB code sample:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" ( _
ByVal dwMilliseconds As Long)
Private Declare Function GetDefaultPrinter Lib "winspool.drv" _
Alias "GetDefaultPrinterA" (ByVal pszBuffer As String, _
pcchBuffer As Long) As Long
Private Declare Function SetDefaultPrinter Lib "winspool.drv" _
Alias "SetDefaultPrinterA" (ByVal pszPrinter As String) As Long
Private Declare Function SHGetFolderPath Lib "shell32" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Long, ByVal nFolder As Long, _
ByVal hToken As Long, ByVal dwFlags As Long, _
ByVal pszPath As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32.dll" _
Alias "GetPrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Integer, ByVal lpFileName As String) As Integer
Private Declare Function GetPrivateProfileInt Lib "kernel32.dll" _
Alias "GetPrivateProfileIntA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal nDefault As Integer, _
ByVal lpFileName As String) As Integer
Private Declare Function WritePrivateProfileString Lib "kernel32.dll" _
Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal lpString As String, _
ByVal lpFileName As String) As Integer
Private Declare Function WaitForSingleObject Lib "kernel32.dll" _
(ByVal hHandle As Long, ByVal _
dwMilliseconds As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" (ByVal hKey As Long, _
ByVal lpValueName As String, ByVal lpReserved As Long, _
lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function CreateEvent Lib "kernel32" _
Alias "CreateEventA" (ByVal lpEventAttributes As Long, _
ByVal bManualReset As Long, ByVal bInitialState As _
Long, ByVal lpname As String) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" _
Alias "GetVersionExA" _
(lpVersionInformation As OSVERSIONINFO) As Long
Private Const HKEY_LOCAL_MACHINE = &H80000002
'Registry action types.
Private Const ERROR_SUCCESS = 0
Private Const STANDARD_RIGHTS_READ As Long = &H20000
Private Const KEY_QUERY_VALUE As Long = &H1
Private Const KEY_ENUMERATE_SUB_KEYS As Long = &H8
Private Const KEY_NOTIFY As Long = &H10
Private Const SYNCHRONIZE As Long = &H100000
Private Const KEY_READ As Long = ((STANDARD_RIGHTS_READ Or _
KEY_QUERY_VALUE Or _
KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY) And _
(Not SYNCHRONIZE))
'Used CSIDL values.
Private Const CSIDL_APPDATA As Long = &H1A
Private Const CSIDL_PROGRAM_FILES As Long = &H26
Private Const CSIDL_COMMON_APPDATA As Long = &H23
Private Const CSIDL_COMMON_DOCUMENTS As Long = &H2E
Private Const SHGFP_TYPE_CURRENT = 0
Private Const S_OK As Long = 0
Private Const MAX_PATH = 260
Private Const SW_SHOWNORMAL = 1
Private Const INFINITE = &HFFFF
'Windows-defined type OSVERSIONINFO
Private Type OSVERSIONINFO
OSVSize As Long
dwVerMajor As Long 'dwVerMajor = 6: Vista or above
dwVerMinor As Long
dwBuildNumber As Long
PlatformID As Long
szCSDVersion As String * 128
End Type
'Determines whether the given path refers to an existing
'directory
Function DirExists(ByVal DName As String) As Boolean
Dim sDummy As String
On Error Resume Next
If Right(DName, 1) <> "\" Then DName = DName & "\"
sDummy = Dir$(DName & "*.*", vbDirectory)
DirExists = Not (sDummy = "")
End Function
'Searches a path for a file name
Function GetFilePath(FileName As String) As String
Dim i As Long
For i = Len(FileName) To 1 Step -1
Select Case Mid$(FileName, i, 1)
Case ":"
GetFilePath = Left$(FileName, i)
Exit For
Case "\"
GetFilePath = Left$(FileName, i - 1)
Exit For
End Select
Next
End Function
'Determines Zan Image Printer installation directory
Private Function GetZanInstallDir() As String
Dim sPath As String
Dim szTmp As String * MAX_PATH
Dim lResult As Long
Dim hKey, dwSize As Long
dwSize = MAX_PATH
'first check to see if the uninstall registry entry exists
If RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
"\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50" _
, 0&, KEY_READ, hKey) = ERROR_SUCCESS Then
If RegQueryValueEx(hKey, "UninstallString", _
0&, 0&, ByVal szTmp, dwSize) = ERROR_SUCCESS Then
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
sPath = GetFilePath(sPath)
If DirExists(sPath) Then
GetZanInstallDir = sPath
Exit Function
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
lResult = SHGetFolderPath(0, _
CSIDL_PROGRAM_FILES, _
0, _
SHGFP_TYPE_CURRENT, _
szTmp)
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
If Right$(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
sPath = sPath & "zvprt50"
GetZanInstallDir = sPath
End Function
'Determines Zan Image Printer
'configuration directory for the ini setting files
Private Function GetZanConfigurationDir(szPrinter As String) As String
Dim sPath As String * MAX_PATH
Dim lResult As Long
Dim lPolicy As Long
Dim csidl As Long
Dim osv As OSVERSIONINFO
Dim LRet As Long
Dim sCfg As String
'read the OS info
osv.OSVSize = Len(osv)
LRet = GetVersionEx(osv)
'read configure.ini from
'Zan Image Printer installation directory
sCfg = GetZanInstallDir()
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "configure.ini"
'Read the all users (per-machine) folder policy
'from configure.ini:
'policy=1: auto detect, if Vista or newer,
'use CSIDL_COMMON_DOCUMENTS as the
'all users (per-machine) folder;
'otherwise, use CSIDL_COMMON_APPDATA
'policy=2: use CSIDL_COMMON_APPDATA
'policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", "policy", _
1, sCfg)
'handle the auto detect policy
If lPolicy = 1 Then
'Vista and 2008: dwVerMajor>=6
If osv.dwVerMajor >= 6 Then
lPolicy = 3
Else
lPolicy = 2
End If
End If
If lPolicy = 2 Then
csidl = CSIDL_COMMON_APPDATA
Else
csidl = CSIDL_COMMON_DOCUMENTS
End If
'get the all users (per-machine) folder
lResult = SHGetFolderPath(0, _
csidl, _
0, _
SHGFP_TYPE_CURRENT, _
sPath)
sCfg = Left$(sPath, _
InStr(sPath, vbNullChar) - 1)
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "zvprt50\" & szPrinter
'if the all users (per-machine) folder exists,
'then this zan image printer was installed per-machine:
'all users share the same settings
If DirExists(sCfg) Then
'all users will share the same
'settings for the printer
GetZanConfigurationDir = sCfg
Exit Function
End If
'if the all users (per-machine) folder doesn't exist,
'assume each user has his own settings
'for the printer:
lResult = SHGetFolderPath(0, _
CSIDL_APPDATA, _
0, _
SHGFP_TYPE_CURRENT, _
sPath)
sCfg = Left$(sPath, _
InStr(sPath, vbNullChar) - 1)
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "zvprt50\" & szPrinter
GetZanConfigurationDir = sCfg
End Function
Public Sub Main()
Dim IniFileFolder As String
Dim SaveFolder As String * MAX_PATH
Dim PopupDlgInd As Integer
Dim SaveIniFileFolder As String
Dim ImageIniFileFolder As String
Dim Compress As Integer
IniFileFolder = GetZanConfigurationDir("Zan Image Printer(bw)")
If Right$(IniFileFolder, 1) <> "\" Then
IniFileFolder = IniFileFolder & "\"
End If
'save.ini read/write:
SaveIniFileFolder = IniFileFolder & "save.ini"
GetPrivateProfileString "save", "folder", "", _
SaveFolder, MAX_PATH, SaveIniFileFolder
SaveFolder = Left$(SaveFolder, _
InStr(SaveFolder, vbNullChar) - 1)
WritePrivateProfileString "save", "basefilename", _
"[%DocName]_[%Page]", SaveIniFileFolder
PopupDlgInd = GetPrivateProfileInt("save", "popupdialog", _
0, SaveIniFileFolder)
WritePrivateProfileString "save", "filexistact", "1", _
SaveIniFileFolder
'image.ini read/write:
ImageIniFileFolder = IniFileFolder & "image.ini"
WritePrivateProfileString "image", "fileformat", "2", ImageIniFileFolder
WritePrivateProfileString "image", "imagecolor", "3", ImageIniFileFolder
Compress = GetPrivateProfileInt("image", "compression", _
0, ImageIniFileFolder)
End Sub
Delphi code sample:
unit zanprinter;
interface
uses
Windows, Messages, SysUtils, ShlObj, ShellAPI, SHFolder, ComObj;
function GetDefaultPrinter(prnName:PAnsiChar; var bufSize:DWORD):
BOOL; stdcall; external 'winspool.drv' name 'GetDefaultPrinterA';
function SetDefaultPrinter(prnName:PAnsiChar):
BOOL; stdcall; external 'winspool.drv' name 'SetDefaultPrinterA';
procedure GetZanInstallDir(var APath: String);
procedure GetZanConfigurationDir(var szPrinter: String;
var cfgdir: String);
procedure readwriteini();
implementation
//Determines Zan Image Printer installation directory
procedure GetZanInstallDir(var APath: String);
var
hkeyStartup: HKEY;
dwSize: DWORD;
begin
dwSize := MAX_PATH;
SetLength(APath, MAX_PATH);
//first check to see if the uninstall registry entry exists
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50',
0,
KEY_READ,
hkeyStartup) = ERROR_SUCCESS then
begin
if RegQueryValueEx(hkeyStartup,
'UninstallString', nil, nil,
PBYTE(Pchar(APath)),
@dwSize) = ERROR_SUCCESS then
begin
APath := String (PChar(APath));
APath := ExtractFilePath(APath);
end;
//Close the Key, we won't be needing it anymore
RegCloseKey(hkeyStartup);
if DirectoryExists(APath) then Exit;
end;
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0,
PChar(APath));
APath := String (PChar (APath));
if (APath[Length(APath)] <> '\')
then APath := APath + '\';
APath := APath + 'zvprt50';
end;
//Determines Zan Image Printer
//configuration directory for the ini setting files
procedure GetZanConfigurationDir(var szPrinter: String;
var cfgdir: String);
var
osv: TOSVersionInfo;
lPolicy, csidl: Integer;
begin
SetLength(cfgdir, MAX_PATH);
//read the OS info
FillChar(osv, SizeOf(osv), 0);
osv.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
GetVersionEx(osv);
//read configure.ini from
//Zan Image Printer installation directory
GetZanInstallDir(cfgdir);
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'configure.ini';
//read configure.ini from
//Zan Image Printer installation directory.
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy := GetPrivateProfileInt('allusersfolder', 'policy',
1, PChar(cfgdir));
//handle the auto detect policy
if lPolicy = 1 then
begin
//Vista and 2008: dwVerMajor>=6
if osv.dwMajorVersion >= 6 then lPolicy := 3
else lPolicy := 2;
end;
if lPolicy = 2 then csidl := CSIDL_COMMON_APPDATA
else csidl := CSIDL_COMMON_DOCUMENTS;
//get the all users (per-machine) folder
SetLength(cfgdir, MAX_PATH);
SHGetFolderPath(0, csidl, 0, 0, PChar(cfgdir));
cfgdir := String (PChar (cfgdir));
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'zvprt50\' + szPrinter;
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if DirectoryExists(cfgdir) then Exit;
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, PChar(cfgdir));
cfgdir := String (PChar (cfgdir));
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'zvprt50\' + szPrinter;
end;
procedure readwriteini();
var
inifilepath: String;
saveinifilepath: String;
imageinifilepath: String;
SaveFolder: String;
szPrinter: String;
PopupDlgInd: Integer;
dwCompress: Integer;
begin
szPrinter := 'Zan Image Printer(bw)';
SetLength(SaveFolder, MAX_PATH);
GetZanConfigurationDir(szPrinter, inifilepath);
if (inifilepath[Length(inifilepath)] <> '\')
then inifilepath := inifilepath + '\';
//save.ini read/write:
saveinifilepath := inifilepath + 'save.ini';
GetPrivateProfileString('save','folder','',
PChar(SaveFolder),MAX_PATH, PChar(saveinifilepath));
WritePrivateProfileString('save', 'basefilename',
'[%DocName]_[%Page]', PChar(saveinifilepath));
PopupDlgInd := GetPrivateProfileInt('save','popupdialog',
0, PChar(saveinifilepath));
WritePrivateProfileString('save', 'filexistact', '1',
PChar(saveinifilepath));
//use SaveFolder, PopupDlgInd...
//image.ini read/write:
imageinifilepath := inifilepath + 'image.ini';
WritePrivateProfileString('image', 'fileformat',
'jpeg', PChar(imageinifilepath));
WritePrivateProfileString('image', 'imagecolor',
'True Color', PChar(imageinifilepath));
dwCompress := GetPrivateProfileInt('image','compression',
0, PChar(imageinifilepath));
//use dwCompress ...
end;
end.
C code sample:
#include <windows.h>
#include <winspool.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shellapi.h>
#pragma comment(lib, "shlwapi.lib")
//Determines whether the given path refers to
//an existing directory
BOOL IsFolderExists(char *lpDirectoryName)
{
if(0 == strlen(lpDirectoryName))
{
return FALSE;
}
DWORD dwFileAttr = GetFileAttributes(lpDirectoryName);
if((dwFileAttr != 0xFFFFFFFF) &&
(dwFileAttr & FILE_ATTRIBUTE_DIRECTORY))
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer installation directory
void GetZanInstallDir(char *installfolder)
{
HKEY hkeyStartup;
//first check to see if the uninstall registry entry exists
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50",
0,
KEY_READ,
&hkeyStartup) == ERROR_SUCCESS)
{
DWORD dwSize = MAX_PATH;
if(RegQueryValueEx(hkeyStartup,
"UninstallString",
NULL,
NULL,
(LPBYTE)installfolder,
&dwSize) == ERROR_SUCCESS)
{
PathRemoveFileSpec(installfolder);
PathAddBackslash(installfolder);
}
/*Close the Key, we won't be needing it anymore*/
RegCloseKey(hkeyStartup);
if(IsFolderExists(installfolder))
{
return;
}
}
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, installfolder);
PathAddBackslash(installfolder);
strcat(installfolder,"zvprt50");
}
BOOL IsVistaOrAbove(void)
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
//Try calling GetVersionEx using the OSVERSIONINFOEX structure.
//If that fails, try using the OSVERSIONINFO structure.
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi)))
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx((OSVERSIONINFO*)&osvi))
return FALSE;
}
//vista and 2008: 6
//2003: 5
//xp: 5
if(osvi.dwMajorVersion >= 6)
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
void GetZanConfigurationDir(char *sPrinter, char *sCfg)
{
DWORD lPolicy;
DWORD csidl;
//read configure.ini from
//Zan Image Printer installation directory
GetZanInstallDir(sCfg);
PathAddBackslash(sCfg);
strcat(sCfg,"configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder",
"policy", 1, sCfg);
//handle the auto detect policy
if(1 == lPolicy)
{
if(IsVistaOrAbove()) lPolicy = 3;
else lPolicy = 2;
}
if(2 == lPolicy)
{
csidl = CSIDL_COMMON_APPDATA;
}
else
{
csidl = CSIDL_COMMON_DOCUMENTS;
}
//get the all users (per-machine) folder
SHGetFolderPath(NULL, csidl, NULL, 0, sCfg);
PathAddBackslash(sCfg);
strcat(sCfg, "zvprt50\\");
strcat(sCfg, sPrinter);
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if(IsFolderExists(sCfg)) return;
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, sCfg);
PathAddBackslash(sCfg);
strcat(sCfg, "zvprt50\\");
strcat(sCfg, sPrinter);
}
int main(int argc, char* argv[])
{
char inifilepath[MAX_PATH];
char saveinifilepath[MAX_PATH];
char imageinifilepath[MAX_PATH];
char SaveFolder[MAX_PATH];
DWORD dwPopupDlg;
DWORD dwCompress;
char *szPrinter = "zan image printer(bw)";
GetZanConfigurationDir(szPrinter, inifilepath);
PathAddBackslash(inifilepath);
//save.ini read/write:
strcpy(saveinifilepath, inifilepath);
strcat(saveinifilepath, "save.ini");
GetPrivateProfileString("save", "folder", "", SaveFolder,
MAX_PATH, saveinifilepath);
WritePrivateProfileString("save", "basefilename",
"[%DocName]_[%Page]", saveinifilepath);
dwPopupDlg = GetPrivateProfileInt("save", "popupdialog",
0, saveinifilepath);
WritePrivateProfileString("save", "filexistact", "1",
saveinifilepath);
//image.ini read/write:
strcpy(imageinifilepath, inifilepath);
strcat(imageinifilepath, "image.ini");
WritePrivateProfileString("image", "fileformat", "2",
imageinifilepath);
WritePrivateProfileString("image", "imagecolor", "3",
imageinifilepath);
dwCompress = GetPrivateProfileInt("image", "compression",
0, imageinifilepath);
return 0;
}
VC.NET code sample:
using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
using namespace System::Threading;
using namespace System::IO;
using namespace System::Diagnostics;
using namespace Microsoft::Win32;
// Declare the function that is exported from unmanaged dll:
[DllImport("winspool.drv")]
extern "C" bool _cdecl GetDefaultPrinter(
StringBuilder^ pszBuffer, int *size);
[DllImport("winspool.drv")]
extern "C" bool _cdecl SetDefaultPrinter(
String^ pszPrinter);
[DllImport("KERNEL32.DLL")]
extern "C" int _cdecl GetPrivateProfileString(
String^ lpAppName,
String^ lpKeyName,
String^ lpDefault,
StringBuilder^ lpReturnedString,
int nSize,
String^ lpFileName);
[DllImport("KERNEL32.DLL")]
extern "C" bool _cdecl WritePrivateProfileString(
String^ lpAppName,
String^ lpKeyName,
String^ lpString,
String^ lpFileName);
[DllImport("KERNEL32.DLL")]
extern "C" int _cdecl GetPrivateProfileInt(
String^ lpAppName,
String^ lpKeyName,
int nDefault,
String^ lpFileName);
[DllImport("shell32.dll")]
extern "C" bool _cdecl SHGetFolderPath(int hwndOwner,
int nFolder, int hToken, int dwFlags, StringBuilder^ pszPath);
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
//Determines Zan Image Printer installation directory
String^ GetZanInstallDir(void)
{
String^ installfolder = String::Empty;
RegistryKey ^ rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry::LocalMachine->OpenSubKey(
L"\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if(rkTest)
{
installfolder = rkTest->GetValue(L"UninstallString")->ToString();
rkTest->Close();
if(installfolder->Length)
{
installfolder = Path::GetDirectoryName(installfolder);
DirectoryInfo^ installdir1=gcnew DirectoryInfo(installfolder);
if(installdir1->Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment::GetFolderPath
(Environment::SpecialFolder::ProgramFiles);
if(!installfolder->EndsWith(L"\\"))
installfolder = String::Concat(installfolder, L"\\");
installfolder=String::Concat(installfolder, L"zvprt50");
return installfolder;
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
String^ GetZanConfigurationDir(String^ szPrinter)
{
//read the OS info
OperatingSystem^ os = System::Environment::OSVersion;
String^ sCfg;
int lPolicy;
StringBuilder^ tmpstr = gcnew StringBuilder(256);
//read configure.ini from
//Zan Image Printer installation directory
sCfg = GetZanInstallDir();
if(!sCfg->EndsWith(L"\\"))
sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt(L"allusersfolder", L"policy",
1, sCfg);
//handle the auto detect policy
if(1 == lPolicy)
{
//Vista and 2008: dwVerMajor>=6
if(os->Version->Major >= 6)
{
lPolicy = 3;
}
else
{
lPolicy = 2;
}
}
//get the all users (per-machine) folder
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if(2 == lPolicy)
{
//csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment::GetFolderPath
(Environment::SpecialFolder::CommonApplicationData);
}
else
{
//csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr);
sCfg = tmpstr->ToString();
}
if(!sCfg->EndsWith(L"\\")) sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"zvprt50\\");
sCfg = String::Concat(sCfg, szPrinter);
//all users will share the same
//settings for the printer
DirectoryInfo^ tmpdir = gcnew DirectoryInfo(sCfg);
if(tmpdir->Exists)
{
return sCfg;
}
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
sCfg = Environment::GetFolderPath
(Environment::SpecialFolder::ApplicationData);
if(!sCfg->EndsWith(L"\\")) sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"zvprt50\\");
sCfg = String::Concat(sCfg, szPrinter);
return sCfg;
}
int main(arrayVB.NET code sample:
Imports System
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports Microsoft.Win32
Module Module1
Declare Function GetDefaultPrinter Lib "winspool.drv" Alias _
"GetDefaultPrinterA" (ByVal pszBuffer As System.Text.StringBuilder, _
ByRef size As Int32) As Boolean
Declare Function SetDefaultPrinter Lib "winspool.drv" Alias _
"SetDefaultPrinterA" (ByVal pszPrinter As String) As Boolean
Private Declare Function GetPrivateProfileString Lib "kernel32" _
Alias "GetPrivateProfileStringA" _
(ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As StringBuilder, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
Private Declare Function GetPrivateProfileInt Lib "kernel32.dll" _
Alias "GetPrivateProfileIntA" _
(ByVal lpApplicationName _
As String, ByVal lpKeyName As String, ByVal nDefault As _
Integer, ByVal lpFileName As String) As Integer
Private Declare Function WritePrivateProfileString Lib "kernel32.dll" _
Alias "WritePrivateProfileStringA" _
(ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpString As String, _
ByVal lpFileName As String) As Boolean
Private Declare Function SHGetFolderPath Lib "shell32.dll" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Integer, _
ByVal nFolder As Integer, _
ByVal hToken As Integer, _
ByVal dwFlags As Integer, _
ByVal pszPath As StringBuilder) As Integer
'All Users\Documents
Private Const CSIDL_COMMON_DOCUMENTS = &H2E
'Determines Zan Image Printer installation directory
Function GetZanInstallDir() As String
Dim installfolder As String
Dim rkTest As RegistryKey
'first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey _
("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50")
If Not (rkTest Is Nothing) Then
installfolder = rkTest.GetValue _
("UninstallString").ToString()
rkTest.Close()
If (installfolder.Length > 0) Then
installfolder = Path.GetDirectoryName(installfolder)
Dim installdir1 As DirectoryInfo = _
New DirectoryInfo(installfolder)
If installdir1.Exists Then
Return installfolder
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath _
(Environment.SpecialFolder.ProgramFiles)
If Not installfolder.EndsWith("\") Then
installfolder = String.Concat(installfolder, "\")
End If
installfolder = String.Concat(installfolder, "zvprt50")
Return installfolder
End Function
'Determines Zan Image Printer
'configuration directory for the ini setting files
Function GetZanConfigurationDir(ByVal szPrinter As String) As String
'read the OS info
Dim os As OperatingSystem
Dim sCfg As String
Dim lPolicy As Integer
Dim tmpstr As StringBuilder
tmpstr = New StringBuilder(256)
os = System.Environment.OSVersion
'read configure.ini from
'Zan Image Printer installation directory
sCfg = GetZanInstallDir()
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "configure.ini")
'Read the all users (per-machine) folder policy
'from configure.ini:
'policy=1: auto detect, if Vista or newer,
'use CSIDL_COMMON_DOCUMENTS as the
'all users (per-machine) folder;
'otherwise, use CSIDL_COMMON_APPDATA
'policy=2: use CSIDL_COMMON_APPDATA
'policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", _
"policy", 1, sCfg)
'Vista and 2008: dwVerMajor>=6
If lPolicy = 1 Then
If os.Version.Major >= 6 Then
lPolicy = 3
Else
lPolicy = 2
End If
End If
'get the all users (per-machine) folder
'if the all users (per-machine) folder exists,
'then this zan image printer was installed per-machine:
'all users share the same settings
If lPolicy = 2 Then
'csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment.GetFolderPath( _
Environment.SpecialFolder.CommonApplicationData)
Else
'csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr)
sCfg = tmpstr.ToString()
End If
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "zvprt50\")
sCfg = String.Concat(sCfg, szPrinter)
'all users will share the same
'settings for the printer
Dim tmpdir As DirectoryInfo = _
New DirectoryInfo(sCfg)
If tmpdir.Exists Then
Return sCfg
End If
'if the all users (per-machine) folder doesn't exist,
'assume each user has his own settings
'for the printer:
sCfg = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "zvprt50\")
sCfg = String.Concat(sCfg, szPrinter)
Return sCfg
End Function
Sub Main()
Dim inifilepath As String
Dim saveinifilepath As String
Dim imageinifilepath As String
Dim szFolder As String
Dim tmpstr As StringBuilder
inifilepath = GetZanConfigurationDir("zan image printer(bw)")
If Not inifilepath.EndsWith("\") Then
inifilepath = String.Concat(inifilepath, "\")
End If
'save.ini read/write:
saveinifilepath = String.Concat(inifilepath, "save.ini")
tmpstr = New StringBuilder(256)
GetPrivateProfileString("save", "folder", "", tmpstr, _
tmpstr.Capacity, saveinifilepath)
szFolder = tmpstr.ToString()
WritePrivateProfileString("save", "basefilename", _
"[%DocName]_[%Page]", saveinifilepath)
Dim PopupDlgInd As Integer
PopupDlgInd = GetPrivateProfileInt("save", "popupdialog", 0, _
saveinifilepath)
WritePrivateProfileString("save", "filexistact", "1", saveinifilepath)
'image.ini read/write:
imageinifilepath = String.Concat(inifilepath, "image.ini")
Dim dwCompress As Integer
WritePrivateProfileString("image", "fileformat", "2", imageinifilepath)
WritePrivateProfileString("image", "imagecolor", "3", imageinifilepath)
dwCompress = GetPrivateProfileInt("image", "compression", _
0, imageinifilepath)
End Sub
End Module
C# code sample:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using Microsoft.Win32;
namespace readwriteini_csharp
{
class Program
{
//Determines Zan Image Printer installation directory
static string GetZanInstallDir()
{
string installfolder = string.Empty;
RegistryKey rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if (rkTest != null)
{
installfolder = rkTest.GetValue("UninstallString").ToString();
rkTest.Close();
if (installfolder.Length > 0)
{
installfolder = Path.GetDirectoryName(installfolder);
DirectoryInfo installdir1 = new DirectoryInfo(installfolder);
if (installdir1.Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath
(Environment.SpecialFolder.ProgramFiles);
if (!installfolder.EndsWith("\\"))
installfolder = string.Concat(installfolder, "\\");
installfolder = string.Concat(installfolder, "zvprt50");
return installfolder;
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
static string GetZanConfigurationDir(string szPrinter)
{
//read the OS info
OperatingSystem os = System.Environment.OSVersion;
string sCfg;
uint lPolicy;
StringBuilder tmpstr = new StringBuilder(256);
//read configure.ini from
//Zan Image Printer installation directory
sCfg = GetZanInstallDir();
if (!sCfg.EndsWith("\\"))
sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", "policy",
1, sCfg);
//handle the auto detect policy
if (1 == lPolicy)
{
//Vista and 2008: dwVerMajor>=6
if (os.Version.Major >= 6)
{
lPolicy = 3;
}
else
{
lPolicy = 2;
}
}
//get the all users (per-machine) folder
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if (2 == lPolicy)
{
//csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment.GetFolderPath
(Environment.SpecialFolder.CommonApplicationData);
}
else
{
//csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr);
sCfg = tmpstr.ToString();
}
if (!sCfg.EndsWith("\\")) sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "zvprt50\\");
sCfg = string.Concat(sCfg, szPrinter);
//all users will share the same
//settings for the printer
DirectoryInfo tmpdir = new DirectoryInfo(sCfg);
if (tmpdir.Exists)
{
return sCfg;
}
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
sCfg = Environment.GetFolderPath
(Environment.SpecialFolder.ApplicationData);
if (!sCfg.EndsWith("\\")) sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "zvprt50\\");
sCfg = string.Concat(sCfg, szPrinter);
return sCfg;
}
static void Main(string[] args)
{
string inifilepath;
string saveinifilepath;
string imageinifilepath;
string szFolder;
string szPrinter;
StringBuilder tmpstr = new StringBuilder(256);
szPrinter = "zan image printer(bw)";
inifilepath = GetZanConfigurationDir(szPrinter);
if (!inifilepath.EndsWith("\\")) inifilepath =
String.Concat(inifilepath, "\\");
//save.ini read/write:
saveinifilepath = String.Concat(inifilepath, "save.ini");
GetPrivateProfileString("save", "folder", "",
tmpstr, tmpstr.Capacity, saveinifilepath);
szFolder = tmpstr.ToString();
WritePrivateProfileString("save", "basefilename",
"[%DocName]_[%Page]", saveinifilepath);
uint dwPopupDlg = GetPrivateProfileInt("save", "popupdialog",
0, saveinifilepath);
WritePrivateProfileString("save", "filexistact", "1", saveinifilepath);
//image.ini read/write:
imageinifilepath = String.Concat(inifilepath, "image.ini");
WritePrivateProfileString("image", "fileformat", "2",
imageinifilepath);
WritePrivateProfileString("image", "imagecolor", "3",
imageinifilepath);
uint dwCompress = GetPrivateProfileInt("image",
"compression", 0, imageinifilepath);
}
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool GetDefaultPrinter(StringBuilder pszBuffer,
ref int size);
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileString(string lpAppName,
string lpKeyName, string lpDefault,
StringBuilder lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32.dll")]
static extern bool WritePrivateProfileString(string lpAppName,
string lpKeyName,
string lpString, string lpFileName);
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileInt(string lpAppName,
string lpKeyName, int nDefault, string lpFileName);
[DllImport("shell32.dll")]
static extern bool SHGetFolderPath(int hwndOwner,
int nFolder, int hToken, int dwFlags, StringBuilder pszPath);
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
}
}
zvprtcfg Zan Image Printer(bw) save.basefilename=[%DocName]_[%Page] or: zvprtcfg_win32 Zan Image Printer(bw) save.basefilename=[%DocName]_[%Page] The equivalent command line syntax to set the when file exists option to 1(Auto pick a unique name to prevent collision): zvprtcfg Zan Image Printer(bw) save.filexistact=1 or: zvprtcfg_win32 Zan Image Printer(bw) save.filexistact=1 Settings in image.ini The table below lists all of the supported settings in image.ini.
The command line syntax to set the fileformat to 2 (JPEG) is: zvprtcfg Zan Image Printer(bw) image.fileformat=2 or: zvprtcfg_win32 Zan Image Printer(bw) image.fileformat=2 The equivalent command line syntax to set the imagecolor to 3 (True Color): zvprtcfg Zan Image Printer(bw) image.imagecolor=3 or: zvprtcfg_win32 Zan Image Printer(bw) image.imagecolor=3 Settings in general.ini The table below lists all of the supported settings in general.ini.
Settings in docuname.ini The table below lists all of the supported settings in docuname.ini.
Settings in advimage.ini The table below lists all of the supported settings in advimage.ini.
Settings in app.ini The table below lists all of the supported settings in app.ini.
Settings in text.ini The table below lists all of the supported settings in text.ini.
Settings in event.ini When the application wants printing to begin, it first calls the StartDoc function in the printer driver, which signals the beginning of a new document. The process ends when the application calls EndDoc. Each page itself is delimited by a call to StartPage to begin a page and EndPage to end the page. Zan Image Printer can be configured to send a notification to your application when these events occur during the printing process. All events must have unique name (e.g., "Zan Image Printer(bw) SignalPrintDone" or a GUID string such as "{66A568A9-EECE-4695-BE9F-0CF85135E702}"), so that their names won't conflict with any other Zan Image Printer or Windows application. The "Print files programmatically using the ShellExecute Print verb" section contains the VB, Delphi, C, VC.NET, VB.NET, and C# code samples on how to wait for the EndDoc event to make sure the print is finished before submitting the next print job.
Settings in message.ini Zan Image Printer can be configured to send messages to your application when the following events occur during the printing process: StartDoc, EndDoc, StartPage, EndPage For a registered window message, the WPARAM value (or dwData in COPYDATASTRUCT structure of WM_COPYDATA message) tells you the printing process status: 100: StartDoc 101: EndDoc 102: StartPage 103: EndPage
Settings in orientation.ini The table below lists all of the supported settings in orientation.ini.
Settings in email.ini The table below lists all of the supported settings in email.ini.
Settings in watermark.ini The table below lists all of the supported settings in watermark.ini. In this table, N stands for a number from 1 to 10.
The command line syntax to add a watermark with the text "hello world" is as follows: zvprtcfg zan image printer(bw) watermark.enable=1 zvprtcfg zan image printer(bw) watermark.watermark_1.enable=1 zvprtcfg zan image printer(bw) watermark.watermark_1.displayname=watermark1 zvprtcfg zan image printer(bw) watermark.watermark_1.type=0 zvprtcfg zan image printer(bw) watermark.watermark_1.watermark=hello world zvprtcfg zan image printer(bw) watermark.watermark_1.size=24 zvprtcfg zan image printer(bw) watermark.watermark_1.position=4 Settings in printerredirection.ini The table below lists all of the supported settings in printerredirection.ini. In this table, N stands for a number from 1 to 10.
Settings in ftp.ini The table below lists all of the supported settings in ftp.ini.
change Paper Size and DPI In the past, we have observed the following problems: Some printing applications will include printer settings (DPI resolution, paper size, etc.) in the document itself and will ignore the current settings in Zan Image Printer; Some applications will always use the highest available DPI resolution for the selected printer, regardless of what is configured in Zan Image Printer; Some printing applications have their own printer settings function ("Page Setup", for example) and will ignore the settings you set in Zan Image Printer. These issues are all caused by the printing application and not by Zan Image Printer. One solution to these issues is to restrict the supported DPI/paper size to those that will actually be used by your printing application. You can then print to a printer with only your desired paper size/DPI available. For example, if you need to print at 300 x 300 DPI on Letter paper size, during the setup, you can configure the selected printer to only support 300 x 300 DPI and Letter paper size. In this way, the printing application is forced (restricted) to use 300 x 300 DPI and Letter paper size, i.e., the printing application will not be able to switch from 300 x 300 DPI to 600 x 600 DPI and you will no longer have to worry about the printing application overriding or ignoring Zan Image Printer settings. After Zan Image Printer is installed, you can execute the gpd command provided by the command line utilities zvprtcfg and zvprtcfg_win32 to change the supported DPI and paper size settings. Command line utilities zvprtcfg and zvprtcfg_win32 Although you can call the GetPrivateProfileString, GetPrivateProfileInt and WritePrivateProfileString Win32 APIs to directly access the ini setting files to programmatically control all of the Zan Image Printer specific settings, if you want even easier programmatic control, you can choose to call the command line utilities in your application or script. zvprtcfg is a console mode application, zvprtcfg_win32 is a Win 32 application, but both of them have exactly the same command line syntax and same functionality. The only difference is that zvprtcfg_win32 produces no output and executes the command silently without any windows appearing. If you want to programmatically control Zan Image Printer in your own application seamlessly, use zvprtcfg_win32. For automatic scripting, use zvprtcfg instead. Command line parameters and explanations: C:\Program Files\zvprt50>zvprtcfg Syntax: zvprtcfg printer keyword=value [-silent] Or: zvprtcfg -help Or: zvprtcfg -examples Or: zvprtcfg printer -show Or: zvprtcfg printer -setdefault Or: zvprtcfg -listprinters Where: printer: printer name silent: do not print out any message on screen show: show the current parameters(keyword-value pairs) for the specified printer examples: show usage examples listprinters: show all installed printer instances setdefault: set the specified printer as the default printer All the keywords supported by the command line utilities can be found in the fourth column "Command Line Utility KeyName" in the above ini file tables. For example, if you want to change the save folder for Zan Image Printer, from the save.ini table, you find the save.folder in the column "Command Line Utility KeyName", the command line to set the folder to c:\temp will therefore be (assume printer name is Zan Image Printer(bw)): zvprtcfg Zan Image Printer(bw) save.folder=c:\temp or: zvprtcfg_win32 Zan Image Printer(bw) save.folder=c:\temp To run zvprtcfg_win32 programmatically, call the CreateProcess Win32 API with the corresponding command line parameters. The following code samples illustrate how to set the save folder to c:\temp: VB code sample:
Option Explicit
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private 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 Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Declare Function CreateProcess Lib "kernel32" _
Alias "CreateProcessA" _
(ByVal lpApplicationName As String, _
ByVal lpCommandLine As String, _
lpProcessAttributes As Any, _
lpThreadAttributes As Any, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
lpEnvironment As Any, _
ByVal lpCurrentDriectory As String, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION) As Long
Private Const INFINITE = &HFFFF
Public Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function SHGetFolderPath Lib "shell32" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Long, ByVal nFolder As Long, _
ByVal hToken As Long, ByVal dwFlags As Long, _
ByVal pszPath As String) As Long
Private Const HKEY_LOCAL_MACHINE = &H80000002
'Registry action types.
Private Const ERROR_SUCCESS = 0
Private Const STANDARD_RIGHTS_READ As Long = &H20000
Private Const KEY_QUERY_VALUE As Long = &H1
Private Const KEY_ENUMERATE_SUB_KEYS As Long = &H8
Private Const KEY_NOTIFY As Long = &H10
Private Const SYNCHRONIZE As Long = &H100000
Private Const KEY_READ As Long = ((STANDARD_RIGHTS_READ Or _
KEY_QUERY_VALUE Or _
KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY) And _
(Not SYNCHRONIZE))
Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" (ByVal hKey As Long, _
ByVal lpValueName As String, ByVal lpReserved As Long, _
lpType As Long, lpData As Any, lpcbData As Long) As Long
'Used CSIDL values
Private Const CSIDL_APPDATA As Long = &H1A
Private Const CSIDL_PROGRAM_FILES As Long = &H26
Private Const CSIDL_COMMON_APPDATA As Long = &H23
Private Const SHGFP_TYPE_CURRENT = 0
Private Const S_OK As Long = 0
Const NORMAL_PRIORITY_CLASS = &H20
Private Const MAX_PATH = 260
'Determines whether the given path refers to an existing
'directory
Function DirExists(ByVal DName As String) As Boolean
Dim sDummy As String
On Error Resume Next
If Right(DName, 1) <> "\" Then DName = DName & "\"
sDummy = Dir$(DName & "*.*", vbDirectory)
DirExists = Not (sDummy = "")
End Function
'Searches a path for a file name
Function GetFilePath(FileName As String) As String
Dim i As Long
For i = Len(FileName) To 1 Step -1
Select Case Mid$(FileName, i, 1)
Case ":"
GetFilePath = Left$(FileName, i)
Exit For
Case "\"
GetFilePath = Left$(FileName, i - 1)
Exit For
End Select
Next
End Function
'Determines Zan Image Printer installation directory
Private Function GetZanInstallDir() As String
Dim sPath As String
Dim szTmp As String * MAX_PATH
Dim lResult As Long
Dim hKey, dwSize As Long
dwSize = MAX_PATH
'first check to see if the uninstall registry entry exists
If RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
"\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50" _
, 0&, KEY_READ, hKey) = ERROR_SUCCESS Then
If RegQueryValueEx(hKey, "UninstallString", _
0&, 0&, ByVal szTmp, dwSize) = ERROR_SUCCESS Then
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
sPath = GetFilePath(sPath)
If DirExists(sPath) Then
GetZanInstallDir = sPath
Exit Function
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
lResult = SHGetFolderPath(0, _
CSIDL_PROGRAM_FILES, _
0, _
SHGFP_TYPE_CURRENT, _
szTmp)
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
If Right$(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
sPath = sPath & "zvprt50"
GetZanInstallDir = sPath
End Function
'run application with given parameters
Private Sub util_CreateProcess(command_line As String)
Dim pInfo As PROCESS_INFORMATION
Dim sInfo As STARTUPINFO
Dim sNull As String
Dim lSuccess As Long
Dim lRetValue As Long
sInfo.cb = Len(sInfo)
lSuccess = CreateProcess(sNull, _
command_line, _
ByVal 0&, _
ByVal 0&, _
1&, _
NORMAL_PRIORITY_CLASS, _
ByVal 0&, _
sNull, _
sInfo, _
pInfo)
'lRetValue = WaitForSingleObject(pInfo.hProcess, INFINITE)
lRetValue = CloseHandle(pInfo.hThread)
lRetValue = CloseHandle(pInfo.hProcess)
End Sub
Public Sub Main()
Dim cmdline As String
cmdline = GetZanInstallDir()
If Right$(cmdline, 1) <> "\" Then
cmdline = cmdline & "\"
End If
cmdline = cmdline & _
"zvprtcfg_win32 Zan Image Printer(bw) save.folder=c:\temp"
util_CreateProcess cmdline
End Sub
Delphi code sample:
unit zanprinter;
interface
uses
Windows, Messages, SysUtils, ShlObj,
ShellAPI, SHFolder, Registry;
procedure util_CreateProcess(ProgramName:String);
procedure GetZanInstallDir(var APath: String);
procedure zvprtvfg_test();
implementation
//run application with given parameters
procedure util_CreateProcess(ProgramName:String);
var
StartInfo : TStartupInfo;
ProcInfo : TProcessInformation;
CreateOK : Boolean;
begin
FillChar(StartInfo,SizeOf(TStartupInfo),#0);
FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
StartInfo.cb := SizeOf(TStartupInfo);
CreateOK := CreateProcess(nil,PChar(ProgramName),nil,nil,False,
CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
nil, nil, StartInfo, ProcInfo);
if CreateOK then
begin
//WaitForSingleObject(ProcInfo.hProcess, INFINITE);
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end
end;
//Determines Zan Image Printer installation directory
procedure GetZanInstallDir(var APath: String);
var
hkeyStartup: HKEY;
dwSize: DWORD;
begin
dwSize := MAX_PATH;
SetLength(APath, MAX_PATH);
//first check to see if the uninstall registry entry exists
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50',
0,
KEY_READ,
hkeyStartup) = ERROR_SUCCESS then
begin
if RegQueryValueEx(hkeyStartup,
'UninstallString', nil, nil,
PBYTE(Pchar(APath)),
@dwSize) = ERROR_SUCCESS then
begin
APath := String (PChar(APath));
APath := ExtractFilePath(APath);
end;
//Close the Key, we won't be needing it anymore
RegCloseKey(hkeyStartup);
if DirectoryExists(APath) then Exit;
end;
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0,
PChar(APath));
APath := String (PChar (APath));
if (APath[Length(APath)] <> '\')
then APath := APath + '\';
APath := APath + 'zvprt50';
end;
procedure zvprtvfg_test();
var
szCmdLine: String;
begin
GetZanInstallDir(szCmdLine);
if (szCmdLine[Length(szCmdLine)] <> '\')
then szCmdLine := szCmdLine + '\';
szCmdLine := szCmdLine +
'zvprtcfg_win32 Zan Image Printer(bw) save.folder=c:\temp';
util_CreateProcess(szCmdLine);
end;
end.
C code sample:
#include <windows.h>
#include <winspool.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shellapi.h>
#pragma comment(lib, "shlwapi.lib")
//Determines whether the given path refers to
//an existing directory
BOOL IsFolderExists(char *lpDirectoryName)
{
if(0 == strlen(lpDirectoryName))
{
return FALSE;
}
DWORD dwFileAttr = GetFileAttributes(lpDirectoryName);
if((dwFileAttr != 0xFFFFFFFF) &&
(dwFileAttr & FILE_ATTRIBUTE_DIRECTORY))
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer installation directory
void GetZanInstallDir(char *installfolder)
{
HKEY hkeyStartup;
//first check to see if the uninstall registry entry exists
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50",
0,
KEY_READ,
&hkeyStartup) == ERROR_SUCCESS)
{
DWORD dwSize = MAX_PATH;
if(RegQueryValueEx(hkeyStartup,
"UninstallString",
NULL,
NULL,
(LPBYTE)installfolder,
&dwSize) == ERROR_SUCCESS)
{
PathRemoveFileSpec(installfolder);
PathAddBackslash(installfolder);
}
/*Close the Key, we won't be needing it anymore*/
RegCloseKey(hkeyStartup);
if(IsFolderExists(installfolder))
{
return;
}
}
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, installfolder);
PathAddBackslash(installfolder);
strcat(installfolder,"zvprt50");
}
BOOL util_CreateProcess(char* command_line)
{
PROCESS_INFORMATION pInfo;
STARTUPINFO sInfo;
ZeroMemory(&sInfo, sizeof(STARTUPINFO));
sInfo.cb = sizeof(STARTUPINFO);
sInfo.lpReserved = NULL;
sInfo.lpReserved2 = NULL;
sInfo.cbReserved2 = 0;
sInfo.lpDesktop = NULL;
sInfo.lpTitle = NULL;
sInfo.dwFlags = 0;
sInfo.dwX = 0;
sInfo.dwY = 0;
sInfo.dwFillAttribute = 0;
sInfo.wShowWindow = SW_SHOW;
BOOL bret = CreateProcess(NULL, command_line, NULL, NULL,
FALSE, 0, NULL, NULL, &sInfo, &pInfo);
//WaitForSingleObject(pInfo.hProcess, INFINITE);
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
return bret;
}
int main(int argc, char* argv[])
{
char szCmdLine[MAX_PATH];
GetZanInstallDir(szCmdLine);
PathAddBackslash(szCmdLine);
strcat(szCmdLine,"zvprtcfg_win32 Zan Image Printer(bw) save.folder=c:\\temp");
util_CreateProcess(szCmdLine);
return 0;
}
VC.NET code sample:
using namespace System;
using namespace Microsoft::Win32;
using namespace System::IO;
using namespace System::Diagnostics;
//Determines Zan Image Printer installation directory
String^ GetZanInstallDir(void)
{
String^ installfolder = String::Empty;
RegistryKey ^ rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry::LocalMachine->OpenSubKey(
L"\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if(rkTest)
{
installfolder = rkTest->GetValue(L"UninstallString")->ToString();
rkTest->Close();
if(installfolder->Length)
{
installfolder = Path::GetDirectoryName(installfolder);
DirectoryInfo^ installdir1=gcnew DirectoryInfo(installfolder);
if(installdir1->Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment::GetFolderPath
(Environment::SpecialFolder::ProgramFiles);
if(!installfolder->EndsWith(L"\\"))
installfolder = String::Concat(installfolder, L"\\");
installfolder=String::Concat(installfolder, L"zvprt50");
return installfolder;
}
int main(arrayVB.NET code sample:
Imports System
Imports Microsoft.Win32
Imports System.IO
Imports System.Diagnostics
Module Module1
'Determines Zan Image Printer installation directory
Function GetZanInstallDir() As String
Dim installfolder As String
Dim rkTest As RegistryKey
'first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey _
("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50")
If Not (rkTest Is Nothing) Then
installfolder = rkTest.GetValue _
("UninstallString").ToString()
rkTest.Close()
If (installfolder.Length > 0) Then
installfolder = Path.GetDirectoryName(installfolder)
Dim installdir1 As DirectoryInfo = _
New DirectoryInfo(installfolder)
If installdir1.Exists Then
Return installfolder
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath _
(Environment.SpecialFolder.ProgramFiles)
If Not installfolder.EndsWith("\") Then
installfolder = String.Concat(installfolder, "\")
End If
installfolder = String.Concat(installfolder, "zvprt50")
Return installfolder
End Function
Sub Main()
Dim apppath As String
Dim p As Process
apppath = GetZanInstallDir()
If Not apppath.EndsWith("\") Then
apppath = String.Concat(apppath, "\")
End If
apppath = String.Concat(apppath, "zvprtcfg_win32")
p = Process.Start(apppath, _
" Zan Image Printer(bw) save.folder=c:\temp")
'p.WaitForExit()
End Sub
End Module
C# code sample:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;
namespace callzvprtcfg_csharp
{
class Program
{
//Determines Zan Image Printer installation directory
static string GetZanInstallDir()
{
string installfolder = string.Empty;
RegistryKey rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if (rkTest != null)
{
installfolder = rkTest.GetValue("UninstallString").ToString();
rkTest.Close();
if (installfolder.Length > 0)
{
installfolder = Path.GetDirectoryName(installfolder);
DirectoryInfo installdir1 = new DirectoryInfo(installfolder);
if (installdir1.Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath
(Environment.SpecialFolder.ProgramFiles);
if (!installfolder.EndsWith("\\"))
installfolder = string.Concat(installfolder, "\\");
installfolder = string.Concat(installfolder, "zvprt50");
return installfolder;
}
static void Main(string[] args)
{
string apppath;
Process p;
apppath = GetZanInstallDir();
if (!apppath.EndsWith("\\"))
apppath = String.Concat(apppath, "\\");
apppath = String.Concat(apppath, "zvprtcfg_win32");
p = Process.Start(apppath,
" Zan Image Printer(bw) save.folder=c:\\temp");
//p.WaitForExit();
}
}
}
The command line utilities also allow you to change the standard printer settings (paper size, DPI resolution/print quality, orientation, color, and so on) in the associated printer GPD (Generic Printer Description) file. You can open the associated GPD file by double clicking the Printer GPD File item in the Program Information dialog. Zan Image Printer is Microsoft Unidrv (Universal printer driver / Unidriver) based. Unidrv allows the creation of a printer-specific minidriver in the form of a GPD file. A GPD file is a text-based file that contains information about the printer features (supported paper size, dpi, orientation, color, etc.) that Unidrv will present in the user interface to allow the user to configure the printer. You can execute the gpd command provided by the command line utilities zvprtcfg and zvprtcfg_win32 to manipulate the printer GPD file. Note that you cannot have a vendor defined paper size (A0, A1, B0(ISO), B0(JIS), B1(ISO), B1(JIS), B2(ISO), B2(JIS), B3(ISO), B3(JIS), B4(JIS), B5(JIS), B6(ISO), F Sheet, Square, etc.) as the only paper size in the GPD file. You need to specify at least one standard paper size such as Letter, A4, Legal, etc. You also need to set the standard paper size as the default.
Some gpd command usage examples: Restrict the supported paper size to Letter and A4, and set the default paper size to Letter: zvprtcfg "Zan Image Printer(bw)" gpd.papersize=Letter,A4:Letter Use default paper size list, and set the default paper size to A4: zvprtcfg "Zan Image Printer(bw)" gpd.papersize=default:A4 Restrict the supported DPI to 200 x 200 and 200 x 100, and set the default DPI to 200 x 200: zvprtcfg Zan Image Printer(bw) gpd.dpi=200,200x100:200 Use all group 1 DPI resolutions, and set the default DPI to 300 x 300: zvprtcfg Zan Image Printer(bw) gpd.dpi=group1:300x300 User interface customization, private labeling The dialog box templates and other resources (bitmap, string table, etc.) used by Zan Image Printer are stored in zvprtres.dll. By modifying this resource dll, developers can customize the appearance of Zan Image Printer. Developers can customize the user interface by following the steps below: 1. Open the Printers folder (Start > Printers and Faxes), right click on the printer, and click Properties. 2. On the General tab, change the text in the Location/Comment box to your desired text. 3. Download a free resource editor called Resource Hacker. It is only a few hundred kilobytes and does not require installation. Start Resource Hacker by running the ResHacker.exe file, use the File menu to open zvprtres.dll. Select the resources you want to edit from the tree control on the left listing, and edit/view all the text, icons, dialogs and all of the other resources on the right panel. When you are done, Resource Hacker should ask if you want to compile this script (save your changes), answer yes. After you are finished, click Save from the File menu and quit Resource Hacker. If you have installed Microsoft Visual Studio, you can also open zvprtres.dll as a resource file and then edit it: From Visual Studio, choose File/Open, select zvprtres.dll, choose "Open as: Resources" before clicking Open. Extract text from PDF files Zan Image Printer is able to extract text from most documents, but the extracted text from PDF documents will usually be just long strings of '?' instead of the textual data. This may be caused by the following possible reasons: One possible solution is using pdftotext from the xpdf package to directly extract the text from your PDF documents. pdftotext is a command line program that can convert entire PDF documents or individual pages to plain text while maintaining layout. The extracted text can be converted to a wide choice of standard encodings including UTF-8 and ASCII. To install pdftotext: 1. Make a folder on your computer, for example c:\xpdf 2. Go to http://www.foolabs.com/xpdf/download.html, scroll down to "Precompiled binaries" and you will see a paragraph starting with "x86, DOS/Win32", click the Win32 download link in that paragraph and download the file to c:\xpdf, then unzip all the files. Examples (read the accompanying pdftotext.txt file for more usage information): pdftotext filename.pdf, this usage produces a text file (filename.txt) with the same name as the input file. pdftotext filename.pdf -layout layout.txt, this usage produces a text file layout.txt and maintains original physical layout. pdftotext filename.pdf -enc UTF-8, this usage produces a text file in UTF-8 encoding format. Generate a sentinel file after printing finishes The "Generate a sentinel file after printing finishes" option on the Settings->General tab specifies whether or not a sentinel file should be generated. The sentinel file is deleted at the start of each print session, and is recreated in the same folder as the image file after printing is finished. The sentinel file is generated according to the template. The purpose of the sentinel file is to give a printing done (finished) signal to other applications or scripts. This feature is useful for batch processing, a user application can choose to delete the sentinel file before calling Zan Image Printer, then wait for the sentinel file to be generated before starting the next print. Due to the inherent issues with Windows file system refreshes, we recommend that you use the newly added event or message notification interface instead if your application needs to monitor the printing process. Send Email from command line You can send Emails directly from the command line by using the email.send command provided by the command line utilities zvprtcfg and zvprtcfg_win32. This is a wrapper around Zan Image Printer's Email sending program zvprtemail.exe. You can even copy zvprtemail.exe and zvprtcfg.exe/zvprtcfg_win32.exe to another computer and use them together as standalone utilities for sending Emails without a full installation of Zan Image Printer. email.send command syntax (all options start with a single hyphen '-'): zvprtcfg [printername] email.send=[-option value] ... zvprtcfg_win32 [printername] email.send=[-option value] ... For a list of options and values you can use in the email.send command, see the email.ini table. In the table, the KeyName column represents the option and the Description column lists what values (string or DWORD) are allowed for the option. In addition to the options listed in the email.ini table, the email.send command also supports the following options: -cfg: read the Email options from a configuration file. The configuration file uses the email.ini format. -file: read from a file. The value of the previous option is taken from the specified file rather than the command line. Can be used after the following options: -body, -subject, -cc, -to, -attach For example, if a single line body is all that required, it can be specified on the command line using the -body option. However if a larger Email body is required, the body can be read from a file by specifying the -file option after the -body option. -dump: dump all Email sending options and values on screen when sending Emails. If the printername option is specified, Zan Image Printer will use the configuration file for that printer, the configuration file can also be specified by the -cfg option. Zan Image Printer will use the options in the configuration file by default. If an option is specified in both the configuration file and the command line, the command line value will override the configuration file. If you don't have or want a configuration file, you will need to specify all applicable options on the command line. The following examples show the use of the email.send command. Sample configuration files used in the examples: C:\email\smtpgmail.ini: [email] method=2 port=465 from=me@gmail.com to=me@example.com cc= displayname=John Smith servername=smtp.gmail.com username=me password= priority=0 ssl=1 auth=5 encoding=21 subject=Hello zip=0 maxsize=20 C:\email\mapi.ini: [email] method=1 mapi=0 to=me@example.com cc= subject=Hello maxsize=20 C:\email\attach.txt: C:\attach\attach1.pdf C:\attach\attach2.pdf C:\attach\text1.txt,text2.txt,image.jpg C:\email\manual.pdf,document.doc,report.xls,data.txt C:\email\to.txt: john@example.com smith@recipients.com david@mail.com admin@isp.net Send an Email using the configuration file email.ini for the printer "zan image printer(bw)". The email.ini file is automatically modified and saved by Zan Image Printer when you configure the Email settings on the Settings->Email page. C:\Program Files\zvprt50>zvprtcfg "zan image printer(bw)" email.send=1 Send Email using Google's Gmail service: C:\Program Files\zvprt50>zvprtcfg email.send=-cfg "c:\email\smtpgmail.ini" -to -file "c:\email\to.txt" -attach -file "c:\email\attach.txt" -body -file "c:\email\body.txt" -password xxxxx -username john Send Email through a MAPI compliant client like Outlook, Outlook Express, Mozilla Thunderbird, or Eudora: C:\Program Files\zvprt50>zvprtcfg email.send=-cfg "c:\email\mapi.ini" -to "info@isp.net, john@example.com, david@mail.com" -body "Hi, this is a test email" -subject "test" -dump 1 -attach "c:\attach\report.pdf;manual.doc;c:\help\manual.pdf" back up, restore, and copy a Zan Image Printer configuration Back up, restore, and copy Zan Image Printer configuration by using the command line utilities zvprtcfg and zvprtcfg_win32.
add and delete printers from the command line Add and delete printers by using the command line utilities zvprtcfg and zvprtcfg_win32.
Batch document conversion, command line printing, programmatically print files To perform batch document conversion with Zan Image Printer: 1. Set Zan Image Printer as the default printer: Open the Printers folder (Start > Printers and Faxes), right-click the printer, and click Set as Default Printer. 2. Configure Zan Image Printer to operate in silent mode: On the Save page, set the "Before Printing Starts Show the:" to "No Dialogs" and set "Before Printing Starts Show the:" to "Auto pick a unique name to prevent collision" or "Always overwrite":
zvprtcfg Zan Image Printer(bw) save.silentmode=1 zvprtcfg_win32 Zan Image Printer(bw) save.silentmode=1 To configure Zan Image Printer to operate in silent mode and show the status dialog using the command line utilities: zvprtcfg Zan Image Printer(bw) save.silentmode=0 zvprtcfg_win32 Zan Image Printer(bw) save.silentmode=0 3. Open Windows Explorer, select all the files that you want to convert, right click and choose Print from the context menu to start the batch conversion. Many Windows programs can accept a command line argument to print. For example, the Kodak Imaging Preview program on Windows 2000 can be used to print an image to the default printer: C:\Program files\WindowsNT\Accessories\ImageVue\KodakPrv.exe /p test.bmp This is essentially what happens when you select a bmp file in Windows Explorer with a right click and then choose Print from the context menu. There is no difference between command line printing in a batch file and [right-click]-[Print]. If you want to programmatically print using this method, just call CreateProcess with the required command line parameters or call the ShellExecute Win32 API with the Print verb in your application, you may need to pass a full application path to CreateProcess when calling it (for example, "C:\Program files\WindowsNT\Accessories\ImageVue\KodakPrv.exe /p test.bmp"). You can use the Explorer file types dialog to view the syntax of the context menu Print command for your specific file type: 1. Open Windows Explorer 2. Select the Tools menu 3. Select Folder Options 4. Click the File Types tab 5. Click the file type whose association you want to view, and then click Advanced 6. Click Print 7. Press the Edit button to view The command line utilities zvprtcfg and zvprtcfg_win32, provided by Zan Image Printer, support several batch printing commands. Use these commands to batch print Excel, Word, HTML, PDF, images, and other file types to Zan Image Printer. Specify the -recursive switch to print the files in a folder recursively. Use ';' as the separator to specify multiple files. (The '*' and '?' wildcard characters are allowed.) Specify the -watchfolder switch to monitor a folder and automate printing as files get copied to this folder.
The command line utilities zvprtcfg and zvprtcfg_win32 provided by Zan Image Printer also support the print.script command which allows you to automate the batch printing with a script file. A script is a sequence of commands for which you have a repeated use. This sequence is executed by entering the name of the script on the command line: zvprtcfg zan image printer(color) print.script=your script file Example: zvprtcfg zan image printer(color) print.script=c:\batchscript\batchprint.txt This loads c:\batchscript\batchprint.txt and executes all commands in it one by one. To create a script, open a new empty file in your editor (Notepad for example). Put Zan Image Printer zvprtcfg and zvprtcfg_win32 commands in the new empty file, like you would enter them on the command line with zvprtcfg and zvprtcfg_win32. Here is a sample script file:
;; Zan Image Printer batch print script
save.folder=c:\image
save.basefilename=[%DocName]_[04d%Page]
save.filenameindex=1
save.filexistact=auto pick
save.popupdialog=none
docuname.removestrings=1
docuname.removepath=1
image.pagetype=serialized
general.hidestsdialog=0
general.opacity=40
for imageformat in ['gif','tiff','jpeg', 'bmp', "pdf', 'jp2", "png']
image.fileformat=$imageformat
for imagecolor in ['bw','256','grayscale', 'true']
image.imagecolor=$imagecolor
for dpi in {'100', "150", "200", "240", "300"}
gpd.dpi=$dpi
print.html=c:\mydocs\*.htm
print.shellexecute=c:\mydocs\*.doc
end
end
end
This scrip iterates over the items in a string sequence using the for-end loop statement, in the order that they appear in the sequence, where it's described as:
for variable in {"value1", "value2", ...}
commands to do something
end
In the script file, all lines beginning with two semi-colons ';' are considered comments and do not have any effect. The table below lists some common applications and the command line parameters needed to start a print.
Silent install and uninstall, installing multiple printers, full version, create a custom install For OEM/developer features such as silent install/uninstall, installing multiple printers, and custom printer names, click here! For OEM partners, we can provide a special version which does not require registration after installation. Dynamically remove unwanted string from the document name via regular expression Create images named by a field value within the document via regular expression If the document name passed in by the printing application contains unwanted strings in addition to the original document name, you can use regular expressions to eliminate the unwanted strings. Image files can also be custom named based on a field value within the document via regular expression. For more details, read the Document Name page. TIFF compatibility, TIFF Tag Viewer For the TIFF compatibility issue, see the Image->TIFF page. Set folder and file name programmatically via the StartDoc Win32 API If you are a software developer and are writing applications that will print to Zan Image Printer, you can control the output folder and file name on the fly. Just set lpszDocName field of the DOCINFO structure to the fully qualified path name of the file, then pass the DOCINFO structure to the StartDoc Win32 API. But by default, this feature is disabled, you need to enable it first by setting startdocfilename to 1 in general.ini. Also, please set the file name to [%DocName] on the Save tab. For the examples below, the printer name Zan Image Printer(bw) is assumed for illustration purposes only, replace this name with your own printer name if it is different. Using the command line utilities: zvprtcfg Zan Image Printer(bw) general.startdocfilename=1 zvprtcfg Zan Image Printer(bw) save.basefilename=[%DocName] Or zvprtcfg_win32 Zan Image Printer(bw) general.startdocfilename=1 zvprtcfg_win32 Zan Image Printer(bw) save.basefilename=[%DocName] The code samples below demonstrate how to get the name of the default printer and then send text output to it. If you have set startdocfilename to 1 in file general.ini, the generated output files are saved to e:\app folder as specified in the DOCINFO structure. VB code sample:
Option Explicit
Private Declare Function GetDefaultPrinter Lib "winspool.drv" Alias _
"GetDefaultPrinterA" (ByVal pszBuffer As String, pcchBuffer As Long) As Long
Private Declare Function CreateDC Lib "gdi32" Alias _
"CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, _
ByVal lpOutput As String, lpInitData As Any) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" _
(ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _
ByVal lpString As String, ByVal nCount As Long) As Long ' or Boolean
Private Declare Function StartDoc Lib "gdi32" Alias "StartDocA" _
(ByVal hdc As Long, lpdi As DOCINFO) As Long
Private Declare Function EndDoc Lib "gdi32" (ByVal hdc As Long) _
As Long
Private Declare Function StartPage Lib "gdi32" (ByVal hdc As Long) _
As Long
Private Declare Function EndPage Lib "gdi32" (ByVal hdc As Long) _
As Long
Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type
Public Sub Main()
Dim sPrinterName As String
Dim sNameBuff As String, lLen As Long
Dim OutString As String
Dim result As Long
Dim hPrintDc As Long 'Handle to printer dc
Dim di As DOCINFO 'Structure for Print Document info
Dim i As Integer
GetDefaultPrinter vbNullChar, lLen
sNameBuff = Space$(lLen)
GetDefaultPrinter sNameBuff, lLen
sPrinterName = Left$(sNameBuff, _
InStr(sNameBuff, vbNullChar) - 1)
di.cbSize = Len(di)
di.lpszDocName = "e:\app\test.doc"
'Create a printer device context
hPrintDc=CreateDC(vbNullString,sPrinterName,vbNullString,ByVal 0&)
result = StartDoc(hPrintDc, di) 'Start a new print document
For i = 1 To 5
result = StartPage(hPrintDc) 'Start a new page
'Send text to printer
OutString = _
"Message from default printer " & sPrinterName & " page #" & i
result=TextOut(hPrintDc, 20, 20, OutString, Len(OutString))
result = EndPage(hPrintDc) 'End the page
Next
result = EndDoc(hPrintDc) 'End the print job
result = DeleteDC(hPrintDc) 'Delete the device context
End Sub
Delphi code sample:
uses
Windows, SysUtils, ShlObj, ShellAPI, SHFolder,
Graphics, WinSpool;
function GetDefaultPrinterA(prnName:PAnsiChar; var bufSize:DWORD):
BOOL; stdcall; external 'winspool.drv' name 'GetDefaultPrinterA';
procedure test_defprinter();
implementation
function getDefaultPrinterName:string;
var
lprnName: PAnsiChar;
lBufSize: DWord;
begin
GetMem(lprnName, MAX_PATH);
try
lBufSize := MAX_PATH;
GetDefaultPrinterA(lprnName, lBufSize);
Result := lprnName;
finally
FreeMem(lprnName);
end;
end;
procedure test_defprinter();
var
stPrinter: String;
msg: String;
PrinterDC: HDC;
DocInfo: TDocInfo;
i: Integer;
begin
stPrinter := getDefaultPrinterName();
PrinterDC := CreateDC(nil, PChar(stPrinter), nil, nil);
//Fill Out the DocInfo structure for the spooler
FillChar(DocInfo, sizeof(DocInfo), #0);
GetMem(DocInfo.lpszDocName, 64);
DocInfo.cbSize := SizeOf(DocInfo);
StrPCopy(DocInfo.lpszDocName, 'e:\app\test.doc');
StartDoc(PrinterDC, DocInfo);
for i := 1 to 4 do begin
StartPage(PrinterDC);
msg := 'Message from default printer ' + stPrinter + ' page #' + IntToStr(i);
TextOut(PrinterDC, 20, 20, PChar(msg), Length(msg));
EndPage(PrinterDC);
end;
FreeMem(DocInfo.lpszDocName);
EndDoc(PrinterDC);
DeleteDC(PrinterDC);
end;
C code sample:
BOOL PrintTest(void)
{
DWORD size;
HDC hdcPrint;
//get the size of the default printer name
GetDefaultPrinter(NULL, &size);
char *buffer = new char[size + 32];
if(buffer == NULL)
{
return FALSE;
}
//buffer contains the printer name
if(!GetDefaultPrinter(buffer, &size))
{
delete[] buffer;
return FALSE;
}
hdcPrint = CreateDC(NULL, buffer, NULL, NULL);
if(hdcPrint == NULL)
{
delete[] buffer;
return FALSE;
}
DOCINFO di;
memset( &di, 0, sizeof(DOCINFO));
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "e:\\app\\test.doc";
di.lpszOutput = (LPTSTR) NULL;
di.fwType = 0;
int nError = StartDoc(hdcPrint, &di);
if(nError == SP_ERROR)
{
delete[] buffer;
return FALSE;
}
char tmpstr[MAX_PATH];
//print 5 pages
for(int i = 1; i < 5; i++)
{
StartPage(hdcPrint);
wsprintf(tmpstr,
"Message from default printer %s, page #%d", buffer, i);
TextOut(hdcPrint, 20, 20, tmpstr, strlen(tmpstr));
EndPage(hdcPrint);
}
EndDoc(hdcPrint);
DeleteDC(hdcPrint);
delete[] buffer;
return TRUE;
}
VB, Delphi, C, VC.NET, VB.NET and C# code samples: print files programmatically using the ShellExecute Print verb The ShellExecute Win32 API lets you print all shell printable documents (e.g., PDF files, Microsoft Office documents, text files and many other files) to Zan Image Printer as long as the associated default programs have been installed on your computer. If you simply have a document you wish to print, and aren't too fussy about controlling the process, then you can use the ShellExecute approach. However, there are also several issues associated with ShellExecute print approach: The code samples below demonstrate how to print to Zan Image Printer using the ShellExecute function. It also demonstrates how to change the default printer and wait for the EndDoc event to make sure the print is finished. The code samples below simply use the "SignalPrintDone" as the EndDoc event name. However, in a real application, for uniqueness, we recommend using an event name such as "Zan Image Printer(bw) SignalPrintDone" or a GUID string such as "{66A568A9-EECE-4695-BE9F-0CF85135E702}", so that it won't conflict with any other Zan Image Printer and Windows application. VB code sample:
Option Explicit
Private Declare Function GetDefaultPrinter Lib "winspool.drv" Alias _
"GetDefaultPrinterA" (ByVal pszBuffer As String, pcchBuffer As Long) As Long
Private Declare Function SetDefaultPrinter Lib "winspool.drv" _
Alias "SetDefaultPrinterA" _
(ByVal pszPrinter As String) As Long
Private Declare Function SHGetFolderPath Lib "shell32" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Long, ByVal nFolder As Long, _
ByVal hToken As Long, ByVal dwFlags As Long, _
ByVal pszPath As String) As Long
Private Declare Function WritePrivateProfileString Lib "kernel32.dll" _
Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal lpString As String, _
ByVal lpFileName As String) As Integer
Private Declare Function GetPrivateProfileInt Lib "kernel32.dll" _
Alias "GetPrivateProfileIntA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal nDefault As Integer, _
ByVal lpFileName As String) As Integer
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 WaitForSingleObject Lib "kernel32.dll" _
(ByVal hHandle As Long, ByVal _
dwMilliseconds As Long) As Long
Private Declare Function CreateEvent Lib "kernel32" _
Alias "CreateEventA" (ByVal lpEventAttributes As Long, _
ByVal bManualReset As Long, ByVal bInitialState As _
Long, ByVal lpname As String) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" (ByVal hKey As Long, _
ByVal lpValueName As String, ByVal lpReserved As Long, _
lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" _
Alias "GetVersionExA" _
(lpVersionInformation As OSVERSIONINFO) As Long
Private Const HKEY_LOCAL_MACHINE = &H80000002
'Registry action types.
Private Const ERROR_SUCCESS = 0
Private Const STANDARD_RIGHTS_READ As Long = &H20000
Private Const KEY_QUERY_VALUE As Long = &H1
Private Const KEY_ENUMERATE_SUB_KEYS As Long = &H8
Private Const KEY_NOTIFY As Long = &H10
Private Const SYNCHRONIZE As Long = &H100000
Private Const KEY_READ As Long = ((STANDARD_RIGHTS_READ Or _
KEY_QUERY_VALUE Or _
KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY) And _
(Not SYNCHRONIZE))
'Used CSIDL values.
Private Const CSIDL_APPDATA As Long = &H1A
Private Const CSIDL_PROGRAM_FILES As Long = &H26
Private Const CSIDL_COMMON_APPDATA As Long = &H23
Private Const CSIDL_COMMON_DOCUMENTS As Long = &H2E
Private Const SHGFP_TYPE_CURRENT = 0
Private Const S_OK As Long = 0
Private Const MAX_PATH = 260
Private Const SW_SHOWNORMAL = 1
Private Const INFINITE = &HFFFF
'Windows-defined type OSVERSIONINFO
Private Type OSVERSIONINFO
OSVSize As Long
dwVerMajor As Long 'dwVerMajor = 6: Vista or above
dwVerMinor As Long
dwBuildNumber As Long
PlatformID As Long
szCSDVersion As String * 128
End Type
'Determines whether the given path refers to an existing
'directory
Function DirExists(ByVal DName As String) As Boolean
Dim sDummy As String
On Error Resume Next
If Right(DName, 1) <> "\" Then DName = DName & "\"
sDummy = Dir$(DName & "*.*", vbDirectory)
DirExists = Not (sDummy = "")
End Function
'Searches a path for a file name
Function GetFilePath(FileName As String) As String
Dim i As Long
For i = Len(FileName) To 1 Step -1
Select Case Mid$(FileName, i, 1)
Case ":"
GetFilePath = Left$(FileName, i)
Exit For
Case "\"
GetFilePath = Left$(FileName, i - 1)
Exit For
End Select
Next
End Function
'Determines Zan Image Printer installation directory
Private Function GetZanInstallDir() As String
Dim sPath As String
Dim szTmp As String * MAX_PATH
Dim lResult As Long
Dim hKey, dwSize As Long
dwSize = MAX_PATH
'first check to see if the uninstall registry entry exists
If RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
"\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50" _
, 0&, KEY_READ, hKey) = ERROR_SUCCESS Then
If RegQueryValueEx(hKey, "UninstallString", _
0&, 0&, ByVal szTmp, dwSize) = ERROR_SUCCESS Then
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
sPath = GetFilePath(sPath)
If DirExists(sPath) Then
GetZanInstallDir = sPath
Exit Function
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
lResult = SHGetFolderPath(0, _
CSIDL_PROGRAM_FILES, _
0, _
SHGFP_TYPE_CURRENT, _
szTmp)
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
If Right$(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
sPath = sPath & "zvprt50"
GetZanInstallDir = sPath
End Function
'Determines Zan Image Printer
'configuration directory for the ini setting files
Private Function GetZanConfigurationDir(ByVal szPrinter As String) As String
Dim sPath As String * MAX_PATH
Dim lResult As Long
Dim lPolicy As Long
Dim csidl As Long
Dim osv As OSVERSIONINFO
Dim LRet As Long
Dim sCfg As String
'read the OS info
osv.OSVSize = Len(osv)
LRet = GetVersionEx(osv)
'read configure.ini from
'Zan Image Printer installation directory
sCfg = GetZanInstallDir()
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "configure.ini"
'Read the all users (per-machine) folder policy
'from configure.ini:
'policy=1: auto detect, if Vista or newer,
'use CSIDL_COMMON_DOCUMENTS as the
'all users (per-machine) folder;
'otherwise, use CSIDL_COMMON_APPDATA
'policy=2: use CSIDL_COMMON_APPDATA
'policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", "policy", _
1, sCfg)
'handle the auto detect policy
If lPolicy = 1 Then
'Vista and 2008: dwVerMajor>=6
If osv.dwVerMajor >= 6 Then
lPolicy = 3
Else
lPolicy = 2
End If
End If
If lPolicy = 2 Then
csidl = CSIDL_COMMON_APPDATA
Else
csidl = CSIDL_COMMON_DOCUMENTS
End If
'get the all users (per-machine) folder
lResult = SHGetFolderPath(0, _
csidl, _
0, _
SHGFP_TYPE_CURRENT, _
sPath)
sCfg = Left$(sPath, _
InStr(sPath, vbNullChar) - 1)
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "zvprt50\" & szPrinter
'if the all users (per-machine) folder exists,
'then this zan image printer was installed per-machine:
'all users share the same settings
If DirExists(sCfg) Then
'all users will share the same
'settings for the printer
GetZanConfigurationDir = sCfg
Exit Function
End If
'if the all users (per-machine) folder doesn't exist,
'assume each user has his own settings
'for the printer:
lResult = SHGetFolderPath(0, _
CSIDL_APPDATA, _
0, _
SHGFP_TYPE_CURRENT, _
sPath)
sCfg = Left$(sPath, _
InStr(sPath, vbNullChar) - 1)
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "zvprt50\" & szPrinter
GetZanConfigurationDir = sCfg
End Function
Private Sub ShellExecutePrint(myDocument As String)
ShellExecute 0, "print", myDocument, _
vbNullString, vbNullString, SW_SHOWNORMAL
End Sub
Public Sub ShellExecutePrintTest()
Dim szPrinter, szEnddocEvent, strPath, szDefPrinter As String
Dim hEndDoc As Long
Dim i As Long
Dim sNameBuff As String, lLen As Long
szPrinter = "Zan Image Printer(bw)"
szEnddocEvent = "SignalPrintDone"
hEndDoc = CreateEvent(ByVal 0&, False, False, szEnddocEvent)
GetDefaultPrinter vbNullChar, lLen
sNameBuff = Space$(lLen)
GetDefaultPrinter sNameBuff, lLen
szDefPrinter = Left$(sNameBuff, InStr(sNameBuff, vbNullChar) - 1)
szDefPrinter = LCase(szDefPrinter)
szPrinter = LCase(szPrinter)
If szPrinter <> szDefPrinter Then
SetDefaultPrinter szPrinter
End If
strPath = GetZanConfigurationDir(szPrinter)
If Right$(strPath, 1) <> "\" Then
strPath = strPath & "\"
End If
strPath = strPath & "event.ini"
'enable event notification
WritePrivateProfileString "event", "enable", _
"1", strPath
'set enddoc event name
WritePrivateProfileString "event", "enddoc", szEnddocEvent, strPath
ShellExecutePrint "c:\abc\1.doc"
i = WaitForSingleObject(hEndDoc, INFINITE)
ShellExecutePrint "c:\abc\1.pdf"
i = WaitForSingleObject(hEndDoc, INFINITE)
If szPrinter <> szDefPrinter Then
SetDefaultPrinter szDefPrinter
End If
CloseHandle (hEndDoc)
End Sub
Public Sub Main()
ShellExecutePrintTest
End Sub
Delphi code sample:
unit zanprinter;
interface
uses
Windows, Messages, SysUtils, ShlObj, ShellAPI, SHFolder;
function GetDefaultPrinter(prnName:PAnsiChar; var bufSize:DWORD):
BOOL; stdcall; external 'winspool.drv' name 'GetDefaultPrinterA';
function SetDefaultPrinter(prnName:PAnsiChar):
BOOL; stdcall; external 'winspool.drv' name 'SetDefaultPrinterA';
procedure ShellExecutePrint(myDocument:String);
procedure ShellExecutePrintTest();
procedure GetZanInstallDir(var APath: String);
procedure GetZanConfigurationDir(var szPrinter: String;
var cfgdir: String);
implementation
//Determines Zan Image Printer installation directory
procedure GetZanInstallDir(var APath: String);
var
hkeyStartup: HKEY;
dwSize: DWORD;
begin
dwSize := MAX_PATH;
SetLength(APath, MAX_PATH);
//first check to see if the uninstall registry entry exists
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50',
0,
KEY_READ,
hkeyStartup) = ERROR_SUCCESS then
begin
if RegQueryValueEx(hkeyStartup,
'UninstallString', nil, nil,
PBYTE(Pchar(APath)),
@dwSize) = ERROR_SUCCESS then
begin
APath := String (PChar(APath));
APath := ExtractFilePath(APath);
end;
//Close the Key, we won't be needing it anymore
RegCloseKey(hkeyStartup);
if DirectoryExists(APath) then Exit;
end;
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0,
PChar(APath));
APath := String (PChar (APath));
if (APath[Length(APath)] <> '\')
then APath := APath + '\';
APath := APath + 'zvprt50';
end;
//Determines Zan Image Printer
//configuration directory for the ini setting files
procedure GetZanConfigurationDir(var szPrinter: String;
var cfgdir: String);
var
osv: TOSVersionInfo;
lPolicy, csidl: Integer;
begin
SetLength(cfgdir, MAX_PATH);
//read the OS info
FillChar(osv, SizeOf(osv), 0);
osv.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
GetVersionEx(osv);
//read configure.ini from
//Zan Image Printer installation directory
GetZanInstallDir(cfgdir);
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'configure.ini';
//read configure.ini from
//Zan Image Printer installation directory.
//Read the all users (per-machine) folder policy
//rom configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy := GetPrivateProfileInt('allusersfolder', 'policy',
1, PChar(cfgdir));
//handle the auto detect policy
if lPolicy = 1 then
begin
//Vista and 2008: dwVerMajor>=6
if osv.dwMajorVersion >= 6 then lPolicy := 3
else lPolicy := 2;
end;
if lPolicy = 2 then csidl := CSIDL_COMMON_APPDATA
else csidl := CSIDL_COMMON_DOCUMENTS;
//get the all users (per-machine) folder
SetLength(cfgdir, MAX_PATH);
SHGetFolderPath(0, csidl, 0, 0, PChar(cfgdir));
cfgdir := String (PChar (cfgdir));
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'zvprt50\' + szPrinter;
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if DirectoryExists(cfgdir) then Exit;
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, PChar(cfgdir));
cfgdir := String (PChar (cfgdir));
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'zvprt50\' + szPrinter;
end;
procedure ShellExecutePrint(myDocument:String);
begin
ShellExecute(0, 'print', PChar(myDocument), nil, nil, SW_SHOW);
end;
procedure ShellExecutePrintTest();
var
szPrinter, szEnddocEvent, strPath, szDefPrinter: String;
lBufSize: DWord;
hEndDoc: THandle;
begin
szPrinter := 'Zan Image Printer(bw)';
szEnddocEvent := 'SignalPrintDone';
hEndDoc := CreateEvent(nil,False,False,Pchar(szEnddocEvent));
SetLength(szDefPrinter, MAX_PATH);
lBufSize := MAX_PATH;
GetDefaultPrinter(Pchar(szDefPrinter), lBufSize);
szDefPrinter := String (PChar(szDefPrinter));
szDefPrinter := LowerCase(szDefPrinter);
szPrinter := LowerCase(szPrinter);
//change the default printer prior to calling the
//ShellExecutePrint function.
if(szPrinter <> szDefPrinter)
then SetDefaultPrinter(PChar(szPrinter));
GetZanConfigurationDir(szPrinter, strPath);
if (strPath[Length(strPath)] <> '\')
then strPath := strPath + '\';
strPath :=strPath + 'event.ini';
//enable event notification
WritePrivateProfileString('event',
'enable', '1', Pchar(strPath));
//set enddoc event name
WritePrivateProfileString('event',
'enddoc', Pchar(szEnddocEvent), Pchar(strPath));
//The print job status is "sent to printer" when
//ShellExecutePrint returns.
ShellExecutePrint('c:\abc\1.doc');
//wait for the EndDoc event to be received,
//an indication that the submitted print
//job has indeed completed
WaitForSingleObject(hEndDoc, INFINITE);
//The print job status is "sent to printer" when
//ShellExecutePrint returns.
ShellExecutePrint('c:\abc\1.pdf');
//wait for the EndDoc event to be received,
//an indication that the submitted print
//job has indeed completed
WaitForSingleObject(hEndDoc, INFINITE);
//set default printer back to original
if(szPrinter <> szDefPrinter)
then SetDefaultPrinter(PChar(szDefPrinter));
CloseHandle(hEndDoc);
end;
end.
C code sample:
#include <windows.h>
#include <winspool.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shellapi.h>
/*#import statement and smart pointers*/
#import <shdocvw.dll>
#pragma comment(lib, "shlwapi.lib")
//Determines whether the given path refers to
//an existing directory
BOOL IsFolderExists(char *lpDirectoryName)
{
if(0 == strlen(lpDirectoryName))
{
return FALSE;
}
DWORD dwFileAttr = GetFileAttributes(lpDirectoryName);
if((dwFileAttr != 0xFFFFFFFF) &&
(dwFileAttr & FILE_ATTRIBUTE_DIRECTORY))
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer installation directory
void GetZanInstallDir(char *installfolder)
{
HKEY hkeyStartup;
//first check to see if the uninstall registry entry exists
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50",
0,
KEY_READ,
&hkeyStartup) == ERROR_SUCCESS)
{
DWORD dwSize = MAX_PATH;
if(RegQueryValueEx(hkeyStartup,
"UninstallString",
NULL,
NULL,
(LPBYTE)installfolder,
&dwSize) == ERROR_SUCCESS)
{
PathRemoveFileSpec(installfolder);
PathAddBackslash(installfolder);
}
/*Close the Key, we won't be needing it anymore*/
RegCloseKey(hkeyStartup);
if(IsFolderExists(installfolder))
{
return;
}
}
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, installfolder);
PathAddBackslash(installfolder);
strcat(installfolder,"zvprt50");
}
BOOL IsVistaOrAbove(void)
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
//Try calling GetVersionEx using the OSVERSIONINFOEX structure.
//If that fails, try using the OSVERSIONINFO structure.
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi)))
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx((OSVERSIONINFO*)&osvi))
return FALSE;
}
//vista and 2008: 6
//2003: 5
//xp: 5
if(osvi.dwMajorVersion >= 6)
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
void GetZanConfigurationDir(char *sPrinter, char *sCfg)
{
DWORD lPolicy;
DWORD csidl;
//read configure.ini from
//Zan Image Printer installation directory
GetZanInstallDir(sCfg);
PathAddBackslash(sCfg);
strcat(sCfg,"configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder",
"policy", 1, sCfg);
//handle the auto detect policy
if(1 == lPolicy)
{
if(IsVistaOrAbove()) lPolicy = 3;
else lPolicy = 2;
}
if(2 == lPolicy)
{
csidl = CSIDL_COMMON_APPDATA;
}
else
{
csidl = CSIDL_COMMON_DOCUMENTS;
}
//get the all users (per-machine) folder
SHGetFolderPath(NULL, csidl, NULL, 0, sCfg);
PathAddBackslash(sCfg);
strcat(sCfg, "zvprt50\\");
strcat(sCfg, sPrinter);
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if(IsFolderExists(sCfg)) return;
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, sCfg);
PathAddBackslash(sCfg);
strcat(sCfg, "zvprt50\\");
strcat(sCfg, sPrinter);
}
void ShellExecutePrint(char *myDocument)
{
ShellExecute(NULL, "print", myDocument,
NULL, NULL, SW_SHOWNORMAL);
}
int main(int argc, char* argv[])
{
char* szPrinter = "Zan Image Printer(bw)";
char* szEnddocEvent = "SignalPrintDone";
char strPath[MAX_PATH];
char szDefPrinter[MAX_PATH];
HANDLE hEndDoc;
hEndDoc = CreateEvent(NULL, FALSE, FALSE, szEnddocEvent);
if(hEndDoc == NULL)
{
return -1;
}
DWORD dwBufSize = MAX_PATH;
GetDefaultPrinter(szDefPrinter, &dwBufSize);
/*
change the default printer prior to calling the
ShellExecutePrint function.
*/
if(strcmpi(szPrinter, szDefPrinter))
{
SetDefaultPrinter(szPrinter);
}
GetZanConfigurationDir(szPrinter, strPath);
PathAddBackslash(strPath);
strcat(strPath,"event.ini");
//enable event notification
WritePrivateProfileString("event", "enable", "1", strPath);
//set enddoc event name
WritePrivateProfileString("event", "enddoc",
szEnddocEvent, strPath);
//The print job status is "sent to printer" when
//ShellExecutePrint returns.
ShellExecutePrint("c:\\abc\\1.doc");
//wait for the EndDoc event to be received,
//an indication that the submitted print job has
//indeed completed
WaitForSingleObject(hEndDoc, INFINITE);
//The print job status is "sent to printer" when
//ShellExecutePrint returns.
ShellExecutePrint("c:\\abc\\1.pdf");
//wait for the EndDoc event to be received,
//an indication that the submitted print job has
//indeed completed
WaitForSingleObject(hEndDoc, INFINITE);
/*set default printer back to original*/
if(strcmpi(szPrinter, szDefPrinter))
{
SetDefaultPrinter(szDefPrinter);
}
return 0;
}
VC.NET code sample:
using namespace System;
using namespace System::Text;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
using namespace System::Diagnostics;
using namespace System::Threading;
using namespace Microsoft::Win32;
// Declare the function that is exported from unmanaged dll:
[DllImport("KERNEL32.DLL")]
extern "C" int _cdecl GetPrivateProfileString(
String^ lpAppName,
String^ lpKeyName,
String^ lpDefault,
StringBuilder^ lpReturnedString,
int nSize,
String^ lpFileName);
[DllImport("KERNEL32.DLL")]
extern "C" bool _cdecl WritePrivateProfileString(
String^ lpAppName,
String^ lpKeyName,
String^ lpString,
String^ lpFileName);
[DllImport("KERNEL32.DLL")]
extern "C" int _cdecl GetPrivateProfileInt(
String^ lpAppName,
String^ lpKeyName,
int nDefault,
String^ lpFileName);
[DllImport("shell32.dll")]
extern "C" bool _cdecl SHGetFolderPath(int hwndOwner,
int nFolder, int hToken, int dwFlags, StringBuilder^ pszPath);
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
[DllImport("winspool.drv")]
extern "C" bool _cdecl GetDefaultPrinter(
StringBuilder^ pszBuffer, int *size);
[DllImport("winspool.drv")]
extern "C" bool _cdecl SetDefaultPrinter(
String^ pszPrinter);
//Determines Zan Image Printer installation directory
String^ GetZanInstallDir(void)
{
String^ installfolder = String::Empty;
RegistryKey ^ rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry::LocalMachine->OpenSubKey(
L"\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if(rkTest)
{
installfolder = rkTest->GetValue(L"UninstallString")->ToString();
rkTest->Close();
if(installfolder->Length)
{
installfolder = Path::GetDirectoryName(installfolder);
DirectoryInfo^ installdir1=gcnew DirectoryInfo(installfolder);
if(installdir1->Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment::GetFolderPath
(Environment::SpecialFolder::ProgramFiles);
if(!installfolder->EndsWith(L"\\"))
installfolder = String::Concat(installfolder, L"\\");
installfolder=String::Concat(installfolder, L"zvprt50");
return installfolder;
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
String^ GetZanConfigurationDir(String^ szPrinter)
{
//read the OS info
OperatingSystem^ os = System::Environment::OSVersion;
String^ sCfg;
int lPolicy;
StringBuilder^ tmpstr = gcnew StringBuilder(256);
//read configure.ini from
//Zan Image Printer installation directory
sCfg = GetZanInstallDir();
if(!sCfg->EndsWith(L"\\"))
sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt(L"allusersfolder", L"policy",
1, sCfg);
//handle the auto detect policy
if(1 == lPolicy)
{
//Vista and 2008: dwVerMajor>=6
if(os->Version->Major >= 6)
{
lPolicy = 3;
}
else
{
lPolicy = 2;
}
}
//get the all users (per-machine) folder
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if(2 == lPolicy)
{
//csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment::GetFolderPath
(Environment::SpecialFolder::CommonApplicationData);
}
else
{
//csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr);
sCfg = tmpstr->ToString();
}
if(!sCfg->EndsWith(L"\\")) sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"zvprt50\\");
sCfg = String::Concat(sCfg, szPrinter);
//all users will share the same
//settings for the printer
DirectoryInfo^ tmpdir = gcnew DirectoryInfo(sCfg);
if(tmpdir->Exists)
{
return sCfg;
}
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
sCfg = Environment::GetFolderPath
(Environment::SpecialFolder::ApplicationData);
if(!sCfg->EndsWith(L"\\")) sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"zvprt50\\");
sCfg = String::Concat(sCfg, szPrinter);
return sCfg;
}
void ShellExecutePrint(String ^myDocument)
{
Process^ myProcess = gcnew Process;
myProcess->StartInfo->FileName = myDocument;
myProcess->StartInfo->Verb = L"Print";
myProcess->StartInfo->CreateNoWindow = true;
myProcess->Start();
}
int main(arrayVB.NET code sample:
Imports System
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Diagnostics
Imports System.Threading
Imports System.IO
Imports Microsoft.Win32
Module Module1
Declare Function GetDefaultPrinter Lib "winspool.drv" _
Alias "GetDefaultPrinterA" _
(ByVal pszBuffer As System.Text.StringBuilder, _
ByRef size As Int32) As Boolean
Declare Function SetDefaultPrinter Lib "winspool.drv" _
Alias "SetDefaultPrinterA" _
(ByVal pszPrinter As String) As Boolean
Private Declare Function GetPrivateProfileString Lib "kernel32" _
Alias "GetPrivateProfileStringW" _
(ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As StringBuilder, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
Private Declare Function GetPrivateProfileInt Lib "kernel32.dll" _
Alias "GetPrivateProfileIntA" _
(ByVal lpApplicationName _
As String, ByVal lpKeyName As String, ByVal nDefault As _
Integer, ByVal lpFileName As String) As Integer
Private Declare Function WritePrivateProfileString Lib "kernel32.dll" _
Alias "WritePrivateProfileStringA" _
(ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpString As String, _
ByVal lpFileName As String) As Boolean
Private Declare Function SHGetFolderPath Lib "shell32.dll" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Integer, _
ByVal nFolder As Integer, _
ByVal hToken As Integer, _
ByVal dwFlags As Integer, _
ByVal pszPath As StringBuilder) As Integer
'All Users\Documents
Private Const CSIDL_COMMON_DOCUMENTS = &H2E
'Determines Zan Image Printer installation directory
Function GetZanInstallDir() As String
Dim installfolder As String
Dim rkTest As RegistryKey
'first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey _
("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50")
If Not (rkTest Is Nothing) Then
installfolder = rkTest.GetValue _
("UninstallString").ToString()
rkTest.Close()
If (installfolder.Length > 0) Then
installfolder = Path.GetDirectoryName(installfolder)
Dim installdir1 As DirectoryInfo = _
New DirectoryInfo(installfolder)
If installdir1.Exists Then
Return installfolder
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath _
(Environment.SpecialFolder.ProgramFiles)
If Not installfolder.EndsWith("\") Then
installfolder = String.Concat(installfolder, "\")
End If
installfolder = String.Concat(installfolder, "zvprt50")
Return installfolder
End Function
'Determines Zan Image Printer
'configuration directory for the ini setting files
Function GetZanConfigurationDir(ByVal szPrinter As String) As String
'read the OS info
Dim os As OperatingSystem
Dim sCfg As String
Dim lPolicy As Integer
Dim tmpstr As StringBuilder
tmpstr = New StringBuilder(256)
os = System.Environment.OSVersion
'read configure.ini from
'Zan Image Printer installation directory
sCfg = GetZanInstallDir()
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "configure.ini")
'Read the all users (per-machine) folder policy
'from configure.ini:
'policy=1: auto detect, if Vista or newer,
'use CSIDL_COMMON_DOCUMENTS as the
'all users (per-machine) folder;
'otherwise, use CSIDL_COMMON_APPDATA
'policy=2: use CSIDL_COMMON_APPDATA
'policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", _
"policy", 1, sCfg)
'Vista and 2008: dwVerMajor>=6
If lPolicy = 1 Then
If os.Version.Major >= 6 Then
lPolicy = 3
Else
lPolicy = 2
End If
End If
'get the all users (per-machine) folder
'if the all users (per-machine) folder exists,
'then this zan image printer was installed per-machine:
'all users share the same settings
If lPolicy = 2 Then
'csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment.GetFolderPath( _
Environment.SpecialFolder.CommonApplicationData)
Else
'csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr)
sCfg = tmpstr.ToString()
End If
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "zvprt50\")
sCfg = String.Concat(sCfg, szPrinter)
'all users will share the same
'settings for the printer
Dim tmpdir As DirectoryInfo = _
New DirectoryInfo(sCfg)
If tmpdir.Exists Then
Return sCfg
End If
'if the all users (per-machine) folder doesn't exist,
'assume each user has his own settings
'for the printer:
sCfg = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "zvprt50\")
sCfg = String.Concat(sCfg, szPrinter)
Return sCfg
End Function
Private Sub ShellExecutePrint(ByVal myDocument As String)
Dim myProcess As Process = New Process
myProcess.StartInfo.FileName = myDocument
myProcess.StartInfo.Verb = "Print"
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
End Sub
Sub Main()
Dim szPrinter As String = "Zan Image Printer(bw)"
Dim szEnddocEvent As String = "SignalPrintDone"
Dim strPath As String
Dim tempstr As StringBuilder
tempstr = New StringBuilder(256)
Dim szDefPrinter As String
Dim dwBufSize As Integer
dwBufSize = tempstr.Capacity
GetDefaultPrinter(tempstr, dwBufSize)
szDefPrinter = tempstr.ToString()
'change the default printer prior to calling the
'ShellExecutePrint function.
If String.Compare(szPrinter, szDefPrinter, True) <> 0 Then
SetDefaultPrinter(szPrinter)
End If
strPath = GetZanConfigurationDir(szPrinter)
If Not strPath.EndsWith("\") Then
strPath = String.Concat(strPath, "\")
End If
strPath = String.Concat(strPath, "event.ini")
'enable event notification
WritePrivateProfileString("event", "enable", "1", strPath)
'set enddoc event name
WritePrivateProfileString("event", "enddoc", szEnddocEvent, strPath)
Dim ewh As EventWaitHandle
ewh = New EventWaitHandle(False, _
EventResetMode.AutoReset, szEnddocEvent)
'The print job status is "sent to printer" when
'ShellExecutePrint returns.
ShellExecutePrint("c:\abc\1.doc")
'wait for the EndDoc event to be received,
'an indication that the submitted print job has indeed completed
ewh.WaitOne()
'The print job status is "sent to printer" when
'ShellExecutePrint returns.
ShellExecutePrint("c:\abc\1.pdf")
'wait for the EndDoc event to be received,
'an indication that the submitted print job has indeed completed
ewh.WaitOne()
'set default printer back to original
If String.Compare(szPrinter, szDefPrinter, True) <> 0 Then
SetDefaultPrinter(szDefPrinter)
End If
End Sub
End Module
C# code sample:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.IO;
using Microsoft.Win32;
namespace shellexec_csharp
{
class Program
{
//Determines Zan Image Printer installation directory
static string GetZanInstallDir()
{
string installfolder = string.Empty;
RegistryKey rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if (rkTest != null)
{
installfolder = rkTest.GetValue("UninstallString").ToString();
rkTest.Close();
if (installfolder.Length > 0)
{
installfolder = Path.GetDirectoryName(installfolder);
DirectoryInfo installdir1 = new DirectoryInfo(installfolder);
if (installdir1.Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath
(Environment.SpecialFolder.ProgramFiles);
if (!installfolder.EndsWith("\\"))
installfolder = string.Concat(installfolder, "\\");
installfolder = string.Concat(installfolder, "zvprt50");
return installfolder;
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
static string GetZanConfigurationDir(string szPrinter)
{
//read the OS info
OperatingSystem os = System.Environment.OSVersion;
string sCfg;
uint lPolicy;
StringBuilder tmpstr = new StringBuilder(256);
//read configure.ini from
//Zan Image Printer installation directory
sCfg = GetZanInstallDir();
if (!sCfg.EndsWith("\\"))
sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", "policy",
1, sCfg);
//handle the auto detect policy
if (1 == lPolicy)
{
//Vista and 2008: dwVerMajor>=6
if (os.Version.Major >= 6)
{
lPolicy = 3;
}
else
{
lPolicy = 2;
}
}
//get the all users (per-machine) folder
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if (2 == lPolicy)
{
//csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment.GetFolderPath
(Environment.SpecialFolder.CommonApplicationData);
}
else
{
//csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr);
sCfg = tmpstr.ToString();
}
if (!sCfg.EndsWith("\\")) sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "zvprt50\\");
sCfg = string.Concat(sCfg, szPrinter);
//all users will share the same
//settings for the printer
DirectoryInfo tmpdir = new DirectoryInfo(sCfg);
if (tmpdir.Exists)
{
return sCfg;
}
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
sCfg = Environment.GetFolderPath
(Environment.SpecialFolder.ApplicationData);
if (!sCfg.EndsWith("\\")) sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "zvprt50\\");
sCfg = string.Concat(sCfg, szPrinter);
return sCfg;
}
static void ShellExecutePrint(string myDocument)
{
Process myProcess = new Process();
myProcess.StartInfo.FileName = myDocument;
myProcess.StartInfo.Verb = "Print";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
}
static void Main(string[] args)
{
string szPrinter = "Zan Image Printer(bw)";
string szEnddocEvent = "SignalPrintDone";
string strPath;
StringBuilder tempstr = new StringBuilder(256);
string szDefPrinter;
int dwBufSize = tempstr.Capacity;
GetDefaultPrinter(tempstr, ref dwBufSize);
szDefPrinter = tempstr.ToString();
/*
change the default printer prior to calling the
ShellExecutePrint function.
*/
if (string.Compare(szPrinter, szDefPrinter, true) != 0)
{
SetDefaultPrinter(szPrinter);
}
strPath = GetZanConfigurationDir(szPrinter);
if (!strPath.EndsWith("\\")) strPath = string.Concat(strPath, "\\");
strPath = string.Concat(strPath, "event.ini");
//enable event notification
WritePrivateProfileString("event", "enable", "1", strPath);
//set enddoc event name
WritePrivateProfileString("event", "enddoc", szEnddocEvent, strPath);
EventWaitHandle ewh;
ewh = new EventWaitHandle(false, EventResetMode.AutoReset, szEnddocEvent);
//The print job status is "sent to printer" when
//ShellExecutePrint returns.
ShellExecutePrint("c:\\abc\\1.doc");
//wait for the EndDoc event to be received,
//an indication that the submitted print job has indeed completed
ewh.WaitOne();
//The print job status is "sent to printer" when
//ShellExecutePrint returns.
ShellExecutePrint("c:\\abc\\1.pdf");
//wait for the EndDoc event to be received,
//an indication that the submitted print job has indeed completed
ewh.WaitOne();
/*set default printer back to original*/
if (string.Compare(szPrinter, szDefPrinter, true) != 0)
{
SetDefaultPrinter(szDefPrinter);
}
}
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool GetDefaultPrinter(StringBuilder pszBuffer,
ref int size);
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileString(string lpAppName,
string lpKeyName, string lpDefault,
StringBuilder lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32.dll")]
static extern bool WritePrivateProfileString(string lpAppName,
string lpKeyName,
string lpString, string lpFileName);
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileInt(string lpAppName,
string lpKeyName, int nDefault, string lpFileName);
[DllImport("shell32.dll")]
static extern bool SHGetFolderPath(int hwndOwner,
int nFolder, int hToken, int dwFlags, StringBuilder pszPath);
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
}
}
Internet Explorer automation VB, Delphi, C, VC.NET, VB.NET and C# code samples: print HTML files programmatically You can write an application that uses the Microsoft WebBrowser Control to print HTML files programmatically without displaying the print dialog. You can immediately print the current document in the WebBrowser without prompting the user for the printer dialog as follows: ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER If you want to change the page margins, header, and footer settings, and the default Internet Explorer printer programmatically, please read the Microsoft Knowledge Base Articles Q267240 "How to print custom headers and footers for a WebBrowser control in Internet Explorer" and Q236777 "How to change print settings for Internet Explorer and the WebBrowser control programmatically in Internet Explorer". VB, Delphi, C/C++, VC.NET, VB.NET and C# code samples that illustrate using Internet Explorer's automation to print HTML files programmatically are shown below. The code samples will all wait for the EndDoc event to make sure that the printing is done before destroying the Internet Explorer. The code samples simply use the "SignalPrintDone" as the EndDoc event name. However, in a real application, for uniqueness, we recommend using an event name such as "Zan Image Printer(bw) SignalPrintDone" or a GUID string such as "{66A568A9-EECE-4695-BE9F-0CF85135E702}", so that it won't conflict with any other Zan Image Printer and Windows application. To compile the VC.NET, VB.NET and C# code samples, you first need to set a reference to the "Microsoft Internet Controls" in your project by following the steps below: 1. In Solution Explorer, right click the project node, then click Add Reference. 2. In the Add Reference dialog, click the COM tab. 3. Click the "Microsoft Internet Controls", and then click Select. Tips: VB code sample:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" ( _
ByVal dwMilliseconds As Long)
Private Declare Function GetDefaultPrinter Lib "winspool.drv" _
Alias "GetDefaultPrinterA" (ByVal pszBuffer As String, _
pcchBuffer As Long) As Long
Private Declare Function SetDefaultPrinter Lib "winspool.drv" _
Alias "SetDefaultPrinterA" (ByVal pszPrinter As String) As Long
Private Declare Function SHGetFolderPath Lib "shell32" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Long, ByVal nFolder As Long, _
ByVal hToken As Long, ByVal dwFlags As Long, _
ByVal pszPath As String) As Long
Private Declare Function GetPrivateProfileInt Lib "kernel32.dll" _
Alias "GetPrivateProfileIntA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal nDefault As Integer, _
ByVal lpFileName As String) As Integer
Private Declare Function WritePrivateProfileString Lib "kernel32.dll" _
Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As String, ByVal lpString As String, _
ByVal lpFileName As String) As Integer
Private Declare Function WaitForSingleObject Lib "kernel32.dll" _
(ByVal hHandle As Long, ByVal _
dwMilliseconds As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" (ByVal hKey As Long, _
ByVal lpValueName As String, ByVal lpReserved As Long, _
lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function CreateEvent Lib "kernel32" _
Alias "CreateEventA" (ByVal lpEventAttributes As Long, _
ByVal bManualReset As Long, ByVal bInitialState As _
Long, ByVal lpname As String) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" _
Alias "GetVersionExA" _
(lpVersionInformation As OSVERSIONINFO) As Long
Private Const HKEY_LOCAL_MACHINE = &H80000002
'Registry action types.
Private Const ERROR_SUCCESS = 0
Private Const STANDARD_RIGHTS_READ As Long = &H20000
Private Const KEY_QUERY_VALUE As Long = &H1
Private Const KEY_ENUMERATE_SUB_KEYS As Long = &H8
Private Const KEY_NOTIFY As Long = &H10
Private Const SYNCHRONIZE As Long = &H100000
Private Const KEY_READ As Long = ((STANDARD_RIGHTS_READ Or _
KEY_QUERY_VALUE Or _
KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY) And _
(Not SYNCHRONIZE))
'Used CSIDL values.
Private Const CSIDL_APPDATA As Long = &H1A
Private Const CSIDL_PROGRAM_FILES As Long = &H26
Private Const CSIDL_COMMON_APPDATA As Long = &H23
Private Const CSIDL_COMMON_DOCUMENTS As Long = &H2E
Private Const SHGFP_TYPE_CURRENT = 0
Private Const S_OK As Long = 0
Private Const MAX_PATH = 260
Private Const SW_SHOWNORMAL = 1
Private Const INFINITE = &HFFFF
'Windows-defined type OSVERSIONINFO
Private Type OSVERSIONINFO
OSVSize As Long
dwVerMajor As Long 'dwVerMajor = 6: Vista or above
dwVerMinor As Long
dwBuildNumber As Long
PlatformID As Long
szCSDVersion As String * 128
End Type
'Determines whether the given path refers to an existing
'directory
Function DirExists(ByVal DName As String) As Boolean
Dim sDummy As String
On Error Resume Next
If Right(DName, 1) <> "\" Then DName = DName & "\"
sDummy = Dir$(DName & "*.*", vbDirectory)
DirExists = Not (sDummy = "")
End Function
'Searches a path for a file name
Function GetFilePath(FileName As String) As String
Dim i As Long
For i = Len(FileName) To 1 Step -1
Select Case Mid$(FileName, i, 1)
Case ":"
GetFilePath = Left$(FileName, i)
Exit For
Case "\"
GetFilePath = Left$(FileName, i - 1)
Exit For
End Select
Next
End Function
'Determines Zan Image Printer installation directory
Private Function GetZanInstallDir() As String
Dim sPath As String
Dim szTmp As String * MAX_PATH
Dim lResult As Long
Dim hKey, dwSize As Long
dwSize = MAX_PATH
'first check to see if the uninstall registry entry exists
If RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
"\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50" _
, 0&, KEY_READ, hKey) = ERROR_SUCCESS Then
If RegQueryValueEx(hKey, "UninstallString", _
0&, 0&, ByVal szTmp, dwSize) = ERROR_SUCCESS Then
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
sPath = GetFilePath(sPath)
If DirExists(sPath) Then
GetZanInstallDir = sPath
Exit Function
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
lResult = SHGetFolderPath(0, _
CSIDL_PROGRAM_FILES, _
0, _
SHGFP_TYPE_CURRENT, _
szTmp)
sPath = Left$(szTmp, _
InStr(szTmp, vbNullChar) - 1)
If Right$(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
sPath = sPath & "zvprt50"
GetZanInstallDir = sPath
End Function
'Determines Zan Image Printer
'configuration directory for the ini setting files
Private Function GetZanConfigurationDir(szPrinter As String) As String
Dim sPath As String * MAX_PATH
Dim lResult As Long
Dim lPolicy As Long
Dim csidl As Long
Dim osv As OSVERSIONINFO
Dim LRet As Long
Dim sCfg As String
'read the OS info
osv.OSVSize = Len(osv)
LRet = GetVersionEx(osv)
'read configure.ini from
'Zan Image Printer installation directory
sCfg = GetZanInstallDir()
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "configure.ini"
'Read the all users (per-machine) folder policy
'from configure.ini:
'policy=1: auto detect, if Vista or newer,
'use CSIDL_COMMON_DOCUMENTS as the
'all users (per-machine) folder;
'otherwise, use CSIDL_COMMON_APPDATA
'policy=2: use CSIDL_COMMON_APPDATA
'policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", "policy", _
1, sCfg)
'handle the auto detect policy
If lPolicy = 1 Then
'Vista and 2008: dwVerMajor>=6
If osv.dwVerMajor >= 6 Then
lPolicy = 3
Else
lPolicy = 2
End If
End If
If lPolicy = 2 Then
csidl = CSIDL_COMMON_APPDATA
Else
csidl = CSIDL_COMMON_DOCUMENTS
End If
'get the all users (per-machine) folder
lResult = SHGetFolderPath(0, _
csidl, _
0, _
SHGFP_TYPE_CURRENT, _
sPath)
sCfg = Left$(sPath, _
InStr(sPath, vbNullChar) - 1)
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "zvprt50\" & szPrinter
'if the all users (per-machine) folder exists,
'then this zan image printer was installed per-machine:
'all users share the same settings
If DirExists(sCfg) Then
'all users will share the same
'settings for the printer
GetZanConfigurationDir = sCfg
Exit Function
End If
'if the all users (per-machine) folder doesn't exist,
'assume each user has his own settings
'for the printer:
lResult = SHGetFolderPath(0, _
CSIDL_APPDATA, _
0, _
SHGFP_TYPE_CURRENT, _
sPath)
sCfg = Left$(sPath, _
InStr(sPath, vbNullChar) - 1)
If Right$(sCfg, 1) <> "\" Then
sCfg = sCfg & "\"
End If
sCfg = sCfg & "zvprt50\" & szPrinter
GetZanConfigurationDir = sCfg
End Function
Public Sub printhtml(szPrinter As String, htmlfile As String)
Const OLECMDID_PRINT = 6
Const OLECMDEXECOPT_DONTPROMPTUSER = 2
Const OLECMDEXECOPT_PROMPTUSER = 1
Dim IE
Dim szDefPrinter As String, lLen As Long
Dim sNameBuff As String
Dim szEnddocEvent, strPath As String
Dim hEndDoc As Long
Dim i As Long
szEnddocEvent = "SignalPrintDone"
hEndDoc = CreateEvent(ByVal 0&, False, False, szEnddocEvent)
'remember current default printer
GetDefaultPrinter vbNullChar, lLen
sNameBuff = Space$(lLen)
GetDefaultPrinter sNameBuff, lLen
szDefPrinter = Left$(sNameBuff, _
InStr(sNameBuff, vbNullChar) - 1)
szDefPrinter = LCase(szDefPrinter)
szPrinter = LCase(szPrinter)
'change the default printer prior to calling the
'ExecWB function.
If szDefPrinter <> Trim$(szPrinter) Then
SetDefaultPrinter szPrinter
End If
strPath = GetZanConfigurationDir(szPrinter)
If Right$(strPath, 1) <> "\" Then
strPath = strPath & "\"
End If
strPath = strPath & "event.ini"
'enable event notification
WritePrivateProfileString "event", "enable", _
"1", strPath
'set enddoc event name
WritePrivateProfileString "event", "enddoc", _
szEnddocEvent, strPath
'IE automation via Microsoft WebBrowser control
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate htmlfile
'Wait until URL navigation is done
Do While IE.ReadyState <> 4
Sleep 250
Loop
'The print job status is "sent to printer" when
'ExecWB returns
IE.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER
'wait for the EndDoc event to be received,
'an indication that the submitted print job
'has indeed completed
i = WaitForSingleObject(hEndDoc, INFINITE)
IE.Quit
Set IE = Nothing
'set default printer back to original
If szDefPrinter <> Trim$(szPrinter) Then
SetDefaultPrinter szDefPrinter
End If
CloseHandle (hEndDoc)
End Sub
Public Sub Main()
printhtml "zan image printer(bw)", "C:\htmlfiles\document.htm"
End Sub
unit zanprinter;
interface
uses
Windows, Messages, SysUtils, ShlObj, ShellAPI, SHFolder, ComObj;
function GetDefaultPrinter(prnName:PAnsiChar; var bufSize:DWORD):
BOOL; stdcall; external 'winspool.drv' name 'GetDefaultPrinterA';
function SetDefaultPrinter(prnName:PAnsiChar):
BOOL; stdcall; external 'winspool.drv' name 'SetDefaultPrinterA';
procedure GetZanInstallDir(var APath: String);
procedure printhtml(szPrinter:String; htmlfile:String);
procedure GetZanConfigurationDir(var szPrinter: String; var cfgdir: String);
implementation
//Determines Zan Image Printer installation directory
procedure GetZanInstallDir(var APath: String);
var
hkeyStartup: HKEY;
dwSize: DWORD;
begin
dwSize := MAX_PATH;
SetLength(APath, MAX_PATH);
//first check to see if the uninstall registry entry exists
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'\Software\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50',
0,
KEY_READ,
hkeyStartup) = ERROR_SUCCESS then
begin
if RegQueryValueEx(hkeyStartup,
'UninstallString', nil, nil,
PBYTE(Pchar(APath)),
@dwSize) = ERROR_SUCCESS then
begin
APath := String (PChar(APath));
APath := ExtractFilePath(APath);
end;
//Close the Key, we won't be needing it anymore
RegCloseKey(hkeyStartup);
if DirectoryExists(APath) then Exit;
end;
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, 0,
PChar(APath));
APath := String (PChar (APath));
if (APath[Length(APath)] <> '\')
then APath := APath + '\';
APath := APath + 'zvprt50';
end;
//Determines Zan Image Printer
//configuration directory for the ini setting files
procedure GetZanConfigurationDir(var szPrinter: String; var cfgdir: String);
var
osv: TOSVersionInfo;
lPolicy, csidl: Integer;
begin
SetLength(cfgdir, MAX_PATH);
//read the OS info
FillChar(osv, SizeOf(osv), 0);
osv.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
GetVersionEx(osv);
//read configure.ini from
//Zan Image Printer installation directory
GetZanInstallDir(cfgdir);
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'configure.ini';
//read configure.ini from
//Zan Image Printer installation directory.
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy := GetPrivateProfileInt('allusersfolder', 'policy',
1, PChar(cfgdir));
//handle the auto detect policy
if lPolicy = 1 then
begin
//Vista and 2008: dwVerMajor>=6
if osv.dwMajorVersion >= 6 then lPolicy := 3
else lPolicy := 2;
end;
if lPolicy = 2 then csidl := CSIDL_COMMON_APPDATA
else csidl := CSIDL_COMMON_DOCUMENTS;
//get the all users (per-machine) folder
SetLength(cfgdir, MAX_PATH);
SHGetFolderPath(0, csidl, 0, 0, PChar(cfgdir));
cfgdir := String (PChar (cfgdir));
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'zvprt50\' + szPrinter;
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if DirectoryExists(cfgdir) then Exit;
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, PChar(cfgdir));
cfgdir := String (PChar (cfgdir));
if (cfgdir[Length(cfgdir)] <> '\') then cfgdir := cfgdir + '\';
cfgdir := cfgdir + 'zvprt50\' + szPrinter;
end;
procedure printhtml(szPrinter:String; htmlfile:String);
const
OLECMDID_PRINT = $00000006;
OLECMDEXECOPT_DONTPROMPTUSER = $00000002;
var
ie: Variant;
szDefPrinter, szEnddocEvent, strPath: String;
lBufSize: DWord;
hEndDoc: THandle;
begin
//remember current default printer
SetLength(szDefPrinter, MAX_PATH);
lBufSize := MAX_PATH;
GetDefaultPrinter(Pchar(szDefPrinter), lBufSize);
szDefPrinter := String (PChar(szDefPrinter));
szDefPrinter := LowerCase(szDefPrinter);
szPrinter := LowerCase(szPrinter);
//change the default printer prior to calling the
//ExecWB function.
if szDefPrinter <> szPrinter then
SetDefaultPrinter(PChar(szPrinter));
szEnddocEvent := 'SignalPrintDone';
hEndDoc := CreateEvent(nil,False,False,Pchar(szEnddocEvent));
GetZanConfigurationDir(szPrinter, strPath);
if (strPath[Length(strPath)] <> '\')
then strPath := strPath + '\';
strPath :=strPath + 'event.ini';
//enable event notification
WritePrivateProfileString('event','enable','1',Pchar(strPath));
//set enddoc event name
WritePrivateProfileString('event', 'enddoc',
Pchar(szEnddocEvent), Pchar(strPath));
//IE automation via Microsoft WebBrowser control
ie := CreateOleObject('InternetExplorer.Application');
ie.Visible := True;
ie.Navigate(htmlfile);
//Wait until URL navigation is done
while ie.ReadyState <> 4 do
sleep(250);
//The print job status is "sent to printer" when
//ExecWB returns
ie.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER);
//wait for the EndDoc event to be received,
//an indication that the submitted print
//job has indeed completed
WaitForSingleObject(hEndDoc, INFINITE);
ie.quit;
//set default printer back to original
if szDefPrinter <> szPrinter then
SetDefaultPrinter(pchar(szDefPrinter));
CloseHandle(hEndDoc);
end;
end.
#include <windows.h>
#include <winspool.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shellapi.h>
/*#import statement and smart pointers*/
#import <shdocvw.dll>
#pragma comment(lib, "shlwapi.lib")
//Determines whether the given path refers to
//an existing directory
BOOL IsFolderExists(char *lpDirectoryName)
{
if(0 == strlen(lpDirectoryName))
{
return FALSE;
}
DWORD dwFileAttr = GetFileAttributes(lpDirectoryName);
if((dwFileAttr != 0xFFFFFFFF) &&
(dwFileAttr & FILE_ATTRIBUTE_DIRECTORY))
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer installation directory
void GetZanInstallDir(char *installfolder)
{
HKEY hkeyStartup;
//first check to see if the uninstall registry entry exists
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50",
0,
KEY_READ,
&hkeyStartup) == ERROR_SUCCESS)
{
DWORD dwSize = MAX_PATH;
if(RegQueryValueEx(hkeyStartup,
"UninstallString",
NULL,
NULL,
(LPBYTE)installfolder,
&dwSize) == ERROR_SUCCESS)
{
PathRemoveFileSpec(installfolder);
PathAddBackslash(installfolder);
}
/*Close the Key, we won't be needing it anymore*/
RegCloseKey(hkeyStartup);
if(IsFolderExists(installfolder))
{
return;
}
}
//fallback to the \Program Files\zvprt50 folder:
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, installfolder);
PathAddBackslash(installfolder);
strcat(installfolder,"zvprt50");
}
BOOL IsVistaOrAbove(void)
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
//Try calling GetVersionEx using the OSVERSIONINFOEX structure.
//If that fails, try using the OSVERSIONINFO structure.
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi)))
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx((OSVERSIONINFO*)&osvi))
return FALSE;
}
//vista and 2008: 6
//2003: 5
//xp: 5
if(osvi.dwMajorVersion >= 6)
{
return TRUE;
}
else
{
return FALSE;
}
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
void GetZanConfigurationDir(char *sPrinter, char *sCfg)
{
DWORD lPolicy;
DWORD csidl;
//read configure.ini from
//Zan Image Printer installation directory
GetZanInstallDir(sCfg);
PathAddBackslash(sCfg);
strcat(sCfg,"configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder",
"policy", 1, sCfg);
//handle the auto detect policy
if(1 == lPolicy)
{
if(IsVistaOrAbove()) lPolicy = 3;
else lPolicy = 2;
}
if(2 == lPolicy)
{
csidl = CSIDL_COMMON_APPDATA;
}
else
{
csidl = CSIDL_COMMON_DOCUMENTS;
}
//get the all users (per-machine) folder
SHGetFolderPath(NULL, csidl, NULL, 0, sCfg);
PathAddBackslash(sCfg);
strcat(sCfg, "zvprt50\\");
strcat(sCfg, sPrinter);
//if the all users (per-machine) folder exists,
//this zan image printer was installed per-machine:
//all users share the same settings
if(IsFolderExists(sCfg)) return;
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, sCfg);
PathAddBackslash(sCfg);
strcat(sCfg, "zvprt50\\");
strcat(sCfg, sPrinter);
}
void printhtml(char *printername, char *htmlfile)
{
char olddefprinter[MAX_PATH] = "";
DWORD dwcchBufLen = MAX_PATH;
/*remember current default printer*/
GetDefaultPrinter(olddefprinter, &dwcchBufLen);
/*
change the default printer prior to calling the
ExecWB function.
*/
if(strlen(olddefprinter)
&& strcmpi(olddefprinter, printername)
)
{
/*set default printer*/
SetDefaultPrinter(printername);
}
//enddoc event name
char* szEnddocEvent = "SignalPrintDone";
HANDLE hEndDoc;
hEndDoc=CreateEvent(NULL, FALSE, FALSE, szEnddocEvent);
if(hEndDoc == NULL)
{
return;
}
char strPath[MAX_PATH];
GetZanConfigurationDir(printername, strPath);
PathAddBackslash(strPath);
strcat(strPath,"event.ini");
//enable event notification
WritePrivateProfileString("event", "enable", "1",strPath);
//set enddoc event name
WritePrivateProfileString("event", "enddoc",
szEnddocEvent, strPath);
/*IE automation via Microsoft WebBrowser control*/
/*CoInitialize(0) creates a single-threaded apartment*/
/*CoInitialize(0);*/
/*Need to define _WIN32_DCOM preprocessor symbol in your project settings*/
/*CoInitializeEx with the COINIT_MULTITHREADED flag
produces a multi-threaded apartment
*/
CoInitializeEx(NULL, COINIT_MULTITHREADED);
{
/*IE Automation*/
SHDocVw::IWebBrowser2Ptr pIE(__uuidof(SHDocVw::InternetExplorer));
pIE->Visible = false;
pIE->Navigate(htmlfile);
/*Wait until URL navigation is done*/
//120 seconds
DWORD nTimeout = 120*1000;
READYSTATE result;
DWORD nFirstTick = GetTickCount();
do
{
pIE->get_ReadyState(&result);
if(result != READYSTATE_COMPLETE)
Sleep(250);
if(nTimeout > 0)
{
if((GetTickCount() - nFirstTick) > nTimeout)
{
break;
}
}
}while (result != READYSTATE_COMPLETE);
VARIANT vNull;
vNull.vt = VT_EMPTY;
//The print job status is "sent to printer" when
//ExecWB returns.
HRESULT hr = pIE->ExecWB(OLECMDID_PRINT,
OLECMDEXECOPT_DONTPROMPTUSER, &vNull, &vNull);
//wait for the EndDoc event to be received,
//an indication that the submitted print job has indeed completed
WaitForSingleObject(hEndDoc, INFINITE);
pIE->Quit();
}
CoUninitialize();
/*set default printer back to original*/
if(strlen(olddefprinter)
&& strcmpi(olddefprinter, printername)
)
{
SetDefaultPrinter(olddefprinter);
}
CloseHandle(hEndDoc);
}
int main(int argc, char* argv[])
{
printhtml("zan image printer(bw)", "c:\\htmlfiles\\document.htm");
return 0;
}
VC.NET code sample:
using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
using namespace System::Threading;
using namespace Microsoft::Win32;
using namespace System::IO;
using namespace System::Diagnostics;
using namespace SHDocVw;
// Declare the function that is exported from unmanaged dll:
[DllImport("winspool.drv")]
extern "C" bool _cdecl GetDefaultPrinter(
StringBuilder^ pszBuffer, int *size);
[DllImport("winspool.drv")]
extern "C" bool _cdecl SetDefaultPrinter(
String^ pszPrinter);
[DllImport("KERNEL32.DLL")]
extern "C" int _cdecl GetPrivateProfileString(
String^ lpAppName,
String^ lpKeyName,
String^ lpDefault,
StringBuilder^ lpReturnedString,
int nSize,
String^ lpFileName);
[DllImport("KERNEL32.DLL")]
extern "C" bool _cdecl WritePrivateProfileString(
String^ lpAppName,
String^ lpKeyName,
String^ lpString,
String^ lpFileName);
[DllImport("KERNEL32.DLL")]
extern "C" int _cdecl GetPrivateProfileInt(
String^ lpAppName,
String^ lpKeyName,
int nDefault,
String^ lpFileName);
[DllImport("shell32.dll")]
extern "C" bool _cdecl SHGetFolderPath(int hwndOwner,
int nFolder, int hToken, int dwFlags, StringBuilder^ pszPath);
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
//Determines Zan Image Printer installation directory
String^ GetZanInstallDir(void)
{
String^ installfolder = String::Empty;
RegistryKey ^ rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry::LocalMachine->OpenSubKey(
L"\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if(rkTest)
{
installfolder = rkTest->GetValue(L"UninstallString")->ToString();
rkTest->Close();
if(installfolder->Length)
{
installfolder = Path::GetDirectoryName(installfolder);
DirectoryInfo^ installdir1=gcnew DirectoryInfo(installfolder);
if(installdir1->Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment::GetFolderPath
(Environment::SpecialFolder::ProgramFiles);
if(!installfolder->EndsWith(L"\\"))
installfolder = String::Concat(installfolder, L"\\");
installfolder=String::Concat(installfolder, L"zvprt50");
return installfolder;
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
String^ GetZanConfigurationDir(String^ szPrinter)
{
//read the OS info
OperatingSystem^ os = System::Environment::OSVersion;
String^ sCfg;
int lPolicy;
StringBuilder^ tmpstr = gcnew StringBuilder(256);
//read configure.ini from
//Zan Image Printer installation directory
sCfg = GetZanInstallDir();
if(!sCfg->EndsWith(L"\\"))
sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt(L"allusersfolder", L"policy",
1, sCfg);
//handle the auto detect policy
if(1 == lPolicy)
{
//Vista and 2008: dwVerMajor>=6
if(os->Version->Major >= 6)
{
lPolicy = 3;
}
else
{
lPolicy = 2;
}
}
//get the all users (per-machine) folder
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if(2 == lPolicy)
{
//csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment::GetFolderPath
(Environment::SpecialFolder::CommonApplicationData);
}
else
{
//csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr);
sCfg = tmpstr->ToString();
}
if(!sCfg->EndsWith(L"\\")) sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"zvprt50\\");
sCfg = String::Concat(sCfg, szPrinter);
//all users will share the same
//settings for the printer
DirectoryInfo^ tmpdir = gcnew DirectoryInfo(sCfg);
if(tmpdir->Exists)
{
return sCfg;
}
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
sCfg = Environment::GetFolderPath
(Environment::SpecialFolder::ApplicationData);
if(!sCfg->EndsWith(L"\\")) sCfg = String::Concat(sCfg, L"\\");
sCfg = String::Concat(sCfg, L"zvprt50\\");
sCfg = String::Concat(sCfg, szPrinter);
return sCfg;
}
void printhtml(String^ szPrinter, String^ htmlfile)
{
StringBuilder^ tmpstr = gcnew StringBuilder(256);
String^ szDefPrinter;
int dwBufSize = tmpstr->Capacity;
/*
change the default printer prior to calling the
ExecWB function.
*/
GetDefaultPrinter(tmpstr, &dwBufSize);
szDefPrinter = tmpstr->ToString();
if(String::Compare(szPrinter, szDefPrinter, true) != 0)
{
SetDefaultPrinter(szPrinter);
}
//enddoc event name
String^ szEnddocEvent = L"SignalPrintDone";
String^ strPath;
strPath = GetZanConfigurationDir(szPrinter);
if(!strPath->EndsWith(L"\\")) strPath=String::Concat(strPath, L"\\");
strPath = String::Concat(strPath, L"event.ini");
//enable event notification
WritePrivateProfileString(L"event", L"enable", L"1", strPath);
//set enddoc event name
WritePrivateProfileString(L"event",L"enddoc",szEnddocEvent, strPath);
EventWaitHandle^ ewh;
ewh=gcnew EventWaitHandle(false,EventResetMode::AutoReset,szEnddocEvent);
InternetExplorer^ explorer = gcnew InternetExplorerClass;
IWebBrowserApp^ webBrowser = explorer;
Object^ noValue = System::Reflection::Missing::Value;
webBrowser->Visible = true;
webBrowser->Navigate(htmlfile, noValue, noValue, noValue, noValue);
/*Wait until URL navigation is done*/
while(webBrowser->Busy)
{
Thread::Sleep(250);
}
//The print job status is "sent to printer" when
//ExecWB returns.
explorer->ExecWB(SHDocVw::OLECMDID::OLECMDID_PRINT,
SHDocVw::OLECMDEXECOPT::OLECMDEXECOPT_DONTPROMPTUSER,
noValue,
noValue);
//wait for the EndDoc event to be received,
//an indication that the submitted print job has
//indeed completed
ewh->WaitOne();
explorer->Quit();
/*set default printer back to original*/
if(String::Compare(szPrinter, szDefPrinter, true) != 0)
{
SetDefaultPrinter(szDefPrinter);
}
}
int main(arrayVB.NET code sample:
Imports System
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.IO
Imports System.Diagnostics
Imports System.Threading
Imports Microsoft.Win32
Imports SHDocVw
Module Module1
Declare Function GetDefaultPrinter Lib "winspool.drv" Alias _
"GetDefaultPrinterA" (ByVal pszBuffer As System.Text.StringBuilder, _
ByRef size As Int32) As Boolean
Declare Function SetDefaultPrinter Lib "winspool.drv" Alias _
"SetDefaultPrinterA" (ByVal pszPrinter As String) As Boolean
Private Declare Function GetPrivateProfileString Lib "kernel32" _
Alias "GetPrivateProfileStringW" _
(ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As StringBuilder, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
Private Declare Function GetPrivateProfileInt Lib "kernel32.dll" _
Alias "GetPrivateProfileIntA" _
(ByVal lpApplicationName _
As String, ByVal lpKeyName As String, ByVal nDefault As _
Integer, ByVal lpFileName As String) As Integer
Private Declare Function WritePrivateProfileString Lib "kernel32.dll" _
Alias "WritePrivateProfileStringA" _
(ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpString As String, _
ByVal lpFileName As String) As Boolean
Private Declare Function SHGetFolderPath Lib "shell32.dll" _
Alias "SHGetFolderPathA" _
(ByVal hwndOwner As Integer, _
ByVal nFolder As Integer, _
ByVal hToken As Integer, _
ByVal dwFlags As Integer, _
ByVal pszPath As StringBuilder) As Integer
'All Users\Documents
Private Const CSIDL_COMMON_DOCUMENTS = &H2E
'Determines Zan Image Printer installation directory
Function GetZanInstallDir() As String
Dim installfolder As String
Dim rkTest As RegistryKey
'first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey _
("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\zvprt50")
If Not (rkTest Is Nothing) Then
installfolder = rkTest.GetValue _
("UninstallString").ToString()
rkTest.Close()
If (installfolder.Length > 0) Then
installfolder = Path.GetDirectoryName(installfolder)
Dim installdir1 As DirectoryInfo = _
New DirectoryInfo(installfolder)
If installdir1.Exists Then
Return installfolder
End If
End If
End If
'fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath _
(Environment.SpecialFolder.ProgramFiles)
If Not installfolder.EndsWith("\") Then
installfolder = String.Concat(installfolder, "\")
End If
installfolder = String.Concat(installfolder, "zvprt50")
Return installfolder
End Function
'Determines Zan Image Printer
'configuration directory for the ini setting files
Function GetZanConfigurationDir(ByVal szPrinter As String) As String
'read the OS info
Dim os As OperatingSystem
Dim sCfg As String
Dim lPolicy As Integer
Dim tmpstr As StringBuilder
tmpstr = New StringBuilder(256)
os = System.Environment.OSVersion
'read configure.ini from
'Zan Image Printer installation directory
sCfg = GetZanInstallDir()
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "configure.ini")
'Read the all users (per-machine) folder policy
'from configure.ini:
'policy=1: auto detect, if Vista or newer,
'use CSIDL_COMMON_DOCUMENTS as the
'all users (per-machine) folder;
'otherwise, use CSIDL_COMMON_APPDATA
'policy=2: use CSIDL_COMMON_APPDATA
'policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", _
"policy", 1, sCfg)
'Vista and 2008: dwVerMajor>=6
If lPolicy = 1 Then
If os.Version.Major >= 6 Then
lPolicy = 3
Else
lPolicy = 2
End If
End If
'get the all users (per-machine) folder
'if the all users (per-machine) folder exists,
'then this zan image printer was installed per-machine:
'all users share the same settings
If lPolicy = 2 Then
'csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment.GetFolderPath( _
Environment.SpecialFolder.CommonApplicationData)
Else
'csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr)
sCfg = tmpstr.ToString()
End If
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "zvprt50\")
sCfg = String.Concat(sCfg, szPrinter)
'all users will share the same
'settings for the printer
Dim tmpdir As DirectoryInfo = _
New DirectoryInfo(sCfg)
If tmpdir.Exists Then
Return sCfg
End If
'if the all users (per-machine) folder doesn't exist,
'assume each user has his own settings
'for the printer:
sCfg = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
If Not sCfg.EndsWith("\") Then
sCfg = String.Concat(sCfg, "\")
End If
sCfg = String.Concat(sCfg, "zvprt50\")
sCfg = String.Concat(sCfg, szPrinter)
Return sCfg
End Function
Sub printhtml(ByVal szPrinter As String, ByVal htmlfile As String)
Dim szEnddocEvent As String = "SignalPrintDone"
Dim strPath As String
Dim tmpstr As StringBuilder
tmpstr = New StringBuilder(256)
Dim szDefPrinter As String
Dim dwBufSize As Integer
dwBufSize = tmpstr.Capacity
GetDefaultPrinter(tmpstr, dwBufSize)
szDefPrinter = tmpstr.ToString()
'change the default printer prior to calling the
'ExecWB function.
If String.Compare(szPrinter, szDefPrinter, True) <> 0 Then
SetDefaultPrinter(szPrinter)
End If
strPath = GetZanConfigurationDir(szPrinter)
If Not strPath.EndsWith("\") Then
strPath = String.Concat(strPath, "\")
End If
strPath = String.Concat(strPath, "event.ini")
'enable event notification
WritePrivateProfileString("event", "enable", "1", strPath)
'set enddoc event name
WritePrivateProfileString("event", "enddoc", _
szEnddocEvent, strPath)
Dim ewh As EventWaitHandle
ewh = New EventWaitHandle(False, EventResetMode.AutoReset, _
szEnddocEvent)
Dim explorer As InternetExplorer = New InternetExplorerClass()
Dim WebBrowser As IWebBrowserApp = CType(explorer, IWebBrowserApp)
Dim noValue As Object = Nothing
WebBrowser.Visible = True
WebBrowser.Navigate(htmlfile, noValue, noValue, noValue, noValue)
'Wait until URL navigation is done
While WebBrowser.Busy
Thread.Sleep(250)
End While
'printing without print dialog
'The print job status is "sent to printer" when
'ExecWB returns.
explorer.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT, _
SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, _
noValue, noValue)
'wait for the EndDoc event to be received,
'an indication that the submitted print job has indeed completed
ewh.WaitOne()
explorer.Quit()
'set default printer back to original
If String.Compare(szPrinter, szDefPrinter, True) <> 0 Then
SetDefaultPrinter(szDefPrinter)
End If
End Sub
Sub Main()
printhtml("zan image printer(bw)", "c:\htmlfiles\document.htm")
End Sub
End Module
C# code sample:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using Microsoft.Win32;
using SHDocVw;
namespace printhtml_csharp
{
class Program
{
//Determines Zan Image Printer installation directory
static string GetZanInstallDir()
{
string installfolder = string.Empty;
RegistryKey rkTest;
//first check to see if the uninstall registry entry exists
rkTest = Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\zvprt50");
if (rkTest != null)
{
installfolder = rkTest.GetValue("UninstallString").ToString();
rkTest.Close();
if (installfolder.Length > 0)
{
installfolder = Path.GetDirectoryName(installfolder);
DirectoryInfo installdir1 = new DirectoryInfo(installfolder);
if (installdir1.Exists)
{
return installfolder;
}
}
}
//fallback to the \Program Files\zvprt50 folder:
installfolder = Environment.GetFolderPath
(Environment.SpecialFolder.ProgramFiles);
if (!installfolder.EndsWith("\\"))
installfolder = string.Concat(installfolder, "\\");
installfolder = string.Concat(installfolder, "zvprt50");
return installfolder;
}
//Determines Zan Image Printer
//configuration directory for the ini setting files
static string GetZanConfigurationDir(string szPrinter)
{
//read the OS info
OperatingSystem os = System.Environment.OSVersion;
string sCfg;
uint lPolicy;
StringBuilder tmpstr = new StringBuilder(256);
//read configure.ini from
//Zan Image Printer installation directory
sCfg = GetZanInstallDir();
if (!sCfg.EndsWith("\\"))
sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "configure.ini");
//Read the all users (per-machine) folder policy
//from configure.ini:
//policy=1: auto detect, if Vista or newer,
//use CSIDL_COMMON_DOCUMENTS as the
//all users (per-machine) folder;
//otherwise, use CSIDL_COMMON_APPDATA
//policy=2: use CSIDL_COMMON_APPDATA
//policy=3: use CSIDL_COMMON_DOCUMENTS
lPolicy = GetPrivateProfileInt("allusersfolder", "policy",
1, sCfg);
//handle the auto detect policy
if (1 == lPolicy)
{
//Vista and 2008: dwVerMajor>=6
if (os.Version.Major >= 6)
{
lPolicy = 3;
}
else
{
lPolicy = 2;
}
}
//get the all users (per-machine) folder
//if the all users (per-machine) folder exists,
//then this zan image printer was installed per-machine:
//all users share the same settings
if (2 == lPolicy)
{
//csidl = CSIDL_COMMON_APPDATA;
sCfg = Environment.GetFolderPath
(Environment.SpecialFolder.CommonApplicationData);
}
else
{
//csidl = CSIDL_COMMON_DOCUMENTS;
SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, 0, tmpstr);
sCfg = tmpstr.ToString();
}
if (!sCfg.EndsWith("\\")) sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "zvprt50\\");
sCfg = string.Concat(sCfg, szPrinter);
//all users will share the same
//settings for the printer
DirectoryInfo tmpdir = new DirectoryInfo(sCfg);
if (tmpdir.Exists)
{
return sCfg;
}
//if the all users (per-machine) folder doesn't exist,
//assume each user has his own settings
//for the printer:
sCfg = Environment.GetFolderPath
(Environment.SpecialFolder.ApplicationData);
if (!sCfg.EndsWith("\\")) sCfg = string.Concat(sCfg, "\\");
sCfg = string.Concat(sCfg, "zvprt50\\");
sCfg = string.Concat(sCfg, szPrinter);
return sCfg;
}
static void printhtml(string szPrinter, string htmlfile)
{
StringBuilder tempstr = new StringBuilder(256);
string szDefPrinter;
int dwBufSize = tempstr.Capacity;
/*
change the default printer prior to calling the
ExecWB function.
*/
GetDefaultPrinter(tempstr, ref dwBufSize);
szDefPrinter = tempstr.ToString();
if (string.Compare(szPrinter, szDefPrinter, true) != 0)
{
SetDefaultPrinter(szPrinter);
}
//enddoc event name
string szEnddocEvent = "SignalPrintDone";
string strPath;
strPath = GetZanConfigurationDir(szPrinter);
if (!strPath.EndsWith("\\"))
strPath = string.Concat(strPath, "\\");
strPath = string.Concat(strPath,"event.ini");
//enable event notification
WritePrivateProfileString("event", "enable", "1", strPath);
//set enddoc event name
WritePrivateProfileString("event", "enddoc", szEnddocEvent, strPath);
EventWaitHandle ewh;
ewh = new EventWaitHandle(false, EventResetMode.AutoReset, szEnddocEvent);
InternetExplorer explorer = new InternetExplorerClass();
IWebBrowserApp webBrowser = explorer;
Object noValue = null;
webBrowser.Visible = true;
webBrowser.Navigate(htmlfile, ref noValue,
ref noValue, ref noValue, ref noValue);
/*Wait until URL navigation is done*/
while (webBrowser.Busy)
{
Thread.Sleep(250);
}
//printing without print dialog
//The print job status is "sent to printer" when
//ExecWB returns.
explorer.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT,
SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
ref noValue,
ref noValue);
//wait for the EndDoc event to be received,
//an indication that the submitted print job has indeed completed
ewh.WaitOne();
explorer.Quit();
/*set default printer back to original*/
if (string.Compare(szPrinter, szDefPrinter, true) != 0)
{
SetDefaultPrinter(szDefPrinter);
}
}
static void Main(string[] args)
{
printhtml("zan image printer(bw)", "c:\\htmlfiles\\document.htm");
}
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool GetDefaultPrinter(StringBuilder pszBuffer,
ref int size);
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileString(string lpAppName,
string lpKeyName, string lpDefault,
StringBuilder lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32.dll")]
static extern bool WritePrivateProfileString(string lpAppName,
string lpKeyName,
string lpString, string lpFileName);
[DllImport("kernel32.dll")]
static extern uint GetPrivateProfileInt(string lpAppName,
string lpKeyName, int nDefault, string lpFileName);
[DllImport("shell32.dll")]
static extern bool SHGetFolderPath(int hwndOwner,
int nFolder, int hToken, int dwFlags, StringBuilder pszPath);
const int CSIDL_COMMON_DOCUMENTS = 0x002e;
}
}
Microsoft Word automation VB, Delphi, C, VC.NET, VB.NET and C# code samples: print Word DOC files programmatically Below are the code samples that illustrate using Microsoft Word automation to print DOC files programmatically. To compile the VC.NET, VB.NET and C# code samples, you first need to set a reference to the "Microsoft Word Object Library" in your project by following the steps below: 1. In Solution Explorer, right click the project node, then click Add Reference. 2. In the Add Reference dialog, click the COM tab. 3. Click the "Microsoft Word X.0 Object Library"(X is the version number), and then click Select. VB code sample:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" ( _
ByVal dwMilliseconds As Long)
Public Sub printdoc(szPrinter As String, docfile As String)
Dim wdApp As Object
Dim oldactiveprinter As String
'Word Automation
Set wdApp = CreateObject("Word.Application")
'show Word window
wdApp.Visible = True
wdApp.Documents.Open (docfile)
'remember current active printer
oldactiveprinter = wdApp.ActivePrinter
oldactiveprinter = LCase(oldactiveprinter)
szPrinter = LCase(szPrinter)
If oldactiveprinter <> Trim$(szPrinter) Then
wdApp.ActivePrinter = szPrinter
End If
wdApp.ActiveDocument.PrintOut
'Make sure all of the documents are gone from the queue
Do While wdApp.BackgroundPrintingStatus > 0
Sleep 100
Loop
'set active printer back to original
If oldactiveprinter <> Trim$(szPrinter) Then
wdApp.ActivePrinter = oldactiveprinter
End If
wdApp.ActiveDocument.Close (False)
'Close instance of MS Word
wdApp.Quit
Set wdApp = Nothing
End Sub
Public Sub Main()
printdoc "zan image printer(bw)", "c:\abc\1.doc"
End Sub
Delphi code sample:
uses Windows, ComObj;
procedure printdoc(printername:String; docfile:String);
implementation
procedure printdoc(printername:String; docfile:String);
var
wdApp: Variant;
oldactiveprinter: String;
begin
//Word automation
//start an instance of MS Word
wdApp := CreateOleObject('Word.Application');
//show Word window
wdApp.Visible := True;
//remember current active printer
oldactiveprinter := wdApp.ActivePrinter;
wdApp.ActivePrinter := printername;
wdApp.Documents.Open(docfile);
wdApp.ActiveDocument.PrintOut;
//Make sure all of the documents are gone from the queue
while(wdApp.BackgroundPrintingStatus > 0) do
Sleep(250);
//set active printer back to original
if oldactiveprinter <> printername then
wdApp.ActivePrinter := oldactiveprinter;
wdApp.ActiveDocument.Close(False);
wdApp.quit(False);
end;
printdoc('zan image printer(bw)', 'c:\abc\1.doc');
#include <windows.h>
#include <winspool.h>
#include <ole2.h>
#pragma warning(disable:4146)
//#import statement and smart pointers:
//The #import statement is different for each version of the
//Microsoft Word Object Library, change the path to your own Word
//type library if needed
#import "c:\Program Files\Common Files\Microsoft Shared\Office10\MSO.DLL"
#import "c:\Program Files\\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.olb"
#import "c:\Program Files\Microsoft Office\Office10\MSWORD.olb" \
rename("ExitWindows","ExitWindowsEx")
void printdoc(char *printername, char *docfile)
{
CoInitialize(NULL);
CLSID clsid;
/*Word automation*/
CLSIDFromProgID(L"Word.Application", &clsid);
Word::_ApplicationPtr pApp;
pApp.CreateInstance (clsid, NULL);
/*show Word window*/
pApp->PutVisible(VARIANT_TRUE);
/*remember current active printer*/
BSTR org_activeprinter;
pApp->get_ActivePrinter(&org_activeprinter);
_variant_t bstrFileName(docfile);
pApp->GetDocuments()->Open(&bstrFileName);
pApp->put_ActivePrinter(_bstr_t(printername));
Word::_DocumentPtr pWordDocument = pApp->GetActiveDocument();
//print the document
pWordDocument->PrintOut();
// Make sure all of the documents are gone from the queue
while(pApp->BackgroundPrintingStatus > 0)
{
Sleep(250);
}
/*set active printer back to original*/
pApp->put_ActivePrinter(org_activeprinter);
SysFreeString(org_activeprinter);
_variant_t v((long)Word::wdDoNotSaveChanges);
pApp->Quit(&v);
CoUninitialize();
}
printdoc("zan image printer(bw)", "c:\\abc\\1.doc");
VC.NET code sample:
using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
using namespace System::Threading;
void printdoc(String^ szPrinter, String^ docfile)
{
Word::ApplicationClass^ ac = gcnew Word::ApplicationClass();
Word::Application^ app = ac->Application;
String^ szActiveprinter;
Object^ missing = System::Reflection::Missing::Value;
szActiveprinter = app->ActivePrinter;
//remember current active printer
if(String::Compare(szPrinter, szActiveprinter, true) != 0)
{
app->ActivePrinter = szPrinter;
}
app->Visible = true;
Word::Document^ aDoc = gcnew Word::Document();
aDoc = app->Documents->Add(docfile, missing, missing, missing);
app->PrintOut(missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
// Make sure all of the documents are gone from the queue
while(app->BackgroundPrintingStatus > 0)
{
Thread::Sleep(250);
}
//set active printer back to original
if(String::Compare(szPrinter, szActiveprinter, true) != 0)
{
app->ActivePrinter = szActiveprinter;
}
ac->Quit(missing, missing, missing);
}
printdoc(L"zan image printer(bw)", L"c:\\abc\\1.doc");
VB.NET code sample:
Imports System.Runtime.InteropServices
Imports System.Text
Imports System
Imports System.Threading
Module Module1
Sub printdoc(ByVal szPrinter As String, ByVal docfile As Object)
Dim ac As Word.ApplicationClass = New Word.ApplicationClass()
Dim app As Word.Application = ac.Application
Dim szActiveprinter As String
szActiveprinter = app.ActivePrinter
'remember current active printer
If String.Compare(szPrinter, szActiveprinter, True) <> 0 Then
app.ActivePrinter = szPrinter
End If
app.Visible = True
Dim aDoc As Word.Document = New Word.Document()
Dim missing As Object
missing = System.Reflection.Missing.Value
aDoc = app.Documents.Open(docfile, _
missing, missing, missing, _
missing, missing, missing, _
missing, missing, missing, _
missing, missing)
app.PrintOut(missing, missing, missing, missing, missing, missing, _
missing, missing, missing, missing, missing, missing, _
missing, missing, missing, missing, missing, missing, _
missing)
' Make sure all of the documents are gone from the queue
While app.BackgroundPrintingStatus > 0
Thread.Sleep(250)
End While
'set active printer back to original
'remember current active printer
If String.Compare(szPrinter, szActiveprinter, True) <> 0 Then
app.ActivePrinter = szActiveprinter
End If
ac.Quit(missing, missing, missing)
End Sub
Sub Main()
printdoc("zan image printer(bw)", "c:\abc\1.doc")
End Sub
End Module
C# code sample:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
class Program
{
static void printdoc(string szPrinter, object docfile)
{
Word.ApplicationClass ac = new Word.ApplicationClass();
Word.Application app = ac.Application;
string szActiveprinter;
szActiveprinter = app.ActivePrinter;
//remember current active printer
if (String.Compare(szPrinter, szActiveprinter, true) != 0)
{
app.ActivePrinter = szPrinter;
}
app.Visible = true;
Word.Document aDoc = new Word.Document();
object missing = System.Reflection.Missing.Value;
aDoc = app.Documents.Open(ref docfile,
ref missing, ref missing,
ref missing, ref missing,
ref missing, ref missing,
ref missing, ref missing,
ref missing, ref missing,
ref missing);
app.PrintOut(ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing);
// Make sure all of the documents are gone from the queue
while (app.BackgroundPrintingStatus > 0)
{
Thread.Sleep(250);
}
//set active printer back to original
if (String.Compare(szPrinter,szActiveprinter,true) != 0)
{
app.ActivePrinter = szActiveprinter;
}
ac.Quit(ref missing, ref missing, ref missing);
}
static void Main(string[] args)
{
printdoc("zan image printer(bw)", "c:\\abc\\1.doc");
}
}
Microsoft Excel automation VB, Delphi, C, VC.NET, VB.NET and C# code samples: print Excel XLS files programmatically Below are the code samples that illustrate using Microsoft Excel automation to print XLS files programmatically. The code samples will print all sheets in the workbook. The VB, Delphi and C/C++ code samples also contain commented out code showing how to print just the selected sheet (such as the first sheet), you can uncomment it and put it back if needed. To compile the VC.NET, VB.NET and C# code samples, you first need to set a reference to the "Microsoft Excel Object Library" in your project by following the steps below: 1. In Solution Explorer, right click the project node, then click Add Reference. 2. In the Add Reference dialog, click the COM tab. 3. Click the "Microsoft Excel X.0 Object Library"(X is the version number), and then click Select. VB code sample:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" ( _
ByVal dwMilliseconds As Long)
'print to the current default printer
Public Sub printxls(xlsfile As String)
Dim ExcelApp As Object
Dim ObjSheet As Object
'Excel Automation
Set ExcelApp = CreateObject("excel.Application")
ExcelApp.Visible = True
ExcelApp.Workbooks.Open (xlsfile)
'print all sheets in the workbook
ExcelApp.ActiveWorkbook.PrintOut
'print the first sheet, sheet index starts from 1
Set ObjSheet = ExcelApp.ActiveWorkbook.WorkSheets(1)
'ObjSheet.PrintOut
'close instance of MS Excel
ExcelApp.ActiveWorkbook.Close (False)
ExcelApp.Quit
Set ExcelApp = Nothing
End Sub
Public Sub Main()
printxls "c:\abc\1.xls"
End Sub
Delphi code sample:
uses Windows, ComObj;
procedure printxls(xlsfile:String);
implementation
procedure printxls(xlsfile:String);
var
ExcelApp: Variant;
ObjSheet: Variant;
begin
//Excel automation
//start an instance of MS Excel
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.Visible := True;
ExcelApp.Workbooks.Open(xlsfile);
//print all sheets in the workbook
ExcelApp.ActiveWorkbook.PrintOut;
//print the first sheet, sheet index starts from 1
ObjSheet := ExcelApp.ActiveWorkBook.WorkSheets [1];
//ObjSheet.PrintOut;
ExcelApp.ActiveWorkbook.Close(False);
//Quit Excel
ExcelApp.Quit;
end;
printxls('c:\abc\1.xls');
#include <windows.h>
#include <ole2.h>
#pragma warning(disable:4146)
//#import statement and smart pointers below:
//The #import statement is different for each version of the
//Microsoft Excel Object Library, change the path to your own Excel
//type library if needed
#import "c:\Program Files\Common Files\Microsoft Shared\Office10\MSO.DLL"
#import "c:\Program Files\\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.olb"
#import "C:\Program Files\Microsoft Office\Office10\EXCEL.EXE" \
rename("DialogBox","_DialogBox") \
rename("RGB","_RGB") \
exclude("IFont","IPicture")
/*print to the current default printer*/
void printxls(char *xlsfile)
{
Excel::_ApplicationPtr ExcelApp;
Excel::WorkbooksPtr ExcelWorkBooks;
Excel::_WorkbookPtr ExcelWorkBook;
/*Excel automation*/
CoInitialize(NULL);
if(ExcelApp.CreateInstance(__uuidof(Excel::Application)) == S_OK)
{
ExcelApp->PutVisible(0, VARIANT_TRUE);
ExcelWorkBooks = ExcelApp->GetWorkbooks();
ExcelWorkBook = ExcelWorkBooks->Open(_bstr_t(xlsfile));
/*print all sheets in the workbook*/
ExcelWorkBook->PrintOut();
/*print the selected sheet*/
Excel::WorksheetsPtr pSheets = ExcelApp->GetSheets();
/*Get first sheet*/
VARIANT vt;
VariantInit(&vt);
vt.vt = VT_I2;
/*sheet index starts from 1*/
vt.iVal = (short)1;
Excel::_WorksheetPtr worksheet = pSheets->GetItem(vt);
/*worksheet->PrintOut();*/
ExcelWorkBook->Close();
ExcelApp->Quit();
}
CoUninitialize();
}
printxls("C:\\abc\\1.xls");
VC.NET code sample:
using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
using namespace System::Threading;
/*print to the current default printer*/
void printxls(String^ xlsfile)
{
/*Excel automation*/
Excel::ApplicationClass^ ac = gcnew Excel::ApplicationClass();
Excel::Application^ app = ac->Application;
Excel::Workbooks^ workbooks = app->Workbooks;
Object^ missing = System::Reflection::Missing::Value;
Excel::Workbook^ workbook = workbooks->Open(xlsfile,
missing, missing, missing, missing,
missing, missing, missing, missing,
missing, missing, missing, missing);
app->Visible = true;
/*print all sheets in the workbook*/
//The print job status is "sent to printer" when
//PrintOut returns.
workbook->PrintOut(missing, missing, missing, missing,
missing, missing, missing, missing);
workbook->Close(missing, missing, missing);
app->Quit();
}
printxls(L"C:\\abc\\1.xls");
VB.NET code sample:
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Threading
Module Module1
'print to the current default printer
Sub printxls(ByVal xlsfile As String)
'Excel automation
Dim ac As Excel.ApplicationClass = New Excel.ApplicationClass()
Dim app As Excel.Application = ac.Application
Dim workbooks As Excel.Workbooks = app.Workbooks
Dim missing As Object = System.Reflection.Missing.Value
Dim workbook As Excel.Workbook = workbooks.Open(xlsfile, _
missing, missing, missing, missing, _
missing, missing, missing, missing, _
missing, missing, missing, missing)
app.Visible = True
'print all sheets in the workbook
'The print job status is "sent to printer" when
'PrintOut returns.
workbook.PrintOut(missing, missing, missing, missing, _
missing, missing, missing, missing)
workbook.Close(missing, missing, missing)
app.Quit()
End Sub
Sub Main()
printxls("C:\abc\1.xls")
End Sub
End Module
C# code sample:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
class Program
{
/*print to the current default printer*/
static void printxls(string xlsfile)
{
/*Excel automation*/
Excel.ApplicationClass ac = new Excel.ApplicationClass();
Excel.Application app = ac.Application;
app.Visible = true;
Excel.Workbooks workbooks = app.Workbooks;
Object missing = System.Reflection.Missing.Value;
Excel.Workbook workbook =
workbooks.Open(xlsfile,
missing, missing, missing, missing,
missing, missing, missing, missing,
missing, missing, missing, missing);
/*print all sheets in the workbook*/
//The print job status is "sent to printer" when
//PrintOut returns.
workbook.PrintOut(missing, missing, missing, missing,
missing, missing, missing, missing);
workbook.Close(missing, missing, missing);
app.Quit();
}
static void Main(string[] args)
{
printxls("C:\\abc\\1.xls");
}
}
VB, Delphi, C, VC.NET, VB.NET and C# code samples: get and set the default printer in Windows The GetDefaultPrinter Win32 API retrieves the printer name of the default printer for the current user on the local computer. The SetDefaultPrinter Win32 API sets the printer name of the default printer for the current user on the local computer. The following code samples illustrate the technique to change the default printer: VB code sample:
Option Explicit
Private Declare Function GetDefaultPrinter Lib "winspool.drv" Alias _
"GetDefaultPrinterA" (ByVal pszBuffer As String, pcchBuffer As Long) As Long
Private Declare Function SetDefaultPrinter Lib "winspool.drv" _
Alias "SetDefaultPrinterA" _
(ByVal pszPrinter As String) As Long
Public Sub Main()
Dim sPrinterName As String
Dim sNameBuff As String, lLen As Long
GetDefaultPrinter vbNullChar, lLen
sNameBuff = Space$(lLen)
GetDefaultPrinter sNameBuff, lLen
sPrinterName = Left$(sNameBuff, _
InStr(sNameBuff, vbNullChar) - 1)
SetDefaultPrinter "zan image printer(bw)"
End Sub
uses
Windows, Messages, SysUtils, ShlObj, ShellAPI, SHFolder, ComObj;
function GetDefaultPrinter(prnName:PAnsiChar; var bufSize:DWORD):
BOOL; stdcall; external 'winspool.drv' name 'GetDefaultPrinterA';
function SetDefaultPrinter(prnName:PAnsiChar):
BOOL; stdcall; external 'winspool.drv' name 'SetDefaultPrinterA';
procedure test_defprinter();
implementation
procedure test_defprinter();
var
szDefPrinter: String;
lBufSize: DWord;
begin
SetLength(szDefPrinter, MAX_PATH);
lBufSize := MAX_PATH;
GetDefaultPrinter(Pchar(szDefPrinter), lBufSize);
szDefPrinter := String (PChar(szDefPrinter));
SetDefaultPrinter('zan image printer(bw)');
end;
C code sample:
#include <windows.h>
#include <winspool.h>
char szDefPrinter[MAX_PATH];
DWORD dwBufSize;
dwBufSize = MAX_PATH;
GetDefaultPrinter(szDefPrinter, &dwBufSize);
SetDefaultPrinter("zan image printer(bw)");
VC.NET code sample:
using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
// Declare the function that is exported from unmanaged dll:
[DllImport("winspool.drv")]
extern "C" bool _cdecl GetDefaultPrinter(
StringBuilder^ pszBuffer, int *size);
[DllImport("winspool.drv")]
extern "C" bool _cdecl SetDefaultPrinter(
String^ pszPrinter);
StringBuilder^ tempstr = gcnew StringBuilder(256);
String^ szDefPrinter;
int dwBufSize = tempstr->Capacity;
GetDefaultPrinter(tempstr, &dwBufSize);
szDefPrinter = tempstr->ToString();
SetDefaultPrinter(L"zan image printer(bw)");
VB.NET code sample:
Imports System.Runtime.InteropServices
Imports System.Text
Imports System
Module Module1
Declare Function GetDefaultPrinter Lib "winspool.drv" _
Alias "GetDefaultPrinterA" (ByVal pszBuffer As System.Text.StringBuilder, _
ByRef size As Int32) As Boolean
Declare Function SetDefaultPrinter Lib "winspool.drv" Alias _
"SetDefaultPrinterA" (ByVal pszPrinter As String) As Boolean
Sub Main()
Dim sPrinterName As String
Dim tempstr As StringBuilder
tempstr = New StringBuilder(256)
GetDefaultPrinter(tempstr, tempstr.Capacity)
sPrinterName = tempstr.ToString()
SetDefaultPrinter("zan image printer(bw)")
End Sub
End Module
C# code sample:
using System.Runtime.InteropServices;
class Program
{
static void Main(string[] args)
{
StringBuilder tempstr = new StringBuilder(256);
string szDefPrinter ;
int dwBufSize = tempstr.Capacity;
GetDefaultPrinter(tempstr, ref dwBufSize);
szDefPrinter = tempstr.ToString();
// Set default printer
SetDefaultPrinter("zan image printer(bw)");
}
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool GetDefaultPrinter(StringBuilder pszBuffer,
ref int size);
[DllImport("winspool.drv", CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
}
Copyright © 2002-2010, http://www.zan1011.com, All Rights Reserved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||