现在的位置: 首页 > 综合 > 正文

.net C# RichTextBox的打印预览

2013年09月10日 ⁄ 综合 ⁄ 共 6498字 ⁄ 字号 评论关闭
1、继承RichTextBox,创建

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Printing;

/// <summary>
/// An extension for RichTextBox suitable for printing.
/// </summary>

public class RichTextBoxEx : RichTextBox
{
    [StructLayout(LayoutKind.Sequential)]
    
private struct STRUCT_RECT
    
{
        
public Int32 left;
        
public Int32 top;
        
public Int32 right;
        
public Int32 bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    
private struct STRUCT_CHARRANGE
    
{
        
public Int32 cpMin;
        
public Int32 cpMax;
    }


    [StructLayout(LayoutKind.Sequential)]
    
private struct STRUCT_FORMATRANGE
    
{
        
public IntPtr hdc;
        
public IntPtr hdcTarget;
        
public STRUCT_RECT rc;
        
public STRUCT_RECT rcPage;
        
public STRUCT_CHARRANGE chrg;
    }


    [StructLayout(LayoutKind.Sequential)]
    
private struct CHARFORMATSTRUCT
    
{
        
public int cbSize;
        
public UInt32 dwMask;
        
public UInt32 dwEffects;
        
public Int32 yHeight;
        
public Int32 yOffset;
        
public Int32 crTextColor;
        
public byte bCharSet;
        
public byte bPitchAndFamily;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst 
= 32)]
        
public char[] szFaceName;
    }


    [DllImport(
"user32.dll")]
    
private static extern Int32 SendMessage(IntPtr hWnd, Int32 msg,
        Int32 wParam, IntPtr lParam);

    
// Windows Messages defines
    private const Int32 WM_USER = 0x400;
    
private const Int32 EM_FORMATRANGE = WM_USER + 57;
    
private const Int32 EM_GETCHARFORMAT = WM_USER + 58;
    
private const Int32 EM_SETCHARFORMAT = WM_USER + 68;

    
// Defines for EM_SETCHARFORMAT/EM_GETCHARFORMAT
    private const Int32 SCF_SELECTION = 0x0001;
    
private const Int32 SCF_WORD = 0x0002;
    
private const Int32 SCF_ALL = 0x0004;

    
// Defines for STRUCT_CHARFORMAT member dwMask
    private const UInt32 CFM_BOLD = 0x00000001;
    
private const UInt32 CFM_ITALIC = 0x00000002;
    
private const UInt32 CFM_UNDERLINE = 0x00000004;
    
private const UInt32 CFM_STRIKEOUT = 0x00000008;
    
private const UInt32 CFM_PROTECTED = 0x00000010;
    
private const UInt32 CFM_LINK = 0x00000020;
    
private const UInt32 CFM_SIZE = 0x80000000;
    
private const UInt32 CFM_COLOR = 0x40000000;
    
private const UInt32 CFM_FACE = 0x20000000;
    
private const UInt32 CFM_OFFSET = 0x10000000;
    
private const UInt32 CFM_CHARSET = 0x08000000;

    
// Defines for STRUCT_CHARFORMAT member dwEffects
    private const UInt32 CFE_BOLD = 0x00000001;
    
private const UInt32 CFE_ITALIC = 0x00000002;
    
private const UInt32 CFE_UNDERLINE = 0x00000004;
    
private const UInt32 CFE_STRIKEOUT = 0x00000008;
    
private const UInt32 CFE_PROTECTED = 0x00000010;
    
private const UInt32 CFE_LINK = 0x00000020;
    
private const UInt32 CFE_AUTOCOLOR = 0x40000000;

    
/// <summary>
    
/// Calculate or render the contents of our RichTextBox for printing
    
/// </summary>
    
/// <param name="measureOnly">If true, only the calculation is performed,
    
/// otherwise the text is rendered as well</param>
    
/// <param name="e">The PrintPageEventArgs object from the
    
/// PrintPage event</param>
    
/// <param name="charFrom">Index of first character to be printed</param>
    
/// <param name="charTo">Index of last character to be printed</param>
    
/// <returns>(Index of last character that fitted on the
    
/// page) + 1</returns>

    public int FormatRange(bool measureOnly, PrintPageEventArgs e,
        
int charFrom, int charTo)
    
{
        
// Specify which characters to print
        STRUCT_CHARRANGE cr;
        cr.cpMin 
= charFrom;
        cr.cpMax 
= charTo;

        
// Specify the area inside page margins
        STRUCT_RECT rc;
        rc.top 
= HundredthInchToTwips(e.MarginBounds.Top);
        rc.bottom 
= HundredthInchToTwips(e.MarginBounds.Bottom);
        rc.left 
= HundredthInchToTwips(e.MarginBounds.Left);
        rc.right 
= HundredthInchToTwips(e.MarginBounds.Right);

        
// Specify the page area
        STRUCT_RECT rcPage;
        rcPage.top 
= HundredthInchToTwips(e.PageBounds.Top);
        rcPage.bottom 
= HundredthInchToTwips(e.PageBounds.Bottom);
        rcPage.left 
= HundredthInchToTwips(e.PageBounds.Left);
        rcPage.right 
= HundredthInchToTwips(e.PageBounds.Right);

        
// Get device context of output device
        IntPtr hdc = e.Graphics.GetHdc();

        
// Fill in the FORMATRANGE struct
        STRUCT_FORMATRANGE fr;
        fr.chrg 
= cr;
        fr.hdc 
= hdc;
        fr.hdcTarget 
= hdc;
        fr.rc 
= rc;
        fr.rcPage 
= rcPage;

        
// Non-Zero wParam means render, Zero means measure
        Int32 wParam = (measureOnly ? 0 : 1);

        
// Allocate memory for the FORMATRANGE struct and
        
// copy the contents of our struct to this memory
        IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr));
        Marshal.StructureToPtr(fr, lParam, 
false);

        
// Send the actual Win32 message
        int res = SendMessage(Handle, EM_FORMATRANGE, wParam, lParam);

        
// Free allocated memory
        Marshal.FreeCoTaskMem(lParam);

        
// and release the device context
        e.Graphics.ReleaseHdc(hdc);

        
return res;
    }

    
/// <summary>
    
/// Convert between 1/100 inch (unit used by the .NET framework)
    
/// and twips (1/1440 inch, used by Win32 API calls)
    
/// </summary>
    
/// <param name="n">Value in 1/100 inch</param>
    
/// <returns>Value in twips</returns>

    private Int32 HundredthInchToTwips(int n)
    
{
        
return (Int32)(n * 14.4);
    }

    
/// <summary>
    
/// Free cached data from rich edit control after printing
    
/// </summary>

    public void FormatRangeDone()
    
{
        IntPtr lParam 
= new IntPtr(0);
        SendMessage(Handle, EM_FORMATRANGE, 
0, lParam);
    }


   
    

    
/// <summary>
    
/// Sets the font size only for the selected part of the rich text box
    
/// without modifying the other properties like font or style
    
/// </summary>
    
/// <param name="size">new point size to use</param>
    
/// <returns>true on success, false on failure</returns>

    public bool SetSelectionSize(int size)
    
{
        CHARFORMATSTRUCT cf 
= new CHARFORMATSTRUCT();
        cf.cbSize 
= Marshal.SizeOf(cf);
        cf.dwMask 
= CFM_SIZE;
        
// yHeight is in 1/20 pt
        cf.yHeight = size * 20;

        IntPtr lParam 
= Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
        Marshal.StructureToPtr(cf, lParam, 
false);

        
int res = SendMessage(Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
        
return (res == 0);
    }


抱歉!评论已关闭.