public void FormatRange(Graphics g, int startChar, int endChar) { STRUCT_CHARRANGE chrg = default(STRUCT_CHARRANGE); chrg.cpMin = startChar; chrg.cpMax = endChar; STRUCT_RECT rc = default(STRUCT_RECT); rc.top = 0; rc.bottom = ToTwips(MasterControl.ClientSize.Height + 40); rc.left = 0; if (MasterControl.Size.Width - MasterControl.ClientSize.Width == 20) { rc.right = ToTwips((float)MasterControl.ClientSize.Width + (float)MasterControl.ClientSize.Width / 80f + 4f); } else { rc.right = ToTwips((float)MasterControl.ClientSize.Width + (float)MasterControl.ClientSize.Width / 100f + 5f); } STRUCT_RECT rcPage = default(STRUCT_RECT); rcPage.top = 0; rcPage.bottom = ToTwips(MasterControl.Size.Height); rcPage.left = 0; rcPage.right = ToTwips(MasterControl.Size.Width); IntPtr hdc = g.GetHdc(); STRUCT_FORMATRANGE structure = default(STRUCT_FORMATRANGE); structure.chrg = chrg; structure.hdc = hdc; structure.hdcTarget = hdc; structure.rc = rc; structure.rcPage = rcPage; IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, intPtr, fDeleteOld: false); SendMessageToMaster(EM_FORMATRANGE, (IntPtr)1, intPtr, 1); SendMessageToMaster(EM_FORMATRANGE, IntPtr.Zero, IntPtr.Zero, -1); Marshal.FreeCoTaskMem(intPtr); g.ReleaseHdc(hdc); }
/// <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) { // Specify which characters to print STRUCT_CHARRANGE cr = default(STRUCT_CHARRANGE); cr.cpMin = charFrom; cr.cpMax = charTo; // Specify the area inside page margins STRUCT_RECT rc = default(STRUCT_RECT); rc.top = HundredthInchToTwips(e.MarginBounds.Top); rc.bottom = HundredthInchToTwips(e.MarginBounds.Bottom); rc.left = HundredthInchToTwips(e.MarginBounds.Left); rc.right = HundredthInchToTwips(e.MarginBounds.Right); // Specify the page area STRUCT_RECT rcPage = default(STRUCT_RECT); rcPage.top = HundredthInchToTwips(e.PageBounds.Top); rcPage.bottom = HundredthInchToTwips(e.PageBounds.Bottom); rcPage.left = HundredthInchToTwips(e.PageBounds.Left); rcPage.right = HundredthInchToTwips(e.PageBounds.Right); // Get device context of output device IntPtr hdc = default(IntPtr); hdc = e.Graphics.GetHdc(); // Fill in the FORMATRANGE structure STRUCT_FORMATRANGE fr = default(STRUCT_FORMATRANGE); 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 = default(Int32); if (measureOnly) { wParam = 0; } else { wParam = 1; } // Allocate memory for the FORMATRANGE struct and // copy the contents of our struct to this memory IntPtr lParam = default(IntPtr); lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr)); Marshal.StructureToPtr(fr, lParam, false); // Send the actual Win32 message int res = 0; res = SendMessage(Handle, EM_FORMATRANGE, wParam, lParam); // Free allocated memory Marshal.FreeCoTaskMem(lParam); // and release the device context e.Graphics.ReleaseHdc(hdc); return(res); }