Modifying Printer Settings
This article shows how to implement the method given in the Microsoft 'How To'
advice on changing printer settings.
From the article -
"SUMMARY
SetPrinter is a new API for Windows 95, Windows NT, Windows 2000, and Windows XP
that allows applications to change various printer attributes. However, as the
code in this article demonstrates, a certain amount of preparation is necessary
in order to call SetPrinter correctly."
The full text including the C code ( C++Builder users will prefer it) is here.
Sources :
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q140285
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q167345
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q246772
Below is a translation to Delphi. The logic follows the C example as
far as possible, with the exception created by the fact that the Printer_info_2
structure in Delphi does NOT have a 'pDevMode' member.
The procedure below is for setting a printers paper source (bin). It can be
easily adapted to set any printer code.
It is hoped that the inclusion of the 'DocumentProperties()' call will also fix
some other problems that have been experienced with printing.
These changes will be incorporated in the next release of QuickReport in summer 2002.
// This is translated from the C example given by MS Oct 01
// Also see WinAPI Help on 'DocumentProperties()' and 'SetPrinter'
procedure SetPrinterBin( Printername : pchar; BinCode : integer );
var
SpaceNeeded : word; // for pDriverinfo2
pDBuff : _devicemodeA; // dummy
Driver_info_2 : pDriverinfo2;
DevModeSize : integer;
dPtr : Pointer;
hPrinter : THandle;
begin
// Get the printer handle
OpenPrinter(Printername, hPrinter, nil);
// find out how much space we need for the info stuct
GetPrinter( hPrinter, 2, 0, 0, @SpaceNeeded);
// allocate the necessary
GetMem( Driver_info_2, SpaceNeeded);
// The second GetPrinter fills in all the current settings
GetPrinter( hPrinter, 2, Driver_info_2, SpaceNeeded, @SpaceNeeded);
// If GetPrinter didn't fill in the DEVMODE, try to get it by calling
// Documentproperties() - this is always true in Delphi, so ...
// Zero in last arg returns buffer size - if it's -1 the call failed..
DevModeSize := DocumentProperties(0, hPrinter, Printername, pDBuff, pDBuff, 0);
// get space
dPtr := allocmem( DevModeSize );
devmode := pDevmode( dPtr );
// this call fills our DevMode struct
DocumentProperties(0, hPrinter, Printername,
_devicemodeA( dPtr^), pDBuff, DM_OUT_BUFFER );
// make changes to devmode
devmode^.dmFields := DM_DEFAULTSOURCE;
devmode^.dmDefaultSource := BinCode;
try
// implement the change ...
SetPrinter( hPrinter, 2, devmode, 0);
// make sure all of devmode is copied back
DocumentProperties(0, hPrinter, Printername, _devicemodeA( dPtr^),
_devicemodeA( dPtr^), DM_IN_BUFFER+DM_OUT_BUFFER );
except
// bomb out. If it's a 'Printer index out of bounds' it might
// be an invalid code.
end;
FreeMem( Driver_info_2, SpaceNeeded);
freemem( dPtr, DevmodeSize);
Closeprinter( hPrinter );
end;