trichview.com Forum Index trichview.com
TRichView support forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[RichViewActions] How to access page setup properties

 
Post new topic   Reply to topic    trichview.com Forum Index -> Examples, Demos
View previous topic :: View next topic  
Author Message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Sun Aug 28, 2005 11:26 am    Post subject: [RichViewActions] How to access page setup properties Reply with quote

1) Margins are stored in RVPrint, assigned to RVAControlPanel.RVPrint
2) Properties of header and footer are stored in global objects
RVA_HeaderInfo and RVA_FooterInfo (Text, Alignment, PrintOnFirstPage
properties)
3) Page size, orientation and source are stored in the global for the
application printer settings. They are accessible via global Printer object
(units Printers). Only orientation can be changed easily -
Printer.Orientation.
Other properties can be changed using WinAPI functions:

3.a) Changing paper source

Code:
// make sure that WinSpool is defined after Windows in uses
uses Printers, WinSpool;

type
  TBinName = array [0..23] of Char;
  TBinNames = array [0..1000] of TBinName;
  PBinNames = ^TBinNames;
  TWordArray = array [0..1000] of Word;
  PWordArray = ^TWordArray;


 procedure GetAvailablePaperSources;
  var ADevice, ADriver, APort: array[0..79] of Char;
      ADeviceMode: THandle;
      DevMode: PDeviceMode;
      BinCount: Integer;
      BinNames: PBinNames;
      BinCodes: PWordArray;
  begin
    Printer.GetPrinter(ADevice,ADriver,APort,ADeviceMode);
    if ADeviceMode<>0 then begin
      DevMode := PDeviceMode(GlobalLock(ADeviceMode))
      end
    else
      raise Exception.Create('Error initializing printer');
    BinCount := DeviceCapabilities(ADevice, APort, DC_BINNAMES, nil, DevMode);
    GetMem(BinNames, sizeof(TBinName)*BinCount);
    GetMem(BinCodes, sizeof(Integer)*BinCount);
    try
       DeviceCapabilities(ADevice, APort, DC_BINNAMES, Pointer(BinNames), DevMode);
       DeviceCapabilities(ADevice, APort, DC_BINS, Pointer(BinCodes), DevMode);
       {
          At this point, BinNames[0..BinCount-1] contain names of paper sources,
          BinCodes[0..BinCount-1] contain their codes that can be used in SetPaperSource.
          Store them somewhere.
       }
    finally
      FreeMem(BinNames);
      FreeMem(BinCodes);
    end;
    GlobalUnlock(ADeviceMode);
 end;


 procedure SetPaperSource(PaperSource: Integer);
  var ADevice, ADriver, APort: array[0..79] of Char;
      ADeviceMode: THandle;
      DevMode: PDeviceMode;
  begin
    Printer.GetPrinter(ADevice,ADriver,APort,ADeviceMode);
    if ADeviceMode<>0 then begin
      DevMode := PDeviceMode(GlobalLock(ADeviceMode))
      end
    else
      raise Exception.Create('Error initializing printer');
    DevMode.dmFields := DevMode.dmFields or DM_DEFAULTSOURCE;
    DevMode.dmDefaultSource := PaperSource;
    GlobalUnlock(ADeviceMode);
    Printer.SetPrinter(ADevice,ADriver,APort,ADeviceMode);
  end;


3.b) Paper size

Code:
uses Printers;

  procedure SetPaperSize(PaperSize: Integer);
  var ADevice, ADriver, APort: array[0..79] of Char;
      ADeviceMode: THandle;
      DevMode: PDeviceMode;
  begin
    Printer.GetPrinter(ADevice,ADriver,APort,ADeviceMode);
    if ADeviceMode<>0 then begin
      DevMode := PDeviceMode(GlobalLock(ADeviceMode))
      end
    else
      raise Exception.Create('Error initializing printer');
    DevMode.dmFields := DevMode.dmFields or DM_PAPERSIZE;
    DevMode.dmPaperSize := PaperSize;
    GlobalUnlock(ADeviceMode);
    Printer.SetPrinter(ADevice,ADriver,APort,ADeviceMode);
  end;


You can find a list of available paper sizes in Windows API Help (Delphi
menu: Help | Windows SDK).
Search DEVMODE in the help index, then search for DMPAPER_*** constants.

For example, SetPaperSize(DMPAPER_A4)

Do not forget to call RVPrint.FormatPages after any change in paper sizes.

You can get the current printer's paper size:

Code:
function GetPaperSize: Integer;
var ADevice, ADriver, APort: array[0..79] of Char;
    ADeviceMode: THandle;
    DevMode: PDeviceMode;
begin
  Printer.GetPrinter(ADevice,ADriver,APort,ADeviceMode);
  if ADeviceMode<>0 then begin
    DevMode := PDeviceMode(GlobalLock(ADeviceMode))
    end
  else
    raise Exception.Create('Error initializing printer');
  Result := DevMode.dmPaperSize;
end;


You can see how to get a list of available paper sizes and their names in
the RichViewActions source code (in page setup form)


Last edited by Sergey Tkachenko on Mon Dec 18, 2006 8:44 pm; edited 2 times in total
Back to top
View user's profile Send private message Visit poster's website
marcpleysier



Joined: 13 Aug 2006
Posts: 39

PostPosted: Sun Aug 13, 2006 12:53 pm    Post subject: Reply with quote

Perhaps someting simple and stupid, but...
When runing my editor made from RichViewAction demo, the Page setup menu is not enabled.
So I can't modify printer margins at runtime.
Who to enabled it?
Back to top
View user's profile Send private message Visit poster's website
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Sun Aug 13, 2006 8:50 pm    Post subject: Reply with quote

Place TRVAControlPanel component to the form (if you do not have it already). Place TRVPrint component there. Assign RVAControlPanel1.RVPrint = RVPrint.

(as you can see from the explanations above, some of page setup properties are stored in TRVPrint component; what's why this action is not enabled if RVPrint is not specified)
Back to top
View user's profile Send private message Visit poster's website
Byron Short



Joined: 15 Jun 2006
Posts: 4
Location: Scottsdale, Arizona, USA

PostPosted: Mon Dec 11, 2006 9:40 pm    Post subject: Re: How to access page setup properties Reply with quote

Hi Sergey,

I'm trying to use the example code you gave for getting the list of available bins from the Windows API. So far, I'm just trying to actually load the list of bins, using your "procedure GetAvailablePaperSources", as listed in your post from 27 Aug, 2005.

There were a few typos in the source code you gave which I think I correctly resolved as follows:

1. BinNames and BinCodes were never declared as vars; I declared them as:
BinNames:PBinNames;
BinCodes:PWordArray;

2. Your calls to DeviceCapabilities seem to be short one parameter--I inserted a parameter for ADriver as per the following example:
DeviceCapabilities(ADriver,ADevice,APort,DC_BINNAMES,nil,DevMode);

3. After using GetMem on BinNames and BinCodes, you use FreeMem on "PaperNames" and "PaperCodes", so I changed the FreeMem calls to refer back to BinNames and BinCodes again.

So with those three exceptions, I'm using your code as presented. It all compiles fine. But at start-up, I get an error before the program starts, that I think must be coming from the Windows API.

It comes up in a dialog titled "AFS.exe - Entry Point Not Found" (where AFS.exe is my executable name). The text of the message in the dialog is "The procedure entry point DeviceCapabilitiesA could not be located in the dynamic link library gdi32.dll."

What am I doing wrong? How could it not find a standard dll? Sorry, I must seem brain dead, but I thought I was following your code okay...

THANKS in advance!

--Byron
Back to top
View user's profile Send private message Visit poster's website
Byron Short



Joined: 15 Jun 2006
Posts: 4
Location: Scottsdale, Arizona, USA

PostPosted: Tue Dec 12, 2006 12:57 am    Post subject: Reply with quote

Sergey,

I think I found it...

The clue was that part where DeviceCapabilities asked for one more parameter...I was using the wrong "DeviceCapabilities". Found some documentation searching around the web. It appears that because I called only "DeviceCapabilities", and I had "Windows" in my Uses statement, I was calling "Windows.DeviceCapabilities" which sometime in Windows XP, no longer support DeviceCapabilities. What I needed to do was to put "WinSpool" in my Uses statement, so that I am actualling calling "WinSpool.DeviceCapabilities". To be sure, I explicitly called "WinSpool.DeviceCapabilities" in my code. And now everything works as it should.

I hope this is consistent for all XP? I'm on Professional, and documentation seems to suggest it will work for both, but I guess I'll find out. Any comments?

--Byron
Back to top
View user's profile Send private message Visit poster's website
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Mon Dec 18, 2006 8:43 pm    Post subject: Reply with quote

I corrected errors in the function.
Yes, this function is from WinSpool.
Similar code is used in Delphi VCL itself. And no problems were reported.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    trichview.com Forum Index -> Examples, Demos All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group