home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / kompon / d345 / PPREV.ZIP / BenPreview / PrevForm.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-06-19  |  28.3 KB  |  898 lines

  1. Unit PrevForm;
  2.  
  3. {
  4.    Print Preview
  5.    Version 2.0
  6.    by Ben Ziegler
  7.  
  8.    Updated on:
  9.    - April 11, 1998
  10.    - December 18, 1997
  11.  
  12. TODO:
  13.    Printing in a thread (Refresh Next buttons as new pages come, etc)
  14. {
  15.  
  16. Program Title:           Ben Zeigler's Print Preview Component
  17. Program FileName:        PrevForm.pas
  18. Creation Date:           You'll have to ask Ben
  19. Notes:                   Created by Ben Ziegler (bziegler@Radix.Net)
  20. Required Files:          Requires PrevPrinter & FormSettings & Res files Components
  21. Programming Language:    Delphi 5 now...
  22. Targeted OS:             32-bit calls everywhere -- Win32
  23.  
  24. Version      Date     Programmer        Notes
  25.   2.00     ??????       BZ         Initial release by Ben.
  26.   3.00     ??????       JGW        Initial release by JGW for Delhpi 5.  I have attempted
  27.                               to support several things.  Notably the ability to have
  28.                               landscape and portrait plots at the same time as well as
  29.                               a bounding box-zoom control but didn't succeed.  Mostly, I
  30.                               changed things to be compatable with all of the other code I had,
  31.                               and altered a few things based upon the kind of users I had--they
  32.                               got confused a lot.
  33.   3.01     09Feb01      JGW       Problem:  The original method of drawing was to simply
  34.                               take the metafile created and draw it to the canvas as is.  What
  35.                               happened, however, was that whenever you changed printers, the
  36.                               metafile still had the attributes of the old printer, and even
  37.                               with minor differences, the printouts became inconsistant.  And
  38.                               attempting to simply alter the metafiles was even more inconsistent.
  39.                                   Solution (one of many I'm sure):  Since metafiles are vectored,
  40.                               I will simply use StretchDraw to print the metafile and to view
  41.                               it on the screen.  And since the bounds of the metafile seem to be
  42.                               variable, I picked a happy median that worked.
  43.                                   Fun stuff, windows.
  44.   3.02     05May2001    jgw       Added additional support so that the previewed images can be
  45.                               copied to the clipboard as jpeg's.  This is intended to give support
  46.                               to sharing "pages" over HTML-based email.  Because of this, it now 
  47.                   requires the jpeg support that comes with delphi.  If you don't have
  48.                   it, then comment out all "SaveAsJpeg" support.    
  49.  
  50. }
  51.  
  52. Interface
  53.  
  54. Uses
  55.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  56.   StdCtrls, ExtCtrls, Buttons, PrevPrinter, Menus;
  57.  
  58. Const
  59.   crZoom = 40;
  60.   ZOOMFACTOR = 1.5;
  61.  
  62. Type
  63.   TPreviewForm = Class( TForm )
  64.     ToolBarPanel: TPanel;
  65.     GridBut: TSpeedButton;
  66.     ZoomCursorBut: TSpeedButton;
  67.     HandCursorBut: TSpeedButton;
  68.     OnePageBut: TSpeedButton;
  69.     TwoPageBut: TSpeedButton;
  70.     PrintBut: TButton;
  71.     NextPageBut: TButton;
  72.     PrevPageBut: TButton;
  73.     CloseBut: TButton;
  74.     AboutBut: TButton;
  75.     ZoomBox: TComboBox;
  76.     StatBarPanel: TPanel;
  77.     CurPageLabel: TPanel;
  78.     ZoomLabel: TPanel;
  79.     Panel1: TPanel;
  80.     HintLabel: TLabel;
  81.     MoveButPanel: TPanel;
  82.     FirstPageSpeed: TSpeedButton;
  83.     PrevPageSpeed: TSpeedButton;
  84.     NextPageSpeed: TSpeedButton;
  85.     LastPageSpeed: TSpeedButton;
  86.     PageNumSpeed: TSpeedButton;
  87.     ScrollBox1: TScrollBox;
  88.     ContainPanel: TPanel;
  89.     PagePanel: TPanel;
  90.     PB1: TPaintBox;
  91.     PagePanel2: TPanel;
  92.     PB2: TPaintBox;
  93.     PrintDialog1: TPrintDialog;
  94.     FitPageBut: TSpeedButton;
  95.     FitWidthBut: TSpeedButton;
  96.     SavePicture: TSaveDialog;
  97.     CopyToClipboard: TButton;
  98.     spdNewZoom: TSpeedButton;
  99.     lbXYLoc: TLabel;
  100.     PrinterSetupDialog1: TPrinterSetupDialog;
  101.     CopyToClipboard2: TButton;
  102.     PopupMenu1: TPopupMenu;
  103.     spdMenu: TSpeedButton;
  104.     SaveasEMF1: TMenuItem;
  105.     SaveasJpeg1: TMenuItem;
  106.     N1: TMenuItem;
  107.     CopytoClipboardasEMF1: TMenuItem;
  108.     CopytoClipboardasJpeg1: TMenuItem;
  109.     N2: TMenuItem;
  110.     Close1: TMenuItem;
  111.     Procedure FormCreate( Sender: TObject );
  112.     Procedure CloseButClick( Sender: TObject );
  113.     Procedure FormClose( Sender: TObject; Var Action: TCloseAction );
  114.     Procedure ScrollBox1Resize( Sender: TObject );
  115.     Procedure PBPaint( Sender: TObject );
  116.     Procedure GridButClick( Sender: TObject );
  117.     Procedure FormShow( Sender: TObject );
  118.     Procedure ZoomBoxChange( Sender: TObject );
  119.     Procedure TwoPageButClick( Sender: TObject );
  120.     Procedure NextPageButClick( Sender: TObject );
  121.     Procedure PrevPageButClick( Sender: TObject );
  122.     Procedure FirstPageSpeedClick( Sender: TObject );
  123.     Procedure LastPageSpeedClick( Sender: TObject );
  124.     Procedure ZoomCursorButClick( Sender: TObject );
  125.     Procedure HandCursorButClick( Sender: TObject );
  126.     Procedure PB1MouseDown( Sender: TObject; Button: TMouseButton;
  127.       Shift: TShiftState; X, Y: Integer );
  128.     Procedure PB1MouseMove( Sender: TObject; Shift: TShiftState; X,
  129.       Y: Integer );
  130.     Procedure PB1MouseUp( Sender: TObject; Button: TMouseButton;
  131.       Shift: TShiftState; X, Y: Integer );
  132.     Procedure PrintButClick( Sender: TObject );
  133.     Procedure PageNumSpeedClick( Sender: TObject );
  134.     Procedure OnePageButMouseUp( Sender: TObject; Button: TMouseButton;
  135.       Shift: TShiftState; X, Y: Integer );
  136.     Procedure FitPageButClick( Sender: TObject );
  137.     Procedure FitWidthButClick( Sender: TObject );
  138.     Procedure AboutButClick( Sender: TObject );
  139.     Procedure CopyToClipboardClick( Sender: TObject );
  140.     Procedure FormKeyDown( Sender: TObject; Var Key: Word;
  141.       Shift: TShiftState );
  142.     Procedure FormKeyUp( Sender: TObject; Var Key: Word;
  143.       Shift: TShiftState );
  144.     Procedure lbXYLocClick( Sender: TObject );
  145.     Procedure CopyToClipboard2Click( Sender: TObject );
  146.     procedure spdMenuClick(Sender: TObject);
  147.     procedure SaveasJpeg1Click(Sender: TObject);
  148.   Protected
  149.     RightShiftDown: Boolean;
  150.     LeftShiftDown: Boolean;
  151.     FCurPage: integer;
  152.     OldHint: TNotifyEvent;
  153.     DownX, DownY: integer;
  154.     Moving: boolean;
  155.     MouseOrigin: TPoint;
  156.     PrevPoint: TPoint;
  157.     NewOrigin: TPoint;
  158.     OldOrigin: TPoint;
  159.     MouseDragging: Boolean;
  160.     Aspect: Single;
  161.     Procedure DrawMetaFile( PB: TPaintBox; mf: TMetaFile );
  162.     Procedure OnHint( Sender: TObject );
  163.     Procedure SetCurPage( Val: integer );
  164.     Procedure CheckEnable;
  165.     Property CurPage: integer Read FCurPage Write SetCurPage;
  166.   Public
  167.     Zoom: double;
  168.     PrevPrinterObj: TPreviewPrinter;
  169.   End;
  170.  
  171. Implementation
  172.  
  173. Uses Gopage, Clipbrd, Printers, Jpeg;
  174.  
  175. {$R *.DFM}
  176. {$R GRID.RES}
  177.  
  178. Function MaxInt( Int1, Int2: Integer ): Integer;
  179. Begin
  180.   If Int1 > Int2 Then
  181.     Result := Int1
  182.   Else
  183.     Result := Int2;
  184. End;                                    {MaxInt}
  185.  
  186. Function MinInt( Int1, Int2: Integer ): Integer;
  187. Begin
  188.   If Int1 < Int2 Then
  189.     Result := Int1
  190.   Else
  191.     Result := Int2;
  192. End;                                    {MinInt}
  193.  
  194. Function MaxFloat( Int1, Int2: Single ): Single;
  195. Begin
  196.   If Int1 > Int2 Then
  197.     Result := Int1
  198.   Else
  199.     Result := Int2;
  200. End;                                    {MaxInt}
  201.  
  202. Function MinFloat( Int1, Int2: Single ): Single;
  203. Begin
  204.   If Int1 < Int2 Then
  205.     Result := Int1
  206.   Else
  207.     Result := Int2;
  208. End;                                    {MinInt}
  209.  
  210. Procedure TPreviewForm.FormCreate( Sender: TObject );
  211. Begin
  212.   ZoomBox.ItemIndex := 0;
  213.   WindowState := wsMaximized;
  214.   Screen.Cursors[ crZoom ] := LoadCursor( hInstance, 'ZOOM_CURSOR' );
  215.   ZoomCursorButClick( Nil );
  216.   Caption := Application.Title;
  217.   MouseDragging := False;
  218.   RightShiftDown := False;
  219.   LeftShiftDown := False;
  220.   NewOrigin.X := 0;
  221.   NewOrigin.Y := 0;
  222. End;
  223.  
  224. Procedure TPreviewForm.CloseButClick( Sender: TObject );
  225. Begin
  226.   Close;
  227. End;
  228.  
  229. Procedure TPreviewForm.FormClose( Sender: TObject;
  230.   Var Action: TCloseAction );
  231. Begin
  232.   Action := caFree;
  233.   Application.OnHint := OldHint;
  234. End;
  235.  
  236. Procedure TPreviewForm.ScrollBox1Resize( Sender: TObject );
  237. Const
  238.   BORD = 20;
  239. Var
  240.   z: double;
  241.   tmp: integer;
  242.   TotWid: integer;
  243. Begin
  244.   Aspect := MinInt( ScrollBox1.ClientWidth, ScrollBox1.ClientHeight ) /
  245.     MaxInt( ScrollBox1.ClientWidth, ScrollBox1.ClientHeight );
  246.   Case ZoomBox.ItemIndex Of
  247.     0: FitPageBut.Down := True;
  248.     1: FitWidthBut.Down := True;
  249.     Else
  250.       Begin
  251.         FitPageBut.Down := False;
  252.         FitWidthBut.Down := False;
  253.       End;
  254.   End;
  255.  
  256.   If ZoomBox.ItemIndex = -1 Then
  257.     ZoomBox.ItemIndex := 0;
  258.  
  259.   Case ZoomBox.ItemIndex Of
  260.     0:
  261.       z := ( ( ScrollBox1.ClientHeight - BORD ) / PixelsPerInch ) /
  262.         ( PrevPrinterObj.PageHeight / PrevPrinterObj.PixelsPerInchY );
  263.     1:
  264.       z := ( ( ScrollBox1.ClientWidth - BORD ) / PixelsPerInch ) /
  265.         ( PrevPrinterObj.PageWidth / PrevPrinterObj.PixelsPerInchX );
  266.     2: z := Zoom;
  267.     3: z := 0.25;
  268.     4: z := 0.50;
  269.     5: z := 0.75;
  270.     6: z := 1.00;
  271.     7: z := 1.25;
  272.     8: z := 1.50;
  273.     9: z := 2.00;
  274.     10: z := 3.00;
  275.     11: z := 4.00;
  276.     Else
  277.       z := 1;
  278.   End;
  279.  
  280.   If z > 20 Then
  281.     z := 20
  282.   Else If z < 0.15 Then
  283.     z := 0.15;
  284.   If ZoomBox.ItemIndex <> 0 Then OnePageBut.Down := True;
  285.  
  286.    // Page Width and height *should* change by orientations...
  287.   PagePanel.Height := TRUNC( PixelsPerInch * z * PrevPrinterObj.PageHeight / PrevPrinterObj.PixelsPerInchY );
  288.   PagePanel.Width := TRUNC( PixelsPerInch * z * PrevPrinterObj.PageWidth / PrevPrinterObj.PixelsPerInchX );
  289.  
  290.   PagePanel2.Visible := TwoPageBut.Down;
  291.   If TwoPageBut.Down Then
  292.     Begin
  293.       PagePanel2.Width := PagePanel.Width;
  294.       PagePanel2.Height := PagePanel.Height;
  295.     End;
  296.  
  297.   TotWid := PagePanel.Width + BORD;
  298.   If TwoPageBut.Down Then
  299.     TotWid := TotWid + PagePanel2.Width + BORD;
  300.  
  301.    // Resize the Contain Panel
  302.   tmp := PagePanel.Height + BORD;
  303.   If tmp < ScrollBox1.ClientHeight Then tmp := ScrollBox1.ClientHeight - 1;
  304.   ContainPanel.Height := tmp;
  305.  
  306.   tmp := TotWid;
  307.   If tmp < ScrollBox1.ClientWidth Then tmp := ScrollBox1.ClientWidth - 1;
  308.   ContainPanel.Width := tmp;
  309.  
  310.    // Center the Page Panel
  311.   If PagePanel.Height + BORD < ContainPanel.Height Then
  312.     Begin
  313.       PagePanel.Top := ContainPanel.Height Div 2 - PagePanel.Height Div 2;
  314.     End
  315.   Else
  316.     Begin
  317.       PagePanel.Top := BORD Div 2;
  318.     End;
  319.   PagePanel2.Top := PagePanel.Top;
  320.  
  321.   If TotWid < ContainPanel.Width Then
  322.     Begin
  323.       PagePanel.Left := ContainPanel.Width Div 2 - ( TotWid - BORD ) Div 2;
  324.     End
  325.   Else
  326.     Begin
  327.       PagePanel.Left := BORD Div 2;
  328.     End;
  329.   PagePanel2.Left := PagePanel.Left + PagePanel.Width + BORD;
  330.  
  331.    // Set the Zoom Variable
  332.   Zoom := z;
  333.   ZoomLabel.Caption := Format( '%1.0n', [ z * 100 ] ) + '%';
  334. End;
  335.  
  336. Procedure TPreviewForm.DrawMetaFile( PB: TPaintBox; mf: TMetaFile );
  337. Begin
  338. //   PB.Canvas.Draw(0, 0, mf);
  339.   Case PrevPrinterObj.Orientation Of
  340.     poLandscape:
  341.       PB.Canvas.StretchDraw( Rect( 0, 0, Round( 10.75 * PrevPrinterObj.PixelsPerInchX ),
  342.         Round( 8.15 * PrevPrinterObj.PixelsPerInchY ) ), MF );
  343.     poPortrait:
  344.       PB.Canvas.StretchDraw( Rect( 0, 0, Round( 8.15 * PrevPrinterObj.PixelsPerInchX ),
  345.         Round( 10.75 * PrevPrinterObj.PixelsPerInchY ) ), MF );
  346.   End;
  347. End;
  348.  
  349. Procedure TPreviewForm.PBPaint( Sender: TObject );
  350. Var
  351.   PB: TPaintBox;
  352.   x1, y1: integer;
  353.   x, y: integer;
  354.   Draw: boolean;
  355.   Page: integer;
  356. Begin
  357.   PB := Sender As TPaintBox;
  358.  
  359.   If PB = PB1 Then
  360.     Begin
  361.       Draw := CurPage < PrevPrinterObj.LastAvailPage;
  362.       Page := CurPage;
  363.     End
  364.   Else
  365.     Begin
  366.       // PB2
  367.       Draw := TwoPageBut.Down And ( CurPage + 1 < PrevPrinterObj.LastAvailPage );
  368.       Page := CurPage + 1;
  369.     End;
  370.  
  371.   SetMapMode( PB.Canvas.Handle, MM_ANISOTROPIC );
  372.   SetWindowExtEx( PB.Canvas.Handle, PrevPrinterObj.PageWidth, PrevPrinterObj.PageHeight, Nil );
  373.   SetViewportExtEx( PB.Canvas.Handle, PB.Width, PB.Height, Nil );
  374.  
  375.   If Draw Then
  376.     DrawMetaFile( PB, PrevPrinterObj.MetaFiles[ Page ] );
  377.  
  378.   If GridBut.Down Then
  379.     Begin
  380.       PB.Canvas.Pen.Color := clLtGray;
  381.  
  382.       For x := 1 To PrevPrinterObj.PageWidth Div PrevPrinterObj.PixelsPerInchX Do
  383.         Begin
  384.           x1 := Round( PrevPrinterObj.PixelsPerInchX * x );
  385.           PB.Canvas.MoveTo( x1, 0 );
  386.           PB.Canvas.LineTo( x1, PrevPrinterObj.PageHeight );
  387.         End;
  388.  
  389.       For y := 1 To PrevPrinterObj.PageHeight Div PrevPrinterObj.PixelsPerInchY Do
  390.         Begin
  391.           y1 := Round( PrevPrinterObj.PixelsPerInchY * y );
  392.           PB.Canvas.MoveTo( 0, y1 );
  393.           PB.Canvas.LineTo( PrevPrinterObj.PageWidth, y1 );
  394.         End;
  395.     End;
  396. End;
  397.  
  398. Procedure TPreviewForm.GridButClick( Sender: TObject );
  399. Begin
  400.   PB1.Invalidate;
  401.   PB2.Invalidate;
  402. End;
  403.  
  404. Procedure TPreviewForm.OnHint( Sender: TObject );
  405. Begin
  406.   HintLabel.Caption := Application.Hint;
  407. End;
  408.  
  409. Procedure TPreviewForm.FormShow( Sender: TObject );
  410. Begin
  411.   CurPage := 0;
  412.   OldHint := Application.OnHint;
  413.   Application.OnHint := OnHint;
  414.   CheckEnable;
  415. End;
  416.  
  417. Procedure TPreviewForm.SetCurPage( Val: integer );
  418. Var
  419.   tmp: integer;
  420. Begin
  421.   FCurPage := Val;
  422.   tmp := 0;
  423.   If PrevPrinterObj <> Nil Then tmp := PrevPrinterObj.LastAvailPage;
  424.   CurPageLabel.Caption := Format( 'Page %d of %d', [ Val + 1, tmp ] );
  425.   PB1.Invalidate;
  426.   PB2.Invalidate;
  427. End;
  428.  
  429. Procedure TPreviewForm.ZoomBoxChange( Sender: TObject );
  430. Begin
  431.   ScrollBox1Resize( Nil );
  432.   ScrollBox1Resize( Nil );
  433. End;
  434.  
  435. Procedure TPreviewForm.TwoPageButClick( Sender: TObject );
  436. Begin
  437.   ZoomBox.ItemIndex := 0;
  438.   ScrollBox1Resize( Nil );
  439. End;
  440.  
  441. Procedure TPreviewForm.NextPageButClick( Sender: TObject );
  442. Begin
  443.   CurPage := CurPage + 1;
  444.   CheckEnable;
  445. End;
  446.  
  447. Procedure TPreviewForm.PrevPageButClick( Sender: TObject );
  448. Begin
  449.   CurPage := CurPage - 1;
  450.   CheckEnable;
  451. End;
  452.  
  453. Procedure TPreviewForm.CheckEnable;
  454. Begin
  455.   NextPageBut.Enabled := CurPage + 1 < PrevPrinterObj.LastAvailPage;
  456.   PrevPageBut.Enabled := CurPage > 0;
  457.  
  458.   NextPageSpeed.Enabled := NextPageBut.Enabled;
  459.   PrevPageSpeed.Enabled := PrevPageBut.Enabled;
  460.  
  461.   FirstPageSpeed.Enabled := PrevPageBut.Enabled;
  462.   LastPageSPeed.Enabled := NextPageBut.Enabled;
  463.  
  464.   PageNumSpeed.Enabled := PrevPrinterObj.LastAvailPage > 1;
  465. End;
  466.  
  467. Procedure TPreviewForm.FirstPageSpeedClick( Sender: TObject );
  468. Begin
  469.   CurPage := 0;
  470.   CheckEnable;
  471. End;
  472.  
  473. Procedure TPreviewForm.LastPageSpeedClick( Sender: TObject );
  474. Begin
  475.   CurPage := PrevPrinterObj.LastAvailPage - 1;
  476.   CheckEnable;
  477. End;
  478.  
  479. Procedure TPreviewForm.ZoomCursorButClick( Sender: TObject );
  480. Begin
  481.   PB1.Cursor := crZoom;
  482.   PB2.Cursor := crZoom;
  483. End;
  484.  
  485. Procedure TPreviewForm.HandCursorButClick( Sender: TObject );
  486. Begin
  487.   PB1.Cursor := crHandPoint;
  488.   PB2.Cursor := crHandPoint;
  489. End;
  490.  
  491. Procedure TPreviewForm.PB1MouseDown( Sender: TObject; Button: TMouseButton;
  492.   Shift: TShiftState; X, Y: Integer );
  493. Var
  494.   sx, sy: single;
  495.   nx, ny: integer;
  496. Begin
  497.   If ( ZoomCursorBut.Down ) Then
  498.     Begin
  499.       sx := X / PagePanel.Width;
  500.       sy := Y / PagePanel.Height;
  501.  
  502.       If ssLeft In Shift Then
  503.         Zoom := Zoom * ZOOMFACTOR;
  504.       If ssRight In Shift Then
  505.         Zoom := Zoom / ZOOMFACTOR;
  506.       ZoomBox.ItemIndex := 2;
  507.       ScrollBox1Resize( Nil );
  508.  
  509.       nx := TRUNC( sx * PagePanel.Width );
  510.       ny := TRUNC( sy * PagePanel.Height );
  511.       ScrollBox1.HorzScrollBar.Position := nx - ScrollBox1.Width Div 2;
  512.       ScrollBox1.VertScrollBar.Position := ny - ScrollBox1.Height Div 2;
  513.     End
  514.   Else If ( spdNewZoom.Down ) And ( ssLeft In Shift ) Then
  515.     Begin
  516.       SetCapture( PB1.Canvas.Handle );
  517.       MouseOrigin := Point( X, Y );
  518.       PrevPoint := Point( X, Y );
  519.       NewOrigin := Point( X, Y );
  520.       PB1.Canvas.Pen.Color := clBlack;
  521.       PB1.Canvas.Pen.Style := psDot;
  522.       MouseDragging := TRUE;
  523.     End
  524.   Else If ( spdNewZoom.Down ) And ( ssRight In Shift ) Then
  525.     Begin
  526.       ZoomBox.ItemIndex := 0;
  527.       Zoom := 100.0;
  528.       ScrollBox1.HorzScrollBar.Position := 0;
  529.       ScrollBox1.VertScrollBar.Position := 0;
  530.       ScrollBox1Resize( Nil );
  531.       Pb1.Invalidate;
  532.       MouseDragging := False;
  533.     End;
  534.   If HandCursorBut.Down Then
  535.     Begin
  536.       DownX := X;
  537.       DownY := Y;
  538.       Moving := True;
  539.     End;
  540. End;
  541.  
  542. Procedure TPreviewForm.PB1MouseMove( Sender: TObject; Shift: TShiftState; X,
  543.   Y: Integer );
  544. Var
  545.   newWidth, NewHeight: LongInt;
  546.   x1, x2, y1, y2: LongInt;
  547. Begin
  548.   If ( moving ) And Not ( MouseDragging ) Then
  549.     Begin
  550.       ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position + ( DownX - X );
  551.       ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position + ( DownY - Y );
  552.     End
  553.   Else If MouseDragging Then
  554.     Begin
  555.       With PB1.Canvas Do
  556.         Begin
  557.           SetROP2( Handle, R2_XORPEN );
  558.           NewWidth := MaxInt( X, MouseOrigin.X ) - MinInt( X, MouseOrigin.X );
  559.           NewHeight := MaxInt( Y, MouseOrigin.Y ) - MinInt( Y, MouseOrigin.Y );
  560.  
  561.            (*
  562.               This is "Zooming Code" that doesn't...work... ahem... help?
  563.            if ScrollBox1.ClientWidth > ScrollBox1.ClientHeight then
  564.              begin
  565.                if NewHeight > NewWidth then  // This should read that "Aspect" is the
  566.                  NewWidth := Round( NewHeight / Aspect ) // percentage the small is of the larger;
  567.                else                              // I just need to do the resizing
  568.                  NewHeight := Round( NewWidth * Aspect );
  569.              end
  570.            else
  571.              begin
  572.                if NewWidth > NewHeight then  // This should read that "Aspect" is the
  573.                  NewHeight := Round( NewWidth / Aspect ) // percentage the small is of the larger;
  574.                else                              // I just need to do the resizing
  575.                  NewWidth := Round( NewHeight * Aspect );
  576.              end;*)
  577.  
  578.           If ( MouseOrigin.x <> PrevPoint.x ) Or ( MouseOrigin.y <> PrevPoint.y ) Then
  579.             PolyLine( [ MouseOrigin, Point( MouseOrigin.X, PrevPoint.Y ),
  580.               PrevPoint, Point( PrevPoint.X, MouseOrigin.Y ),
  581.                 MouseOrigin ] );
  582.  
  583.           NewOrigin.X := ( MinInt( MouseOrigin.X, X ) - MaxInt( MouseOrigin.X, X ) ) Div 2 + MinInt( MouseOrigin.X, X );
  584.           NewOrigin.Y := ( MinInt( MouseOrigin.Y, Y ) - MaxInt( MouseOrigin.Y, Y ) ) Div 2 + MinInt( MouseOrigin.Y, Y );
  585.  
  586.            { // More zooming code
  587.            if ( X > MouseOrigin.X ) then
  588.              PrevPoint.X := MouseOrigin.X + NewWidth
  589.            else if ( X < MouseOrigin.X ) then
  590.              MouseOrigin.X := PrevPoint.X + NewWidth;
  591.            if ( Y > MouseOrigin.Y ) then
  592.              PrevPoint.Y := MouseOrigin.Y + NewHeight
  593.            else if ( Y < MouseOrigin.Y ) then
  594.              MouseOrigin.Y := PrevPoint.Y + NewHeight;}
  595.  
  596.           PrevPoint := Point( X, Y );
  597.           PolyLine( [ MouseOrigin, Point( MouseOrigin.X, PrevPoint.Y ),
  598.             PrevPoint, Point( PrevPoint.X, MouseOrigin.Y ),
  599.               MouseOrigin ] );
  600.  
  601.         End;
  602.     End;
  603. (*
  604.    I was using this to try and debug the zooming box...
  605.   if MouseDragging then
  606.     begin
  607.        lbXYLoc.Caption := '[ ( ' + IntToStr(X) + ', ' + IntToStr(Y) + ' ) ' + IntToStr( NewWidth ) + ',' + IntToStr( NewHeight ) + ' ]';
  608.        lbXYLoc.Caption := lbXYLoc.Caption + ' [ L:' + IntToStr( PB1.Left ) + ', T:' + IntToStr( PB1.Top ) + ' ]';
  609.     end
  610.   else
  611.     lbXYLoc.Caption := '[ ( ' + IntToStr(X) + ', ' + IntToStr(Y) + ' ) ' + IntToStr( ContainPanel.Top ) + ',' + IntToStr( ContainPanel.Left) + ' ]';*)
  612. End;
  613.  
  614. Procedure TPreviewForm.PB1MouseUp( Sender: TObject; Button: TMouseButton;
  615.   Shift: TShiftState; X, Y: Integer );
  616. Var
  617.   NewWidth, NewHeight: LongInt;
  618.   OffsetX, OffsetY: LongInt;
  619.   Target, sx, sy: single;
  620. Begin
  621.   Moving := False;
  622.  
  623.   If MouseDragging Then
  624.     Begin
  625.       MouseDragging := FALSE;
  626.       ReleaseCapture;
  627.       NewOrigin.X := ( MinInt( MouseOrigin.X, X ) - MaxInt( MouseOrigin.X, X ) ) Div 2 + MinInt( MouseOrigin.X, X );
  628.       NewOrigin.Y := ( MinInt( MouseOrigin.Y, Y ) - MaxInt( MouseOrigin.Y, Y ) ) Div 2 + MinInt( MouseOrigin.Y, Y );
  629.  
  630.       With PB1.Canvas Do
  631.         Begin
  632.           SetROP2( Handle, R2_XORPEN );
  633.           PolyLine( [ MouseOrigin, Point( MouseOrigin.X, PrevPoint.Y ),
  634.             PrevPoint, Point( PrevPoint.X, MouseOrigin.Y ),
  635.               MouseOrigin ] );
  636.         End;
  637.       NewWidth := MaxInt( X, MouseOrigin.X ) - MinInt( X, MouseOrigin.X );
  638.       NewHeight := MaxInt( Y, MouseOrigin.Y ) - MinInt( Y, MouseOrigin.Y );
  639.  
  640.       If NewWidth <> 0 Then
  641.         NewWidth := ScrollBox1.ClientWidth Div ( ScrollBox1.ClientWidth Div NewWidth ) //Pb1.Width div (PB1.Width div NewWidth)
  642.       Else
  643.         NewWidth := ScrollBox1.ClientWidth;
  644.       If NewHeight <> 0 Then
  645.         NewHeight := ScrollBox1.ClientHeight Div ( ScrollBox1.ClientHeight Div NewHeight ) //Pb1.Height div (PB1.Height div NewHeight)
  646.       Else
  647.         NewHeight := ScrollBox1.ClientHeight;
  648.  
  649.       If ScrollBox1.ClientWidth > ScrollBox1.ClientHeight Then
  650.         Begin
  651.           If NewHeight > NewWidth Then  // This should read that "Aspect" is the
  652.             NewWidth := Round( NewHeight / Aspect ) // percentage the small is of the larger;
  653.           Else                          // I just need to do the resizing
  654.             NewHeight := Round( NewWidth * Aspect );
  655.         End
  656.       Else
  657.         Begin
  658.           If NewWidth > NewHeight Then  // This should read that "Aspect" is the
  659.             NewHeight := Round( NewWidth / Aspect ) // percentage the small is of the larger;
  660.           Else                          // I just need to do the resizing
  661.             NewWidth := Round( NewHeight * Aspect );
  662.         End;
  663.  
  664.       If NewWidth <> 0 Then
  665.         sx := ScrollBox1.ClientWidth / ( NewWidth )
  666.       Else
  667.         Sx := 1;
  668.       If NewHeight <> 0 Then
  669.         sy := ScrollBox1.ClientHeight / ( NewHeight )
  670.       Else
  671.         Sy := 1;
  672.  
  673.       Target := MinFloat( Sx, SY );
  674.       If Target = 0 Then
  675.         Target := 1;
  676.  
  677. {       NewOrigin.X := Round( MouseOrigin.X * Target + ( ContainPanel.Left * Target )) ;
  678.        NewOrigin.Y := Round( MouseOrigin.Y * Target + ( ContainPanel.Top * Target ));}
  679.       NewOrigin.X := Round( ( MouseOrigin.X + ContainPanel.Left + ( NewWidth Div 2 ) ) * Sx );
  680.       NewOrigin.Y := Round( ( MouseOrigin.Y + ContainPanel.Top + ( NewHeight Div 2 ) ) * Sy );
  681.       ZoomBox.ItemIndex := 2;
  682.       Zoom := Target;
  683.       ScrollBox1Resize( Nil );
  684.  
  685.        // Original Code
  686.       Panel1.Width := Round( Sx * Panel1.Width );
  687.       Panel1.Height := Round( Sy * Panel1.Height );
  688.  
  689.       With ScrollBox1 Do
  690.         Begin
  691.           HorzScrollBar.Range := Pb1.Width;
  692.           VertScrollBar.Range := Pb1.Height;
  693.           HorzScrollBar.Position := NewOrigin.X - ( NewWidth Div 2 );
  694.           VertScrollBar.Position := NewOrigin.Y - ( NewHeight Div 2 );
  695.         End;
  696.  
  697.        //ScrollBox1.HorzScrollBar.Position := ( NewOrigin.X );
  698.        //ScrollBox1.VertScrollBar.Position := ( NewOrigin.Y );
  699.  
  700.       PB1.Invalidate;
  701.     End;
  702. End;
  703.  
  704. Procedure TPreviewForm.PrintButClick( Sender: TObject );
  705. Begin
  706.   PrevPrinterObj.CurPageIndex := CurPage;
  707.   PrevPrinterObj.PrintDialog;
  708.   PB1.Repaint;
  709.   PB2.Repaint;
  710. End;
  711.  
  712. Procedure TPreviewForm.PageNumSpeedClick( Sender: TObject );
  713. Var
  714.   gp: TGoPageForm;
  715. Begin
  716.   gp := TGoPageForm.Create( Self );
  717.   gp.PageNum.MaxValue := PrevPrinterObj.LastAvailPage;
  718.   gp.PageNum.Value := CurPage + 1;
  719.  
  720.   If gp.ShowModal = mrOK Then
  721.     Begin
  722.       CurPage := gp.PageNum.Value - 1;
  723.       CheckEnable;
  724.     End;
  725.   gp.Free;
  726. End;
  727.  
  728. Procedure TPreviewForm.OnePageButMouseUp( Sender: TObject;
  729.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer );
  730. Begin
  731.   ZoomBox.ItemIndex := 0;
  732.   ScrollBox1Resize( Nil );
  733. End;
  734.  
  735. Procedure TPreviewForm.FitPageButClick( Sender: TObject );
  736. Begin
  737.   ZoomBox.ItemIndex := 0;
  738.   ZoomBoxChange( Nil );
  739. End;
  740.  
  741. Procedure TPreviewForm.FitWidthButClick( Sender: TObject );
  742. Begin
  743.   ZoomBox.ItemIndex := 1;
  744.   ZoomBoxChange( Nil );
  745. End;
  746.  
  747. Procedure TPreviewForm.AboutButClick( Sender: TObject );
  748. Var
  749.   X: LongInt;
  750. Begin
  751.   If SavePicture.Execute Then
  752.     Begin
  753.       For X := 0 To PrevPrinterObj.PageNumber - 1 Do
  754.         Begin
  755.           If Not ( ( X > -1 ) And ( X < PrevPrinterObj.PageTitles.Count ) ) Then
  756.             PrevPrinterObj.MetaFiles[ X ].SaveToFile( Copy( SavePicture.FileName, 1,
  757.               Pos( '.', SavePicture.FileName ) - 1 ) + IntToStr( X + 1 ) + '.EMF' )
  758.           Else
  759.             PrevPrinterObj.MetaFiles[ X ].SaveToFile( PrevPrinterObj.PageTitles[ x ] + IntToStr( X + 1 ) + '.EMF' )
  760.         End;
  761.     End;
  762. End;
  763.  
  764. Procedure TPreviewForm.CopyToClipboardClick( Sender: TObject );
  765. Begin
  766.   Clipboard.Assign( PrevPrinterObj.MetaFiles[ FCurPage ] );
  767. End;
  768.  
  769. Procedure TPreviewForm.FormKeyDown( Sender: TObject; Var Key: Word;
  770.   Shift: TShiftState );
  771. Begin
  772.   If ssRight In Shift Then
  773.     RightShiftDown := True
  774.   Else
  775.     RightShiftDown := False;
  776.   If ssLeft In Shift Then
  777.     LeftShiftDown := True
  778.   Else
  779.     LeftShiftDown := False;
  780. End;
  781.  
  782. Procedure TPreviewForm.FormKeyUp( Sender: TObject; Var Key: Word;
  783.   Shift: TShiftState );
  784. Begin
  785.   If ssRight In Shift Then
  786.     RightShiftDown := True
  787.   Else
  788.     RightShiftDown := False;
  789.   If ssLeft In Shift Then
  790.     LeftShiftDown := True
  791.   Else
  792.     LeftShiftDown := False;
  793. End;
  794.  
  795. Procedure TPreviewForm.lbXYLocClick( Sender: TObject );
  796. Begin
  797.   lbXYLoc.Caption := '( ' + IntToStr( ScrollBox1.HorzScrollBar.Position ) + ', ' + IntToStr( ScrollBox1.VertScrollBar.Position ) + ' )';
  798. End;
  799.  
  800. Procedure TPreviewForm.CopyToClipboard2Click( Sender: TObject );
  801. Var
  802.   aBitmap: TBitmap;
  803.   aJpeg: TJpegImage;
  804.   OldCursor: TCursor;
  805. Begin
  806.   aBitmap := TBitmap.Create;
  807.   aJpeg := TJpegImage.Create;
  808.   OldCursor := Screen.Cursor;
  809.   try
  810.     Screen.Cursor := crHourglass;
  811.     aBitmap.Width := GetDeviceCaps( Printer.Handle, PHYSICALWIDTH );
  812.     aBitmap.Height := GetDeviceCaps( Printer.Handle, PHYSICALHEIGHT );
  813.  
  814.     aBitmap.Canvas.Brush.Color := clWhite;
  815.     aBitmap.Canvas.FillRect( Rect( 0, 0, aBitmap.Width, aBitmap.Height ) );
  816.  
  817.     Windows.PlayEnhMetaFile(
  818.       aBitmap.Canvas.Handle,
  819.       PrevPrinterObj.Metafiles[ FCurPage ].Handle,
  820.       Rect( 0, 0, aBitmap.Width, aBitmap.Height ) );
  821.  
  822.     aJpeg.CompressionQuality := 100;
  823.     aJpeg.Assign( aBitmap );
  824.     aJpeg.Compress;
  825.  
  826.     Clipboard.Assign( aJpeg );
  827.   finally
  828.     aJpeg.Free;
  829.     aBitmap.Free;
  830.     Screen.Cursor := OldCursor;
  831.   end;
  832. End;
  833.  
  834. procedure TPreviewForm.spdMenuClick(Sender: TObject);
  835. var
  836.   P: TPoint;
  837. begin
  838.   P := ClientToScreen( Point(0, Self.Top+spdMenu.Height-Self.Top) );
  839.   PopupMenu1.Popup( P.X+spdMenu.Left, P.Y );
  840. end;
  841.  
  842. procedure TPreviewForm.SaveasJpeg1Click(Sender: TObject);
  843. Var
  844.   X: LongInt;
  845.   aWid, aHei: LongInt;
  846.   aBitmap: TBitmap;
  847.   aJpeg: TJpegImage;
  848.   OldCursor: TCursor;
  849. Begin
  850.   SavePicture.Filter := 'JPEG Files|*.jpg;*.jpeg|All Files|*.*';
  851.   try
  852.   If SavePicture.Execute Then
  853.     Begin
  854.       aBitmap := TBitmap.Create;
  855.       aJpeg := TJpegImage.Create;
  856.       OldCursor := Screen.Cursor;
  857.       try
  858.         Screen.Cursor := crHourglass;
  859.  
  860.         aWid := GetDeviceCaps( Printer.Handle, PHYSICALWIDTH );
  861.         aHei := GetDeviceCaps( Printer.Handle, PHYSICALHEIGHT );
  862.         For X := 0 To PrevPrinterObj.PageNumber - 1 Do
  863.           Begin
  864.             aBitmap.Width := aWid;
  865.             aBitmap.Height := aHei;
  866.             aBitmap.Canvas.Brush.Color := clWhite;
  867.             aBitmap.Canvas.FillRect( Rect( 0, 0, aBitmap.Width, aBitmap.Height ) );
  868.  
  869.             Windows.PlayEnhMetaFile( aBitmap.Canvas.Handle,
  870.               PrevPrinterObj.Metafiles[ X ].Handle,
  871.               Rect( 0, 0, aBitmap.Width, aBitmap.Height ) );
  872.  
  873.             aJpeg.CompressionQuality := 100;
  874.             aJpeg.Assign( aBitmap );
  875.             aJpeg.Compress;
  876.  
  877.             If Not ( ( X > -1 ) And ( X < PrevPrinterObj.PageTitles.Count ) ) Then
  878.               aJpeg.SaveToFile( Copy( SavePicture.FileName, 1,
  879.                 Pos( '.', SavePicture.FileName ) - 1 ) + IntToStr( X + 1 ) + '.JPG' )
  880.             Else
  881.               aJpeg.SaveToFile( PrevPrinterObj.PageTitles[ x ] + IntToStr( X + 1 ) + '.JPG' );
  882.             Application.ProcessMessages;
  883.           End;
  884.       finally
  885.         aJpeg.Free;
  886.         aBitmap.Free;
  887.         Screen.Cursor := OldCursor;
  888.  
  889.       end;
  890.     End;
  891.   finally
  892.     SavePicture.Filter := 'Windows MetaFiles|*.WMF|All Files|*.*';
  893.   end;
  894. end;
  895.  
  896. End.
  897.  
  898.