Click here to Skip to main content
15,921,622 members
Home / Discussions / .NET (Core and Framework)
   

.NET (Core and Framework)

 
Questionusing the contol.paint event Pin
Martin Beukes11-Jan-10 9:39
Martin Beukes11-Jan-10 9:39 
AnswerRe: using the contol.paint event Pin
Luc Pattyn11-Jan-10 9:54
sitebuilderLuc Pattyn11-Jan-10 9:54 
GeneralRe: using the contol.paint event Pin
Martin Beukes11-Jan-10 11:29
Martin Beukes11-Jan-10 11:29 
GeneralRe: using the contol.paint event !!! MODIFIED AGAIN !!! Pin
Luc Pattyn11-Jan-10 11:34
sitebuilderLuc Pattyn11-Jan-10 11:34 
GeneralRe: using the contol.paint event !!! MODIFIED AGAIN !!! Pin
Martin Beukes11-Jan-10 12:20
Martin Beukes11-Jan-10 12:20 
GeneralRe: using the contol.paint event Pin
Luc Pattyn11-Jan-10 12:38
sitebuilderLuc Pattyn11-Jan-10 12:38 
GeneralRe: using the contol.paint event Pin
Martin Beukes11-Jan-10 12:49
Martin Beukes11-Jan-10 12:49 
GeneralRe: using the contol.paint event Pin
Luc Pattyn11-Jan-10 12:56
sitebuilderLuc Pattyn11-Jan-10 12:56 
Here you go:

////////////////////////////////////////////////////////////////////////////////////////////////
//
//	CopyRight 2009, www.perceler.com, Luc Pattyn
//
//	Version 1.0
//
//	use freely for non-commercial use as long as this notice remains present;
//	ask me before using commercially.
//
////////////////////////////////////////////////////////////////////////////////////////////////

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

namespace LP_Core {

	/// <summary>
	/// LP_RichTextBox is an extended RichTextBox offering Print functionality (courtesy Microsoft)
	/// and a proprietary method to draw all the content to a bitmap
	/// </summary>
	/// <remarks>"http://support.microsoft.com/kb/812425"</remarks>
	[System.ComponentModel.DesignerCategory("Code")]
	class LP_RichTextBox : 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;

		[StructLayout(LayoutKind.Sequential)]
		private struct RECT {
			public int Left;
			public int Top;
			public int Right;
			public int Bottom;
		}

		[StructLayout(LayoutKind.Sequential)]
		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)
		}

		[StructLayout(LayoutKind.Sequential)]
		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;

		[DllImport("USER32.dll")]
		private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

		// Render the contents of the RichTextBox for printing
		//	Return the last character printed + 1 (printing start from this point for next page)
		// WARNING: I have not tested this method, I only used it as a starting point
		//	to create the next method!
		public int Print(int charFrom, int charTo, PrintPageEventArgs e) {
			//Calculate the area to render and print
			RECT rectToPrint;
			rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);
			rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);
			rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);
			rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);

			//Calculate the size of the page
			RECT rectPage;
			rectPage.Top = (int)(e.PageBounds.Top * anInch);
			rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);
			rectPage.Left = (int)(e.PageBounds.Left * anInch);
			rectPage.Right = (int)(e.PageBounds.Right * anInch);

			IntPtr hdc = e.Graphics.GetHdc();

			FORMATRANGE fmtRange;
			fmtRange.chrg.cpMax = charTo;		//Indicate character from to character to 
			fmtRange.chrg.cpMin = charFrom;
			fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering
			fmtRange.hdcTarget = hdc;              //Point at printer hDC
			fmtRange.rc = rectToPrint;             //Indicate the area on page to print
			fmtRange.rcPage = rectPage;            //Indicate size of page

			IntPtr res = IntPtr.Zero;

			IntPtr wparam = IntPtr.Zero;
			wparam = new IntPtr(1);

			//Get the pointer to the FORMATRANGE structure in memory
			IntPtr lparam= IntPtr.Zero;
			lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
			Marshal.StructureToPtr(fmtRange, lparam, false);

			//Send the rendered data for printing 
			res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);

			//Free the block of memory allocated
			Marshal.FreeCoTaskMem(lparam);

			//Release the device context handle obtained by a previous call
			e.Graphics.ReleaseHdc(hdc);

			//Return last + 1 character printer
			return res.ToInt32();
		}

		public void DrawToBitmap(Bitmap bitmap) {
			//Calculate the area to render and print
			RECT rectToPrint;
			rectToPrint.Top = 0;
			rectToPrint.Bottom = (int)(bitmap.Height*anInch);
			rectToPrint.Left = 0;
			rectToPrint.Right = (int)(bitmap.Width*anInch);

			//Calculate the size of the page
			RECT rectPage;
			rectPage.Top = 0;
			rectPage.Bottom = (int)(bitmap.Height*anInch);
			rectPage.Left = 0;
			rectPage.Right = (int)(bitmap.Width*anInch);

			Graphics g=Graphics.FromImage(bitmap);
			IntPtr hdc = g.GetHdc();

			FORMATRANGE fmtRange;
			// [0,-1]=everything
			fmtRange.chrg.cpMax = -1;		//Indicate character from to character to 
			fmtRange.chrg.cpMin = 0;
			fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering
			fmtRange.hdcTarget = hdc;              //Point at printer hDC
			fmtRange.rc = rectToPrint;             //Indicate the area on page to print
			fmtRange.rcPage = rectPage;            //Indicate size of page

			IntPtr res = IntPtr.Zero;

			IntPtr wparam = IntPtr.Zero;
			wparam = new IntPtr(1);

			//Get the pointer to the FORMATRANGE structure in memory
			IntPtr lparam= IntPtr.Zero;
			lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
			Marshal.StructureToPtr(fmtRange, lparam, false);

			//Send the rendered data for printing 
			res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);

			//Free the block of memory allocated
			Marshal.FreeCoTaskMem(lparam);

			//Release the device context handle obtained by a previous call
			g.ReleaseHdc(hdc);

		}
	}
}


Please let me know the results when they become available, and/or any changes you consider necessary.

Smile | :)

Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]

Happy New Year to all.
We hope 2010 soon brings us automatic PRE tags!
Until then, please insert them manually.


AnswerRe: using the contol.paint event Pin
DaveyM6911-Jan-10 10:39
professionalDaveyM6911-Jan-10 10:39 
QuestionDeployment / Permissions for control embedded in a web page Pin
sitruc711-Jan-10 5:19
sitruc711-Jan-10 5:19 
AnswerRe: Deployment / Permissions for control embedded in a web page Pin
Eddy Vluggen13-Jan-10 8:26
professionalEddy Vluggen13-Jan-10 8:26 
QuestionAccess data in a remote server Pin
jonatan_55611-Jan-10 1:39
jonatan_55611-Jan-10 1:39 
AnswerRe: Access data in a remote server Pin
dan!sh 11-Jan-10 3:39
professional dan!sh 11-Jan-10 3:39 
GeneralRe: Access data in a remote server Pin
jonatan_55611-Jan-10 4:08
jonatan_55611-Jan-10 4:08 
QuestionDesig VB.net Table Pin
Thomas O'Donoghue10-Jan-10 1:51
Thomas O'Donoghue10-Jan-10 1:51 
AnswerRe: Desig VB.net Table Pin
Ashfield10-Jan-10 5:43
Ashfield10-Jan-10 5:43 
Questionarraylist to byte array & viceversa---plz. help me....... Pin
thivya n9-Jan-10 19:16
thivya n9-Jan-10 19:16 
AnswerRe: arraylist to byte array & viceversa---plz. help me....... Pin
Luc Pattyn10-Jan-10 0:57
sitebuilderLuc Pattyn10-Jan-10 0:57 
AnswerRe: arraylist to byte array & viceversa---plz. help me....... Pin
thivya n10-Jan-10 3:01
thivya n10-Jan-10 3:01 
QuestionMessageBox with custom background color Pin
peterdrozd8-Jan-10 5:07
peterdrozd8-Jan-10 5:07 
AnswerRe: MessageBox with custom background color Pin
Richard MacCutchan8-Jan-10 5:21
mveRichard MacCutchan8-Jan-10 5:21 
GeneralRe: MessageBox with custom background color Pin
peterdrozd8-Jan-10 10:54
peterdrozd8-Jan-10 10:54 
GeneralRe: MessageBox with custom background color Pin
Richard MacCutchan8-Jan-10 22:15
mveRichard MacCutchan8-Jan-10 22:15 
AnswerRe: MessageBox with custom background color Pin
Palash Biswas4-Feb-10 2:24
Palash Biswas4-Feb-10 2:24 
QuestionRich text box equivalent textbox Pin
Ajakblackgoat7-Jan-10 20:54
Ajakblackgoat7-Jan-10 20:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.