The text is wrapped to a new line, every 5 characters, and prints to a new
page every 4 lines in both the printpreview and the actual print. I tried
walking through the PrintPreview event but it doesn't go any where.
Below is code for the customized RichTextBox and the event handler code in
my application. Can you see where is causing this behavior? Thank you.
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Printing;
namespace RichTextBoxPrintCtrl
{
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 const double anInch = 1;
[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)
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();
}
}
}
private void tsPageSetup_Click(object sender, EventArgs e)
{
pageSetupDialog1.ShowDialog();
}
private void tsPagePreview_Click(object sender, EventArgs e)
{
printPreviewDialog1.ShowDialog();
}
private void tsPrint_Click(object sender, EventArgs e)
{
if (printDialog1.ShowDialog() == DialogResult.OK)
printDocument1.Print();
}
private void printDocument1_BeginPrint(object sender,
System.Drawing.Printing.PrintEventArgs e)
{
checkPrint = 0;
}
private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
// Print the content of RichTextBox. Store the last character
printed.
checkPrint = richTextBoxPrintCtrl1.Print(checkPrint,
richTextBoxPrintCtrl1.TextLength, e);
// Check for more pages
if (checkPrint < richTextBoxPrintCtrl1.TextLength)
e.HasMorePages = true;
else
e.HasMorePages = false;
}
namespace PAImport
{
partial class frmGroupMembershipLog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new
System.ComponentModel.ComponentResourceManager(typeof(frmGroupMembershipLog));
this.msMembership = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.tsPageSetup = new System.Windows.Forms.ToolStripMenuItem();
this.tsPagePreview = new System.Windows.Forms.ToolStripMenuItem();
this.tsPrint = new System.Windows.Forms.ToolStripMenuItem();
this.tsSaveAs = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.btnPrevious = new System.Windows.Forms.Button();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.btnFinish = new System.Windows.Forms.Button();
this.txtMembership = new System.Windows.Forms.TextBox();
this.btnApply = new System.Windows.Forms.Button();
this.printDialog1 = new System.Windows.Forms.PrintDialog();
this.printDocument1 = new System.Drawing.Printing.PrintDocument();
this.pageSetupDialog1 = new
System.Windows.Forms.PageSetupDialog();
this.printPreviewDialog1 = new
System.Windows.Forms.PrintPreviewDialog();
this.richTextBoxPrintCtrl1 = new
RichTextBoxPrintCtrl.RichTextBoxPrintCtrl();
this.msMembership.SuspendLayout();
this.SuspendLayout();
//
// msMembership
//
this.msMembership.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.helpToolStripMenuItem});
this.msMembership.Location = new System.Drawing.Point(0, 0);
this.msMembership.Name = "msMembership";
this.msMembership.Size = new System.Drawing.Size(972, 24);
this.msMembership.TabIndex = 0;
this.msMembership.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.tsPageSetup,
this.tsPagePreview,
this.tsPrint,
this.tsSaveAs});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// tsPageSetup
//
this.tsPageSetup.Name = "tsPageSetup";
this.tsPageSetup.Size = new System.Drawing.Size(150, 22);
this.tsPageSetup.Text = "P&age Setup";
this.tsPageSetup.Click += new
System.EventHandler(this.tsPageSetup_Click);
//
// tsPagePreview
//
this.tsPagePreview.Name = "tsPagePreview";
this.tsPagePreview.Size = new System.Drawing.Size(150, 22);
this.tsPagePreview.Text = "Page Pre&view";
this.tsPagePreview.Click += new
System.EventHandler(this.tsPagePreview_Click);
//
// tsPrint
//
this.tsPrint.Name = "tsPrint";
this.tsPrint.Size = new System.Drawing.Size(150, 22);
this.tsPrint.Text = "&Print";
this.tsPrint.Click += new System.EventHandler(this.tsPrint_Click);
//
// tsSaveAs
//
this.tsSaveAs.Name = "tsSaveAs";
this.tsSaveAs.Size = new System.Drawing.Size(150, 22);
this.tsSaveAs.Text = "&Save As...";
this.tsSaveAs.Click += new
System.EventHandler(this.tsSaveAs_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// btnPrevious
//
this.btnPrevious.Location = new System.Drawing.Point(812, 546);
this.btnPrevious.Name = "btnPrevious";
this.btnPrevious.Size = new System.Drawing.Size(75, 27);
this.btnPrevious.TabIndex = 14;
this.btnPrevious.Text = "&Previous";
this.btnPrevious.UseVisualStyleBackColor = true;
//
// statusStrip1
//
this.statusStrip1.Location = new System.Drawing.Point(0, 578);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(972, 22);
this.statusStrip1.TabIndex = 15;
this.statusStrip1.Text = "statusStrip1";
//
// btnFinish
//
this.btnFinish.Location = new System.Drawing.Point(896, 546);
this.btnFinish.Name = "btnFinish";
this.btnFinish.Size = new System.Drawing.Size(75, 27);
this.btnFinish.TabIndex = 16;
this.btnFinish.Text = "&Finish";
this.btnFinish.UseVisualStyleBackColor = true;
this.btnFinish.Click += new
System.EventHandler(this.button1_Click);
//
// txtMembership
//
this.txtMembership.BackColor =
System.Drawing.SystemColors.Control;
this.txtMembership.BorderStyle =
System.Windows.Forms.BorderStyle.None;
this.txtMembership.Location = new System.Drawing.Point(7, 42);
this.txtMembership.Multiline = true;
this.txtMembership.Name = "txtMembership";
this.txtMembership.Size = new System.Drawing.Size(707, 42);
this.txtMembership.TabIndex = 17;
this.txtMembership.TabStop = false;
this.txtMembership.Text = "Acive Directory Membership should ";
//
// btnApply
//
this.btnApply.Location = new System.Drawing.Point(728, 42);
this.btnApply.Name = "btnApply";
this.btnApply.Size = new System.Drawing.Size(75, 27);
this.btnApply.TabIndex = 18;
this.btnApply.Text = "Apply";
this.btnApply.UseVisualStyleBackColor = true;
this.btnApply.Click += new
System.EventHandler(this.btnApply_Click);
//
// printDialog1
//
this.printDialog1.AllowPrintToFile = false;
this.printDialog1.Document = this.printDocument1;
this.printDialog1.UseEXDialog = true;
//
// printDocument1
//
this.printDocument1.DocumentName = "Membership Log";
this.printDocument1.PrintPage += new
System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);
this.printDocument1.BeginPrint += new
System.Drawing.Printing.PrintEventHandler(this.printDocument1_BeginPrint);
//
// pageSetupDialog1
//
this.pageSetupDialog1.Document = this.printDocument1;
this.pageSetupDialog1.MinMargins = new
System.Drawing.Printing.Margins(3, 3, 3, 3);
//
// printPreviewDialog1
//
this.printPreviewDialog1.AutoScrollMargin = new
System.Drawing.Size(0, 0);
this.printPreviewDialog1.AutoScrollMinSize = new
System.Drawing.Size(0, 0);
this.printPreviewDialog1.ClientSize = new
System.Drawing.Size(400, 300);
this.printPreviewDialog1.Document = this.printDocument1;
this.printPreviewDialog1.Enabled = true;
this.printPreviewDialog1.Icon =
((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon")));
this.printPreviewDialog1.Name = "printPreviewDialog1";
this.printPreviewDialog1.ShowIcon = false;
this.printPreviewDialog1.Visible = false;
//
// richTextBoxPrintCtrl1
//
this.richTextBoxPrintCtrl1.Cursor =
System.Windows.Forms.Cursors.Default;
this.richTextBoxPrintCtrl1.Font = new
System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.richTextBoxPrintCtrl1.Location = new
System.Drawing.Point(0, 91);
this.richTextBoxPrintCtrl1.Name = "richTextBoxPrintCtrl1";
this.richTextBoxPrintCtrl1.ReadOnly = true;
this.richTextBoxPrintCtrl1.Size = new System.Drawing.Size(973,
448);
this.richTextBoxPrintCtrl1.TabIndex = 19;
this.richTextBoxPrintCtrl1.TabStop = false;
this.richTextBoxPrintCtrl1.Text = "PowerADvantage Group
Membership Log";
//
// frmGroupMembershipLog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(972, 600);
this.Controls.Add(this.richTextBoxPrintCtrl1);
this.Controls.Add(this.btnApply);
this.Controls.Add(this.txtMembership);
this.Controls.Add(this.btnFinish);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.btnPrevious);
this.Controls.Add(this.msMembership);
this.Icon =
((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "frmGroupMembershipLog";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "frmGroupMembershipLog";
this.FormClosed += new
System.Windows.Forms.FormClosedEventHandler(this.frmGroupMembershipLog_FormClosed);
this.Load += new
System.EventHandler(this.frmGroupMembershipLog_Load);
this.msMembership.ResumeLayout(false);
this.msMembership.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip msMembership;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem tsPrint;
private System.Windows.Forms.ToolStripMenuItem tsSaveAs;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.Button btnPrevious;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.Button btnFinish;
private System.Windows.Forms.TextBox txtMembership;
private System.Windows.Forms.Button btnApply;
private System.Windows.Forms.ToolStripMenuItem tsPageSetup;
private System.Windows.Forms.ToolStripMenuItem tsPagePreview;
private System.Windows.Forms.PrintDialog printDialog1;
private System.Windows.Forms.PageSetupDialog pageSetupDialog1;
private System.Drawing.Printing.PrintDocument printDocument1;
private System.Windows.Forms.PrintPreviewDialog printPreviewDialog1;
private RichTextBoxPrintCtrl.RichTextBoxPrintCtrl
richTextBoxPrintCtrl1;
}
}
--
Thanks.
Peter Duniho said:
[...]
I now have a new problem though. The text are displayed just fine in the
rtb but when I do a printpreview or the actual print, each line of text
is
only 5 characters. Is it some property that I'm not setting correctly?
I don't know. Again, you didn't post any code that would illustrate what
you're doing.
Is the text clipped or wrapped? The answer to that should lead you to
looking more at the printing code (clipped) or the RTB WM_FORMATRANGE
usage (wrapped). No guarantees, but that's the way I'd lean. For sure,
the first thing you need to do is step line-by-line through all of the
code involved, to make sure that all the calculations and results come out
as you'd expect.
Pete