2012-03-21 7 views
7

मेरे पास एक डेल्फी 2006 ऐप है जो त्रुटि स्थिति के जवाब में एक मोडल संवाद पॉप अप कर सकता है। ऐसा लगता है कि यह खुद को ऐसे राज्य में ले जाता है जहां इन मोडल संवादों में से एक खुला है, जो मुख्य रूप के सामने स्थित है, लेकिन न तो फॉर्म संदेश का जवाब दे रहा है। या तो क्लिक करने से "बोनक" मिलता है। ऐप ठीक चल रहा है, यूआई मुख्य रूप अपडेट कर रहा है, लेकिन आप कुछ भी नहीं कर सकते हैं। मुझे लगता है कि मुख्य रूप में एक और मोडल संवाद संभवतः है। चाहे यह मेरा है या विंडोज़ में से एक है, मुझे कोई जानकारी नहीं है।डेल्फी - मैं कैसे पता लगा सकता हूं कि कौन से मोडल संवाद ने ध्यान केंद्रित किया है और इसे सामने लाया है?

अन्य अंक:

  • एप्लिकेशन ठीक कीबोर्ड शॉर्टकट प्रतिक्रिया करता है। इन शॉर्टकट्स में से एक ने ऐप को शानदार तरीके से बंद कर दिया और यह काम किया। मैं तब से स्थिति को पुन: पेश करने में असमर्थ रहा हूं।
  • ऐप में एक ट्रे आइकन है। यह सही माउस क्लिक का जवाब देता है। यदि मैं यहां से ऐप को छोटा करता हूं तो मुख्य रूप कम से कम फोकस किए बिना मोडल डायलॉग को कम करता है और छोड़ देता है। अगर मैं मुख्य रूप को पुनर्स्थापित करता हूं, तो चीजें होती हैं जैसे कि खिड़की पर ध्यान केंद्रित नहीं किया जाता है। Alt-Tab के समान परिणाम हैं।
  • मंच विंडोज 7
  • है मैं DisableProcessWindowsGhosting फोन से पहले किसी भी रूपों बनाई गई हैं
  • मैं

    ModalDialog.PopupParent := MainForm ; 
    ModalDialog.ShowModal ; 
    
  • साथ मोडल संवाद खोल मैं इन त्रुटि संवाद को स्थगित करता है, तो अन्य मोडल संवाद खुले हैं:

    if (Application.ModalLevel = 0) then 
        {open modal dialog} 
    

मेरी क्वा एस्टियन के दो भाग हैं:

क्या प्रोग्राम की खोज करने का कोई तरीका है कि कौन सी विंडो फोकस कर रही है? इसके बाद मैं इस परिदृश्य या आखिरी उपाय के लिए कुछ कार्रवाई कर सकता था, मैं उन्हें सामने लाने के लिए शॉर्टकट कुंजी प्रदान कर सकता था या मॉड्यूलरसेट को एमआरकैंकल सेट करने जैसे कुछ अपवर्तक कार्रवाई (संवाद के आधार पर) ले सकता था।

यह स्थिति कैसे उत्पन्न हो सकती है? आम तौर पर जब मुझे मुख्य रूप के पीछे एक मॉडल संवाद मिलता है (मैं इसे खोलने के लिए मोडल संवाद प्राप्त करके, ट्रे आइकन से ऐप को कम करके, फिर ऐप को पुन: स्थापित कर सकता हूं - ऐप मुख्य फ़ॉर्म संवाद के सामने पुनर्स्थापित करता है संवाद अभी भी ध्यान केंद्रित कर रहा है), मैं ट्रे आइकन पर क्लिक करके इसे फिर से सामने ला सकता हूं, या Esc कुंजी के साथ बंद कर सकता हूं लेकिन यह इस मामले में काम नहीं करता है।

** अद्यतन * *

Misha के ठीक TSaveDialog जैसी गैर-डेल्फी संवादों से अलग काम किया। Execute पर कॉल करने से ठीक पहले Application.ModalPopupMode := pmAuto ; जोड़कर मैं उन्हें काम करने में सक्षम था।

  • बचाने खुले संवाद
  • ट्रे आइकन से एप्लिकेशन
  • ट्रे आइकन से एप्लिकेशन को बहाल कम से कम:

    से मेरा मतलब है कि बचाने के संवाद निम्न क्रम के बाद सामने था, "यह काम करने के लिए मिल गया है"

जबकि यह ModalPopupMode := pmAuto के बिना मुख्य रूप के पीछे था।

तो मुझे उम्मीद है कि ये परिवर्तन (अभी तक अप्रत्याशित) समस्या में मदद करेंगे।

+2

पता लगाना जो खिड़की ध्यान केंद्रित किया है और ले जा सुधारात्मक कार्रवाई करने में मदद करने नहीं जा रहा है। आपको स्रोत पर समस्या से निपटने की जरूरत है। और इसका मतलब है कि खिड़की के स्वामित्व को समझना (यानी पॉपअपपेरेंट)। –

+0

धन्यवाद @ डेविड।यह पता लगाने के लिए कि कौन सी खिड़की पर ध्यान केंद्रित किया गया है निश्चित रूप से मदद करने जा रहा है क्योंकि यह संभवतः मुझे दिखाएगा कि मैं समस्या को पुन: उत्पन्न कैसे कर सकता हूं, जिसे मैं वर्तमान में नहीं कर सकता। – rossmcm

+0

एक बार जब आप इसे प्रकट कर लेते हैं तो आपको स्वामित्व संबंधों को समझने के लिए Spy ++ जैसे कुछ का उपयोग करने में सक्षम होना चाहिए। मैं इसे बाहर से डीबग करने की कोशिश करता हूं, कम से कम जब तक आपके पास एक रिप्रो न हो। –

उत्तर

4

अंतिम सक्रिय पॉपअप विंडो (VCL या नहीं) GetLastActivePopup साथ पूछे जा सकता है:

function GetTopWindow: HWND; 
begin 
    Result := GetLastActivePopup(Application.Handle); 
    if (Result = 0) or (Result = Application.Handle) or 
     not IsWindowVisible(Result) then 
    Result := Screen.ActiveCustomForm.Handle; 
end; 

यह कुछ हद तक है TApplication.BringToFront से कॉपी किया गया।

सामने इस विंडो लाना SetForegroundWindow के द्वारा किया जा सकता है:

SetForegroundWindow(GetTopWindow); 

ध्यान दें कि Application.BringToFront चाल पूरी तरह कर सकते हैं, लेकिन मैं एक बार, एक स्थिति मैं करने में सक्षम नहीं किया गया अनुभव यह ठीक ढंग से काम नहीं किया हालांकि से पुनरुत्पादन।

+1

आपको 'असाइन किए गए (स्क्रीन.एक्टिव कस्टमफॉर्म)' की जांच करने की आवश्यकता है। मैं अपने ऐप को 'एप्लिकेशन.शोमेनफॉर्म: = गलत' के साथ ट्रे में चला रहा हूं, अगर मैं 'GetTopWindow' कहता हूं, जब कोई फॉर्म दिखाया नहीं गया है तो यह एवी फेंकता है। – saastn

0

GetForegroundWindow() वह फ़ंक्शन है जिसे आप ढूंढ रहे हैं, अगर आपको शीर्षक पता है या मोडल विंडो का हैंडल यह सरल है।

एचडब्ल्यूएनडी GetForegroundWindow();

अग्रभूमि खिड़की (विंडो उपयोगकर्ता जिसके साथ वर्तमान में काम कर रहा है) के लिए एक संभाल पुन: प्राप्त करता। सिस्टम थ्रेड को थोड़ा अधिक प्राथमिकता देता है जो अन्य थ्रेडों के लिए अग्रभूमि विंडो बनाता है।

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633505%28v=vs.85%29.aspx

5

एक रूप है कि ध्यान केंद्रित किया बहुत समय लगता है, संदेश (Form1) के लिए प्रतिक्रिया करने ताकि विंडोज सोचता Form1 उत्तर नहीं देता है, और Form1 तो एक मॉडल फार्म (Form2) को प्रदर्शित करता है, Form2 है के बाद तो प्रदर्शित और एप्लिकेशन फिर से संदेशों को संसाधित कर रहा है, फॉर्म 1 को सामने लाया जाएगा, जिससे संभावित रूप से "कवर" फॉर्म 2 होगा।

Application.OnIdle घटना में इस लाना चाल करना होगा:

if Assigned(Screen.ActiveForm) then 
    begin 
    if (fsModal in Screen.ActiveForm.FormState) and 
     (Application.DialogHandle <= 0)) then 
    begin 
     Screen.ActiveForm.BringToFront; 
    end; 
    end; 
+0

धन्यवाद @ मिशा। ऐसा लगता है कि जब कोई गैर-वीसीएल संवाद खुला होता है, तो यह चाल चलती है, उदा। एक लोड फ़ाइल संवाद, इसलिए हम अभी तक काफी नहीं हैं। मैंने टाइमर का उपयोग किया क्योंकि ऑनइडल इवेंट आग नहीं है (उदाहरण के लिए) यदि आपके पास एक संदर्भ मेनू खुला है – rossmcm

+0

अद्यतन के लिए ओपी देखें। – rossmcm

0

मैंने मिशा के समाधान का उपयोग किया और आरएसएसएमसीएम की समस्याओं को हल करने के लिए थोड़ा आगे (एनजीएलएन कोड का उपयोग करके) काम किया (गैर वीसीएल संवादों को संभालना)।

निम्नलिखित कोड मैं एक टाइमर चल रहा है:

type 
    TCustomFormAccess = class(TCustomForm); 


if Assigned(Screen.ActiveCustomForm) then 
begin 
    if ((fsModal in Screen.ActiveCustomForm.FormState) and 
     (Application.DialogHandle <= 0)) then 
    begin 
    TopWindow := GetLastActivePopup(Application.Handle); 
    TopWindowForm := nil; 
    for i := 0 to Screen.CustomFormCount - 1 do 
    begin 
     CustomFormAccess := TCustomFormAccess(Screen.CustomForms[i]); 
     if CustomFormAccess.WindowHandle = TopWindow then TopWindowForm := CustomFormAccess; 
    end; 
    if Assigned(TopWindowForm) and (Screen.ActiveCustomForm.Handle <> TopWindow) then 
    begin 
     Screen.ActiveCustomForm.BringToFront; 
    end; 
    end; 
end; 
संबंधित मुद्दे

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