Now I'm A Farmer(Peter-KIM)


[C#] RTF to Image

Filed under: Programming — Peter_KIM @ 07:45

WIN32 EM_FORMATRANGE 메시지를 이용하여,Rich Edit Control (RichTextBox)내부에 존재하는 RTF 문서를 이미지 형태로 변환합니다.


그림의 왼쪽은 RichTextBox 컨트롤이고, 오른쪽은 PictureBox 컨트롤입니다.


우선, RichTextBox 클래스를 상속받는 클래스를 아래와 같이 작성합니다.

using System;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;


public class RichTextBoxPrintCtrl : RichTextBox


    //Convert the unit used by the .NET framework (1/100 inch)

    //and the unit used by Win32 API calls (twips 1/1440 inch)

    private const double anInch = 14.4;



    private struct RECT


        public int Left;

        public int Top;

        public int Right;

        public int Bottom;




    private struct CHARRANGE


        public int cpMin;         //First character of range (0 for start of doc)

        public int cpMax;         //Last character of range (-1 for end of doc)




    private struct FORMATRANGE


        public IntPtr hdc;             //Actual DC to draw on

        public IntPtr hdcTarget;       //Target DC for determining text formatting

        public RECT rc;                //Region of the DC to draw to (in twips)

        public RECT rcPage;            //Region of the whole DC (page size) (in twips)

        public CHARRANGE chrg;         //Range of text to draw (see earlier declaration)



    private const int WM_USER = 0x0400;

    private const int EM_FORMATRANGE = WM_USER + 57;



    private static extern IntPtr SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam);


    public int PrintImage(int nStartFrom, Graphics g)


        RECT rcToPrint = default(RECT);

        FORMATRANGE fr = default(FORMATRANGE);

        IntPtr iptHdc = IntPtr.Zero;

        IntPtr iptRes = IntPtr.Zero;

        IntPtr iptParam = IntPtr.Zero;


        // Calculate the area to render and print

        rcToPrint.Top = 0;

        rcToPrint.Bottom = (int)Math.Ceiling((g.VisibleClipBounds.Height * anInch));

        rcToPrint.Left = 0;

        rcToPrint.Right = (int)Math.Ceiling((g.VisibleClipBounds.Width * anInch));


        iptHdc = g.GetHdc();


        //Indicate character from to character to

        fr.chrg.cpMin = nStartFrom;

        fr.chrg.cpMax = -1;

        //Use the same DC for measuring and rendering point at printer hDC       

        fr.hdc = fr.hdcTarget = iptHdc;


        //Indicate the area on page to print

        fr.rc = rcToPrint;


        //Get the pointer to the FORMATRANGE structure in memory

        iptParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr));

        Marshal.StructureToPtr(fr, iptParam, false);


        //Send the rendered data for printing

        iptRes = SendMessage(this.Handle, EM_FORMATRANGE, 1, iptParam.ToInt32());


        //Free the block of memory allocated



        //Release the device context handle obtained by a previous call



        //Return last + 1 character printer

        return iptRes.ToInt32();



버튼을 클릭 이벤트를 아래와 같이 구현합니다.

private void btnMakeImage_Click(object sender, System.EventArgs e)


    Image image = new Bitmap(richTextBox1.Width, richTextBox1.Height + 20);

    Graphics g = Graphics.FromImage(image);


    richTextBox1.PrintImage(0, g);


    this.pictureBox1.BackColor = this.richTextBox1.BackColor;

    this.pictureBox1.Image = image;




참고 문서:

전체 소스 코드는 아래에서 내려 받을 수 있습니다.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Create a free website or blog at

%d bloggers like this: