473,387 Members | 1,724 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

c# - Printing content of RichTextBox to image in WYSIWYG mode

Dear all,

I have implemented a class to export the content of RichTextBox to
image in WYSISYG mode so that line breaks on the screen are the same as
exported.
C# Code:
[ StructLayout( LayoutKind.Sequential )]
public struct STRUCT_RECT
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}

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

[ StructLayout( LayoutKind.Sequential )]
public struct STRUCT_FORMATRANGE
{
public IntPtr hdc;
public IntPtr hdcTarget;
public STRUCT_RECT rc;
public STRUCT_RECT rcPage;
public STRUCT_CHARRANGE chrg;
}
/// <summary>
/// Summary description for RtfToPicture2.
/// </summary>
public class RtfToPicture2
{
public RtfToPicture2()
{
//
// TODO: Add constructor logic here
//
}

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

private const Int32 WM_USER = 0x400;
private const Int32 EM_FORMATRANGE = WM_USER+57;


private int m_nFirstCharOnPage;

// C#
/// <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)
public int FormatRange(bool measureOnly, ref RichTextBox RTB,
PictureBox pb, 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(0);
rc.bottom = HundredthInchToTwips(pb.Height);
rc.left = HundredthInchToTwips(0);
rc.right = HundredthInchToTwips(pb.Width);

// Specify the page area
STRUCT_RECT rcPage;
rcPage.top = HundredthInchToTwips(0);
rcPage.bottom = HundredthInchToTwips(pb.Height);
rcPage.left = HundredthInchToTwips(0);
rcPage.right = HundredthInchToTwips(pb.Width);

// Get device context of output device
Graphics g = pb.CreateGraphics();
IntPtr hdc = g.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(RTB.Handle, EM_FORMATRANGE, wParam, lParam);

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

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

g.Dispose();

return res;
}

public int FormatRange(bool measureOnly, ref RichTextBox RTB, ref
Bitmap b, 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(0);
rc.bottom = HundredthInchToTwips(b.Height);
rc.left = HundredthInchToTwips(0);
rc.right = HundredthInchToTwips(b.Width);

// Specify the page area
STRUCT_RECT rcPage;
rcPage.top = HundredthInchToTwips(0);
rcPage.bottom = HundredthInchToTwips(b.Height);
rcPage.left = HundredthInchToTwips(0);
rcPage.right = HundredthInchToTwips(b.Width);

// Get device context of output device
Graphics g = Graphics.FromImage(b);
IntPtr hdc = g.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(RTB.Handle, EM_FORMATRANGE, wParam, lParam);

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

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

g.Dispose();

return res;
}

// C#
/// <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);
}
// C#
/// <summary>
/// Free cached data from rich edit control after printing
/// </summary>
public void FormatRangeDone(ref RichTextBox RTB)
{
IntPtr lParam = new IntPtr(0);
SendMessage(RTB.Handle, EM_FORMATRANGE, 0, lParam);
}

public void RTFtoPictureBox(ref RichTextBox RTB, ref PictureBox PB)
{
this.m_nFirstCharOnPage = 0;

do
{
this.m_nFirstCharOnPage = this.FormatRange(false, ref RTB, PB,
this.m_nFirstCharOnPage, RTB.Text.Length);
if(this.m_nFirstCharOnPage!= RTB.Text.Length)
{
PB.Height +=1;
this.m_nFirstCharOnPage = 0;
}
}
while(this.m_nFirstCharOnPage < RTB.Text.Length);

this.FormatRangeDone(ref RTB);

}

public void RTFtoBitmap(ref RichTextBox RTB, ref Bitmap b)
{
this.m_nFirstCharOnPage = 0;

do
{
this.m_nFirstCharOnPage = this.FormatRange(false, ref RTB, ref b,
this.m_nFirstCharOnPage, RTB.Text.Length);
if(this.m_nFirstCharOnPage!= RTB.Text.Length)
{
b = new Bitmap(b.Width, b.Height+1);
this.m_nFirstCharOnPage = 0;
}
}
while(this.m_nFirstCharOnPage < RTB.Text.Length);

this.FormatRangeDone(ref RTB);

}

}

By using ContentsResizedEventArgs of ContentsResized function, I can
obtain the content size of RichTextBox content and create a new bitmap.
The RTFtoBitmap method of RtfToPicture2 class is then called to export
the content of RichTextBox in WYSIWYG mode to the bitmap created
before.

The class works at most of the time but I find that sometimes the line
break in the bitmap is not exactly the same as that in the richtextbox.

Does anyone have idea how to fix the above problem?

Many Thanks,
Vincent

Aug 15 '06 #1
0 11095

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: mercurius_1 | last post by:
I am having a problem with content being wrapped down the page in Internet Explorer. This is the page in question, which I have validated: www.lynngoldstein.com When the browser window is...
1
by: Sachin | last post by:
If an image is inserted in the RichTextBox at runtime, how to drag/move it inside the RichTextBox with the help of mouse, just like we can move any control on the form during design time. Please...
3
by: Ron Courteau | last post by:
All the printing examples I've found in countless books and online examples deal with text files. I want to print the contents of a form that has a couple of text boxes and 4 RichTextBoxes. I...
5
by: Urs Vogel | last post by:
Hi When printing coloured text from a RichTextbox, it turns out to be a quite and timeconsuming job to position all differently coloured strings on the Page with DrawString(). Is there a...
2
by: Dennis | last post by:
How can I print the contents of a rich text box to the graphics object of the PrintPageEventArgs and maintain all the correct colors, bolds, etc. -- Dennis in Houston
8
by: Neo Geshel | last post by:
Greetings. BACKGROUND: My sites are pure XHTML 1.1 with CSS 2.1 for markup. My pages are delivered as application/xhtml+xml for all non-MS web clients, and as text/xml for all MS web...
2
by: deepakfordotnet | last post by:
Hi, First of all let me confess that I could not get the solution to the same problem from an earlier post Printing :by Mr.Richard MSL (dated September 24th 2006) working. (Replied by Mr.Walter...
1
by: txomin | last post by:
Hi all, Following the instructions of this link http://support.microsoft.com/kb/812425, i've been able to print the content of a RichTextBox control . Apart from that , I want to have the chance...
0
by: bschomp | last post by:
Hi, when I try to print from my richtextbox it's not printing what I have typed in. I want to be able to print the image that it shows. So if I type in Hello World it will print out Hello World. This...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.