2009-03-05 7 views
7

मेरे पास एक ऐसा एप्लिकेशन है जो किसी विशेष डिवाइस के लिए कुछ सेटिंग्स सेट करने के लिए कुछ अन्य उपयोगिता अनुप्रयोग को कॉल करता है। उस उपयोगिता अनुप्रयोग को ShellExecuteEx का उपयोग करके बुलाया जाता है।मैं अपनी प्रक्रिया में मोडल प्रकट करने के लिए एक बाल प्रक्रिया विंडो कैसे बना सकता हूं?

तो जैसा कि उपयोगकर्ता भ्रमित करने के लिए नहीं है, यह मेरी मुख्य विंडो पर उपयोगिता आवेदन मोडल की खिड़की बनाया करने के लिए बेहतर होगा। कोई इसे कैसे करता है?

बातें मैं कोशिश की है: ShellExecuteEx, अनंत TIMEOUT के बाद प्रक्रिया पर

  1. WaitForSingleObjectEx - खिड़की मॉडल है, लेकिन मुख्य आवेदन फिर से रंगना नहीं करता
  2. WaitForSingleObjectEx (क्योंकि यह एक वस्तु के लिए इंतज़ार कर रहा है!) ShellExecuteEx के बाद प्रक्रिया पर, कुछ छोटे टाइमआउट, फिर Peekmessage और DispatchMessage को कॉल करें - अब काम करता है, लेकिन उपयोगिता अनुप्रयोग अब "मोडल" नहीं है। मुख्य आवेदन माउस क्लिक, बटन क्लिक, आदि
  3. EnableWindow (FALSE) का जवाब है, तो, विधि # 2 करते तो EnableWindow (TRUE) - काम करता है !!!, लेकिन इस के बाद, अपने आवेदन के ज़ेड-ऑर्डर बदल दिया है। (यह अब कुछ अन्य विंडो के नीचे है)। क्यूं कर?!
+0

अनुरोधित संपादन: शीर्षक में परिवर्तन "मैं अपनी प्रक्रिया में मोडल प्रकट करने के लिए एक बाल प्रक्रिया विंडो कैसे बना सकता हूं?"। आपका वर्तमान शीर्षक एक बच्चे विंडो मोडल बनाने और अपनी विंडो को दूसरी प्रक्रिया में इंजेक्ट करने के बीच अंतर को प्रतिबिंबित नहीं करता है (सेटपेरेंट() देखें –

उत्तर

3

संक्षिप्त उत्तर कोई रास्ता मूल धागा एक में एक खिड़की के लिए धागा मोडल में एक खिड़की बनाने के लिए, भले ही धागे में एक ही प्रक्रिया में हैं है कि वहाँ है। यदि आपके पास दोनों विंडो के लिए कोड है, तो आप करीब आ सकते हैं, लेकिन उस स्थिति में आप अपने सभी UI को एक थ्रेड में डालकर प्रयास के लिए बेहतर परिणाम प्राप्त करेंगे।

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

कि बचने के लिए, मैं इस दृष्टिकोण ले जाएगा:

  1. उपयोगकर्ता canner.exe की मुख्य विंडो में "एफडीए निरीक्षण" क्लिक करता है। canner.exe एक मॉडल संवाद दिखाता है जो दर्शाता है कि यह एक बाहरी प्रोग्राम खोल रहा है ("बोटुलिज्म सेटिंग्स खोलना ...")। यह मुख्य विंडो इत्यादि को अक्षम करता है ताकि उपयोगकर्ता जानता है कि एक मोडल इंटरैक्शन हो रहा है।
  2. canner.exe botulism.exe शुरू करने के लिए ShellExecuteEx() पर कॉल करता है।
  3. canner.exe संभाल ShellExecuteEx से लौटे WaitForInputIdle() पर कॉल()। WaitForInputIdle() वापस आ जाएगा (लगभग, लेकिन आमतौर पर पर्याप्त बंद) जब botulsim.exe उपयोगकर्ता इंटरैक्शन के लिए तैयार है। यदि botulism.exe आमतौर पर इसके UI को दिखाने के लिए पांच या अधिक सेकंड लेता है, तो मैं लूप में WaitforInputIdle() के साथ एक छोटा टाइमआउट का उपयोग कर सकता हूं और कभी-कभी PeekMessage()/ProcessMessage() के साथ किसी भी लंबित संदेशों को संसाधित करता हूं।
  4. canner.exe अपने संवाद पाठ में परिवर्तन है कि यह botulism.exe बंद करने के लिए उपयोगकर्ता के लिए प्रतीक्षा कर रहा है को प्रतिबिंबित करने के ("जारी रखने के लिए बंद बोटुलिज़्म सेटिंग्स ...")।
  5. canner.exe तक botulsim.exe बंद कर देता है प्रतीक्षा करने के लिए MsgWaitForMultipleObjects() एक पाश में कहता है। MsgWaitForMultipleObjects() वापस आ जाएगा जब हैंडल पास किए गए हैं या जब थ्रेड की कतार में संदेश प्रतीक्षा कर रहे हैं।
  6. उपयोगकर्ता जबकि canner.exe इंतज़ार कर रहा है canner.exe के मॉडल संवाद में करीब बॉक्स क्लिक करता है, canner.exe उपयोगकर्ता कि botulism.exe अभी भी चल रहा है का संकेत देता है ("बोटुलिज़्म सेटिंग्स अभी भी खुला है, फिर भी जारी?", " हाँ, मुझे पता है "या" नहीं, मैं नहीं कर रहा ")। अगर पुष्टि हुई है, तो canner.exe संवाद बंद कर देता है और मूल FDA निरीक्षण चरण 1 में शुरू होता है और मुख्य विंडो के संदेश पाश पर लौटता है।
  7. MsgWaitForMultipleObjects() इंगित करता है कि botulism.exe समाप्त हो गया है, canner.exe संवाद बंद और एफडीए निरीक्षण के साथ सामान्य रूप से जारी है चरण में 1.

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

+0

आपने ओपी के निर्दिष्ट इरादे को याद किया। वह यह निर्बाध बनाना चाहता है, वह चाहता है कि twp ऐप्स एक के रूप में दिखाई दें। यह समाधान नलसाजी का खुलासा करता है। अपनी शब्दावली का उपयोग करके, अंतिम उपयोगकर्ता को "botulism.exe" के बारे में जानना नहीं चाहिए। – jdigital

+0

दुर्भाग्य से विंडोज मॉडल, और निश्चित रूप से संवाद प्रबंधक, जो सामान्यता का सामान्य एजेंट है, प्रक्रिया सीमाओं में सहज नहीं है। और अगर मुझे सीम मिलनी है, तो मैं एक छिपी हुई सीम पर एक मजबूत, दृश्यमान सीम पसंद करता हूं जो यात्रा के दौरान खुलता है। –

+0

आप सही हैं कि ऐसा करने के लिए कोई सीधा/सीधा तरीका नहीं है। हालांकि, यह लगभग निश्चित रूप से करने योग्य है। सवाल यह है कि क्या यह 150 पीटी के लायक है। ब्योरा विवरण बिताने के लिए समय बिताने के लिए।यह सामान्य परामर्श शुल्क से बहुत कम है ;-) – jdigital

0

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

सीधे विंडो को अक्षम करने के बजाय, उपयोगकर्ता इनपुट को अनदेखा करके इसे अक्षम करने का प्रयास करें। तो EnableWindow को कॉल करने के बजाय, इनपुट संदेश फ़िल्टर करने के लिए अपना संदेश पाश बदलें। विशेष रूप से, यदि

msg >= WM_KEYFIRST || msg <= WM_KEYLAST || msg >= WM_MOUSEFIRST || msg <= WM_MOUSELAST 

फिर संदेश को छोड़ दें; अन्यथा, इसे सामान्य प्रेषण पाश पर पास करें। आप जो कर रहे हैं वह आपकी अपनी अक्षम विंडो बना रहा है, लेकिन विंडोज़ यह नहीं जानता है।

4

आपके पास अनुकरण करने के लिए दो चीजें हैं: स्वामित्व और औपचारिकता।

स्वामित्व अनुकरण करने के लिए: आपको अपनी नई बाल प्रक्रिया विंडो के मालिक को अपनी विंडो में सेट करने की आवश्यकता है। यह किसी भी जेड ऑर्डरिंग मुद्दों को कम करना चाहिए। हालांकि मुझे नहीं पता कि यह किसी अन्य प्रक्रिया से काम करता है या नहीं। यदि नहीं तो आपको अपनी थ्रेड इनपुट कतार संलग्न करनी पड़ सकती है और फिर उसे कॉल करनी पड़ सकती है। या कुछ अन्य कोड इंजेक्शन तकनीक का उपयोग करें।

SetWindowLong <target window handle>, GWL_HWNDPARENT, <new owner handle> 

साधन अनुकरण करने के लिए, मुझे लगता है कि आप EnableWindow और WaitForSingleObjectEx साथ सही रास्ते पर हैं।

+3

SetWindowLong GWL_HWNDPARENT प्रक्रियाओं में काम करता है, यह आपके लिए इनपुट कतार में शामिल हो जाता है। –

2

सक्षम विन्डो सही है, यह आमतौर पर संदेश बॉक्स और अन्य "मोडल" विंडोज़ करता है। ज़ेडर बदलने के लिए, आप WM_WINDOWPOSCHANGING संदेश को रोक सकते हैं और Zorder परिवर्तन को रोकने के लिए SWP_NOZORDER ध्वज सेट कर सकते हैं। सुनिश्चित करें कि आप केवल यह सुनिश्चित करते हैं कि आप EnableWindow (false) सेट कर रहे हैं।

1

बस तार्किक सुझाव,
शायद तुम अदृश्य मोडल प्रपत्र बना सकते हैं और उनसे का उपयोग विधि 1 #।

+0

मैं अब यह कोशिश कर रहा हूँ। – moogs

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

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