2011-02-11 34 views
2

如果我有一個richTextBox並在其上運行DrawToBitmap,它不會在richTextBox內繪製任何文本。richTextBox.DrawToBitmap不會繪製包含文本?

Bitmap b = new Bitmap(rtb.Width, rtb.Height); 
inputControl.DrawToBitmap(b, new Rectangle(0, 0, b.Width, b.Height)); 

有什麼辦法解決這個問題嗎?

回答

2

This thread在Google中排名第二。似乎有你想要的。因爲我想象你正在從這個問題Accepting Form Elements As Method Arguments?的函數中使用它,所以最好做這樣的事情。

if(inputControl is RichTextBox) 
{ 
    //do specifc magic here 
} 
else 
{ 
    //general case 
} 

您可以檢查包含RichTextBox中控制遞歸

bool ContainsOrIsRichTextBox(Control inputControl) 
{ 
    if(inputControl is RichTextBox) return true; 
    foreach(Control control in inputControl.Controls) 
    { 
     if(ContainsOrIsRichTextBox(control)) return true; 
    } 
    return false; 
} 

我沒有編這一點,而且也這樣做,而不用擔心一個StackOverflowException的一種方式,但這應該讓你開始。

+0

比方說,我發送一個包含richTextBox的面板。有沒有辦法檢查面板是否包含richTextBox? – sooprise 2011-02-11 21:40:11

+0

你必須遍歷控件樹。我提供了一個片段。 – Novikov 2011-02-11 22:28:13

3

從MSDN庫文章RichTextBox.DrawToBitmap():

這種方法是不適合此類。

一個最低級的方式說,本地Windows RichEdit控件不支持WM_PRINT。採取屏幕截圖是一種選擇,諾維科夫給你一個鏈接到我的答案。

4

我知道這是比較老了,但我發現在http://www.windows-tech.info/3/8ffaf21eed5de2d4.php一個有效的解決方案:

public static Bitmap RtbToBitmap(RichTextBox rtb) 
{ 
    rtb.Update(); // Ensure RTB fully painted 
    Bitmap bmp = new Bitmap(rtb.Width, rtb.Height); 
    using (Graphics gr = Graphics.FromImage(bmp)) 
    { 
     gr.CopyFromScreen(rtb.PointToScreen(Point.Empty), Point.Empty, rtb.Size); 
    } 
    return bmp; 
} 
1

我發現了一個相關答案在這裏:how to print Rich text box contents on any device contenxt with proper formatting?

我改變了這種渲染我關閉屏幕的RichTextBox到一個位圖。這樣我可以創建一個位圖關閉屏幕,然後將其發送到OpenGL。

// 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); 

    /// <summary> 
    /// Render the specified RichTextBox onto the specified bitmap 
    /// </summary> 
    /// <param name="textBox">RichTextBox to render</param> 
    /// <param name="bitmap">Bitmap to render the RichTextBox onto</param> 
    public void RenderToBitmap(RichTextBox textBox, Bitmap bitmap) 
    { 
     // Set area to render to be entire bitmap 
     RECT rect; 
     rect.Left = 0; 
     rect.Top = 0; 
     rect.Right = (int)(bitmap.Width * anInch); 
     rect.Bottom = (int)(bitmap.Height * anInch); 

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

     FORMATRANGE fmtRange; 
     fmtRange.chrg.cpMin = textBox.GetCharIndexFromPosition(new Point(0,0)); 
     fmtRange.chrg.cpMax = textBox.GetCharIndexFromPosition(new Point(bitmap.Width,bitmap.Height)); 
     fmtRange.hdc  = hdc;     // Use the same DC for measuring and rendering 
     fmtRange.hdcTarget = hdc; 
     fmtRange.rc   = rect; 
     fmtRange.rcPage  = rect; 

     IntPtr lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange)); 
     Marshal.StructureToPtr(fmtRange, lparam, false); 

     // Render the control to the bitmap 
     SendMessage(textBox.Handle, EM_FORMATRANGE, new IntPtr(1), lparam); 

     // Clean up 
     Marshal.FreeCoTaskMem(lparam); 
     g.ReleaseHdc(hdc); 
    } 
0

對於它的價值,RichTextBox控件的更高版本正確支持DrawToBitmap方法;它還提高了性能並具有更多功能。

internal class RichTextBox5: RichTextBox 
{ 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    static extern IntPtr LoadLibrary(string lpFileName); 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cparams = base.CreateParams; 
      if (LoadLibrary("msftedit.dll") != IntPtr.Zero) 
      { 
       cparams.ClassName = "RICHEDIT50W"; 
      } 
      return cparams; 
     } 
    } 
}