Solved

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

Posted on 2011-09-11
7
977 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
  • 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
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 
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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
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 …

803 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