/// <summary> /// Calculate or render the contents of our RichTextBox for printing /// </summary> /// <param name="e">The PrintPageEventArgs object from the PrintPage event</param> /// <param name="posIniChar">Index of first character to be printed</param> /// <param name="posEndChar">Index of last character to be printed</param> /// <returns>Index of last character that fitted on the page, plus 1</returns> public int DoPrint(int posIniChar, int posEndChar, PrintPageEventArgs e) { // Fill in the FORMATRANGE struct var fr = FORMATRANGE.Set(e, posIniChar, posEndChar); // Allocate memory for the FORMATRANGE struct and copy this to the memory IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr)); Marshal.StructureToPtr(fr, lParam, false); // Zero wParam means measure, non-zero wParam means render Int32 wParam = (MeasureOnly ? 0 : 1); // Measure to get end char index needed for call delegate before print if (beforePagePrintDelegate != null && !MeasureOnly) { int nextIndex = SendMessage(richTextBox.Handle, EM_FORMATRANGE, 0, lParam); beforePagePrintDelegate(posIniChar, nextIndex - 1, e); } // Send the Win32 message for printing int res = SendMessage(richTextBox.Handle, EM_FORMATRANGE, wParam, lParam); // Free allocated memory Marshal.FreeCoTaskMem(lParam); // Release the device context handle obtained by a previous call e.Graphics.ReleaseHdc(fr.hdc); return(res); }