home *** CD-ROM | disk | FTP | other *** search
- {'Printer Preview' .Pas Module.
-
- CopyRight Belmont Imaging 1996.
-
- Demo Program by :- Andrew Hutchison 100022,1047@Compuserve.com
-
- All rights reserved. No part of this program may be photocopied, reproduced,
- translated to another programming language or transported to any computer system
- without the prior written consent of Belmont Imaging.
-
- This Demo is provided for use by Media Architects in there Delphi Demo's only.
- The unit must not be re-used without the permission of Media Architects or Belmont
- Imaging. Copyright Belmont Imaging 1996. It is supplied AS-IS. Use at your
- own risk.}
-
-
- unit UPrntPvw;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- ExtCtrls, OleCtrls, ImageKnife32, Printers, Buttons, StdCtrls, ComCtrls,
- Spin;
-
- type
- TTE_PrintPreview = class(TForm)
- TE_PP_Paper_Boundary: TPanel;
- TE_PP_PPrint: TPrintDialog;
- TE_PP_PSetup: TPrinterSetupDialog;
- TE_PP_Paper: TPanel;
- TE_PP_PreviewImage: TPicbuf;
- TE_PP_Location_Group: TGroupBox;
- TE_PP_Label_2: TLabel;
- TE_PP_Label_1: TLabel;
- TE_PP_Label_3: TLabel;
- TE_PP_Label_4: TLabel;
- TE_PP_Label_ImageTop: TLabel;
- TE_PP_Label_ImageLeft: TLabel;
- TE_PP_Label_ImageWidth: TLabel;
- TE_PP_Label_ImageHeight: TLabel;
- TE_PP_Print_Group: TGroupBox;
- TE_PP_Print_Icon: TSpeedButton;
- TE_PP_PrintSetup_Icon: TSpeedButton;
- TE_PP_Copies: TSpinEdit;
- Label1: TLabel;
- TE_PP_Header: TLabel;
- TE_PP_Footer: TLabel;
- TE_PP_Caption: TLabel;
- TE_PP_Captions: TGroupBox;
- TE_PP_HeaderText: TEdit;
- TE_PP_CaptionText: TEdit;
- TE_PP_FooterText: TEdit;
- TE_PP_HeaderText_Check: TCheckBox;
- TE_PP_CaptionText_Check: TCheckBox;
- TE_PP_FooterText_Check: TCheckBox;
- TE_PP_QuickPrint_Icon: TSpeedButton;
- Label2: TLabel;
- Label3: TLabel;
- Label4: TLabel;
- TE_PP_Font: TFontDialog;
- TE_PP_PrinterFont_Icon: TSpeedButton;
- TE_PP_Reset: TSpeedButton;
- LoadButton: TSpeedButton;
- procedure FormCreate(Sender: TObject);
- procedure FormActivate(Sender: TObject);
- procedure TE_PP_PreviewImageMouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- procedure TE_PP_PreviewImageMouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- procedure TE_PP_PrintSetup_IconClick(Sender: TObject);
- procedure TE_PP_Print_IconClick(Sender: TObject);
- procedure TE_PP_Caption_Down(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure TE_PP_Caption_Move(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
- procedure TE_PP_QuickPrint_IconClick(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure TE_PP_PrinterFont_IconClick(Sender: TObject);
- procedure TE_PP_ResetClick(Sender: TObject);
- procedure LoadButtonClick(Sender: TObject);
- private
- {Private declarations }
-
- {Make Sure Paper View Stays within Bounds of Form}
- procedure CheckandScale;
-
- {Update Print Location Labels}
- procedure UpdateLabels;
-
- {Print Captions}
- procedure PrintCaptions;
-
- public
- {Public declarations}
-
- {Used to Hold Global Print Location Values}
- PrintImageHeight,PrintImageWidth,PrintImageLeft,PrintImageTop:Integer;
- end;
-
- var
- TE_PrintPreview: TTE_PrintPreview;
-
- {Variables - This Unit}
- PrinterXres,PrinterYres,PrinterPageX,PrinterPageY,OffsetMouseX,OffsetMouseY,
- MouseDragDownX,MouseDragDownY,ExceedHeight,ExceedWidth:Integer;
- RatioXY,CorrectionRatio:Real;
-
- implementation
-
- uses UPBDISK;
- {$R *.DFM}
-
- {--------------------------------------------------------------------------------}
- {Creation - Set areas and sizes in case someone does not use the Preview Screen,
- in effect these are the 'Design Time Defaults'}
- procedure TTE_PrintPreview.FormCreate(Sender: TObject);
- begin
- Application.HintPAuse:=10;
- Application.HintColor:=clAqua;
- {Do an update by forcing an form 'Activate Event' - See Below}
- TE_PrintPreview.FormActivate(Sender);
- end;
-
- {--------------------------------------------------------------------------------}
- {Set Paper Area and Size to Reflect Printer Paper Size. When the Activate event
- is called use API calls to get the current settings for the installed default
- Printers. Store the results in global variables. Note the division by 25.4 this
- is for conversion from inches to metric mm's. All Paper View are updated within
- the 'CheckandScale' procedure - See Below}
- procedure TTE_PrintPreview.FormActivate(Sender: TObject);
- begin
- PrinterXres:= round((GetDeviceCaps(Printer.Handle,LOGPIXELSX))/25.4); {DPI}
- PrinterYres:= round((GetDeviceCaps(Printer.Handle,LOGPIXELSY))/25.4); {DPI}
- PrinterPageX:=GetDeviceCaps(Printer.Handle,HORZSIZE); {Paper Size}
- PrinterPageY:=GetDeviceCaps(Printer.Handle,VERTSIZE); {Paper Size}
- CheckandScale;{See Below - Size 'Preview Paper' to printer paper size}
- end;
-
- {--------------------------------------------------------------------------------}
- {Make Sure Preview Paper View Stays within form Bounds - Set Preview Paper
- view to size and location. Refering to the main form the 'paper area' is named
- 'TE_PP_Paper', the blue background area is called 'TE_PP_Paper_Boundary'. Basically
- waht the following procedure does is to size the 'Paper area' to reflect the size
- of the installed printers page. The API calls above return the Printers Page
- Width - X and Height - Y in Pixels. All that is required is to set the TE_PP-Paper
- width and Height to the same dimensions - no conversion is required since Delphi
- forms are sized in pixel units as well. The reason for the additional code below
- is because we wish to limit the size of the 'Preview Screen'. If we did not do this
- then printers supporting large paper sizes, would cause the preview window to fill
- your monitor. This is the reason for having the TE_PP_Paper_Boundary area. What we
- do is check to see if the sized preview paper exceeds this blue area, if it does
- we apply a scale factor to the Paper Size so it does not exceed the Blue area. In
- reality you will find the only paper sizes above A3 will require scaleing. Sizes
- less than this will fit the area.}
- procedure TTE_PrintPreview.CheckandScale;
- Var
- HeightDifference,WidthDifference:Integer;
- begin
-
- {With/Height - No correction required - default - papaer smaller than boundary}
- TE_PP_Paper.Height := PrinterPageY; {Set Paper Area to PrinterPageY - API}
- TE_PP_Paper.Width := PrinterPageX ; {Set Paper Area to PrinterPageY - API}
- CorrectionRatio := 1;{No Correction required so set global ratio to 1}
-
- {Find Out if the Preview Paper needs shrunk to fit blue boundary area - height}
- If PrinterPageY > TE_PP_Paper_Boundary.Height then {Printer does exceed boundary}
- HeightDifference:= PrinterPageY - TE_PP_Paper_Boundary.Height {Store the Excess}
- else
- HeightDifference:= 0; {As Defualt no Height Difference}
-
- {Find Out if the Preview Paper needs shrunk to fit blue boundary area - Width}
- If PrinterPageX > TE_PP_Paper_Boundary.Width then {Printer does exceed boundary}
- WidthDifference := PrinterPageX - TE_PP_Paper_Boundary.Width
- else
- WidthDifference := 0; {As Defualt no width Difference}
-
- {Scale Preview Image depending on which value above is the Largest - use which
- ever is the larger of the above to scale the 'paper' area}
-
- {Height the largest}
- If HeightDifference > WidthDifference then
- begin
- {How Much does the Printer Excced the Height}
- ExceedHeight := PrinterPageY - TE_PP_Paper_Boundary.Height;
- {Set the Paper Height to the Max Possible ie boundary height}
- TE_PP_Paper.Height := TE_PP_Paper_Boundary.Height;
- {Scale the Width to the same RATIO as the new Height/Actual Height}
- TE_PP_Paper.Width := TE_PP_Paper_Boundary.Width - ((ExceedHeight * TE_PP_Paper.Height) div
- TE_PP_Paper.Width);
- {Store Scale Ratio so we can correctly print the Image}
- CorrectionRatio:= PrinterPageY / TE_PP_Paper.Height;
- end;
-
- {As above}
- {Width the largest}
- If WidthDifference > HeightDifference then
- begin
- ExceedWidth := PrinterPageX - TE_PP_Paper_Boundary.Width;
- TE_PP_Paper.Width := TE_PP_Paper_Boundary.Width;
- TE_PP_Paper.Height := TE_PP_Paper.Height - ((ExceedWidth * TE_PP_Paper.Height) div
- TE_PP_Paper.Width);
- {Store Scale Ratio}
- CorrectionRatio:= PrinterPageX / TE_PP_Paper.Width;
- end;
-
- {Centre Paper View to Resulting Size and Location. All we do here is to make sure
- the Paper Area appears at the middle of the blue boundary area.}
- TE_PP_Paper.Top:=(TE_PP_Paper_Boundary.Height div 2) - (TE_PP_Paper.Height div 2);
- TE_PP_Paper.Left:=(TE_PP_Paper_Boundary.Width div 2) - (TE_PP_Paper.Width div 2);
-
- {Set Print Location Globals and Apply to 'Picbuf Image' - TE_PP_PreviewImage is the
- name of the Picbuf Control - it is this Image that is printed on the paper. Note:-
- you are setting the Globals to the Size and Location of the Picbuf Image. Since
- all units are in Pixels then all that is required is to use the Picbufs Top, Left
- Width, and Height Properties. Notice how we apply the Correction Ratio then Multipy
- the result by the Printers DPI value. This results in the correct Image Size and
- Location when printed.}
- with TE_PP_PreviewImage do{Reference the Picbuf}
- begin{Start With}
- PrintImageHeight := round((Height * CorrectionRatio) * PrinterYres);
- PrintImageWidth := round((Width * CorrectionRatio)* PrinterXres);
- PrintImageLeft := round ((Left * CorrectionRatio) * PrinterXres); { ADD CORRECTION FACTOR }
- PrintImageTop := round ((Top * CorrectionRatio)* PrinterYres); { ADD CORRECTION FACTOR }
- end;{End With}
-
- {Update Labels}
- UpdateLabels;{See Below - Basically this gets the Location of the Labels and
- correctly locates them on the finished page}
- end;
-
- {--------------------------------------------------------------------------------}
- {Get Mouse Down Locations - Used for Moving the Picture around the Screen}
- procedure TTE_PrintPreview.TE_PP_PreviewImageMouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- with sender as TPicbuf do
- begin
- OffsetMouseX := (Width - X);{Calculates the X/Y location relative to Objects 0,0}
- OffsetMouseY := (Height - Y);
- RatioXY := (Height / Width); {Used so user can Size Image}
- MouseDragDownX := X; {Store X for MouseDown location}
- MouseDragDownY := Y; {Store Y for MouseDown location}
- end;
- end;
-
- {--------------------------------------------------------------------------------}
- {Move and Size Image}
- procedure TTE_PrintPreview.TE_PP_PreviewImageMouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- begin
- With Sender as TPicbuf do {Reference Picbuf}
- begin
- if ssLeft in Shift then {Left button moves Image}
- begin {End Left Loop}
- Top := Top - (MouseDragDownY - Y);
- Left:= Left -(MouseDragDownX - X);
- end; {End Left Loop}
- if ssRight in Shift then {Right and Shift Sizes Image}
- begin
- if ssShift in Shift then
- begin
- if (X + (OffsetmouseX)) < 10 then Exit;
- if round((Width * RatioXY)) < 10 then exit;
- Width := (X + (OffsetmouseX)); {Set Height}
- Height := round((Width * RatioXY)); {Set Width based on ratio}
- end {End Shift}
- else
- begin
- if (X + (OffsetmouseX)) < 10 then Exit;
- if (Y + (OffsetMouseY)) < 10 then Exit;
- Width := (X + (OffsetmouseX)); {Set Height}
- Height:= (Y + (OffsetmouseY)); {Set Width - no Set Ratio}
- end;
- end;
- {Update Labels}
- UpdateLabels; {Update Location Labels}
- end;
- end;
-
- {--------------------------------------------------------------------------------}
- {Update Print Location Labels - Just use the Labels Location * Correction Ration}
- procedure TTE_PrintPreview.UpdateLabels;
- begin
- with TE_PrintPreview.TE_PP_PreviewImage do {Reference Picbuf}
- begin
- TE_PrintPreview.TE_PP_Label_ImageHeight.Caption := inttostr(round((Height * CorrectionRatio)));
- TE_PrintPreview.TE_PP_Label_ImageWidth.Caption := inttostr(round((Width * CorrectionRatio)));
- TE_PrintPreview.TE_PP_Label_ImageTop.Caption := inttostr(round((Top * CorrectionRatio)));
- TE_PrintPreview.TE_PP_Label_ImageLeft.Caption := inttostr(round((Left * CorrectionRatio)));
- end;
- end;
-
- {--------------------------------------------------------------------------------}
- {Print Options - Display 'Printer Setup' Common Dialog Control}
- procedure TTE_PrintPreview.TE_PP_PrintSetup_IconClick(Sender: TObject);
- begin
- TE_PP_PSetup.execute;
- {After it has executed, force Paper Display to update itself - in case a new Printer
- has been picked by the user}
- TE_PrintPreview.FormActivate(Sender); {Recall Activate method}
- end;
-
- {--------------------------------------------------------------------------------}
- {Print Image - This does the Printing}
- procedure TTE_PrintPreview.TE_PP_Print_IconClick(Sender: TObject);
- Var
- CopyCount:Integer;
- begin
- if TE_PP_PreviewImage.contents <> 1 then exit; {No Image Exit}
-
- {Update user copies - Update Copies number in dialog control}
- TE_PP_PPrint.Copies := TE_PP_Copies.Value;
-
- {User Select Print ie 'OK'}
- if TE_PP_PPrint.Execute then
- begin
- Application.ProcessMessages;
-
- {Update Copy Display on main form to Dialog Copy Count}
- TE_PP_Copies.Value := TE_PP_PPrint.Copies;
-
- {Update View Screen in case user altered anything}
- TE_PrintPreview.FormActivate(Sender);
-
- {Set Locations - use our derived location and set Picbuf's properties to them}
- TE_PP_PreviewImage.PrintHeight:=PrintImageHeight;
- TE_PP_PreviewImage.PrintWidth:=PrintImageWidth;
- TE_PP_PreviewImage.PrintLeft:=PrintImageLeft;
- TE_PP_PreviewImage.PrintTop:=PrintImageTop;
- Application.ProcessMessages;
- {Set up a loop equal to the number of copies required}
- for CopyCount := 1 to TE_PP_Copies.Value do {Edit Box Value}
- begin
- {Start Process}
- Printer.BeginDoc;
- {Set Caption Locations and Print}
- PrintCaptions;{See Below - Set Labels to location and then print text}
- TE_PP_PreviewImage.PrinterHDC:=Printer.Handle; {Do Print}
- Printer.Enddoc; {End Print}
- end;
- end;
- end;
-
- {--------------------------------------------------------------------------------}
- {Print Captions - Header / Caption / Footer. Same rules as above. Get labels
- locations, adjust to Ratio if required, then output text to printer.}
- procedure TTE_PrintPreview.PrintCaptions;
- Var
- TextX,TextY : integer;
- begin
- {Set Printer Font}
- Printer.Canvas.Font:= TE_PP_Font.Font; {Get Font from Common Dialogue Control}
- {Header Label}
- if TE_PP_HeaderText_Check.Checked then
- begin
- TextX:= trunc(((TE_PP_Header.Left * CorrectionRatio) * PrinterXres)) ;
- TextY:= trunc(((TE_PP_Header.Top * CorrectionRatio) * PrinterYres));
- Printer.Canvas.TextOut(TextX, TextY, TE_PP_HeaderText.Text); {Print Text}
- end;
- {Caption}
- if TE_PP_CaptionText_Check.Checked then
- begin
- TextX:= trunc (((TE_PP_Caption.Left * CorrectionRatio) * PrinterXres)) ;
- TextY:= trunc(((TE_PP_Caption.Top * CorrectionRatio) * PrinterYres)) ;
- Printer.Canvas.TextOut(TextX, TextY, TE_PP_CaptionText.Text); {Print Text}
- end;
- {Footer}
- if TE_PP_FooterText_Check.Checked then
- begin
- TextX:= trunc (((TE_PP_Footer.Left * CorrectionRatio) * PrinterXres)) ;
- TextY:= trunc(((TE_PP_Footer.Top * CorrectionRatio) * PrinterYres)) ;
- Printer.Canvas.TextOut(TextX, TextY,TE_PP_FooterText.Text); {Print Text}
- end;
- end;
-
-
- {--------------------------------------------------------------------------------}
- {Caption Moves - One event does Header,Footer and Caption. Tie all label events to
- one procedure}
- procedure TTE_PrintPreview.TE_PP_Caption_Down(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- with Sender as TLabel do
- begin
- MouseDragDownX := X;
- MouseDragDownY := Y;
- end;
- end;
-
- {--------------------------------------------------------------------------------}
- {Caption Moves - One event does Header,Footer and Caption}
- procedure TTE_PrintPreview.TE_PP_Caption_Move(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- begin
- With Sender as TLabel do {Reference Sending Label}
- begin
- if ssLeft in Shift then
- begin {End Left Loop}
- Top := Top - (MouseDragDownY - Y);
- Left:= Left -(MouseDragDownX - X);
- end; {End Left Loop}
- end;
- end;
-
- {--------------------------------------------------------------------------------}
- {Quick Print - 1 Copy. Simply calls activate to update screen in case of any
- alterations, then prints single copy, with default printer [last] settings}
- procedure TTE_PrintPreview.TE_PP_QuickPrint_IconClick(Sender: TObject);
- begin
- {Update Screen In case user altered anything}
- TE_PrintPreview.FormActivate(Sender);
- {Set Locations}
- TE_PP_PreviewImage.PrintHeight:=PrintImageHeight;
- TE_PP_PreviewImage.PrintWidth:=PrintImageWidth;
- TE_PP_PreviewImage.PrintLeft:=PrintImageLeft;
- TE_PP_PreviewImage.PrintTop:=PrintImageTop;
- Printer.BeginDoc;
- {Set Caption Locations and Print}
- PrintCaptions;{See Above}
- TE_PP_PreviewImage.PrinterHDC:=Printer.Handle;
- Printer.Enddoc;
- end;
-
- {--------------------------------------------------------------------------------}
- {Empty Preview Image on Exit}
- procedure TTE_PrintPreview.FormClose(Sender: TObject;
- var Action: TCloseAction);
- begin
- TE_PP_PreviewImage.Clear;
- end;
-
- {--------------------------------------------------------------------------------}
- {Set Printer Font}
- procedure TTE_PrintPreview.TE_PP_PrinterFont_IconClick(Sender: TObject);
- begin
- TE_PP_Font.Execute; {Show font common dialogue box}
- end;
-
- {--------------------------------------------------------------------------------}
- {Home Labels and Refresh - This simply aligns the object on the preview page to
- the upper left hand area - stops the controls getting lost if you swap between
- paper sizes}
- procedure TTE_PrintPreview.TE_PP_ResetClick(Sender: TObject);
- begin
- TE_PP_Header.Top := 15;
- TE_PP_Header.Left := 15;
- TE_PP_Caption.Top := 30;
- TE_PP_Caption.Left:= 15;
- TE_PP_PreviewImage.Top := 50;
- TE_PP_PreviewImage.LEft := 15;
- TE_PP_Footer.Top := 145;
- TE_PP_Footer.Left := 15;
- {Update Screen in case user altered anything}
- TE_PrintPreview.FormActivate(Sender);
- end;
-
-
- {-------------------------------------------------------------------------------}
- {For MAI Demo only allow user to load Image into Print Preview from Disk. Use
- Custom I/O 'BI' Disk Control. Note:- You call the I/O dialog with a 'ShowModal'.}
- procedure TTE_PrintPreview.LoadButtonClick(Sender: TObject);
- begin
- {Uses Hybrid I/O Control called PB_DiskControl32V1}
- If PB_DiskControl32V1.ShowModal = MrOK then
- begin
- Application.Processmessages; {Catch Up}
- TE_PP_PreviewImage.FileName:=PB_DiskControl32V1.FileName; {Set Name}
- TE_PP_PreviewImage.Load; {Load Image}
- end;
- end;
-
- end.
-