473,289 Members | 1,929 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,289 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 11070

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: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...

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.