Mega Code Archive

 
Categories / Delphi / Printing
 

Selecting a printer

Title: Selecting a printer Question: 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&Report 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. procedure TWPFPrinter.SetPrinterIndex(Value: Integer); var DrvHandle: THandle; ExtDevCaps: TFarProc; DriverName: String; ExtDevCode: Integer; OutDevMode: PDevMode; ADevice : Array[0..256] of Char; StubDevMode: TDeviceMode; begin CheckPrinting(False); if (Value = -1) or (PrinterIndex = -1) then SetToDefaultPrinter else if (Value = Printers.Count) then RaiseError(SPrinterIndexError); FPrinterIndex := Value; FreeFonts; SetState(psNoHandle); // ------------------------------------------------------------------------ // Now we load the currently selected properties of the // newly selected printer. // otherwise the same 'DeviceMode' memory block to initialize the new printer // ------------------------------------------------------------------------ if DeviceMode0 then begin GlobalUnlock(DeviceMode); GlobalFree(DeviceMode); DeviceMode := 0; end; // ------------------------------------------------------------------------ // This code was copied from the SetPrinters procedure // ------------------------------------------------------------------------ with TPrinterDevice(Printers.Objects[PrinterIndex]) do StrCopy(ADevice, PChar(Device)); if OpenPrinter(ADevice, FPrinterHandle, nil) then begin if DeviceMode = 0 then // alloc new device mode block if one was not passed in begin DeviceMode := GlobalAlloc(GHND, DocumentProperties(0, FPrinterHandle, ADevice, StubDevMode, StubDevMode, 0)); if DeviceMode 0 then begin DevMode := GlobalLock(DeviceMode); if DocumentProperties(0, FPrinterHandle, ADevice, DevMode^, DevMode^, DM_OUT_BUFFER) begin GlobalUnlock(DeviceMode); GlobalFree(DeviceMode); DeviceMode := 0; end end; end; if DeviceMode 0 then SetPrinterCapabilities(DevMode^.dmFields); end; end; (excerpt of printers.pas, Copyright (c) 1995,99 Inprise Corporation) I hope this article helps you with your developments. Don't miss the site www.wptools.com if you need word processing, label and form printing or reporting in RTF format within your project.