2009-05-07 21 views
6

मैंने सी # WinForms में एक नियंत्रण subclassed है, और मेरे OnPaint() हैंडलर में कस्टम ड्राइंग पाठ हूँ। फॉन्ट मेरी रूप में निम्नलिखित कोड का उपयोग कर कूरियर न्यू पर सेट है:क्यों ड्रॉस्ट्रिंग सी # विनफॉर्म में अप्रत्याशित व्यवहार का प्रदर्शन कर रहा है?

FontFamily family = new FontFamily("Courier New"); 
this.myControl.Font = new Font(family, 10); 

नियंत्रण ही में, स्ट्रिंग realText में संग्रहीत किया जाता है, और मैं स्क्रीन पर आकर्षित करने के लिए निम्नलिखित कोड का उपयोग करें:

http://img219.imageshack.us/img219/1778/courier.png

आप जूम इन करते हैं, तो आप देख सकते हैं उदाहरण के लिए, कि '' के रूप में पहले के बीच की जगह टी तुलना में अलग है:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    e.Graphics.DrawString(realText, Font, new SolidBrush(ForeColor), ClientRectangle); 
} 

कुछ यादृच्छिक उदाहरण के लिए लेख परिणाम इस प्रकार है लग रहा है वह दूसरे 'के रूप में' (1 पिक्सल बनाम 2 पिक्सल) के बीच की जगह। क्या किसी को पता है कि इसका क्या कारण हो सकता है, या मैं इसे कैसे होने से रोक सकता हूं? अंतर में बहुत अधिक समान अजीबता है क्योंकि मैं विभिन्न फोंट के साथ आकर्षित करता हूं, लेकिन मुझे लगता है कि वे एक ही समस्या के सभी परिणाम हैं।

आपके विचारों के लिए अग्रिम धन्यवाद।

उत्तर

6

मुझे लगता है कि ऐसा इसलिए है क्योंकि आप TextRenderer.DrawText() के बजाय Graphics.DrawString() का उपयोग कर रहे हैं। जीडीआई + का उपयोग कर पूर्व पेंट्स टेक्स्ट जो क्रैपी और पुराना है। उत्तरार्द्ध जीडीआई का उपयोग करता है जो अधिक आधुनिक है (पाठ प्रतिपादन के संदर्भ में)। मेरा मानना ​​है कि यह पिछले जवाब (WinForms बनाम विंडोज) द्वारा नोट किया गया अंतर है।

आप Graphics.DrawString() के अधिभार को भी आजमा सकते हैं जो StringFormat ऑब्जेक्ट लेता है और StringFormat.GenericTypographic निर्दिष्ट करता है। हालांकि, यह वास्तव में समस्या के आसपास एक हैक का एक सा है। यदि आप .NET 2.0 या बाद में उपयोग कर रहे हैं, तो आपको अपनी सभी टेक्स्ट प्रतिपादन आवश्यकताओं के लिए क्रैपी Graphics कक्षा के बजाय TextRenderer कक्षा का उपयोग करना चाहिए। Graphics.MeasureString() और Graphics.DrawString() .NET 1.0 और 1.1 के साथ पिछड़ा संगतता के लिए सख्ती से मौजूद हैं।

संपादित करें: ओह हाँ, और आपका कोड हर पेंट चक्र पर एक जीडीआई ऑब्जेक्ट लीक करता है। ब्रश ऑब्जेक्ट्स अप्रबंधित संसाधनों के आसपास प्रबंधित रैपर हैं, इस प्रकार उन्हें स्पष्ट रूप से निपटाया जाना चाहिए।

+0

अद्भुत, यह Win32 कोड का उपयोग किए बिना किया। धन्यवाद – Ko9

+0

क्या कचरा कलेक्टर चलाने पर जीडीआई ऑब्जेक्ट जारी किया जाता है? –

+0

नहीं। .NET में ब्रश और पेन ऑब्जेक्ट्स अप्रबंधित संसाधनों (जीडीआई ब्रश या कलम) के आसपास बस प्रबंधित रैपर हैं। जब कचरा कलेक्टर चलता है तो यह .NET wrapper से छुटकारा पाता है, लेकिन अंतर्निहित जीडीआई ऑब्जेक्ट नहीं। जीडीआई वस्तुओं के लिए अंगूठे का सामान्य नियम या तो उन्हें एक प्रयोग ब्लॉक में लपेटना है या स्पष्ट रूप से अपने अंतिम रूप में उनका निपटान करना है। आपको टास्क मैनेजर (जीडीआई ऑब्जेक्ट कॉलम चालू करें) का उपयोग करके इसे सत्यापित करने में सक्षम होना चाहिए और संसाधनों को रिसाव के रूप में गिनती में वृद्धि देखना चाहिए। यदि आप जीसी को कार्रवाई में लाते हैं तो भी गिनती नहीं जाएगी। –

0

मुझे ईमानदार होना है, लेकिन इससे पहले कभी मेरे साथ नहीं हुआ। हालांकि, एंटीएलियासिंग को SmoothingMode स्थापित करने का प्रयास करें: एक तरफ कर

e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 

एक और बात, सुनिश्चित करें कि आपके का उपयोग करने से DoubleBuffer सही पर सेट किया गया है। साथ ही, प्रत्येक ऑनपेंट कॉल में एक नया सॉलिड ब्रश बनाने की कोशिश न करें ..

+0

कोशिश की, दुख की बात कुछ भी नहीं बदला। वास्तव में आपके सभी सुझावों का प्रयास किया, उनमें से कोई भी मदद नहीं की: -/ – Ko9

0

WinForms का उपयोग करके उप-वर्गीकृत नियंत्रण में पेंटिंग टेक्स्ट के साथ मेरा अनुभव यह है कि टेक्स्ट प्रस्तुतीकरण इंजन (जीडीआई +?) विंडोज के अपने फ़ॉन्ट इंजन के जितना अच्छा नहीं है , और जब यह अच्छी तरह से काम करता है तब भी निश्चित रूप से अलग-अलग परिणाम देता है।

मैं विजुअल स्टूडियो एडिन (http://entrian.com/source-search) के लेखक हूं, जो विजुअल स्टूडियो के भीतर नियंत्रण पेंट करने की आवश्यकता है, और फ़ॉन्ट्स को विजुअल स्टूडियो (सूचीदृश्य, वृक्षदृश्य आदि) में मानक नियंत्रण के समान दिखने के लिए।) मुझे WinForms को बाईपास करना है और Win32 API:

[DllImport("gdi32.dll")] 
public static extern bool ExtTextOut(IntPtr hdc, int X, int Y, 
    uint fuOptions, [In] ref RECT lprc, string lpString, uint cbCount, 
    [In] int[] lpDx); 

... और परिवार का उपयोग करके टेक्स्ट पेंट करना होगा।

शायद आप जो सुनना नहीं चाहते थे, लेकिन वहां है।