2011-09-18 17 views
11

मैं हुक्स के साथ कुछ बातें की कोशिश कर रहा है, और मुझे समझ नहीं आता क्यों हुक एक संदेश कतार के साथ इस्तेमाल किया जाना चाहिए साथ प्रयोग किया जा SetWindowsHookEx चाहिएक्यों एक विंडोज़ संदेश कतार

hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0); 
MSG msg; 
while(GetMessage(&msg, NULL, 0, 0) > 0) 
{ 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
} 
UnhookWindowsHookEx(hook); 

क्यों कुछ नहीं है इस काम की तरह?

hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0); 
cin >> aKey; 
UnhookWindowsHookEx(hook); 

बढ़ावा धागे का उपयोग करना, और एक बाधा या तो काम नहीं करता। हुक और अनहूक के बीच इंतजार क्यों नहीं किया जा सकता है?

संपादित करें:

मैं एक गलती जब मैं इस नमूना बनाया है, मैं एक WH_KEYBOARD_LL हुक, WH_KEYBOARD नहीं, (मुझे नहीं लगता कि यह एक बड़ा फर्क नहीं पड़ता है)

इसके अलावा पाश कभी नहीं कार्यान्वित बनाया था केवल GetMessage फ़ंक्शन पर प्रतीक्षा करता है।

लूप निष्पादित करता है जब मैं छोड़ संदेश PostThreadMessage(id, WM_QUIT, 2323, NULL); पोस्ट करता हूं तो मुझे समझ में नहीं आता कि यह प्रतीक्षा के बगल में क्या करता है, क्या कुछ आंतरिक प्रसंस्करण है?

संबंधित:

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

How can I set up a CBT hook on a Win32 console window?

उत्तर

26

निम्न स्तर के हुक, WH_KEYBOARD_LL और WH_MOUSE_LL अन्य सभी हुक से अलग हैं। उन्हें लक्ष्य प्रक्रिया में इंजेक्शन देने के लिए डीएलएल की आवश्यकता नहीं होती है। इसके बजाए, विंडोज़ आपकी खुद की प्रक्रिया के अंदर सीधे आपके हुक कॉलबैक को कॉल करता है। यह काम करने के लिए, एक संदेश लूप की आवश्यकता है। आपके मुख्य थ्रेड पर कॉलबैक करने के लिए विंडोज़ के लिए कोई अन्य तंत्र नहीं है, कॉलबैक केवल तभी हो सकता है जब आपने Get/PeekMessage() को कॉल किया हो ताकि विंडोज नियंत्रण में हो।

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

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

Understanding the low-level mouse and keyboard hook (win32)

+0

तो, अगर मैं इसे सही ढंग से समझता हूं, तो विंडोज केवल मेरे कॉलबैक को कॉल/पेकमेसेज() कॉल में कॉल कर सकता है? – Ha11owed

+2

आप इसे सही ढंग से समझते हैं। थ्रेड में सुरक्षित रूप से कॉल इंजेक्ट करने का कोई अन्य तरीका नहीं है, इसे निष्क्रिय होना चाहिए। यही कारण है कि संदेश loops मौजूद हैं। –

+0

@ हंसपैसेंट को स्पष्टीकरण देने के लिए, क्या आप सुझाव दे रहे हैं कि ग्लोबल हुक जैसे WH_KEYBOARD नामित पाइप का उपयोग मेरे स्वयं के कार्यक्रम में "पास" जानकारी के लिए किया जा सकता है और उस कार्यक्रम को संदेश पंप की आवश्यकता नहीं है? – dave

4

विंडोज हुक हुक विंडोज संदेश पाश: http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook

WH_KEYBOARD हुक WM_KEYDOWN और WM_KEYUP के लिए संदेश यातायात नजर रखने के लिए एक आवेदन पत्र में सक्षम बनाता हैद्वारा वापस लौटने वाले संदेशGetMessage या PeekMessage फ़ंक्शन। संदेश कतार में पोस्ट किए गए कीबोर्ड इनपुट की निगरानी के लिए आप WH_KEYBOARD हुक का उपयोग कर सकते हैं।

कंसोल अनुप्रयोग स्वयं संदेशों को पंप नहीं करते हैं - कंसोल प्रक्रिया करता है। तो यह तब तक काम नहीं करेगा जब तक कि प्रक्रिया में संदेश लूप न हो।

देखें:

How can I set up a CBT hook on a Win32 console window?

C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

+0

धन्यवाद, मैं उन सभी को गर्त चला गया लेकिन मैं अभी भी समझ में नहीं आता क्या GetMessage बगल में इंतजार कर रहे है। मेरे मामले में (कंसोल एप्लिकेशन) जब मैं थ्रेड पर छोड़ संदेश पोस्ट करता हूं तो इसे निष्पादित करने का एकमात्र समय होता है। – Ha11owed

+0

इसके अलावा, चूंकि GetMessage प्रतीक्षा करता है, इसका मतलब यह नहीं है कि कंसोल मेरे छोड़ने वाले संदेश तक कोई संदेश पंप नहीं कर रहा है? – Ha11owed

+0

हान का उत्तर देखें - विंडोज़ केवल आपके धागे को कॉल करेगा जब यह जानता है कि यह निष्क्रिय है। और अगर थ्रेड को GetMesasge() में अवरुद्ध किया गया है, तो विंडोज जानता है कि यह कुछ भी नहीं कर रहा है – shf301

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