2010-10-11 13 views
5

ठीक है, इसलिए मेरे आवेदन में, WinAPI का एक गुच्छा और कुछ कस्टम नियंत्रण हैं। हाँ ...डबल बफरिंग winAPI

अब, सामान्य रूप से, वे चुपचाप एनिमेशन, राज्य बदलने, ect .... के लिए चुपचाप फिर से तैयार करेंगे .... और यह सब ठीक काम करता है।

लेकिन मेरे पास फिक्स() नामक क्लास विंडो की एक विधि है। जब भी पूरी विंडो को अद्यतन करने की आवश्यकता होती है तो इसे तब कहा जाता है। यह नियंत्रण का आकार बदलता है और खिड़की को अमान्य करता है।

जब ऐसा होता है, तो पृष्ठभूमि खींची जाती है, फिर टैब नियंत्रण होता है, फिर अन्य सभी शीर्ष पर। यह बहुत परेशान झुर्रियों का कारण बनता है, खासकर जब खिड़की का आकार बदलता है (ठीक करने के लिए निरंतर कॉल की वजह से)।

मैं क्या कोशिश की है:

  • WS_EX_COMPOSITED। यह व्यक्तिगत नियंत्रण केवल डबल-बफर करता है। यह एक सुधार है, लेकिन झटके अनिवार्य रूप से बनी हुई है।
  • पृष्ठभूमि ड्राइंग को बंद करना। मुश्किल से समस्या हल करता है, और वास्तव में मामलों को और भी खराब बनाता है।

तो: मुझे एक तकनीक/विधि/जो भी खिड़की को पूरी तरह से डबल-बफर करने की अनुमति देने की आवश्यकता है। मुझे लगा कि WM_PAINT संदेश को स्वयं से संभालना एक समाधान हो सकता है, लेकिन मुझे नहीं पता कि कहां से शुरू करना है। मुझे एक भयानक भावना है कि यह भी संभव नहीं है ...

कृपया मदद करें, यह एक महत्वपूर्ण मुद्दा है। जब यह बेवकूफ छोटी समस्या तय हो जाती है तो मुझे बहुत राहत मिल जाएगी।

+0

शायद इस पृष्ठ को चेक करें? http://www.gamedev.net/community/forums/topic.asp?topic_id=411559 –

उत्तर

4

इस समय यह हुआ कि किसी ने मूल डेवलपर्स के लिए माइक्रोस्कोफ्ट की गहराई को महसूस किया। वास्तव में मूलभूत डेवलपर्स को डब्ल्यूपीएफ में जाने के लिए मजबूर करने के लिए माइक्रोसॉफ्ट ने जानबूझकर मूल चित्रकला को तोड़ दिया है, जो वास्तव में पागलपन भ्रम को रोकना शुरू कर सकता है।

सबसे पहले, WS_EX_COMPOSITED पर विचार करें। WS_EX_COMPOSITED सरसों का प्रतीत होता है: - यह कहता है कि यह बाल नियंत्रण के लिए शीर्ष पेंट ऑर्डर के लिए एक कपास लागू करता है, और मूल रूप से WM_PAINT संदेशों को बैच में संभाला जाता है। यह कहता है कि इसे विंडोज 2000 (5.0) और कुछ पंक्तियों में जोड़ा गया था, यह डेस्कटॉप संरचना सक्षम के साथ काम नहीं करता है। यानी यह विंडोज विस्टा (6.0) के रूप में काम करना बंद कर देता है, जब तक एयरो ग्लास बंद न हो और वह ऐसा करने जा रहा है?

  • सबसे पहले आप overpainting की राशि mimimize की जरूरत है,:

    फिर, दो संभावित "हैक्स" मुक्त चित्र कोशिश करते हैं और झिलमिलाहट पाने के लिए काम करने के लिए कर रहे हैं। WS_EX_CLIPCHILDREN | WS_EX_CLIPSIBLINGS यह सुनिश्चित करने के लिए आवश्यक है कि खिड़की का कोई विशेष क्षेत्र केवल एक बार चित्रित किया जाए। BeginDeferWindowPos को क्षणिक राज्यों को सुनिश्चित करने के लिए आकार बदलने के लिए भी जरूरी है - जहां एक खिड़की दूसरे को ओवरलैप करती है - ऐसा न करें (यानी जब विंडो ए का आकार बदल दिया गया हो लेकिन विंडो बी नहीं है)।

बेशक

, जब आप एक चमड़ी संवाद आकर्षित, या समूह के बक्से, या टैब नियंत्रण, या अन्य प्रतिबंध के किसी भी संख्या का उपयोग करने की कोशिश कर रहे हैं, WS_EX_CLIPSIBLINGS बस नहीं उचित है।

  • WM_SETREDRAW एक जादू संदेश है। इस कार्यक्षमता तक पहुंचने के लिए कोई एपीआई नहीं है: WM_SETREDRAW सीधे डिफ़ॉल्ट रूप से खिड़की को अवधि के लिए छिपाने के लिए DefWindowProc द्वारा संभाला जाता है। WM_SETREDRAW, FALSE के बाद, माता-पिता विंडो हैंडल (और उसके सभी बच्चे) का उपयोग करके GetDC/GetDCEx/GetWindowDC आदि पर कॉल करने के लिए एक डीसी वापस आ जाएगी जो स्क्रीन पर नहीं खींचा जाएगा। यह आपको बच्चों की खिड़कियों के लिए सभी प्रकार की चीजें करने का मौका देता है, जब आप एक WM_SETREDRAW,TRUE भेजते हैं, (और उसके बाद विंडो को मैन्युअल रूप से दोहराएं)। सभी बच्चे खिड़कियां - निश्चित रूप से - अपने समय में पेंट करेंगी, और माता-पिता की खिड़की के बाद अपनी मिटा पृष्ठभूमि हो गई है, इसलिए WM_SETREDRAW कोई भी प्रकार का पैनसिया नहीं है।

WS_EX_COMPOSITED तोड़ने, नेट के WinForms में और WPF जमीन से नियंत्रण फिर से लिखा अप देशी नियंत्रण का उपयोग नहीं करने के लिए है, इसलिए वे बफ़र पेंटिंग में वहाँ बेक सकता है के बाद। और अल्फा समर्थन भी।

0

कोड के बिना मैं शायद ही कल्पना करता हूं कि वास्तविक स्थिति क्या है ... लेकिन आप WM_ERASEBKGND को संभालने का प्रयास कर सकते हैं, जब भी आप उन्हें मिटाने के लिए प्राप्त करते हैं तो TRUE वापस लौटें।

+0

मैंने कोशिश की। यह सिर्फ एक बड़ी गड़बड़ कर दिया। आप जानते हैं कि जब आप पृष्ठभूमि मिटा नहीं देते तो क्या होता है? –

+0

पृष्ठभूमि स्पष्ट रूप से "मिटा" नहीं है:>। खैर यदि आपकी पेंटिंग पूरे क्षेत्र को कवर करती है, तो इससे कोई फर्क नहीं पड़ता कि यह मिटा दिया गया है या नहीं। – YeenFei

1

एचएम। लोगों को इस विषय को डुप्लिकेट के रूप में घुमाने और बंद करने से पहले, मैं बेहतर उल्लेख करता हूं कि आपकी समस्या प्रति सेकंड डबल बफरिंग नहीं है, लेकिन नियंत्रण को पुनर्स्थापित करते समय झिलमिलाहट, जिसके लिए "मैनुअल" डबल बफरिंग केवल कई समाधानों में से एक है।

ऐसा हो सकता है कि उदा। BeginDeferWindowPos & दोस्त झटके को ठीक कर सकते हैं।

अस्वीकरण: मुझे एक बार Win16 एपीआई के लगभग सभी विवरण पता था, लेकिन कुछ वर्षों से मैंने एपीआई-स्तरीय प्रोग्रामिंग किया है।

चीयर्स & hth,

-। Alf

+0

यह win32 है ... –

+0

@Alexander, win32 सिर्फ win16s कम बुरा जुड़वां है। –

0

हैंडल WM_ERASEBKGND अपने विंडो के लिए और कार्यान्वयन में अपने बच्चे को नियंत्रण में से प्रत्येक के rects बाहर करते हैं, तो उचित रूप से शेष पृष्ठभूमि को भरने और ढांचे बताते हैं कि आप true लौटकर पृष्ठभूमि को स्वयं चित्रित किया है। अन्य सभी बाल नियंत्रणों के लिए वही काम करें जो बदले में आपके नियंत्रण में टैब नियंत्रण जैसे अन्य नियंत्रण रखे।

एमएफसी का उपयोग कर उदाहरण के लिए here देखें।

+0

यह एक अवांछनीय समाधान है। शायद अंतिम उपाय के रूप में ... –

1

इननेट में ControlStyle.AllPaintingInWmPaint है जो प्रत्येक कंटेनर विंडो (इसलिए मुख्य विंडो और टैब) पर सेट किया जाना चाहिए। मुझे एक winapi समकक्ष नहीं मिला। लेकिन यह क्या करता है पृष्ठभूमि की पेंटिंग को WM_ERASEBKGND से WM_PAINT तक ले जाना है। यह झिलमिलाहट से बचने के लिए अभिभावक से बाल नियंत्रण के क्षेत्र को भी घटा देता है, यह हो सकता है कि आपको इसे मैन्युअल रूप से करने की आवश्यकता हो।

मुझे आश्चर्य है कि WS_EX_COMPOSITED मदद नहीं करता है। यह काम करना चाहिए, अगर आप इसे शीर्ष-स्तरीय विंडो पर सेट करते हैं, और उप-नियंत्रण पर RedrawWindow को कॉल न करें।

डीडब्लूएम/एयरो के साथ और बिना परीक्षण करना सुनिश्चित करें। आप अलग-अलग परिणाम प्राप्त कर सकते हैं।

+0

पीएस मैंने अपने पहले के जवाब में नमूना सी # कोड का एक टुकड़ा लगाया। आप जो प्रभाव देख रहे हैं उसका प्रदर्शन करने के लिए आप इसे संशोधित करने में सक्षम हो सकते हैं। http: // stackoverflow।कॉम/प्रश्न/3735121/direct2d-gdi-and-slow-windows-forms-drawing-what-can-be-done/3735328 # 3735328 –

+0

मैं WM_PAINT में पृष्ठभूमि को मैन्युअल रूप से मिटा सकता हूं। –

+0

@Alexander: यही आपको करने की ज़रूरत है। आपको WM_ERASEBKGND पर भी सही लौटने की आवश्यकता है। पेंट से बाल खिड़की के अंगों को छोड़कर भी उत्तराधिकारी हो सकता है (शायद WS_CLIPCHILDREN जोड़ना चाल करेगा)। –