Author: Tomas Rutkauskas
I want to set the format of my page to a particular format for the printer that is
not A4 (the default) but B5. How can I do this?
Answer:
You have to descend into the depth of the API for that and modify the printers
DEVMODE record. Note that you should first try to select a paper type and let the
driver figure out the bin for that. See win32.hlp entry for DEVMODE for a list of
valid paper format ID's.
1 var
2 Device, Driver, Port: array[0..80] of Char;
3 DevMode: THandle;
4 pDevmode: PDeviceMode;
5 begin
6 {Get printer device name etc.}
7 Printer.GetPrinter(Device, Driver, Port, DevMode);
8 {force reload of DEVMODE}
9 Printer.SetPrinter(Device, Driver, Port, 0);
10 {get DEVMODE handle}
11 Printer.GetPrinter(Device, Driver, Port, DevMode);
12 if Devmode <> 0 then
13 begin
14 {lock it to get pointer to DEVMODE record}
15 pDevMode := GlobalLock(Devmode);
16 if pDevmode <> nil then
17 try
18 with pDevmode^ do
19 begin
20 {modify paper size}
21 dmPapersize := DMPAPER_B5;
22 {tell printer driver that dmPapersize field contains data it needs to
23 inspect}
24 dmFields := dmFields or DM_PAPERSIZE;
25 end;
26 finally
27 {unlock DEVMODE handle}
28 GlobalUnlock(Devmode);
29 end;
30 end;
31 end;
You need to do this before a BeginDoc has been performed.
If this does not work for your purpose you have to modify the dmDefaultSource field
of the DEVMODE (same principle as above). Windows.Pas defines a bunch of DMBIM_*
constants but there is no guarantee that your printer will support them all (or
even use the constant for the bin you think it should use). Better ask it for the
bins it supports.
32 uses winspool;
33
34 procedure GetBinnames(sl: TStrings);
35 type
36 TBinName = array[0..23] of Char;
37 TBinNameArray = array[1..High(Integer) div Sizeof(TBinName)] of TBinName;
38 PBinnameArray = ^TBinNameArray;
39 TBinArray = array[1..High(Integer) div Sizeof(Word)] of Word;
40 PBinArray = ^TBinArray;
41 var
42 Device, Driver, Port: array[0..255] of Char;
43 hDevMode: THandle;
44 i, numBinNames, numBins, temp: Integer;
45 pBinNames: PBinnameArray;
46 pBins: PBinArray;
47 begin
48 Printer.PrinterIndex := -1;
49 Printer.GetPrinter(Device, Driver, Port, hDevmode);
50 numBinNames := WinSpool.DeviceCapabilities(Device, Port, DC_BINNAMES, nil, nil);
51 numBins := WinSpool.DeviceCapabilities(Device, Port, DC_BINS, nil, nil);
52 if numBins <> numBinNames then
53 begin
54 raise Exception.Create('DeviceCapabilities reports different number of bins and
55 '+ 'bin names!');
56 end;
57 if numBinNames > 0 then
58 begin
59 pBins := nil;
60 GetMem(pBinNames, numBinNames * Sizeof(TBinname));
61 GetMem(pBins, numBins * Sizeof(Word));
62 try
63 WinSpool.DeviceCapabilities(Device, Port, DC_BINNAMES, Pchar(pBinNames), nil);
64 WinSpool.DeviceCapabilities(Device, Port, DC_BINS, Pchar(pBins), nil);
65 sl.clear;
66 for i := 1 to numBinNames do
67 begin
68 temp := pBins^[i];
69 sl.addObject(pBinNames^[i], TObject(temp));
70 end;
71 finally
72 FreeMem(pBinNames);
73 if pBins <> nil then
74 FreeMem(pBins);
75 end;
76 end;
77 end;
The integers in the DC_BINS array, which end up in the passed TStrings descendents Object property, are what you need to use for dmDefaultSource.
|