Search code examples
delphidelphi-2010

List local printers


I am using this routine to list the local printers installed on a machine:

var
  p: pointer;
  hpi: _PRINTER_INFO_2A;
  hGlobal: cardinal;
  dwNeeded, dwReturned: DWORD;
  bFlag: boolean;
  i: dword;
begin
  p := nil;
  EnumPrinters(PRINTER_ENUM_LOCAL, nil, 2, p, 0, dwNeeded, dwReturned);
  if (dwNeeded = 0) then exit;
  GetMem(p,dwNeeded);
  if (p = nil) then exit;
  bFlag := EnumPrinters(PRINTER_ENUM_LOCAL, nil, 2, p, dwneeded, dwNeeded, dwReturned);
  if (not bFlag) then exit;
  CbLblPrinterPath.Properties.Items.Clear;
  for i := 0 to dwReturned - 1 do
  begin
    CbLblPrinterPath.Properties.Items.Add(TPrinterInfos(p^)[i].pPrinterName);
  end;
  FreeMem(p);

TPrinterInfos(p^)[i].pPrinterName returns a 'P' for printer name. I have a PdfCreator installed as a printer.

TPrinterInfos is an array of _PRINTER_INFO_2A.

How can I fix this?


Solution

  • Ok, first thing first... Since you tagged this Delphi-2010, I'd assume you are having this problem with D2010.

    Your problem start with your use of _PRINTER_INFO_2A, which is the structure used by the Ansi version of the function EnumPrinters. Ever since unicode has been introduced, the "EnumPrinters" function maps to the unicode version of the function, and thus, you should use _PRINTER_INFO_2W. (Or explicitly call EnumPrintersA). If you are using EnumPrinters(Without A/W) you should use the _PRINTER_INFO_2(without A/W). That way, it will be less likely to break if one day a UTF32 version becomes the new standard.