Search code examples
delphiwinapiprintingvcl

How to use DeviceCapabilities to Retrieve the paper names and sizes from specific printer in Delphi


I have been looking for a way of retrieving the papers supported by an specific printer and their sizes (width and height) in millimeters if possible.

I have seen and "Studied" many posts and sites about using Printer.Getprinter and Printer.SetPrinter but I am really far from understanding the whole process to make that work, I learnt that I have to use DeviceCapabilities in order to retrieve data that is specific to one printer but I really don't know how to use those structures. I need something similar to this but for a specific printer and using the DeviceCapabilities. I use Delphi VCL.

In the question linked, they use EnumForms which I understand is for all the printers, they also mention that DeviceCapabilities is for a specific printer, and that is what I need, to get the supported paper names and sizes but only for the selected printer and not all of them. lets say I select my printer: Printer.PrinterIndex:= Printer.Printers.IndexOf(MyPrinter); I would like to get the papers and paper sizes for those supported by that printer.

Thank you so much for any help provided!


Solution

  • Here is an example that calls DeviceCapabilities for the currently selected printer and outputs supported paper names for "the current default initialization values for the specified printer driver" to a memo. The quoted part in the previous sentence is from the documentation of the function and I'm not absolutely positive that I understand what it means. That happens because a DevMode is not passed.

    procedure TForm1.Button1Click(Sender: TObject);
    var
      PrinterName: string;
      HPrinter: THandle;
      Ret: DWORD;
      Buf: array of array [0..63] of Char;
      i: Integer;
    begin
      PrinterName := Printer.Printers[Printer.PrinterIndex];
      if OpenPrinter(PChar(PrinterName), HPrinter, nil) then begin
        Ret := DeviceCapabilities(PChar(PrinterName), nil, DC_PAPERNAMES, nil, nil);
        if Ret > 0 then begin
          SetLength(Buf, Ret);
          DeviceCapabilities(PChar(PrinterName), nil, DC_PAPERNAMES, Pointer(Buf), nil);
          for i := 0 to Ret - 1 do
            Memo1.Lines.Add(Buf[i]);
        end;
        ClosePrinter(HPrinter);
      end;
    end;
    

    Explaining the code is kind of pointless, I'd be duplicating the documentation. I included the link above.