Author: Julian Ziersch
PrinterIndex selects the current printer but also applies the properties of the
currently active printer.
Answer:
Q: How to change the current printer ?
A: Printer.PrinterIndex := Printer.Printers.IndexOf('printername'); ???
The answer is certainly correct, but there is also a problem. This problem came up
when developing a label printing program for DHL shipping labels using the form
design and print library WPForm&Reporthttp://www.ziersch.com/index.html under
Delphi 5: although the mentioned code selects the printer (this is good) it also
applies the properties of the standard printer to the newly selected printer. So
any preselected paper format is lost and the printer (in our case it was a big
Siemens label printer) used a wrong paper format.
Although it took a while to find this ot, the solution was not too difficult:
The only possible solution for us was making a copy of the original printers.pas
file and changing it. The new printer unit was linked to the project instead of the
old one. (I know, such a change is unfortunate but there are no virtual methods in
the TPrinter object so overriding of the method 'SetPrinterIndex' is not possible)
This code shows you the necessary changes. The idea was to read out the properties
of the newly selected printer before it is activated for printing.
1
2 procedure TWPFPrinter.SetPrinterIndex(Value: Integer);
3 var
4 DrvHandle: THandle;
5 ExtDevCaps: TFarProc;
6 DriverName: string;
7 ExtDevCode: Integer;
8 OutDevMode: PDevMode;
9 ADevice: array[0..256] of Char;
10 StubDevMode: TDeviceMode;
11 begin
12 CheckPrinting(False);
13 if (Value = -1) or (PrinterIndex = -1) then
14 SetToDefaultPrinter
15 else if (Value < 0) or (Value >= Printers.Count) then
16 RaiseError(SPrinterIndexError);
17 FPrinterIndex := Value;
18 FreeFonts;
19 SetState(psNoHandle);
20 // ------------------------------------------------------------------------
21 // Now we load the currently selected properties of the
22 // newly selected printer.
23 // otherwise the same 'DeviceMode' memory block to initialize the new printer
24 // ------------------------------------------------------------------------
25 if DeviceMode <> 0 then
26 begin
27 GlobalUnlock(DeviceMode);
28 GlobalFree(DeviceMode);
29 DeviceMode := 0;
30 end;
31 // ------------------------------------------------------------------------
32 // This code was copied from the SetPrinters procedure
33 // ------------------------------------------------------------------------
34 with TPrinterDevice(Printers.Objects[PrinterIndex]) do
35 StrCopy(ADevice, PChar(Device));
36 if OpenPrinter(ADevice, FPrinterHandle, nil) then
37 begin
38 if DeviceMode = 0 then // alloc new device mode block if one was not passed in
39 begin
40 DeviceMode := GlobalAlloc(GHND,
41 DocumentProperties(0, FPrinterHandle, ADevice, StubDevMode,
42 StubDevMode, 0));
43 if DeviceMode 0 then
44 begin
45 DevMode := GlobalLock(DeviceMode);
46 if DocumentProperties(0, FPrinterHandle, ADevice, DevMode^,
47 DevMode^, DM_OUT_BUFFER) < 0 then
48 begin
49 GlobalUnlock(DeviceMode);
50 GlobalFree(DeviceMode);
51 DeviceMode := 0;
52 end
53 end;
54 end;
55 if DeviceMode 0 then
56 SetPrinterCapabilities(DevMode^.dmFields);
57 end;
58 end;
|