Solved

How to add/remove/modify a custom papersize programmatically?

Posted on 2011-09-11
7
1,002 Views
Last Modified: 2012-05-12
Hi there,

I need to add/remove/modify a custom papersize to the windows 7 / xp print server programmatically.

(The result should be accessible/shown under  the print server properties after adding...)

Any ideas?

TIA- Peter
printserver.png
0
Comment
Question by:bytecook
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 25

Expert Comment

by:epasquier
ID: 36521849
I'm not too good with german, do you mean add a USER paper size for use in the printer config ?
here is a start :
http://www.efg2.com/Lab/Library/UseNet/2000/0314.txt
0
 

Author Comment

by:bytecook
ID: 36521939
Hello epasquier,

thank you for that info, it is in  fact a user paper size, but selecting an user entry is not really aproblem.
I'm in search of ADDING a user custom papersize, and, setting the new form as default value for all printjobs... yesterday evening I found the registry entries for custom papersizes, but tbh, there should
be a better method to add a new printer form.

0
 

Author Comment

by:bytecook
ID: 36521949
@epasquier

btw, have seen that in the botttom text is DMPAPER_USER described - perhaps you're right!

cheers,

Peter
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 25

Expert Comment

by:epasquier
ID: 36521950
you can also have a look at that very complete component TPrinterPreview
http://www.delphiarea.com/products/delphi-components/preview/

it has the ability to set the paper size at runtime according to the one you set in the component, so I guess you can find all you need in the source code (free)

it will look like this (setting of an existing papersize in the printer DEVMODE) :
http://www.efg2.com/Lab/Library/UseNet/2000/0526c.txt

here is also a code I found to add custom paper size, in C. I will try to convert it in Delphi
FORM_INFO_1 form1;
FORM_INFO_1 *pForm = NULL;
HANDLE hPrinter;
DWORD cByteNeeded, nReturned, cByteUsed;
SIZEL sz;
RECTL rc;
int i;

// récupération du handle sur l'imprimante
if (!OpenPrinter("HP DeskJet 1200C",&hPrinter,NULL))
return NULL;
// Récupére la quantité de mémoire à allouer
EnumForms(hPrinter, 1,
NULL,0,(LPDWORD)&cByteNeeded,(LPDWORD)&nReturned);

// allocation
pForm = (FORM_INFO_1 *)malloc(cByteNeeded);
ZeroMemory(pForm, cByteNeeded);

// remplit pForm avec l'ensemble des formats
EnumForms(hPrinter,1,(LPBYTE)pForm, cByteNeeded, (LPDWORD)&cByteUsed,
(LPDWORD)&nReturned);

// affichage du nom du format
for (i=0;i<nReturned;i++)
printf("%s\n",pForm.pName);

// désallocation
free(pForm);

// ajout d'un nouveau format
ZeroMemory(&form1, sizeof(FORM_INFO_1));
form1.Flags = FORM_USER;
form1.pName ="mon format";
sz.cx = 215900;
sz.cy = 279400;
rc.left = 0;
rc.top = 0;
rc.bottom = 279400;
rc.right = 215900;
form1.Size = sz;
form1.ImageableArea =rc;
AddForm(hPrinter,1,(LPBYTE)&form1);

// fermeture
ClosePrinter(hPrinter);

Open in new window

0
 
LVL 25

Accepted Solution

by:
epasquier earned 500 total points
ID: 36522136
Here you go :
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    cbPrinters: TComboBox;
    lbPages: TListBox;
    GroupBox1: TGroupBox;
    edtFormWidth: TSpinEdit;
    edtFormHeight: TSpinEdit;
    btnAddForm: TButton;
    edtFormName: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure cbPrintersChange(Sender: TObject);
    procedure btnAddFormClick(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Uses Winspool,Printers;

procedure ListPrinterForms(PrinterName:String;L:TStrings);
var
  HPrinter: THandle;
  Forms: array of TFormInfo1;
  Count, Needed, Returned: DWORD;
  i: Integer;
begin
 L.BeginUpdate;
 L.Clear;
 if OpenPrinter(PChar(PrinterName), HPrinter, nil) then
  begin
   try
    if not EnumForms(HPrinter, 1, nil, 0, Needed, Returned) then
     begin
      // we should fail here since we didn't pass a buffer
      if GetLastError <> ERROR_INSUFFICIENT_BUFFER then RaiseLastOSError;
      Count := (Needed div SizeOf(TFormInfo1)) + 1;
      SetLength(Forms, Count);
      if EnumForms(HPrinter, 1, @Forms[0], SizeOf(TFormInfo1) * Count, Needed, Returned) then
       begin
        if Returned < Count then SetLength(Forms, Returned);
        for i := 0 to Returned - 1 do
         begin
          L.Add(Format('%s - %dmm x %dmm', [Forms[i].pName,Forms[i].Size.cx div 1000,Forms[i].Size.cy div 1000]))
         end;
       end else RaiseLastOSError;
     end;
  finally
   ClosePrinter(HPrinter);
  end;
 end else RaiseLastOSError;
 L.EndUpdate;
end;

procedure AddPrinterForm(PrinterName,FormName:String;Width,Height:Integer;
                  MarginLeft:Integer=0;MarginTop:Integer=0;MarginRight:Integer=0;MarginBottom:Integer=0);
Var
 Form1:TFormInfo1;
 HPrinter: THandle;
 Size: TSize;
 ImageableArea: TRect;
begin
 if OpenPrinter(PChar(PrinterName), HPrinter, nil) then
  try
   ZeroMemory(@Form1, sizeof(Form1));
   form1.Flags := FORM_USER;
   form1.pName := PChar(FormName);
   Size.cx := Width;
   Size.cy := Height;
   ImageableArea.left  := MarginLeft;
   ImageableArea.top   := MarginTop;
   ImageableArea.right := Width-MarginRight;
   ImageableArea.bottom:= Height-MarginBottom;
   form1.Size := Size;
   form1.ImageableArea :=ImageableArea;
   AddForm(hPrinter,1,@Form1);
  finally
   ClosePrinter(HPrinter);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 cbPrinters.Items.Assign(Printer.Printers);
end;

procedure TForm1.btnAddFormClick(Sender: TObject);
begin
 AddPrinterForm(cbPrinters.Text,edtFormName.Text,edtFormWidth.Value,edtFormHeight.Value);
 ListPrinterForms(cbPrinters.Text,lbPages.Items);
end;

procedure TForm1.cbPrintersChange(Sender: TObject);
begin
 if cbPrinters.ItemIndex<0 then Exit;
 ListPrinterForms(cbPrinters.Text,lbPages.Items);
end;

end.

// DFM
object Form1: TForm1
  Left = 0
  Top = 0
  AutoSize = True
  BorderWidth = 8
  Caption = 'Form1'
  ClientHeight = 393
  ClientWidth = 218
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object cbPrinters: TComboBox
    Left = 0
    Top = 0
    Width = 218
    Height = 21
    Style = csDropDownList
    TabOrder = 0
    OnChange = cbPrintersChange
  end
  object lbPages: TListBox
    Left = 0
    Top = 27
    Width = 217
    Height = 278
    ItemHeight = 13
    TabOrder = 1
  end
  object GroupBox1: TGroupBox
    Left = 0
    Top = 311
    Width = 217
    Height = 82
    Caption = 'New Form Name'
    TabOrder = 2
    object edtFormWidth: TSpinEdit
      Left = 9
      Top = 52
      Width = 65
      Height = 22
      MaxValue = 0
      MinValue = 0
      TabOrder = 0
      Value = 0
    end
    object edtFormHeight: TSpinEdit
      Left = 80
      Top = 52
      Width = 65
      Height = 22
      MaxValue = 0
      MinValue = 0
      TabOrder = 1
      Value = 0
    end
    object btnAddForm: TButton
      Left = 159
      Top = 49
      Width = 50
      Height = 25
      Caption = 'Add'
      TabOrder = 2
      OnClick = btnAddFormClick
    end
    object edtFormName: TEdit
      Left = 8
      Top = 24
      Width = 201
      Height = 21
      MaxLength = 31
      TabOrder = 3
    end
  end
end

Open in new window

0
 
LVL 25

Expert Comment

by:epasquier
ID: 36522151
Note that in my sample application, I do not set the margin of the paper, but the AddPrinterForm procedure can handle it.
0
 

Author Closing Comment

by:bytecook
ID: 36522254
Many thanks epasquier!

All the best,

Peter
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

734 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