2011-10-10 44 views
0

我需要將字符串劃分爲具有完全對齊的位圖。我知道StringFormat.Alignment不支持完全對齊。所以,我正在尋找一個解決方案,以全對齊的方式在位圖上繪製一個字符串。 RictTextBox有充分的理由,但我認爲它使用WinAPI來證明文本的正確性。也許我可以使用RichTextBox繪製文本,但我不知道如何在不顯示窗體的情況下獲取控件位圖(屏幕截圖)。 是否有任何技巧或替代System.Drawing.Graphics的第三方庫?在.NET中繪製完全對齊的字符串

+0

Winforms或WPF? – kenny

+0

Winforms ....... – oruchreis

回答

2

我用一種方法在位圖上繪製RichTextBox

public class ExtendedRichTextBox : RichTextBox 
{ 
    private const double inch = 1440/96;//Not 14.4!!, believe me you can see someone use 1.44 but it doesn't work on big bitmaps. They round the 1440/96 as 14.4 but it works on only small sized works. use /96 

    public void DrawToBitmap(Graphics graphics, Rectangle bound) 
    { 
     Update(); // Ensure RTB fully painted 
     IntPtr hDC = graphics.GetHdc(); 
     FORMATRANGE fmtRange; 

     RECT rect; 
     rect.Left = (int)Math.Ceiling(bound.X * inch); 
     rect.Top = (int)Math.Ceiling(bound.Y * inch); 
     rect.Right = (int)Math.Ceiling(bound.Right * inch); 
     rect.Bottom = (int)Math.Ceiling(bound.Bottom * inch); 
     int fromAPI; 

     fmtRange.hdc = hDC; 
     fmtRange.hdcTarget = hDC; 

     fmtRange.chrg.cpMin = 0; 
     fmtRange.chrg.cpMax = -1; 
     fmtRange.rc = rect; 
     fmtRange.rcPage = rect; 

     IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange)); 
     Marshal.StructureToPtr(fmtRange, lParam, false); 
     fromAPI = SendMessage(Handle, EM_FORMATRANGE, 0, lParam); 
     fromAPI = SendMessage(Handle, EM_FORMATRANGE, 1, lParam); 
     Marshal.FreeCoTaskMem(lParam); 
     fromAPI = SendMessage(Handle, EM_FORMATRANGE, 0, new IntPtr(0)); 
     graphics.ReleaseHdc(hDC); 
    } 
} 

您可以在pinvoke網站上找到WinApi實現。但你也可以參考這裏:

[DllImport("USER32.dll")] 
private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); 
private const int WM_USER = 0x400; 
private const int EM_FORMATRANGE = WM_USER + 57; 
[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; 
    public int cpMax; 
} 

[StructLayout(LayoutKind.Sequential)] 
private struct FORMATRANGE 
{ 
    public IntPtr hdc; 
    public IntPtr hdcTarget; 
    public RECT rc; 
    public RECT rcPage; 
    public CHARRANGE chrg; 
} 

這裏是使用的例子。

var richtext = new ExtendedRichTextBox(); 
/*I've implemented a RichTextBox but it isn't realted with this question. 
You can use simply RichTextBox. ExtendedRichTextBox has support rtl.*/ 

richtext.Font = font; 
richtext.ForeColor = textColor; 
richtext.Text = sometext; 
richtext.SelectAll(); 
richtext.RightToLeft = rtl; 
richtext.SelectionAlignment = align; 

//Fix the rtl bug in RichTextBox 
if (rtl == RightToLeft.Yes) 
{ 
    if (align == TextAlign.Center) 
     richtext.Rtf = richtext.Rtf.Replace(@"\qr", @"\qc"); 
    else if (align == TextAlign.Left) 
     richtext.Rtf = richtext.Rtf.Replace(@"\qr", @"\ql"); 
    else if (align == TextAlign.Justify) 
     richtext.Rtf = richtext.Rtf.Replace(@"\qr", @"\qj"); 
} 

//textRect is where we want to put text in. 
var tempBitmap = new Bitmap(textRect.Width, textRect.Height); 
richtext.DrawToBitmap(Graphics.FromImage(tempBitmap), tempRect); 
tempBitmap.MakeTransparent(richtext.BackColor); 
graph.DrawImage(tempBitmap, panelRect.X, panelRect.Y); 
+0

在例子中,** align **和** TextAlign **是什麼。你的解決方案地址**對齊調整**? –