I'm trying to print out a RichTextBox using MS' sample code, but when I send
the message to print out the control, it's supposed to update the internal
.rc (the rectangle with the drawing bounds) with the dimensions that the
draw operation actually took. Has anyone tried this operation before and
could tell me where I am erring? I want to believe that my error is in
storing an RECT instead of an LPRECT, but I don't know how to declare one in
C# (public ref RECT rc is invalid):
//Calculate the area to render and print
RECT rectToPrint;
rectToPrint.Top = (int) (bounds.Top * 14.4);
rectToPrint.Bottom = (int) (bounds.Bottom * 14.4);
rectToPrint.Left = (int) (bounds.Left * 14.4);
rectToPrint.Right = (int) (bounds.Right * 14.4);
RECT rectToPrint2; // Just for testing
rectToPrint2.Top = (int) (0 * 14.4);
rectToPrint2.Bottom = (int) (1100 * 14.4);
rectToPrint2.Left = (int) (0 * 14.4);
rectToPrint2.Right = (int) (850 * 14.4);
IntPtr hdc = graphics.GetHdc();
FORMATRANGE fmtRange;
fmtRange.chrg.cpMax = this.Text.Length;
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 = rectToPrint2; //Indicate size of
page
IntPtr wparam = new IntPtr(1);
System.Diagnostics.Debug.WriteLine("Start: " +
(fmtRange.rc.Right - fmtRange.rc.Left));
//Get the pointer to the FORMATRANGE structure in memory
IntPtr lparam= IntPtr.Zero;
lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
Marshal.StructureToPtr(fmtRange, lparam, true);
//Send the rendered data for printing
if (SendMessage(Handle, EM_FORMATRANGE, wparam,
lparam).ToInt32() < 0)
{
throw new InvalidOperationException();
}
//Free the block of memory allocated
Marshal.FreeCoTaskMem(lparam);
//Release the device context handle obtained by a previous call
graphics.ReleaseHdc(hdc);
System.Diagnostics.Debug.WriteLine("End: " +
(fmtRange.rc.Right - fmtRange.rc.Left));
Mattias Sjögren - 31 Jan 2007 06:17 GMT
Keith,
With StrucureToPtr you make a copy of the struct data in the unmanaegd
memory buffer. When that copy is updated it doesn't affect your local
fmtRange. You have to read the canges back with PtrToStructure.
Mattias

Signature
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Keith Patrick - 31 Jan 2007 17:09 GMT