PrintPreviewControl.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / Printing / PrintPreviewControl.cs / 1305376 / PrintPreviewControl.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.PrintPreviewControl.PhysicalToPixels(System.Drawing.Size,System.Drawing.Point):System.Drawing.Size")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.PrintPreviewControl.PixelsToPhysical(System.Drawing.Size,System.Drawing.Point):System.Drawing.Size")] 
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.PrintPreviewControl.set_VirtualSize(System.Drawing.Size):System.Void")] 

namespace System.Windows.Forms { 
    using System.Runtime.Serialization.Formatters;
    using System.Runtime.InteropServices;
    using System.Runtime.Remoting;
    using System.Diagnostics; 
    using System;
    using System.Security.Permissions; 
    using System.Drawing; 
    using Microsoft.Win32;
    using System.ComponentModel; 
    using System.Drawing.Printing;
    using CodeAccessPermission = System.Security.CodeAccessPermission;
    using System.Globalization;
 
    /// 
    ///  
    ///     
    ///       The raw "preview" part of print previewing, without any dialogs or buttons.
    ///       Most PrintPreviewControl's are found on PrintPreviewDialog's, 
    ///       but they don't have to be.
    ///    
    /// 
    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [DefaultProperty("Document")] 
    [SRDescription(SR.DescriptionPrintPreviewControl)] 
    public class PrintPreviewControl : Control {
        Size virtualSize = new Size(1,1); 
        Point position = new Point(0,0);
        Point lastOffset;
        bool antiAlias;
 
        private const int SCROLL_PAGE = 100;
        private const int SCROLL_LINE = 5; 
        private const double DefaultZoom = .3; 

        private const int border = 10; // spacing per page, in mm 

        private PrintDocument document;
        private PreviewPageInfo[] pageInfo; // null if needs refreshing
        private int startPage;  // 0-based 
        private int rows = 1;
        private int columns = 1; 
        private bool autoZoom = true; 

        // The following are all computed by ComputeLayout 
        private bool layoutOk;
        private Size imageSize = System.Drawing.Size.Empty; // 100ths of inch, not pixels
        private Point screendpi = Point.Empty;
        private double zoom = DefaultZoom; 
        bool pageInfoCalcPending;
        bool exceptionPrinting; 
 
        /// 
        ///  
        ///    
        ///       Initializes a new instance of the  class.
        ///    
        ///  
        public PrintPreviewControl() {
            ResetBackColor(); 
            ResetForeColor(); 
            Size = new Size(100, 100);
            SetStyle(ControlStyles.ResizeRedraw, false); 
            SetStyle(ControlStyles.Opaque | ControlStyles.OptimizedDoubleBuffer, true);

        }
 
        /// 
        [ 
        SRCategory(SR.CatBehavior), 
        DefaultValue(false),
        SRDescription(SR.PrintPreviewAntiAliasDescr) 
        ]
        public bool UseAntiAlias {
            get {
                return antiAlias; 
            }
            set { 
                antiAlias = value; 
            }
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets a value If true (the default), resizing the control or changing the number of pages shown
        ///       will automatically adjust Zoom to make everything visible. 
        ///     
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(true),
        SRDescription(SR.PrintPreviewAutoZoomDescr)
        ] 
        public bool AutoZoom {
            get { return autoZoom;} 
            set { 
                if (autoZoom != value) {
                    autoZoom = value; 
                    InvalidateLayout();
                }
            }
        } 

        ///  
        ///  
        ///    
        ///       Gets or sets a value indicating the document to preview. 
        ///
        ///    
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(null), 
        SRDescription(SR.PrintPreviewDocumentDescr) 
        ]
        public PrintDocument Document { 
            get { return document;}
            set {
                document = value;
                InvalidatePreview(); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets the number of pages
        ///       displayed horizontally across the screen.
        ///     
        /// 
        [ 
        DefaultValue(1), 
        SRCategory(SR.CatLayout),
        SRDescription(SR.PrintPreviewColumnsDescr) 
        ]
        public int Columns {
            get { return columns;}
            set { 
                if (value < 1 ) {
                    throw new ArgumentOutOfRangeException("Columns", SR.GetString(SR.InvalidLowBoundArgumentEx, "Columns", value.ToString(CultureInfo.CurrentCulture), (1).ToString(CultureInfo.CurrentCulture))); 
                } 

                columns = value; 
                InvalidateLayout();
            }
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Gets the CreateParams used to create the window. 
        ///       If a subclass overrides this function, it must call the base implementation.
        ///
        ///    
        ///  
        protected override CreateParams CreateParams {
            [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] 
            get { 
                CreateParams cp = base.CreateParams;
                cp.Style |= NativeMethods.WS_HSCROLL; 
                cp.Style |= NativeMethods.WS_VSCROLL;
                return cp;
            }
        } 

        ///  
        ///  
        ///     The virtual coordinate of the upper left visible pixel.
        ///  

        [
        SRCategory(SR.CatLayout),
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRDescription(SR.ControlWithScrollbarsPositionDescr) 
        ] 
        private Point Position {
            get { return position;} 
            set {
                SetPositionNoInvalidate(value);
            }
        } 

        ///  
        ///  
        ///    
        ///       Gets or sets the number of pages 
        ///       displayed vertically down the screen.
        ///    
        /// 
        [ 
        DefaultValue(1),
        SRDescription(SR.PrintPreviewRowsDescr), 
        SRCategory(SR.CatBehavior) 
        ]
        public int Rows { 
            get { return rows;}
            set {

                if (value < 1 ) { 
                    throw new ArgumentOutOfRangeException("Rows", SR.GetString(SR.InvalidLowBoundArgumentEx, "Rows", value.ToString(CultureInfo.CurrentCulture), (1).ToString(CultureInfo.CurrentCulture)));
                } 
 
                rows = value;
                InvalidateLayout(); 
            }
        }

        ///  
        /// 
        ///     This is used for international applications where the language 
        ///     is written from RightToLeft. When this property is true, 
        ///     control placement and text will be from right to left.
        ///  
        [
        SRCategory(SR.CatAppearance),
        Localizable(true),
        AmbientValue(RightToLeft.Inherit), 
        SRDescription(SR.ControlRightToLeftDescr)
        ] 
        public override RightToLeft RightToLeft { 
            get {
                return base.RightToLeft; 
            }
            set {
                base.RightToLeft = value;
                InvalidatePreview(); 
            }
        } 
 
        /// 
        [ 
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        Bindable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public override string Text {
            get { 
                return base.Text; 
            }
            set { 
                base.Text = value;
            }
        }
 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler TextChanged {
            add { 
                base.TextChanged += value;
            }
            remove {
                base.TextChanged -= value; 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets the page number of the upper left page.
        ///
        ///     
        /// 
        [ 
        DefaultValue(0), 
        SRDescription(SR.PrintPreviewStartPageDescr),
        SRCategory(SR.CatBehavior) 
        ]
        public int StartPage {
            get {
                int value = startPage; 
                if (pageInfo != null) {
                    value = Math.Min(value, pageInfo.Length - (rows * columns)); 
                } 
                value = Math.Max(value, 0);
 
                return value;
            }
            set {
                if (value < 0 ) { 
                    throw new ArgumentOutOfRangeException("StartPage", SR.GetString(SR.InvalidLowBoundArgumentEx, "StartPage", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture)));
                } 
                int oldValue = StartPage; 
                startPage = value;
                if (oldValue != startPage) { 
                    InvalidateLayout();
                    OnStartPageChanged(EventArgs.Empty);
                }
            } 
        }
 
        private static readonly object EVENT_STARTPAGECHANGED = new object(); 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.RadioButtonOnStartPageChangedDescr)] 
        public event EventHandler StartPageChanged {
            add { 
                Events.AddHandler(EVENT_STARTPAGECHANGED, value); 
            }
            remove { 
                Events.RemoveHandler(EVENT_STARTPAGECHANGED, value);
            }
        }
 
        /// 
        ///  
        ///     How big the control would be if the screen was infinitely large. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRDescription(SR.ControlWithScrollbarsVirtualSizeDescr) 
        ]
        private Size VirtualSize { 
            get { return virtualSize;} 
            set {
                SetVirtualSizeNoInvalidate(value); 
                Invalidate();
            }
        }
 
        /// 
        ///  
        ///     
        ///       Gets or sets a value indicating how large the pages will appear.
        ///     
        /// 
        [
        SRCategory(SR.CatBehavior),
        SRDescription(SR.PrintPreviewZoomDescr), 
        DefaultValue(DefaultZoom)
        ] 
        public double Zoom { 
            get { return zoom;}
            set { 
                if (value <= 0)
                    throw new ArgumentException(SR.GetString(SR.PrintPreviewControlZoomNegative));
                autoZoom = false;
                zoom = value; 
                InvalidateLayout();
            } 
        } 

        private int AdjustScroll(Message m, int pos, int maxPos, bool horizontal) { 
            switch (NativeMethods.Util.LOWORD(m.WParam)) {
                case NativeMethods.SB_THUMBPOSITION:
                case NativeMethods.SB_THUMBTRACK:
                    NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); 
                    si.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO));
                    si.fMask = NativeMethods.SIF_TRACKPOS; 
                    int direction = horizontal ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; 
                    if (SafeNativeMethods.GetScrollInfo(new HandleRef(this, m.HWnd), direction, si))
                    { 
                        pos = si.nTrackPos;
                    }
                    else
                    { 
                        pos = NativeMethods.Util.HIWORD(m.WParam);
                    } 
                    break; 
                case NativeMethods.SB_LINEUP:
                    if (pos > SCROLL_LINE) { 
                        pos-=SCROLL_LINE;
                    }
                    else {
                        pos = 0; 
                    }
                    break; 
                case NativeMethods.SB_LINEDOWN: 
                    if (pos < maxPos-SCROLL_LINE) {
                        pos+=SCROLL_LINE; 
                    }
                    else {
                        pos = maxPos;
                    } 
                    break;
                case NativeMethods.SB_PAGEUP: 
                    if (pos > SCROLL_PAGE) { 
                        pos-=SCROLL_PAGE;
                    } 
                    else {
                        pos = 0;
                    }
                    break; 
                case NativeMethods.SB_PAGEDOWN:
                    if (pos < maxPos-SCROLL_PAGE) { 
                        pos+=SCROLL_PAGE; 
                    }
                    else { 
                        pos = maxPos;
                    }
                    break;
            } 
            return pos;
        } 
 

        // This function computes everything in terms of physical size (millimeters), not pixels 
        //
        private void ComputeLayout() {
            Debug.Assert(pageInfo != null, "Must call ComputePreview first");
            layoutOk = true; 
            if (pageInfo.Length == 0) {
                ClientSize = Size; 
                return; 
            }
 
            Graphics tempGraphics = CreateGraphicsInternal();
            IntPtr dc = tempGraphics.GetHdc();
            screendpi = new Point(UnsafeNativeMethods.GetDeviceCaps(new HandleRef(tempGraphics, dc), NativeMethods.LOGPIXELSX),
                                  UnsafeNativeMethods.GetDeviceCaps(new HandleRef(tempGraphics, dc), NativeMethods.LOGPIXELSY)); 
            tempGraphics.ReleaseHdcInternal(dc);
            tempGraphics.Dispose(); 
 
            Size pageSize = pageInfo[StartPage].PhysicalSize;
            Size controlPhysicalSize = new Size(PixelsToPhysical(new Point(Size), screendpi)); 

            if (autoZoom) {
                double zoomX = ((double) controlPhysicalSize.Width - border*(columns + 1)) / (columns*pageSize.Width);
                double zoomY = ((double) controlPhysicalSize.Height - border*(rows + 1)) / (rows*pageSize.Height); 
                zoom = Math.Min(zoomX, zoomY);
            } 
 
            imageSize = new Size((int) (zoom*pageSize.Width), (int) (zoom*pageSize.Height));
            int virtualX = (imageSize.Width * columns) + border * (columns +1); 
            int virtualY = (imageSize.Height * rows) + border * (rows +1);
            SetVirtualSizeNoInvalidate(new Size(PhysicalToPixels(new Point(virtualX, virtualY), screendpi)));
        }
 
        // "Prints" the document to memory
        private void ComputePreview() { 
            int oldStart = StartPage; 

            if (document == null) 
                pageInfo = new PreviewPageInfo[0];
            else {
                IntSecurity.SafePrinting.Demand();
 
                PrintController oldController = document.PrintController;
                PreviewPrintController previewController = new PreviewPrintController(); 
                previewController.UseAntiAlias = UseAntiAlias; 
                document.PrintController = new PrintControllerWithStatusDialog(previewController,
                                                                               SR.GetString(SR.PrintControllerWithStatusDialog_DialogTitlePreview)); 

                // Want to make sure we've reverted any security asserts before we call Print -- that calls into user code
                document.Print();
                pageInfo = previewController.GetPreviewPageInfo(); 
                Debug.Assert(pageInfo != null, "ReviewPrintController did not give us preview info");
 
                document.PrintController = oldController; 
            }
 
            if (oldStart != StartPage) {
                OnStartPageChanged(EventArgs.Empty);
            }
        } 

        // Recomputes the sizes and positions of pages without forcing a new "preview print" 
        private void InvalidateLayout() { 
            layoutOk = false;
            Invalidate(); 
        }

        /// 
        ///  
        ///    
        ///       Refreshes the preview of the document. 
        ///     
        /// 
        public void InvalidatePreview() { 
            pageInfo = null;
            InvalidateLayout();
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Invalidate the layout, if necessary. 
        ///    
        /// 
        protected override void OnResize(EventArgs eventargs) {
            InvalidateLayout(); 
            base.OnResize(eventargs);
        } 
 
        void CalculatePageInfo() {
            if (pageInfoCalcPending) { 
                return;
            }

            pageInfoCalcPending = true; 
            try {
                if (pageInfo == null) { 
                    try { 
                        ComputePreview();
                    } 
                    catch {
                        exceptionPrinting = true;
                        throw;
                    } 
                    finally {
                        Invalidate(); 
                    } 
                }
            } 
            finally {
                pageInfoCalcPending = false;
            }
        } 

 
        ///  
        /// 
        ///  
        ///    
        ///       Paints the control.
        ///    
        ///  
        protected override void OnPaint(PaintEventArgs pevent) {
            Brush backBrush = new SolidBrush(BackColor); 
 
            try {
                if (pageInfo == null || pageInfo.Length == 0) { 
                    pevent.Graphics.FillRectangle(backBrush, ClientRectangle);

                    if (pageInfo != null || exceptionPrinting) {
                        // Calculate formats 
                        StringFormat format = new StringFormat();
                        format.Alignment = ControlPaint.TranslateAlignment(ContentAlignment.MiddleCenter); 
                        format.LineAlignment = ControlPaint.TranslateLineAlignment(ContentAlignment.MiddleCenter); 

                        // Do actual drawing 
                        SolidBrush brush = new SolidBrush(ForeColor);
                        try {
                            if (exceptionPrinting) {
                                pevent.Graphics.DrawString(SR.GetString(SR.PrintPreviewExceptionPrinting), Font, brush, ClientRectangle, format); 
                            }
                            else { 
                                pevent.Graphics.DrawString(SR.GetString(SR.PrintPreviewNoPages), Font, brush, ClientRectangle, format); 
                            }
                        } 
                        finally {
                            brush.Dispose();
                            format.Dispose();
                        } 
                    }
                    else { 
                        BeginInvoke(new MethodInvoker(CalculatePageInfo)); 
                    }
                 } 
                else {
                    if (!layoutOk)
                        ComputeLayout();
 
                    Size controlPhysicalSize = new Size(PixelsToPhysical(new Point(Size), screendpi));
 
                    //Point imagePixels = PhysicalToPixels(new Point(imageSize), screendpi); 
                    Point virtualPixels = new Point(VirtualSize);
 
                    // center pages on screen if small enough
                    Point offset = new Point(Math.Max(0, (Size.Width - virtualPixels.X) / 2),
                                             Math.Max(0, (Size.Height - virtualPixels.Y) / 2));
                    offset.X -= Position.X; 
                    offset.Y -= Position.Y;
                    lastOffset = offset; 
 
                    int borderPixelsX = PhysicalToPixels(border, screendpi.X);
                    int borderPixelsY = PhysicalToPixels(border, screendpi.Y); 

                    Region originalClip = pevent.Graphics.Clip;
                    Rectangle[] pageRenderArea = new Rectangle[rows * columns];
                    Point lastImageSize = Point.Empty; 
                    int maxImageHeight = 0;
 
                    try { 
                        for (int row = 0; row < rows; row++) {
                            //Initialize our LastImageSize variable... 
                            lastImageSize.X = 0;
                            lastImageSize.Y = maxImageHeight * row;

                            for (int column = 0; column < columns; column++) { 
                                int imageIndex = StartPage + column + row*columns;
                                if (imageIndex < pageInfo.Length) { 
 
                                    Size pageSize = pageInfo[imageIndex].PhysicalSize;
                                    if (autoZoom) { 
                                        double zoomX = ((double) controlPhysicalSize.Width - border*(columns + 1)) / (columns*pageSize.Width);
                                        double zoomY = ((double) controlPhysicalSize.Height - border*(rows + 1)) / (rows*pageSize.Height);
                                        zoom = Math.Min(zoomX, zoomY);
                                    } 

                                    imageSize = new Size((int) (zoom*pageSize.Width), (int) (zoom*pageSize.Height)); 
                                    Point imagePixels = PhysicalToPixels(new Point(imageSize), screendpi); 

 
                                    int x = offset.X + borderPixelsX * (column + 1) + lastImageSize.X;
                                    int y = offset.Y + borderPixelsY * (row + 1) + lastImageSize.Y;

                                    lastImageSize.X += imagePixels.X; 
                                    //The Height is the Max of any PageHeight..
                                    maxImageHeight = Math.Max(maxImageHeight, imagePixels.Y); 
 
                                    pageRenderArea[imageIndex - StartPage] = new Rectangle(x, y, imagePixels.X, imagePixels.Y);
                                    pevent.Graphics.ExcludeClip(pageRenderArea[imageIndex - StartPage]); 
                                }
                            }
                        }
 
                        pevent.Graphics.FillRectangle(backBrush, ClientRectangle);
                    } 
                    finally { 
                        pevent.Graphics.Clip = originalClip;
                    } 

                    for (int i=0; i 
        /// 
        ///    [To be supplied.]
        /// 
        protected virtual void OnStartPageChanged(EventArgs e) { 
            EventHandler eh = Events[EVENT_STARTPAGECHANGED] as EventHandler;
            if (eh != null) { 
                eh(this, e); 
            }
        } 

        private static int PhysicalToPixels(int physicalSize, int dpi) {
            return(int) (physicalSize * dpi / 100.0);
        } 

        private static Point PhysicalToPixels(Point physical, Point dpi) { 
            return new Point(PhysicalToPixels(physical.X, dpi.X), 
                             PhysicalToPixels(physical.Y, dpi.Y));
        } 

        private static Size PhysicalToPixels(Size physicalSize, Point dpi) {
            return new Size(PhysicalToPixels(physicalSize.Width, dpi.X),
                            PhysicalToPixels(physicalSize.Height, dpi.Y)); 
        }
 
        private static int PixelsToPhysical(int pixels, int dpi) { 
            return(int) (pixels * 100.0 / dpi);
        } 

        private static Point PixelsToPhysical(Point pixels, Point dpi) {
            return new Point(PixelsToPhysical(pixels.X, dpi.X),
                             PixelsToPhysical(pixels.Y, dpi.Y)); 
        }
 
        private static Size PixelsToPhysical(Size pixels, Point dpi) { 
            return new Size(PixelsToPhysical(pixels.Width, dpi.X),
                            PixelsToPhysical(pixels.Height, dpi.Y)); 
        }

        /// 
        ///  
        ///     Resets the back color to the defaults for the PrintPreviewControl.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public override void ResetBackColor() {
            BackColor = SystemColors.AppWorkspace; 
        }

        /// 
        ///  
        ///     Resets the back color to the defaults for the PrintPreviewControl.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public override void ResetForeColor() {
            ForeColor = Color.White; 
        }

        /// 
        ///     WM_HSCROLL handler 
        /// 
        ///  
        ///  

        private void WmHScroll(ref Message m) { 

            // The lparam is handle of the sending scrollbar, or NULL when
            // the scrollbar sending the message is the "form" scrollbar...
            // 
            if (m.LParam != IntPtr.Zero) {
                base.WndProc(ref m); 
                return; 
            }
 
            Point locPos = position;
            int pos = locPos.X;
            int maxPos = Math.Max(Width, virtualSize.Width /*- Width*/);
 
            locPos.X = AdjustScroll(m, pos, maxPos, true);
            Position = locPos; 
        } 

        private void SetPositionNoInvalidate(Point value) { 
            Point current = position;

            position = value;
            position.X = Math.Min(position.X, virtualSize.Width - Width); 
            position.Y = Math.Min(position.Y, virtualSize.Height - Height);
            if (position.X < 0) position.X = 0; 
            if (position.Y < 0) position.Y = 0; 

            Rectangle rect = ClientRectangle; 
            NativeMethods.RECT scroll = NativeMethods.RECT.FromXYWH(rect.X, rect.Y, rect.Width, rect.Height);
            SafeNativeMethods.ScrollWindow(new HandleRef(this, Handle),
                                 current.X - position.X,
                                 current.Y - position.Y, 
                                 ref scroll,
                                 ref scroll); 
 
            UnsafeNativeMethods.SetScrollPos(new HandleRef(this, Handle), NativeMethods.SB_HORZ, position.X, true);
            UnsafeNativeMethods.SetScrollPos(new HandleRef(this, Handle), NativeMethods.SB_VERT, position.Y, true); 
        }

        internal void SetVirtualSizeNoInvalidate(Size value) {
            virtualSize = value; 
            SetPositionNoInvalidate(position); // Make sure it's within range
 
            NativeMethods.SCROLLINFO info = new NativeMethods.SCROLLINFO(); 
            info.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE;
            info.nMin = 0; 
            info.nMax = Math.Max(Height, virtualSize.Height) - 1;
            info.nPage = Height;
            UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_VERT, info, true);
 
            info.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE;
            info.nMin = 0; 
            info.nMax = Math.Max(Width, virtualSize.Width) - 1; 
            info.nPage = Width;
            UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_HORZ, info, true); 
        }

        /// 
        ///     WM_VSCROLL handler 
        /// 
        ///  
        ///  

        private void WmVScroll(ref Message m) { 

            // The lparam is handle of the sending scrollbar, or NULL when
            // the scrollbar sending the message is the "form" scrollbar...
            // 
            if (m.LParam != IntPtr.Zero) {
                base.WndProc(ref m); 
                return; 
            }
 
            Point locPos = Position;
            int pos = locPos.Y;
            int maxPos = Math.Max(Height, virtualSize.Height/* - Height*/);
 
            locPos.Y = AdjustScroll(m, pos, maxPos, false);
            Position = locPos; 
        } 

        ///  
        /// 
        ///     Handles the WM_KEYDOWN message.
        /// 
        ///  
        //added to handle keyboard events(71009)subhag
        // 
        private void WmKeyDown(ref Message msg) { 

            Keys keyData = (Keys)((int)msg.WParam | (int)ModifierKeys); 
            Point locPos = Position;
            int pos = 0;
            int maxPos = 0;
 
            switch (keyData & Keys.KeyCode) {
                case Keys.PageUp: 
                    if ((keyData & Keys.Modifiers) == Keys.Control) 
                    {
                        pos = locPos.X; 
                        if (pos > SCROLL_PAGE) {
                            pos-=SCROLL_PAGE;
                        }
                        else { 
                            pos = 0;
                        } 
                        locPos.X = pos; 
                        Position = locPos;
                    } 
                    else if (StartPage > 0)
                    {
                        StartPage--;
                    } 
                    break;
                case Keys.PageDown: 
                    if ((keyData & Keys.Modifiers) == Keys.Control) 
                    {
                        pos = locPos.X; 
                        maxPos = Math.Max(Width, virtualSize.Width /*- Width*/);
                        if (pos < maxPos-SCROLL_PAGE) {
                            pos+=SCROLL_PAGE;
                        } 
                        else {
                            pos = maxPos; 
                        } 
                        locPos.X = pos;
                        Position = locPos; 
                    }
                    else if (StartPage < pageInfo.Length)
                    {
                        StartPage++; 
                    }
                    break; 
                case Keys.Home: 
                    if ((keyData & Keys.Modifiers) == Keys.Control)
                         StartPage=0; 
                    break;
                case Keys.End:
                    if ((keyData & Keys.Modifiers) == Keys.Control)
                         StartPage=pageInfo.Length; 
                    break;
 
                case Keys.Up: 
                    pos = locPos.Y;
                    if (pos > SCROLL_LINE) 
                    {
                        pos-=SCROLL_LINE;
                    }
                    else { 
                        pos = 0;
                    } 
                    locPos.Y = pos; 
                    Position = locPos;
                    break; 
                case Keys.Down:

                    pos = locPos.Y;
                    maxPos = Math.Max(Height, virtualSize.Height/* - Height*/); 

                    if (pos < maxPos-SCROLL_LINE) { 
                        pos+=SCROLL_LINE; 
                    }
                    else { 
                        pos = maxPos;
                    }
                    locPos.Y = pos;
                    Position = locPos; 
                    break;
                case Keys.Left: 
 
                    pos = locPos.X;
                    if (pos > SCROLL_LINE) { 
                        pos-=SCROLL_LINE;
                    }
                    else {
                        pos = 0; 
                    }
                    locPos.X = pos; 
                    Position = locPos; 
                    break;
                case Keys.Right: 
                    pos = locPos.X;
                    maxPos = Math.Max(Width, virtualSize.Width /*- Width*/);
                    if (pos < maxPos-SCROLL_LINE) {
                        pos+=SCROLL_LINE; 
                    }
                    else { 
                        pos = maxPos; 
                    }
                    locPos.X = pos; 
                    Position = locPos;
                    break;
            }
        } 

        ///  
        ///  
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m) { 
            switch (m.Msg) {
                case NativeMethods.WM_VSCROLL:
                    WmVScroll(ref m);
                    break; 
                case NativeMethods.WM_HSCROLL:
                    WmHScroll(ref m); 
                    break; 
                //added case to handle keyboard events(71009)subhag
                // 
                case NativeMethods.WM_KEYDOWN:
                    WmKeyDown(ref m);
                    break;
                default: 
                    base.WndProc(ref m);
                    break; 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Indicates whether the  property should be 
        ///       persisted.
        ///     
        ///  
        internal override bool ShouldSerializeBackColor() {
            return !BackColor.Equals(SystemColors.AppWorkspace); 
        }

        /// 
        ///  
        ///    
        ///       Indicates whether the  property should be 
        ///       persisted. 
        ///    
        ///  
        internal override bool ShouldSerializeForeColor() {
            return !ForeColor.Equals(Color.White);
        }
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.PrintPreviewControl.PhysicalToPixels(System.Drawing.Size,System.Drawing.Point):System.Drawing.Size")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.PrintPreviewControl.PixelsToPhysical(System.Drawing.Size,System.Drawing.Point):System.Drawing.Size")] 
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="System.Windows.Forms.PrintPreviewControl.set_VirtualSize(System.Drawing.Size):System.Void")] 

namespace System.Windows.Forms { 
    using System.Runtime.Serialization.Formatters;
    using System.Runtime.InteropServices;
    using System.Runtime.Remoting;
    using System.Diagnostics; 
    using System;
    using System.Security.Permissions; 
    using System.Drawing; 
    using Microsoft.Win32;
    using System.ComponentModel; 
    using System.Drawing.Printing;
    using CodeAccessPermission = System.Security.CodeAccessPermission;
    using System.Globalization;
 
    /// 
    ///  
    ///     
    ///       The raw "preview" part of print previewing, without any dialogs or buttons.
    ///       Most PrintPreviewControl's are found on PrintPreviewDialog's, 
    ///       but they don't have to be.
    ///    
    /// 
    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [DefaultProperty("Document")] 
    [SRDescription(SR.DescriptionPrintPreviewControl)] 
    public class PrintPreviewControl : Control {
        Size virtualSize = new Size(1,1); 
        Point position = new Point(0,0);
        Point lastOffset;
        bool antiAlias;
 
        private const int SCROLL_PAGE = 100;
        private const int SCROLL_LINE = 5; 
        private const double DefaultZoom = .3; 

        private const int border = 10; // spacing per page, in mm 

        private PrintDocument document;
        private PreviewPageInfo[] pageInfo; // null if needs refreshing
        private int startPage;  // 0-based 
        private int rows = 1;
        private int columns = 1; 
        private bool autoZoom = true; 

        // The following are all computed by ComputeLayout 
        private bool layoutOk;
        private Size imageSize = System.Drawing.Size.Empty; // 100ths of inch, not pixels
        private Point screendpi = Point.Empty;
        private double zoom = DefaultZoom; 
        bool pageInfoCalcPending;
        bool exceptionPrinting; 
 
        /// 
        ///  
        ///    
        ///       Initializes a new instance of the  class.
        ///    
        ///  
        public PrintPreviewControl() {
            ResetBackColor(); 
            ResetForeColor(); 
            Size = new Size(100, 100);
            SetStyle(ControlStyles.ResizeRedraw, false); 
            SetStyle(ControlStyles.Opaque | ControlStyles.OptimizedDoubleBuffer, true);

        }
 
        /// 
        [ 
        SRCategory(SR.CatBehavior), 
        DefaultValue(false),
        SRDescription(SR.PrintPreviewAntiAliasDescr) 
        ]
        public bool UseAntiAlias {
            get {
                return antiAlias; 
            }
            set { 
                antiAlias = value; 
            }
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets a value If true (the default), resizing the control or changing the number of pages shown
        ///       will automatically adjust Zoom to make everything visible. 
        ///     
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(true),
        SRDescription(SR.PrintPreviewAutoZoomDescr)
        ] 
        public bool AutoZoom {
            get { return autoZoom;} 
            set { 
                if (autoZoom != value) {
                    autoZoom = value; 
                    InvalidateLayout();
                }
            }
        } 

        ///  
        ///  
        ///    
        ///       Gets or sets a value indicating the document to preview. 
        ///
        ///    
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(null), 
        SRDescription(SR.PrintPreviewDocumentDescr) 
        ]
        public PrintDocument Document { 
            get { return document;}
            set {
                document = value;
                InvalidatePreview(); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets the number of pages
        ///       displayed horizontally across the screen.
        ///     
        /// 
        [ 
        DefaultValue(1), 
        SRCategory(SR.CatLayout),
        SRDescription(SR.PrintPreviewColumnsDescr) 
        ]
        public int Columns {
            get { return columns;}
            set { 
                if (value < 1 ) {
                    throw new ArgumentOutOfRangeException("Columns", SR.GetString(SR.InvalidLowBoundArgumentEx, "Columns", value.ToString(CultureInfo.CurrentCulture), (1).ToString(CultureInfo.CurrentCulture))); 
                } 

                columns = value; 
                InvalidateLayout();
            }
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Gets the CreateParams used to create the window. 
        ///       If a subclass overrides this function, it must call the base implementation.
        ///
        ///    
        ///  
        protected override CreateParams CreateParams {
            [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] 
            get { 
                CreateParams cp = base.CreateParams;
                cp.Style |= NativeMethods.WS_HSCROLL; 
                cp.Style |= NativeMethods.WS_VSCROLL;
                return cp;
            }
        } 

        ///  
        ///  
        ///     The virtual coordinate of the upper left visible pixel.
        ///  

        [
        SRCategory(SR.CatLayout),
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRDescription(SR.ControlWithScrollbarsPositionDescr) 
        ] 
        private Point Position {
            get { return position;} 
            set {
                SetPositionNoInvalidate(value);
            }
        } 

        ///  
        ///  
        ///    
        ///       Gets or sets the number of pages 
        ///       displayed vertically down the screen.
        ///    
        /// 
        [ 
        DefaultValue(1),
        SRDescription(SR.PrintPreviewRowsDescr), 
        SRCategory(SR.CatBehavior) 
        ]
        public int Rows { 
            get { return rows;}
            set {

                if (value < 1 ) { 
                    throw new ArgumentOutOfRangeException("Rows", SR.GetString(SR.InvalidLowBoundArgumentEx, "Rows", value.ToString(CultureInfo.CurrentCulture), (1).ToString(CultureInfo.CurrentCulture)));
                } 
 
                rows = value;
                InvalidateLayout(); 
            }
        }

        ///  
        /// 
        ///     This is used for international applications where the language 
        ///     is written from RightToLeft. When this property is true, 
        ///     control placement and text will be from right to left.
        ///  
        [
        SRCategory(SR.CatAppearance),
        Localizable(true),
        AmbientValue(RightToLeft.Inherit), 
        SRDescription(SR.ControlRightToLeftDescr)
        ] 
        public override RightToLeft RightToLeft { 
            get {
                return base.RightToLeft; 
            }
            set {
                base.RightToLeft = value;
                InvalidatePreview(); 
            }
        } 
 
        /// 
        [ 
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        Bindable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public override string Text {
            get { 
                return base.Text; 
            }
            set { 
                base.Text = value;
            }
        }
 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        new public event EventHandler TextChanged {
            add { 
                base.TextChanged += value;
            }
            remove {
                base.TextChanged -= value; 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets the page number of the upper left page.
        ///
        ///     
        /// 
        [ 
        DefaultValue(0), 
        SRDescription(SR.PrintPreviewStartPageDescr),
        SRCategory(SR.CatBehavior) 
        ]
        public int StartPage {
            get {
                int value = startPage; 
                if (pageInfo != null) {
                    value = Math.Min(value, pageInfo.Length - (rows * columns)); 
                } 
                value = Math.Max(value, 0);
 
                return value;
            }
            set {
                if (value < 0 ) { 
                    throw new ArgumentOutOfRangeException("StartPage", SR.GetString(SR.InvalidLowBoundArgumentEx, "StartPage", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture)));
                } 
                int oldValue = StartPage; 
                startPage = value;
                if (oldValue != startPage) { 
                    InvalidateLayout();
                    OnStartPageChanged(EventArgs.Empty);
                }
            } 
        }
 
        private static readonly object EVENT_STARTPAGECHANGED = new object(); 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.RadioButtonOnStartPageChangedDescr)] 
        public event EventHandler StartPageChanged {
            add { 
                Events.AddHandler(EVENT_STARTPAGECHANGED, value); 
            }
            remove { 
                Events.RemoveHandler(EVENT_STARTPAGECHANGED, value);
            }
        }
 
        /// 
        ///  
        ///     How big the control would be if the screen was infinitely large. 
        /// 
        [ 
        SRCategory(SR.CatLayout),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRDescription(SR.ControlWithScrollbarsVirtualSizeDescr) 
        ]
        private Size VirtualSize { 
            get { return virtualSize;} 
            set {
                SetVirtualSizeNoInvalidate(value); 
                Invalidate();
            }
        }
 
        /// 
        ///  
        ///     
        ///       Gets or sets a value indicating how large the pages will appear.
        ///     
        /// 
        [
        SRCategory(SR.CatBehavior),
        SRDescription(SR.PrintPreviewZoomDescr), 
        DefaultValue(DefaultZoom)
        ] 
        public double Zoom { 
            get { return zoom;}
            set { 
                if (value <= 0)
                    throw new ArgumentException(SR.GetString(SR.PrintPreviewControlZoomNegative));
                autoZoom = false;
                zoom = value; 
                InvalidateLayout();
            } 
        } 

        private int AdjustScroll(Message m, int pos, int maxPos, bool horizontal) { 
            switch (NativeMethods.Util.LOWORD(m.WParam)) {
                case NativeMethods.SB_THUMBPOSITION:
                case NativeMethods.SB_THUMBTRACK:
                    NativeMethods.SCROLLINFO si = new NativeMethods.SCROLLINFO(); 
                    si.cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO));
                    si.fMask = NativeMethods.SIF_TRACKPOS; 
                    int direction = horizontal ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; 
                    if (SafeNativeMethods.GetScrollInfo(new HandleRef(this, m.HWnd), direction, si))
                    { 
                        pos = si.nTrackPos;
                    }
                    else
                    { 
                        pos = NativeMethods.Util.HIWORD(m.WParam);
                    } 
                    break; 
                case NativeMethods.SB_LINEUP:
                    if (pos > SCROLL_LINE) { 
                        pos-=SCROLL_LINE;
                    }
                    else {
                        pos = 0; 
                    }
                    break; 
                case NativeMethods.SB_LINEDOWN: 
                    if (pos < maxPos-SCROLL_LINE) {
                        pos+=SCROLL_LINE; 
                    }
                    else {
                        pos = maxPos;
                    } 
                    break;
                case NativeMethods.SB_PAGEUP: 
                    if (pos > SCROLL_PAGE) { 
                        pos-=SCROLL_PAGE;
                    } 
                    else {
                        pos = 0;
                    }
                    break; 
                case NativeMethods.SB_PAGEDOWN:
                    if (pos < maxPos-SCROLL_PAGE) { 
                        pos+=SCROLL_PAGE; 
                    }
                    else { 
                        pos = maxPos;
                    }
                    break;
            } 
            return pos;
        } 
 

        // This function computes everything in terms of physical size (millimeters), not pixels 
        //
        private void ComputeLayout() {
            Debug.Assert(pageInfo != null, "Must call ComputePreview first");
            layoutOk = true; 
            if (pageInfo.Length == 0) {
                ClientSize = Size; 
                return; 
            }
 
            Graphics tempGraphics = CreateGraphicsInternal();
            IntPtr dc = tempGraphics.GetHdc();
            screendpi = new Point(UnsafeNativeMethods.GetDeviceCaps(new HandleRef(tempGraphics, dc), NativeMethods.LOGPIXELSX),
                                  UnsafeNativeMethods.GetDeviceCaps(new HandleRef(tempGraphics, dc), NativeMethods.LOGPIXELSY)); 
            tempGraphics.ReleaseHdcInternal(dc);
            tempGraphics.Dispose(); 
 
            Size pageSize = pageInfo[StartPage].PhysicalSize;
            Size controlPhysicalSize = new Size(PixelsToPhysical(new Point(Size), screendpi)); 

            if (autoZoom) {
                double zoomX = ((double) controlPhysicalSize.Width - border*(columns + 1)) / (columns*pageSize.Width);
                double zoomY = ((double) controlPhysicalSize.Height - border*(rows + 1)) / (rows*pageSize.Height); 
                zoom = Math.Min(zoomX, zoomY);
            } 
 
            imageSize = new Size((int) (zoom*pageSize.Width), (int) (zoom*pageSize.Height));
            int virtualX = (imageSize.Width * columns) + border * (columns +1); 
            int virtualY = (imageSize.Height * rows) + border * (rows +1);
            SetVirtualSizeNoInvalidate(new Size(PhysicalToPixels(new Point(virtualX, virtualY), screendpi)));
        }
 
        // "Prints" the document to memory
        private void ComputePreview() { 
            int oldStart = StartPage; 

            if (document == null) 
                pageInfo = new PreviewPageInfo[0];
            else {
                IntSecurity.SafePrinting.Demand();
 
                PrintController oldController = document.PrintController;
                PreviewPrintController previewController = new PreviewPrintController(); 
                previewController.UseAntiAlias = UseAntiAlias; 
                document.PrintController = new PrintControllerWithStatusDialog(previewController,
                                                                               SR.GetString(SR.PrintControllerWithStatusDialog_DialogTitlePreview)); 

                // Want to make sure we've reverted any security asserts before we call Print -- that calls into user code
                document.Print();
                pageInfo = previewController.GetPreviewPageInfo(); 
                Debug.Assert(pageInfo != null, "ReviewPrintController did not give us preview info");
 
                document.PrintController = oldController; 
            }
 
            if (oldStart != StartPage) {
                OnStartPageChanged(EventArgs.Empty);
            }
        } 

        // Recomputes the sizes and positions of pages without forcing a new "preview print" 
        private void InvalidateLayout() { 
            layoutOk = false;
            Invalidate(); 
        }

        /// 
        ///  
        ///    
        ///       Refreshes the preview of the document. 
        ///     
        /// 
        public void InvalidatePreview() { 
            pageInfo = null;
            InvalidateLayout();
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Invalidate the layout, if necessary. 
        ///    
        /// 
        protected override void OnResize(EventArgs eventargs) {
            InvalidateLayout(); 
            base.OnResize(eventargs);
        } 
 
        void CalculatePageInfo() {
            if (pageInfoCalcPending) { 
                return;
            }

            pageInfoCalcPending = true; 
            try {
                if (pageInfo == null) { 
                    try { 
                        ComputePreview();
                    } 
                    catch {
                        exceptionPrinting = true;
                        throw;
                    } 
                    finally {
                        Invalidate(); 
                    } 
                }
            } 
            finally {
                pageInfoCalcPending = false;
            }
        } 

 
        ///  
        /// 
        ///  
        ///    
        ///       Paints the control.
        ///    
        ///  
        protected override void OnPaint(PaintEventArgs pevent) {
            Brush backBrush = new SolidBrush(BackColor); 
 
            try {
                if (pageInfo == null || pageInfo.Length == 0) { 
                    pevent.Graphics.FillRectangle(backBrush, ClientRectangle);

                    if (pageInfo != null || exceptionPrinting) {
                        // Calculate formats 
                        StringFormat format = new StringFormat();
                        format.Alignment = ControlPaint.TranslateAlignment(ContentAlignment.MiddleCenter); 
                        format.LineAlignment = ControlPaint.TranslateLineAlignment(ContentAlignment.MiddleCenter); 

                        // Do actual drawing 
                        SolidBrush brush = new SolidBrush(ForeColor);
                        try {
                            if (exceptionPrinting) {
                                pevent.Graphics.DrawString(SR.GetString(SR.PrintPreviewExceptionPrinting), Font, brush, ClientRectangle, format); 
                            }
                            else { 
                                pevent.Graphics.DrawString(SR.GetString(SR.PrintPreviewNoPages), Font, brush, ClientRectangle, format); 
                            }
                        } 
                        finally {
                            brush.Dispose();
                            format.Dispose();
                        } 
                    }
                    else { 
                        BeginInvoke(new MethodInvoker(CalculatePageInfo)); 
                    }
                 } 
                else {
                    if (!layoutOk)
                        ComputeLayout();
 
                    Size controlPhysicalSize = new Size(PixelsToPhysical(new Point(Size), screendpi));
 
                    //Point imagePixels = PhysicalToPixels(new Point(imageSize), screendpi); 
                    Point virtualPixels = new Point(VirtualSize);
 
                    // center pages on screen if small enough
                    Point offset = new Point(Math.Max(0, (Size.Width - virtualPixels.X) / 2),
                                             Math.Max(0, (Size.Height - virtualPixels.Y) / 2));
                    offset.X -= Position.X; 
                    offset.Y -= Position.Y;
                    lastOffset = offset; 
 
                    int borderPixelsX = PhysicalToPixels(border, screendpi.X);
                    int borderPixelsY = PhysicalToPixels(border, screendpi.Y); 

                    Region originalClip = pevent.Graphics.Clip;
                    Rectangle[] pageRenderArea = new Rectangle[rows * columns];
                    Point lastImageSize = Point.Empty; 
                    int maxImageHeight = 0;
 
                    try { 
                        for (int row = 0; row < rows; row++) {
                            //Initialize our LastImageSize variable... 
                            lastImageSize.X = 0;
                            lastImageSize.Y = maxImageHeight * row;

                            for (int column = 0; column < columns; column++) { 
                                int imageIndex = StartPage + column + row*columns;
                                if (imageIndex < pageInfo.Length) { 
 
                                    Size pageSize = pageInfo[imageIndex].PhysicalSize;
                                    if (autoZoom) { 
                                        double zoomX = ((double) controlPhysicalSize.Width - border*(columns + 1)) / (columns*pageSize.Width);
                                        double zoomY = ((double) controlPhysicalSize.Height - border*(rows + 1)) / (rows*pageSize.Height);
                                        zoom = Math.Min(zoomX, zoomY);
                                    } 

                                    imageSize = new Size((int) (zoom*pageSize.Width), (int) (zoom*pageSize.Height)); 
                                    Point imagePixels = PhysicalToPixels(new Point(imageSize), screendpi); 

 
                                    int x = offset.X + borderPixelsX * (column + 1) + lastImageSize.X;
                                    int y = offset.Y + borderPixelsY * (row + 1) + lastImageSize.Y;

                                    lastImageSize.X += imagePixels.X; 
                                    //The Height is the Max of any PageHeight..
                                    maxImageHeight = Math.Max(maxImageHeight, imagePixels.Y); 
 
                                    pageRenderArea[imageIndex - StartPage] = new Rectangle(x, y, imagePixels.X, imagePixels.Y);
                                    pevent.Graphics.ExcludeClip(pageRenderArea[imageIndex - StartPage]); 
                                }
                            }
                        }
 
                        pevent.Graphics.FillRectangle(backBrush, ClientRectangle);
                    } 
                    finally { 
                        pevent.Graphics.Clip = originalClip;
                    } 

                    for (int i=0; i 
        /// 
        ///    [To be supplied.]
        /// 
        protected virtual void OnStartPageChanged(EventArgs e) { 
            EventHandler eh = Events[EVENT_STARTPAGECHANGED] as EventHandler;
            if (eh != null) { 
                eh(this, e); 
            }
        } 

        private static int PhysicalToPixels(int physicalSize, int dpi) {
            return(int) (physicalSize * dpi / 100.0);
        } 

        private static Point PhysicalToPixels(Point physical, Point dpi) { 
            return new Point(PhysicalToPixels(physical.X, dpi.X), 
                             PhysicalToPixels(physical.Y, dpi.Y));
        } 

        private static Size PhysicalToPixels(Size physicalSize, Point dpi) {
            return new Size(PhysicalToPixels(physicalSize.Width, dpi.X),
                            PhysicalToPixels(physicalSize.Height, dpi.Y)); 
        }
 
        private static int PixelsToPhysical(int pixels, int dpi) { 
            return(int) (pixels * 100.0 / dpi);
        } 

        private static Point PixelsToPhysical(Point pixels, Point dpi) {
            return new Point(PixelsToPhysical(pixels.X, dpi.X),
                             PixelsToPhysical(pixels.Y, dpi.Y)); 
        }
 
        private static Size PixelsToPhysical(Size pixels, Point dpi) { 
            return new Size(PixelsToPhysical(pixels.Width, dpi.X),
                            PixelsToPhysical(pixels.Height, dpi.Y)); 
        }

        /// 
        ///  
        ///     Resets the back color to the defaults for the PrintPreviewControl.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public override void ResetBackColor() {
            BackColor = SystemColors.AppWorkspace; 
        }

        /// 
        ///  
        ///     Resets the back color to the defaults for the PrintPreviewControl.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public override void ResetForeColor() {
            ForeColor = Color.White; 
        }

        /// 
        ///     WM_HSCROLL handler 
        /// 
        ///  
        ///  

        private void WmHScroll(ref Message m) { 

            // The lparam is handle of the sending scrollbar, or NULL when
            // the scrollbar sending the message is the "form" scrollbar...
            // 
            if (m.LParam != IntPtr.Zero) {
                base.WndProc(ref m); 
                return; 
            }
 
            Point locPos = position;
            int pos = locPos.X;
            int maxPos = Math.Max(Width, virtualSize.Width /*- Width*/);
 
            locPos.X = AdjustScroll(m, pos, maxPos, true);
            Position = locPos; 
        } 

        private void SetPositionNoInvalidate(Point value) { 
            Point current = position;

            position = value;
            position.X = Math.Min(position.X, virtualSize.Width - Width); 
            position.Y = Math.Min(position.Y, virtualSize.Height - Height);
            if (position.X < 0) position.X = 0; 
            if (position.Y < 0) position.Y = 0; 

            Rectangle rect = ClientRectangle; 
            NativeMethods.RECT scroll = NativeMethods.RECT.FromXYWH(rect.X, rect.Y, rect.Width, rect.Height);
            SafeNativeMethods.ScrollWindow(new HandleRef(this, Handle),
                                 current.X - position.X,
                                 current.Y - position.Y, 
                                 ref scroll,
                                 ref scroll); 
 
            UnsafeNativeMethods.SetScrollPos(new HandleRef(this, Handle), NativeMethods.SB_HORZ, position.X, true);
            UnsafeNativeMethods.SetScrollPos(new HandleRef(this, Handle), NativeMethods.SB_VERT, position.Y, true); 
        }

        internal void SetVirtualSizeNoInvalidate(Size value) {
            virtualSize = value; 
            SetPositionNoInvalidate(position); // Make sure it's within range
 
            NativeMethods.SCROLLINFO info = new NativeMethods.SCROLLINFO(); 
            info.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE;
            info.nMin = 0; 
            info.nMax = Math.Max(Height, virtualSize.Height) - 1;
            info.nPage = Height;
            UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_VERT, info, true);
 
            info.fMask = NativeMethods.SIF_RANGE | NativeMethods.SIF_PAGE;
            info.nMin = 0; 
            info.nMax = Math.Max(Width, virtualSize.Width) - 1; 
            info.nPage = Width;
            UnsafeNativeMethods.SetScrollInfo(new HandleRef(this, Handle), NativeMethods.SB_HORZ, info, true); 
        }

        /// 
        ///     WM_VSCROLL handler 
        /// 
        ///  
        ///  

        private void WmVScroll(ref Message m) { 

            // The lparam is handle of the sending scrollbar, or NULL when
            // the scrollbar sending the message is the "form" scrollbar...
            // 
            if (m.LParam != IntPtr.Zero) {
                base.WndProc(ref m); 
                return; 
            }
 
            Point locPos = Position;
            int pos = locPos.Y;
            int maxPos = Math.Max(Height, virtualSize.Height/* - Height*/);
 
            locPos.Y = AdjustScroll(m, pos, maxPos, false);
            Position = locPos; 
        } 

        ///  
        /// 
        ///     Handles the WM_KEYDOWN message.
        /// 
        ///  
        //added to handle keyboard events(71009)subhag
        // 
        private void WmKeyDown(ref Message msg) { 

            Keys keyData = (Keys)((int)msg.WParam | (int)ModifierKeys); 
            Point locPos = Position;
            int pos = 0;
            int maxPos = 0;
 
            switch (keyData & Keys.KeyCode) {
                case Keys.PageUp: 
                    if ((keyData & Keys.Modifiers) == Keys.Control) 
                    {
                        pos = locPos.X; 
                        if (pos > SCROLL_PAGE) {
                            pos-=SCROLL_PAGE;
                        }
                        else { 
                            pos = 0;
                        } 
                        locPos.X = pos; 
                        Position = locPos;
                    } 
                    else if (StartPage > 0)
                    {
                        StartPage--;
                    } 
                    break;
                case Keys.PageDown: 
                    if ((keyData & Keys.Modifiers) == Keys.Control) 
                    {
                        pos = locPos.X; 
                        maxPos = Math.Max(Width, virtualSize.Width /*- Width*/);
                        if (pos < maxPos-SCROLL_PAGE) {
                            pos+=SCROLL_PAGE;
                        } 
                        else {
                            pos = maxPos; 
                        } 
                        locPos.X = pos;
                        Position = locPos; 
                    }
                    else if (StartPage < pageInfo.Length)
                    {
                        StartPage++; 
                    }
                    break; 
                case Keys.Home: 
                    if ((keyData & Keys.Modifiers) == Keys.Control)
                         StartPage=0; 
                    break;
                case Keys.End:
                    if ((keyData & Keys.Modifiers) == Keys.Control)
                         StartPage=pageInfo.Length; 
                    break;
 
                case Keys.Up: 
                    pos = locPos.Y;
                    if (pos > SCROLL_LINE) 
                    {
                        pos-=SCROLL_LINE;
                    }
                    else { 
                        pos = 0;
                    } 
                    locPos.Y = pos; 
                    Position = locPos;
                    break; 
                case Keys.Down:

                    pos = locPos.Y;
                    maxPos = Math.Max(Height, virtualSize.Height/* - Height*/); 

                    if (pos < maxPos-SCROLL_LINE) { 
                        pos+=SCROLL_LINE; 
                    }
                    else { 
                        pos = maxPos;
                    }
                    locPos.Y = pos;
                    Position = locPos; 
                    break;
                case Keys.Left: 
 
                    pos = locPos.X;
                    if (pos > SCROLL_LINE) { 
                        pos-=SCROLL_LINE;
                    }
                    else {
                        pos = 0; 
                    }
                    locPos.X = pos; 
                    Position = locPos; 
                    break;
                case Keys.Right: 
                    pos = locPos.X;
                    maxPos = Math.Max(Width, virtualSize.Width /*- Width*/);
                    if (pos < maxPos-SCROLL_LINE) {
                        pos+=SCROLL_LINE; 
                    }
                    else { 
                        pos = maxPos; 
                    }
                    locPos.X = pos; 
                    Position = locPos;
                    break;
            }
        } 

        ///  
        ///  
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m) { 
            switch (m.Msg) {
                case NativeMethods.WM_VSCROLL:
                    WmVScroll(ref m);
                    break; 
                case NativeMethods.WM_HSCROLL:
                    WmHScroll(ref m); 
                    break; 
                //added case to handle keyboard events(71009)subhag
                // 
                case NativeMethods.WM_KEYDOWN:
                    WmKeyDown(ref m);
                    break;
                default: 
                    base.WndProc(ref m);
                    break; 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Indicates whether the  property should be 
        ///       persisted.
        ///     
        ///  
        internal override bool ShouldSerializeBackColor() {
            return !BackColor.Equals(SystemColors.AppWorkspace); 
        }

        /// 
        ///  
        ///    
        ///       Indicates whether the  property should be 
        ///       persisted. 
        ///    
        ///  
        internal override bool ShouldSerializeForeColor() {
            return !ForeColor.Equals(Color.White);
        }
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK