2015-07-31 8 views
5

मेरे पास PageControl दो TabSheets के साथ है। उनमें से प्रत्येक पर Frame है, इसे Frame2 पर कॉल करें। मेरे पास पृष्ठभूमि थ्रेड है जो Frame2 पर संदेश पोस्ट कर रहा है जब उसने अपना कार्य पूरा कर लिया है। Frame2 दूसरे TabSheet पर है, इसलिए जब उपयोगकर्ता एप्लिकेशन प्रारंभ होता है तो यह दिखाई नहीं देता है।पहले संदेश नहीं दिखाए जाने के बाद आवेदन लटकता है

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

क्या कोई मुझे सुझाव दे सकता है कि Frame2 बनाने के बाद संदेश कतार को सही तरीके से कैसे प्रारंभ किया जाए ताकि यह तुरंत संदेश सुन सके?

+1

विंडोज़ में कतार नहीं है, फ्रेम के लिए वैध विंडो हैंडल पोस्टमेसेज सफल होने के लिए पर्याप्त होना चाहिए। –

+0

सुझाव के लिए धन्यवाद, दुर्भाग्य से यह मदद नहीं करता है। डेटा प्रदर्शित करने के लिए टैब पर क्लिक करते समय सबकुछ लटकता है। – Wodzu

+0

वह संदेश दिखाएं जिसका उपयोग आप संदेश पोस्ट करने के लिए करते हैं। लटका एक सिंक्रनाइज़ेशन समस्या की तरह अधिक reeks, संभवतः एक संदेश पोस्ट करने के कारण नहीं, लेकिन उसके बाद कुछ। –

उत्तर

10

ऐसा नहीं है कि फ्रेम में कोई संदेश कतार नहीं है - यह थ्रेड है जिसमें संदेश कतार हैं, खिड़कियां नहीं - लेकिन फ्रेम में अभी तक विंडो हैंडल नहीं है। खिड़की हैंडल सबसे अधिक संभावना है जब फ्रेम पहली बार दिखाया जाता है, जब तक कि आप इसे एक संदेश पोस्ट न करें, जिस स्थिति में विंडो मांग पर बनाई गई हो।

यदि आप इसे संदेश पोस्ट करने का प्रयास करते हैं, तो आपके पास शायद इस तरह का एक बयान होगा: PostMessage(Frame2.Handle, ...)

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

आप यह सुनिश्चित यहां तक ​​कि अगर उस फ्रेम के हैंडल से पहले (जैसे मुख्य थ्रेड में HandleNeeded फोन करके के रूप में) यह करने के लिए आपको प्रत्यक्ष संदेश मुख्य थ्रेड में बनाई गई है, वहां अभी भी एक मौका है कि फ्रेम के Handle संपत्ति पढ़ने समस्या पैदा हो जाएगा। ऐसा इसलिए है क्योंकि एक वीसीएल नियंत्रण अपनी खिड़की को फिर से बना सकता है। फिर, एक बार फिर, Handle संपत्ति पढ़ने से गलत धागे में फ्रेम की खिड़की का निर्माण हो सकता है।

सुरक्षित तकनीक केवल एक समर्पित संदेश-केवल विंडो बनाने के लिए AllocateHWnd पर कॉल करने के लिए है। फ्रेम के कन्स्ट्रक्टर में ऐसा करें ताकि मुख्य थ्रेड में होने की गारंटी हो और फिर वहां संदेश पोस्ट करें। जब आप विंडो बनाते हैं, तो आप एक कॉलबैक विधि प्रदान करेंगे जिसे किसी भी समय विंडो कहा जा सकता है। वह कॉलबैक विधि फ्रेम नियंत्रण से संबंधित होनी चाहिए ताकि उसके पास उस फ़ील्ड के सभी फ़ील्ड और विधियों तक पहुंच हो।

+0

धन्यवाद, यह अब काम करता है लेकिन मुझे खुशी नहीं है कि मुझे 'फ्रेम 2' में से एक होने पर संदेशों को प्राप्त करने के लिए अलग छिपी हुई विंडो बनाना है। लोग सिंक्रनाइज़() 'के बजाय 'पोस्टमेसेज()' का उपयोग करने का सुझाव देते हैं लेकिन सिंक्रनाइज़() 'के मामले में मुझे ऐसी समस्याएं नहीं होतीं। – Wodzu

+0

@ वोडज़ू: वीसीएल विंडोज लगातार नहीं हैं और थ्रेड-सुरक्षित नहीं हैं। आप जो प्रयास कर रहे हैं वह लगातार थ्रेड-सुरक्षित विंडो की आवश्यकता है। यदि आप अपने संदेशों के लिए एक समर्पित विंडो नहीं बनाना चाहते हैं, तो आप 'एप्लिकेशन' का उपयोग कर सकते हैं।अपने पोस्ट किए गए संदेशों को प्राप्त करने के लिए 'Application.OnMessage' या 'Application.HookMainWindow()' का उपयोग करके, विंडो को संभाल लें। –

+0

फ्रेम 2 में एक खिड़की है जब तक इसे फिर से बनाया नहीं जाता है। फिर आप खराब हो गए हैं। AllocateHWnd स्वच्छ तरीका है। एप्लिकेशन का उपयोग न करें। हैंडल जो आपके कोड को अपवित्र उलझन में डाल देगा। इलाके को AllocateHWnd के साथ रखें। बेशक TThread.Queue एक और साफ विकल्प है। –

संबंधित मुद्दे