[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 211
  • Last Modified:

getting a printers paperforms and their sizes

Hi there,

I'm having problems finding the size of the different paper forms a printer support. Enumerating for the forms is no problem, but getting the actual size in millimeters or similiar is. Im using DeviceCapabilities to get the form names, but then what ? I've found EnumForms in the API but can't figure out how to use it correctly (it doesn't return any forms, and how the heck do i get the size from a sizel type ??)

Any help ?

Best regards
NetGeek
0
NetGeek
Asked:
NetGeek
  • 3
1 Solution
 
geobulCommented:
Hi,

Try this (the listbox contains the names of the printers):

type
  TForm1 = class(TForm)
    Button1: TButton;
    re: TRichEdit;
    lb: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses Printers, WinSpool;

procedure TForm1.Button1Click(Sender: TObject);
var
  PHD         : THandle;
  info        : array [0..10000] of TFormInfo1;
  pcbNeeded   : DWORD;
  pcReturned  : DWORD;
  i: integer;
begin
 if OpenPrinter(PChar(lb.Items[lb.ItemIndex]), PHD, nil) then begin // open the printer
    EnumForms(PHD, 1, @Info, SizeOf(Info), pcbNeeded, pcReturned); // get the info
    for i := 0 to 10000 do begin
      if Info[i].pName = nil then exit;
      re.Lines.Add(Info[i].pName); // name of the form
      re.Lines.Add(IntToStr(Info[i].Size.cx)); // width
      re.Lines.Add(IntToStr(Info[i].Size.cy)); // height
      re.Lines.Add('');
    end;
    ClosePrinter(PHD);
  end else ShowMessage('Cannot open the printer');
end;

Regards, Geo
0
 
geobulCommented:
If you want to get the sizes only:

procedure TForm1.Button3Click(Sender: TObject);
var
  p: array [0..10000] of char;
  a: array of TPoint;
  i, res: integer;
begin
  res := DeviceCapabilities(PChar(lb.Items[lb.ItemIndex]), nil, DC_PAPERSIZE, p, nil);
  if res > 0 then begin
    SetLength(a, res);
    move(p, a[0], res * SizeOf(Tpoint));
    for i := 0 to res - 1 do begin
      re.Lines.Add(IntToStr(a[i].x)+':'+IntToStr(a[i].y));
    end;
  end;
end;

Regards, Geo
0
 
NetGeekAuthor Commented:
thank you very much geobul :) it wa the openprinter i'd forgotten.

got any code at hand showing how to select a specific form by name for the current printer ?

Best regards
Netgeek
0
 
geobulCommented:
I don't have the code but I think you could try Printer.GetPrinter and Printer.SetPrinter methods. First call GetPrinter in order to obtain the DEVMODE structure. Then set dmFields to DM_FORMNAME and dmFormName member of that structure to the name of the form you want to set to (and others also perhaps - dmPaperLength and dmPaperWidth). Then use Printer.SetPrinter to save the change. Help says that this member doesn't work in Win9x though. There are predefined form constants in Windows.pas (DMPAPER_LETTER = 1, etc.). You may also use them setting dmPaperSize member of DEVMODE only. What is interesting is DMPAPER_USER constant. You can create your own page size setting dmPaperSize to DMPAPER_USER and dmPaperWidth and dmPaperLength to what you need (in tenths of millimeter). Something like:

var
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port   : array[0..255] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
 Printer.GetPrinter(Device, Driver, Port, hDMode);
 if hDMode <> 0 then begin
   pDMode := GlobalLock(hDMode);
   if pDMode <> nil then begin

    {Set to legal}
     pDMode^.dmFields := pDMode^.dmFields or dm_PaperSize;
     pDMode^.dmPaperSize := DMPAPER_LEGAL;

    {or Set to custom size}
     pDMode^.dmFields := pDMode^.dmFields or
                         DM_PAPERSIZE or
                         DM_PAPERWIDTH or
                         DM_PAPERLENGTH;
     pDMode^.dmPaperSize := DMPAPER_USER;
     pDMode^.dmPaperWidth := 1000;
     pDMode^.dmPaperLength := 2000;

    {Set the bin to use}
     pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
     pDMode^.dmDefaultSource := DMBIN_MANUAL;
     
     Printer.SetPrinter(Device,Driver,Port,hDMode);

     GlobalUnlock(hDMode);
  end;
 end;
...

Regards, Geo
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now