2009-04-19 13 views
11

Win32 C++ एप्लिकेशन में, हम एक संदेश लूप शुरू करते हैं जो कतार से संदेश प्राप्त करता है, उनका अनुवाद करता है और फिर उन्हें प्रेषित करता है। आखिरकार, प्रत्येक संदेश हमारे डब्लूडप्रोक तक पहुंचता है जहां संबंधित घटना को संभाला जा सकता है।हुड के तहत लागू Win32 इवेंट-संचालित प्रोग्रामिंग कैसा है?

मैं उस हिस्से को समझता हूं। जो मैं समझ नहीं पा रहा हूं वह चल रहा है। विशेष रूप से:

  1. विभिन्न प्रकार के ओएस इंटरप्ट हैंडलर को 'संदेश कतार' में संदेश रखना होगा, लेकिन प्रक्रिया के भीतर इस कतार का स्थान क्या है? यह इंटरप्ट हैंडलर कोड के संपर्क में कैसे है?
  2. संदेश का अनुवाद करने का क्या अर्थ है? TranslateMessage() पर कॉल वास्तव में क्या करता है?
  3. एक बार DispatchMessage() द्वारा भेजा गया, संदेश मेरे सभी WNDProc तक पहुंचने से पहले स्विंग करता है (यानी ओएस इसके साथ क्या करता है)?

यदि कोई उपरोक्त के उत्तरों को जानता है, तो कृपया मेरी जिज्ञासा को संतुष्ट करें। धन्यवाद।

उत्तर

6

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

एप्लिकेशन संदेशों को संसाधित करने के लिए अपनी स्वयं की कतार रख सकते हैं। उन पंक्तियों को on request बनाया गया है (केवल तभी आवश्यक है)।

संदेश का अनुवाद उन संदेशों को बनाने के लिए किया जाता है जो 'असली' घटनाएं नहीं हैं। उदाहरण के लिए, WM_CONTEXTMENU संदेश या तो माउस राइट-क्लिक, या संदर्भ मेनू कुंजी, या शिफ्ट-एफ 10 से 'अनुवादित' है। WM_CHAR का अनुवाद WM_KEYDOWN संदेशों से किया गया है। और निश्चित रूप से कई अन्य संदेश इस तरह से 'अनुवादित' हैं।

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

+3

यह सब गलत है। इसके कुछ हिस्सों जो सही हैं, केवल तभी सही हैं जब प्रश्न Win16 के बारे में था जहां पूरे ओएस और अनुप्रयोगों को सह-ऑपरेटिव रूप से एक थ्रेड पर निर्धारित किया गया था। –

1

इस लेकिन मेरी सबसे अच्छी अनुमान के बारे में पूरी तरह से सकारात्मक नहीं कहते हैं:

  1. कतार आप Win32 API कॉल के साथ तक पहुँचने है कि एक प्रणाली वस्तु है। यह आपकी प्रक्रिया पता स्थान पर बिल्कुल नहीं है। तो बाधा हैंडलर इसे एक्सेस कर सकते हैं (शायद कर्नेल के एचएएल (हार्डवेयर एब्स्ट्रक्शन लेयर) के माध्यम से)।

  2. Win16 में, उस कॉल ने एक बड़े संदेश के विभिन्न उप-भाग लिया और उन्हें पूरी तरह से मैश किया। तो अनुवाद मैसेज WM_KEYPRESS को जोड़ देगा जब इसे संबंधित WM_KEYDOWN WM_KEYUP अनुक्रम मिलेगा। यह विभिन्न बटन क्लिक संदेशों को आंतरिक सेटिंग और संदेशों के टाइमस्टैम्प के आधार पर डबलक्लिक संदेशों में भी बदल देगा। चाहे यह अभी भी Win32 में करता है, मुझे नहीं पता।

  3. डिस्पैच मैसेज शायद यह है कि विंडो संदेश हुक संसाधित हो जाते हैं। तो यदि आपकी खिड़की पर एक हुक है, तो इसे या तो यहां कहा जाता है या जब GetMessage कहा जाता है। मुझे यकीन नहीं है। इसके अलावा, डिस्पैच मैसेज बस खिड़की से जुड़े WNDProc पते को देखता है और इसे कॉल करता है। इसके लिए और कुछ नहीं है।

आशा है कि मदद करता है।

6

यह इस बात पर निर्भर करता है कि आपका संदेश कैसे भेजा जाता है और यह कैसे प्रबंधित किया जाता है।

जब आप SendMessage को कॉल करते हैं, यदि लक्ष्य विंडो वर्तमान धागे के स्वामित्व में है, तो कॉल विंडो के लिए संदेश कतार को बाईपास करता है और विंडो प्रबंधक सीधे विंडो विंडो पर विंडोप्रोक को कॉल करता है। यदि लक्ष्य विंडो किसी अन्य थ्रेड के स्वामित्व में है, तो विंडो प्रबंधक प्रभावी रूप से पोस्टमेसेज और पंप विंडो संदेशों को कॉल करता है जब तक कि विंडो विंडो से लक्ष्य विंडो वापस नहीं आती।

जब आप पोस्टमेसेज को कॉल करते हैं, तो विंडो प्रबंधक संदेश पैरामीटर मार्शल करता है और लक्ष्य विंडो के लिए संदेश कतार पर संबंधित ऑब्जेक्ट को सम्मिलित करता है। जब यह अगली कॉल GetMessage को संदेश कतार से हटा दिया जाता है।

विंडो प्रबंधक इनपुट डिवाइस (कीबोर्ड और/या माउस) से कच्चे इनपुट ईवेंट के लिए भी पंजीकरण करता है और यह उन इनपुट ईवेंट के लिए संदेश उत्पन्न करता है। इसके बाद यह कतार में उन संदेशों को उचित रूप से सम्मिलित करता है (इनपुट ईवेंट की प्रसंस्करण जटिल है क्योंकि यह इस बात पर निर्भर करता है कि विंडो के लिए संदेश कतार में कौन से संदेश पहले से हैं)।

जैसा स्टीफन इंगित करता है, अनुवाद संदेश केवल त्वरक कुंजी का अनुवाद करता है - उदाहरण के लिए यह मुख्य अनुक्रमों को WM_COMMAND संदेशों में परिवर्तित करता है।

1

पिछले subquestion से निपटने के लिए एक भेजा संदेश के बाद यह सब हुक (WH_CALLWNDPROC)

4

ओएस बाधा संचालकों विभिन्न प्रकार के माध्यम से पहुंचाया गया है अपने WindowProc के लिए जाना जाएगा ने कहा कि 'संदेश कतार में संदेश रखकर किया जाना चाहिए ', लेकिन जहां प्रक्रिया पता स्थान के भीतर यह कतार रहता है? यह इंटरप्ट हैंडलर कोड के संपर्क में कैसे है?

विंडोज थ्रेड से जुड़े हुए हैं। खिड़की के साथ प्रत्येक थ्रेड में प्रक्रिया की पता स्थान में एक थ्रेड कतार है। हार्डवेयर से उत्पन्न घटनाओं के लिए ओएस की अपनी पता स्थान में एक आंतरिक कतार है। घटना और अन्य राज्य की जानकारी के विवरण का उपयोग करना (उदा।, किस विंडो में फोकस है), ओएस हार्डवेयर घटनाओं को उन संदेशों में अनुवादित करता है जिन्हें उचित थ्रेड कतार में रखा जाता है।

पोस्ट किए गए संदेश सीधे लक्षित विंडो के लिए थ्रेड कतार में रखा गया है।

भेजे गए संदेश आमतौर पर सीधे संसाधित होते हैं (कतार को छोड़कर)।

विवरण बालों वाले हो जाते हैं। उदाहरण के लिए, थ्रेड कतार संदेशों की सूचियों से अधिक हैं - वे कुछ राज्य जानकारी भी बनाए रखते हैं। कुछ संदेश (जैसे WM_PAINT) वास्तव में कतारबद्ध नहीं होते हैं, लेकिन जब आप कतार पूछते हैं और यह खाली होता है तो अतिरिक्त राज्य जानकारी से संश्लेषित किया जाता है। अन्य धागे के स्वामित्व वाली खिड़कियों को भेजे गए संदेश वास्तव में सीधे संसाधित होने की बजाय रिसीवर की कतार में पोस्ट किए जाते हैं, लेकिन सिस्टम कॉलर के दृष्टिकोण से नियमित रूप से अवरुद्ध भेजने की तरह दिखाई देता है। Hilarity ensues अगर यह डेडलॉक का कारण बन सकता है (सर्कुलर के कारण मूल धागे पर वापस भेजता है)।

जेफरी रिचटर किताबों में गोरी के विवरण के बहुत सारे (सभी?) हैं। मेरा संस्करण पुराना है (उन्नत विंडोज़)। वर्तमान संस्करण को Windows via C/C++ कहा जाता है।

ओएस संदेश स्ट्रीम को कॉलर को तर्कसंगत (और अपेक्षाकृत सरल) दिखाई देने के लिए बहुत काम करता है।

संदेश का अनुवाद करने का क्या अर्थ है? अनुवाद संदेश() वास्तव में क्या करने के लिए कॉल करता है?

यह वर्चुअल कुंजी संदेशों के लिए देखता है और, जब यह कुंजी-डाउन/की-अप संयोजन को पहचानता है, तो यह वर्ण संदेश जोड़ता है। यदि आप TranslateMessage पर कॉल नहीं करते हैं, तो आपको WM_CHAR जैसे वर्ण संदेश प्राप्त नहीं होंगे।

मुझे संदेह है कि यह वापस लौटने से पहले चरित्र संदेश भेजता है (जैसा कि उन्हें पोस्ट करने के विपरीत)। मैंने कभी जांच नहीं की है, लेकिन मुझे याद है कि WM_CHAR संदेश WM_KEYUP से पहले पहुंचते हैं।

डिस्पैच मैसेज() द्वारा प्रेषित किए जाने के बाद, मेरे WNDProc तक पहुंचने से पहले संदेश क्या स्विंग करता है (यानी ओएस इसके साथ क्या करता है)?

डिस्पैच मैसेज लक्ष्य विंडो के लिए WNDProc को संदेश भेजता है। रास्ते में, कुछ हुक को संदेश देखने का मौका मिल सकता है (और संभवतः इसमें हस्तक्षेप)।

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