Solved

getting a printers paperforms and their sizes

Posted on 2003-12-11
4
200 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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

708 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now