I would like to send a print job to a printer using Delphi. Ideally I would like to be able to do this without having the user select the printer from a print dialog.
I would like to be able to use printers other than the windows default printer.
I have tried setting the printer by the printer name :
Vcl.Printers.Printer.PrinterIndex := Vcl.Printers.Printer.Printers.IndexOf('My Printer Name');
However when I print, it reverts to using the default printer
Select Start > Settings . Go to Devices > Printers & scanners > select a printer > Manage. Then select Set as default. If you don't see the Set as default option, the Let Windows manage my default printer option may be selected.
To Set the Default PrinterFrom the Main Administration Page, under "Network Service Administration," click Printer Administration. Under "Set Default Printer," click Set Default Printer. Select the printer you want to be the default printer from the list. Click OK.
The name passed to IndexOf
must match exactly with what's in Printer.Printers
in order to work. If they're not exact, including CASE, IndexOf
will return -1
, which means "use the default printer".
For a specific example, using IndexOf('hp laserjet')
will return -1 if the actual printer name is HP LaserJet
or hp laserjet 5
.
If you're not specifying the exact name, you can do a partial match by iterating the list. It's highly unlikely that the typical system has too many printers available for this to be efficient; we have a couple of dozen, and it's fine.
Here's the situation we have: Our office is divided into three basic departments (Fiscal, Admin, and Customer Service). Each has a different printer that holds pin-feed (dot matrix) labels, but we have apps that run in all departments. Instead of having the application know which department it's being run in to choose the label printer, we just give the printers names containing the word Labels
- Fiscal Labels
, Admin Labels
, etc. We can then find the appropriate printer with a loop:
function GetLabelPrinterIndex: Integer;
var
i: Integer;
begin
for i := 0 to Printer.Printers.Count - 1 do
if AnsiContainsText(Printer.Printers[i], `Labels`) then
begin
Exit(i);
end;
Result := -1;
end;
As a note: I'd remove the VCL
prefix from your references; it means your code won't be available across platforms. If you just make sure that Printers
is in your uses clause, you can use just Printers.Printer
, and changing the target platform (VCL Win32/64, FMX 32/64, OSX) will adjust the uses clause for you based on the build configuration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With