2012-11-13 15 views
6

मेरे पास 2 ऐप्स हैं, एक छिपी हुई विंडो ("एचडब्लू") है, दूसरा कंसोल ऐप ("सीए") है , से जो मुझे लगता है कि एचडब्ल्यू को आदेश भेजना है। अगर मैं चल रहा हूँ: सांत्वना अनुप्रयोग मैं HW संभाल हो रही है, और यहाँ में एक सवाल हैPostMessage (hwnd, WM_SETTEXT, ..) पोस्टमेसेज (hwnd, WM_QUIT, ..) करता है, जबकि

PostMessage(hwnd, WM_QUIT, NULL, NULL); 

सब कुछ ठीक काम करता है, संदेश HW करने के लिए हो जाता है और .लेकिन यह बंद हो जाती है अगर मैं भेज रहा हूं

PostMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)"texttext"); 

संदेश एचडब्ल्यू नहीं मिलता है। जासूस ++ यह भी दिखाता है कि संदेश एचडब्ल्यू नहीं मिलता है। क्या WM_SETTEXT के बारे में कुछ विशिष्ट है, जो इसे रोकता है? अग्रिम में धन्यवाद।

ठीक है। पाया जवाब यहाँ http://cboard.cprogramming.com/windows-programming/72589-wm_settext-postmessage.html

 
Turns out the API tries to protect me against scope issues; PostMessage() 
always fails with WM_SETTEXT, or any other system-defined message that has 
a pointer as a parameter.Which gets me to SendMessage(), which is not good, 
because i wanted asynchronous messaging....


P.P.S.
इसके अलावा, लग रहा है
तरह

SendMessage(hwnd, WM_QUIT, NULL, NULL); 

HWND hNote; 
if (!(hNote=FindWindow(L"Notepad",NULL))) 
     exit(1); 
SendMessage(hNote, WM_QUIT, NULL, NULL); 

जबकि

PostMessage(hNote, WM_QUIT, NULL, NULL); 

काम करता है की तरह साधारण परीक्षण अनुप्रयोग में app.Even लक्षित करने के लिए कुछ नहीं करता।
जो मेरे लिए इतना तार्किक नहीं दिखता है ... क्या कोई सार्वभौमिक कार्य है जो किसी भी प्रकार के संदेश के साथ ठीक से काम करता है?

+1

मुझे लगता है कि आपका संदेश तुरंत अस्वीकार कर दिया गया है क्योंकि आपके द्वारा प्रदान किए गए पॉइंटर को प्रेषण समय पर मान्य होने की गारंटी नहीं है। आपको उपयोगकर्ता द्वारा परिभाषित/पंजीकृत संदेश का उपयोग करके इसे काम करने की आवश्यकता है जहां आप पेलोड स्ट्रिंग के प्रबंधन के लिए ज़िम्मेदार हैं। या, वहां से अन्यथा विंडो थ्रेड और 'SendMessage' में नियंत्रण पास करें। –

+0

आपको SendMessage() का उपयोग करने की आवश्यकता है। और आम तौर पर एक यूनिकोड स्ट्रिंग का उपयोग करें। –

+0

धन्यवाद। इसे अभी मिला। लेकिन एसिंक संदेश में पूर्वनिर्धारित पाठ नहीं भेजना चाहता था। – user1821599

उत्तर

0

आप जो करने की कोशिश कर रहे हैं वह दो अलग-अलग प्रक्रियाओं को संवाद कर रहा है, नियमित संदेश काम नहीं करेंगे, लेकिन ऐसा कोई भी है जो चाल कर सकता है: WM_COPYDATA संदेश। एक संबंधित प्रश्न here

+0

इसी कारण से 'पोस्टमेसेज' का उपयोग किसी प्रक्रिया में 'WM_SETTEXT' के साथ नहीं किया जा सकता है, न ही इसे' WM_COPYDATA 'वितरित करने के लिए उपयोग किया जा सकता है। http://blogs.msdn.com/b/oldnewthing/archive/2011/09/16/10208976।एएसपीएक्स –

+0

आप सही हैं !, मैं पूरी तरह से 'SendMessage' के बजाय' PostMessage' के माध्यम से संदेश भेजने के बारे में भूल गया था। आपकी प्रतिक्रिया सही है – csanchez

1

आपके अंतिम प्रश्न से शुरू हो सकता है: कोई सार्वभौमिक संदेश फ़ंक्शन नहीं है जो आप चाहते हैं जो करेंगे।

के अपने मामलों का विश्लेषण करते हैं:

  1. WM_SETTEXT: तो तुम, प्रक्रियाओं के बीच सुरक्षित रूप से यह पोस्ट नहीं कर सकते के रूप में वे स्मृति पतों अलग होगा संदेश, एक सूचक लेता है, और एक प्रक्रिया से एक सूचक बेमानी होगी दूसरे को। आप SendMessage() का उपयोग कर सकते हैं क्योंकि विंडोज संदेश के बारे में जानता है, दृश्यों के पीछे डेटा कॉपी करता है और अतिरिक्त हैकिंग करता है। लेकिन PostMessage() के साथ ऐसा जादू नहीं हो सकता है (नहीं हो सकता है)।

  2. WM_QUIT: यह एक विशेष संदेश है जो संदेश लूप को तोड़ देता है। इसे छोटा बनाना, यह सब GetMessageFALSE लौटा रहा है, इसलिए मानक संदेश लूप (1) समाप्त होता है। लेकिन, आह! यह केवल तभी काम करेगा यदि आप PostMessage() इसे काम करते हैं। जब आप SendMessage() संदेश भेजते हैं, तो यह संदेश कतार में भी रुकने के बिना सीधे संबंधित विंडो फ़ंक्शन पर भेजा जाता है। और खिड़कियां WM_QUIT के साथ कुछ भी नहीं करती हैं, क्योंकि वे इसकी अपेक्षा नहीं कर रहे हैं। असल में, यहां पोस्ट किए जाने पर भी, यह संदेश विंडो तक नहीं पहुंच जाएगा, क्योंकि सामान्य लूप इसके लिए DispatchMessage() पर कॉल नहीं करता है।यही कारण है कि इसे आम तौर पर खिड़की के बिना थ्रेड पर पोस्ट किया जाता है, और इसलिए कोई कार्य मौजूद होता है जो यह करता है: PostQuitMessage()

(1) मानक संदेश पाश:

while (GetMessage(&msg, 0, 0, 0)) 
    DispatchMessage(&msg); 

एक फुटनोट के रूप में, आप प्रक्रियाओं के बीच डेटा स्थानांतरित करने के लिए कई चालें का उपयोग कर सकते हैं:

  1. उपयोग WM_COPYDATA। AFAIK इसका उपयोग PostMessage() के साथ नहीं किया जा सकता है, लेकिन हो सकता है कि आप लक्ष्य प्रक्रिया में दो धागे बना सकें ताकि पहले व्यक्ति को WM_COPYDATA प्राप्त हो और जल्दी से लौटाया जा सके और फिर इसे दूसरे थ्रेड द्वारा कतारबद्ध करने के लिए पोस्ट किया जा सके।

  2. साझा स्मृति का उपयोग करें (CreateFileMapping() के लिए खोजें) और PostMessage() उस स्मृति में ऑफ़सेट करें। आपको शायद किसी सिस्टम के बजाय WM_APP + x उपयोगकर्ता परिभाषित संदेश का उपयोग करना चाहिए। हालांकि, सिंक्रनाइज़ेशन समस्याओं से सावधान रहें, आपको म्यूटेक्स या कुछ की आवश्यकता होगी।

  3. नामित पाइप! (मेरा पसंदीदा)

  4. सॉकेट।

8

विभिन्न संदेशों में अलग-अलग आवश्यकताएं हैं। कुछ को कतार में पोस्ट करने की आवश्यकता है। और कुछ को समकालिक रूप से वितरित करने की आवश्यकता है। इसलिए प्रणाली को वितरण तंत्र दोनों की आवश्यकता के लिए डिज़ाइन किया गया है।

WM_SETTEXT के मामले में, इसे हमेशा समकालिक रूप से वितरित करने की आवश्यकता होती है। ऐसा इसलिए है क्योंकि विंडो प्रबंधक को टेक्स्ट डेटा के जीवनकाल को प्रबंधित करने में सक्षम होना चाहिए। रेमंड चेन ने इस मुद्दे के बारे में बात की: Why can't I PostMessage the WM_COPYDATA message, but I can SendMessageTimeout it with a tiny timeout?

खिड़की दूसरी प्रक्रिया में होने पर SendMessage पर कॉल करने के साथ एक संकट है। यदि दूसरी प्रक्रिया लटका दी गई है, तो आपकी प्रक्रिया भी लटका नहीं जाएगी। क्योंकि SendMessage तुल्यकालिक है।

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

+0

और यदि आप वास्तव में यह असीमित होना चाहते हैं तो आप हमेशा थ्रेड पर 'SendMessageTimeout() 'निष्पादित कर सकते हैं। –

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