Set Printer Source or Tray and Change Printer.Orientation

Please discuss general Delphi programming topics here.

Set Printer Source or Tray and Change Printer.Orientation

Postby w2m » May 18th, 2008, 5:33 pm

After searching the internet for 2 days I am unable to create any code that sets a printers source or bin. Why doesn't this work? The code executes but does not change the bin?

Code: Select all
procedure SetPaperBin( PrtrName: string; Bin: word );
var
  hndPrinter: Thandle;
  BuffSize: integer;
  PtrPrtrInfo2: PPrinterInfo2;
begin
  OpenPrinter( PChar( PrtrName ), hndPrinter, nil );
  {get size of buffer for printer info 2}
  GetPrinter( hndPrinter, 2, nil, 0, @BuffSize );
  PtrPrtrInfo2 := AllocMem( BuffSize );
  {get printer info 2 ...}
  GetPrinter( hndPrinter, 2, PtrPrtrInfo2, BuffSize, @BuffSize );
  {... change bin if selected bin <> current bin}
  if ( PtrPrtrInfo2^.pDevMode^.dmDefaultSource <> Bin ) then
  begin
    PtrPrtrInfo2^.pDevMode^.dmDefaultSource := Bin;
    WinSpool.SetPrinter( hndPrinter, 2, PtrPrtrInfo2, 0 );
  end;
  ClosePrinter( hndPrinter );
  FreeMem( PtrPrtrInfo2 );
end;


This code adds the tray codes to a stringlist
Code: Select all
procedure GetDriverInfo(Sender : TObject; BinInfo : tStringList); // call this to get the driver information
var
  I: Integer;
begin
    MemAllocations_Open(Sender);
    if not assigned(fPrinter) then exit;
    // this call returns the FDevice string of the selected printer
    Printer.GetPrinter(FDevice, FDriver, FPort, DeviceMode);
    DevMode := GlobalLock(DeviceMode);

    GetMem(Driver_info_2, 1000);
    try
      OpenPrinter(FDevice, hPrinter, nil);
      try
        GetPrinterDriver(hPrinter, nil, 2, Driver_info_2, 1000, Retrieved);
      except
      end;
    except
    end;

    DeviceCapabilities(FDevice, FPort, DC_BINS, CapBuffer, nil);
    // Bin names
    NumCaps := DeviceCapabilities(FDevice, FPort, DC_BINNAMES, CapBuffer, nil);
    copymemory( pointer(binnames), capbuffer, 2400);
    SetLength(BinCodes, NumCaps);
    Fillchar(Pointer(BinCodes)^, NumCaps * Sizeof(word), #0);
    // Bin codes
    NumCaps := DeviceCapabilities(FDevice, FPort, DC_BINS, PChar(BinCodes), nil);

    // write valid bin codes to the string list
    for I := 0 to NumCaps - 1 do
    begin
      if trim(binnames[i]) <> '' then begin
        BinInfo.Add(binnames[i] + format( ': (%d)', [BinCodes[I]]));
      end;
    end;

    // clean it all up
    FreeMem(Driver_info_2, 255);
    globalunlock( devicemode);
    MemAllocations_Close(Sender);
end;


This selects a tray ok, but it does not change the Printer.Orientation.
Code: Select all
procedure ChangePrinter(ToBin: Integer; ToOrientation: TPrinterOrientation);
var
  ADevice, ADriver, APort: array [0..255] of Char;
  DeviceHandle: THandle;
  DevMode: PDeviceMode; // A Pointer to a TDeviceMode structure
begin
  { First obtain a handle to the TPrinter's DeviceMode structure }
  Printer.GetPrinter(ADevice, ADriver, APort, DeviceHandle);
  { If DeviceHandle is still 0, then the driver was not loaded. Set
    the printer index to force the printer driver to load making the
    handle available }
  if DeviceHandle = 0 then
  begin
    Printer.PrinterIndex := Printer.PrinterIndex;
    Printer.GetPrinter(ADevice, ADriver, APort, DeviceHandle);
  end;
  { If DeviceHandle is still 0, then an error has occurred. Otherwise,
    use GlobalLock() to get a pointer to the TDeviceMode structure }
  if DeviceHandle = 0 then
    Raise Exception.Create('Could Not Initialize TDeviceMode structure')
  else
    DevMode := GlobalLock(DeviceHandle);
    with DevMode^ do
    begin
      dmFields := DM_DEFAULTSOURCE;
      dmDefaultSource := ToBin;
    end;
  Printer.Orientation := ToOrientation;
  if not DeviceHandle = 0 then
    GlobalUnlock(DeviceHandle);
end;


My question is is there a better method that can set a printer tray and Printer.Orientation at the same time?
w2m
w2m
Senior Member
Senior Member
 
Posts: 76
Joined: March 8th, 2003, 7:11 pm
Location: New York, USA

Postby Kambiz » May 19th, 2008, 8:13 am

This should work.

Code: Select all
procedure ChangePrinter(ToBin: Integer; ToOrientation: TPrinterOrientation);
var
  ADevice, ADriver, APort: array [0..255] of Char;
  DeviceHandle: THandle;
  DevMode: PDeviceMode; // A Pointer to a TDeviceMode structure
begin
  { First obtain a handle to the TPrinter's DeviceMode structure }
  Printer.GetPrinter(ADevice, ADriver, APort, DeviceHandle);
  { If DeviceHandle is still 0, then the driver was not loaded. Set
    the printer index to force the printer driver to load making the
    handle available }
  if DeviceHandle = 0 then
  begin
    Printer.PrinterIndex := Printer.PrinterIndex;
    Printer.GetPrinter(ADevice, ADriver, APort, DeviceHandle);
  end;
  { If DeviceHandle is still 0, then an error has occurred. Otherwise,
    use GlobalLock() to get a pointer to the TDeviceMode structure }
  if DeviceHandle = 0 then
    Raise Exception.Create('Could Not Initialize TDeviceMode structure')
  DevMode := GlobalLock(DeviceHandle);
  try
    with DevMode^ do
    begin
      dmFields := DM_DEFAULTSOURCE or DM_ORIENTATION;
      dmDefaultSource := ToBin;
      case ToOrientation of
        poPortrait: dmOrientation := DMORIENT_PORTRAIT;
        poLandscape: dmOrientation := DMORIENT_LANDSCAPE;
      end;
    end;
  finally
    GlobalUnlock(DeviceHandle);
  end;
end;
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Postby w2m » May 19th, 2008, 1:23 pm

Thank-you
w2m
w2m
Senior Member
Senior Member
 
Posts: 76
Joined: March 8th, 2003, 7:11 pm
Location: New York, USA


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron