2013-01-22 60 views
2

這裏有一些用linqpad編寫的C#代碼來重現問題。繪製長度超過65536的字符串時GDI + DrawString泛型異常?

var font = new System.Drawing.Font("Arial", 8); 
using (var g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero)) 
{ 
    //65536 characters is fine 
    g.DrawString("a".PadLeft(65535, 'a'), font, System.Drawing.Brushes.Black, new System.Drawing.RectangleF(0, 0, 1, 1)); 
    //65537 characters causes an error. 
    g.DrawString("a".PadLeft(65536, 'a'), font, System.Drawing.Brushes.Black, new System.Drawing.RectangleF(0, 0, 1, 1)); 
    //65537 characters is however fine if the width is over 600581 
    g.DrawString("a".PadLeft(65536, 'a'), font, System.Drawing.Brushes.Black, new System.Drawing.RectangleF(0, 0, 600582, 1)); 
} 

任何人都知道字符串的長度和佈局矩形的寬度之間的確切關係嗎?數字600581似乎非常武斷。雖然65536更有意義,因爲它是0x10000。

+0

大多數的例外是因爲程序不能寫,因爲權限的文件。也許你正在試驗的數字正在觸發文件緩存。 –

+2

我在Win8上死於32001。避免將GDI +推向邊緣,它會以字節爲單位。你應該在這裏使用TextRenderer。 –

+0

我不這麼認爲,因爲如果佈局寬度超過任意數字,我可以傳遞一個長度爲100萬的字符串。 – Will

回答

2

任何人都知道字符串長度和 佈局矩形的寬度之間的確切關係?數字600581似乎非常武斷。

數字600581確實是任意的,在這種情況下,它反映字體字符寬度(或字體的字形)。

600581/65536爲例,它給出每個字符的平均字符寬度爲9.16像素,對於相當平方的字體(如Arial),當您包含間距時,這是合理的。除此之外,GDI +還爲文本的邊界框添加了填充。

如果您嘗試更寬(或更窄的字體,但您不會注意到,除非減少數字)以及不同的字母組合,您應該得到不同的結果。嘗試一個單間隔字體,你應該能夠非常準確地預測所需的邊界(不要忘記填充)。

如果您確實需要打印長字符串,請嘗試緩衝打印,但是在這些情況下,GDI +不是您最好的朋友。嘗試TextRenderer類(一個GDI封裝)作爲已經建議:「在GDI發生一般性錯誤+」
http://msdn.microsoft.com/en-us/library/system.windows.forms.textrenderer.aspx

相關問題