Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Printer bin selection not working

88 views
Skip to first unread message

Avatar Zondertau

unread,
Nov 9, 2005, 4:59:18 AM11/9/05
to
Hi all,

I'm trying to let my program select the paper tray for printing using
the global Printer object. Reading the API documentation and finding
code samples on the internet i make some functions that i hoped would
be able to do this. The code does not give any error messages, but
doesn't select the correct paper tray either; it remains on automatic
selection (which is the default).

The testing code is below this message.

The results returned by PrinterBinList and PrinterBinGetIndex are
correct. I am also certain that 'Lade 2' is the one i want; i tested
this from Word. I'm also sure that the printer index is correct, since
the program does print the page on the correct printer, though not from
the correct paper tray.

The SetPrinter in PrinterBinSelect with DevMode zero was suggested
somewhere on the internet; it doesn't seem to have any effect though.

Does anyone know what may be wrong with the PrinterBinSelect procedure?

Tanks in advance.

uses
Printers, WinSpool;

procedure PrinterBinList(const PrinterName: string; Bins: TStrings);
const
BIN_NAME_LENGTH = 24;
var
BinName: string;
Buffer: PChar;
Count, I: Integer;
begin
Count := DeviceCapabilities(PChar(PrinterName), nil, DC_BINNAMES,
nil,
nil);
Win32Check(Count >= 0);

GetMem(Buffer, Count * BIN_NAME_LENGTH);
try
Count := DeviceCapabilities(PChar(PrinterName), nil, DC_BINNAMES,

Buffer, nil);
Win32Check(Count >= 0);

for I := 0 to Count - 1 do
begin
SetString(BinName, Buffer + I * BIN_NAME_LENGTH, BIN_NAME_LENGTH);
SetLength(BinName, StrLen(PChar(BinName)));
Bins.Add(BinName);
end;
finally
FreeMem(Buffer);
end;
end;

function PrinterBinGetIndex(const PrinterName, BinName: string):
SmallInt;
var
Count, I: Integer;
Names: TStringList;
Numbers: array of SmallInt;
begin
Names := TStringList.Create;
try
PrinterBinList(PrinterName, Names);

SetLength(Numbers, Names.Count);
Count := DeviceCapabilities(PChar(PrinterName), nil, DC_BINS,
@Numbers[1], nil);
Win32Check(Count >= 0);

Result := DMBIN_AUTO;
for I := 0 to Names.Count - 1 do
if BinName = Names[I] then
begin
Result := Numbers[I];
Break;
end;
finally
Names.Free;
end;
end;

procedure PrinterBinSelect(Printer: TPrinter; const BinName: string);
var
Device, Driver, Port: array[0..MAX_PATH] of Char;
DeviceMode: PDeviceModeA;
DevMode: HGLOBAL;
Number: SmallInt;
begin
Printer.GetPrinter(@Device, @Driver, @Port, DevMode);
Printer.SetPrinter(@Device, @Driver, @Port, 0);
Printer.GetPrinter(@Device, @Driver, @Port, DevMode);

Number := PrinterBinGetIndex(Device, BinName);
if Number < 0 then
raise Exception.CreateFmt('Cannot find printer tray: "%s" on ' +
'printer "%s"', [BinName, Device]);

DeviceMode := GlobalLock(DevMode);
try
DeviceMode^.dmFields := DeviceMode^.dmFields or DM_DEFAULTSOURCE;
DeviceMode^.dmDefaultSource := Number;
finally
GlobalUnlock(DevMode);
end;

Printer.SetPrinter(@Device, @Driver, @Port, DevMode);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Printer.PrinterIndex := 1;
PrinterBinSelect(Printer, 'Lade 2');

Printer.BeginDoc;
try
Printer.Canvas.TextOut(0, 0, 'Testing paper tray selection');
finally
Printer.EndDoc;
end;
end;

Peter Below (TeamB)

unread,
Nov 9, 2005, 2:26:16 PM11/9/05
to
In article <4371d686$1...@newsgroups.borland.com>, Avatar Zondertau wrote:
> I'm trying to let my program select the paper tray for printing using
> the global Printer object. Reading the API documentation and finding
> code samples on the internet i make some functions that i hoped would
> be able to do this. The code does not give any error messages, but
> doesn't select the correct paper tray either; it remains on automatic
> selection (which is the default).
>
> The testing code is below this message.

Try to remove the SetPrinter line at the end of the quoted block below.

> DeviceMode := GlobalLock(DevMode);
> try
> DeviceMode^.dmFields := DeviceMode^.dmFields or DM_DEFAULTSOURCE;
> DeviceMode^.dmDefaultSource := Number;
> finally
> GlobalUnlock(DevMode);
> end;
>
> Printer.SetPrinter(@Device, @Driver, @Port, DevMode);
> end;

--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


Avatar Zondertau

unread,
Nov 10, 2005, 1:32:40 AM11/10/05
to
> > I'm trying to let my program select the paper tray for printing
> > using the global Printer object. Reading the API documentation and
> > finding code samples on the internet i make some functions that i
> > hoped would be able to do this. The code does not give any error
> > messages, but doesn't select the correct paper tray either; it
> > remains on automatic selection (which is the default).
> >
> > The testing code is below this message.
>
> Try to remove the SetPrinter line at the end of the quoted block
> below.

Unfortunately this doesn't seem to fix the problem. The program behaves
as it did before. Thanks for the suggestion though.

Peter Below (TeamB)

unread,
Nov 10, 2005, 2:06:23 PM11/10/05
to
In article <4372f798$1...@newsgroups.borland.com>, Avatar Zondertau wrote:
>
> Unfortunately this doesn't seem to fix the problem. The program behaves
> as it did before. Thanks for the suggestion though.

Well, i can only say that i'm using the following routine successfully
in a program to select a paper tray (mostly the manual feed, in fact) on HP
laser printers...

Procedure SelectPrinterBin( binID: SmallInt );
Var
Device, Driver, Port : array[0..127] of char;
hDeviceMode: THandle;
pDevMode: PDeviceMode;
Begin
With Printer Do Begin
GetPrinter(Device, Driver, Port, hDeviceMode);
pDevMode := GlobalLock( hDevicemode );
If pDevMode <> nil Then
try
With pDevMode^ Do Begin
dmFields := dmFields or DM_DEFAULTSOURCE;
dmDefaultSource := binID;
End; { With }
finally
GlobalUnlock( hDevicemode );
end;
End; { With }
End;

This needs to be done *before* Begindoc, by the way.

0 new messages