Solved

getting a printers paperforms and their sizes

Posted on 2003-12-11
4
202 Views
Last Modified: 2010-04-05
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
Comment
Question by:NetGeek
  • 3
4 Comments
 
LVL 17

Accepted Solution

by:
geobul earned 250 total points
ID: 9920942
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
 
LVL 17

Expert Comment

by:geobul
ID: 9920983
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
 

Author Comment

by:NetGeek
ID: 9922959
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
 
LVL 17

Expert Comment

by:geobul
ID: 9926666
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

806 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question