2008-12-22 16 views
5

मैं स्क्रीन पर एक मॉडलस संवाद दिखाना चाहता हूं और इसमें कुछ जानकारी प्रदर्शित करना चाहता हूं।मैं मॉडल मॉडल कैसे दिखा सकता हूं और इसमें तुरंत जानकारी प्रदर्शित कर सकता हूं?

लेकिन अगर मैं इसे निम्नलिखित तरीके से उपयोग, यह कुछ समस्या है:

function() 
{ 
showdialog(XXX). 
//heavy work. 
update the dialog.. 
//heavy work. 
update the dialog... 
} 

ऐसा लगता संवाद दिखाया गया है, लेकिन यह उस में किसी भी जानकारी को आकर्षित नहीं करता है। जब फ़ंक्शन खत्म हो जाता है तो यह केवल सभी जानकारी खींचता है।

मैं मॉडेलिस संवाद को कैसे संशोधित कर सकता हूं ताकि यह तुरंत जानकारी प्रदर्शित कर सके?

उत्तर

5

कुछ चीजें हैं जो आप कर सकते हैं।

(1) आप पद संवाद CDialog :: OnInitDialog विधि के अंदर से एक संदेश है और फिर उस पोस्ट किए गए संदेश का संदेश हैंडलर में लंबे समारोह संभाल सकता था। इस तरह संवाद पहले प्रदर्शित किया जाएगा और उसके बाद लंबे कार्य को चलाया जाएगा।

(2) दूसरा विकल्प यह सुनिश्चित करना है कि संदेश लूप को कुछ प्रसंस्करण समय मिल जाए। तो अपने लंबे समारोह पाश किसी प्रकार का है अगर सिर्फ बनाने के लिए ProcessMessages को कभी कॉल सुनिश्चित करें, संदेश कतार में रखा जाता है खाली:

void ProcessMessages() 
{ 
    MSG msg; 
    CWinApp* pApp = AfxGetApp(); 
    while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 
    { 
     pApp->PumpMessage(); 
    } 
} 

संपादित करें: यह निश्चित रूप से संभव है धागे का उपयोग करने के इस तरह के है एक परिस्थिति, लेकिन ऐसा करना हमेशा जोखिम और जटिलता के बिना नहीं होता है।

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

ऐसे ही एक मुद्दे के एक उदाहरण के लिए इस लिंक का संदर्भ लें:

http://msdn.microsoft.com/en-us/library/ms644946(VS.85).aspx

जहां है कहते हैं:

PostThreadMessage द्वारा भेजे गए संदेश एक खिड़की के साथ जुड़े नहीं हैं। सामान्य नियम के रूप में, संदेश जो विंडो से जुड़े नहीं हैं डिस्पैच मैसेज फ़ंक्शन द्वारा प्रेषित नहीं हो सकते हैं। इसलिए, यदि प्राप्तकर्ता थ्रेड एक मोडल लूप में है (जैसा कि संदेशबॉक्स या डायलॉगबॉक्स द्वारा उपयोग किया जाता है), संदेश खो जाएंगे। थ्रेड संदेशों को एक मोडल लूप में अवरुद्ध करने के लिए, थ्रेड-विशिष्ट हुक का उपयोग करें।

मैं Zeus IDE में प्रक्रिया संदेश दृष्टिकोण का उपयोग करें और यह सुनिश्चित करें कि जीयूआई उपयोगकर्ता के लिए उत्तरदायी रहता है बनाने में बहुत अच्छी तरह से काम करता है। इसे लागू करने में बहुत आसान होने का लाभ भी है।

+2

आईएमओ प्रक्रिया मैसेज() फ़ंक्शन एक एमएफसी ऐप पर प्रतिक्रिया जोड़ने का तरीका है। – Hapkido

+2

मैं भी प्रोसेस मैसेज विकल्प का उपयोग करूंगा;) – jussij

+0

मैं दृढ़ता से असहमत हूं। 1) एक यूआई विधि बहुत सारे "अन्य" काम नहीं करनी चाहिए, चिंताओं को अलग किया जाना चाहिए। 2) इन परिस्थितियों में से अधिकांश में एक साधारण कार्यकर्ता थ्रेड का उपयोग किया जा सकता है, एकाधिक पंपों की आवश्यकता नहीं है। आप ओपी को धागे से दूर डराने की कोशिश क्यों कर रहे हैं? –

2

अंगूठे के नियम के रूप में, जीयूआई थ्रेड में भारी गणना कभी नहीं रखी जानी चाहिए। चूंकि यह एक मॉडलस संवाद है, इसलिए संवाद संदेश लूप का स्वामित्व नहीं रखेगा।ProcessMessage() समाधान काम करेगा, लेकिन आईएमओ सही तरीका नहीं है। मेरा सुझाव है: 1) OnInitDialog में एक नया धागा स्पंज करें() 2) कुछ दिलचस्प होने पर संवाद के लिए अलग थ्रेड पोस्ट संदेश रखें। इन दिलचस्प चीजों में से एक यह है कि काम किया जाता है।

नोट, हालांकि, इसका मतलब यह होगा कि आपको उचित सिंक्रनाइज़ेशन करने की आवश्यकता है।

4

OnInitDialog में, कंप्यूटेशंस करने के लिए एक कार्यकर्ता धागा शुरू करें। संवाद अद्यतन करने के लिए कार्यकर्ता थ्रेड से उपयोगकर्ता संदेश पोस्ट करें।

यह ProcessMessages कार्यान्वयन से बेहतर है कई कारणों से:

  • गणना करने के लिए कोड यूआई कोड, जहां यह नहीं है से बाहर अलग किया जा सकता।

  • वास्तविक गणना किए जाने पर UI उत्तरदायी बना रहता है। ProcessMessages एकल गणना फ़ंक्शन के दौरान एकाधिक UI अद्यतनों की अनुमति देता है, लेकिन UI को वास्तविक गणना के दौरान अभी भी अवरुद्ध कर दिया जाएगा।

संवाद कोड:

#define WM_NEW_COUNT (WM_USER + 0x101) 

BEGIN_MESSAGE_MAP() 
    ON_MESSAGE(WM_NEW_COUNT, OnNewCount) 
END_MESSAGE_MAP() 

BOOL CMyDialog::OnInitDialog() 
{ 
    CWinThread* pThread = AfxBeginThread(MyCountFunc, this->GetSafeHwnd()); 
    return TRUE; 
} 

LRESULT CMyDialog::OnNewCount(WPARAM wParam, LPARAM) 
{ 
    int newCount = (int)wParam; 

    // m_count is DDX member, e.g. for label 
    m_count = newCount; 

    UpdateData(FALSE); 

    return 0; 
} 

कार्यकर्ता धागा:

UINT MyCountFunc(LPVOID lParam) 
{ 
    HWND hDialogWnd = (HWND)lParam; 

    for (int i=0; i < 100; ++i) 
    { 
     PostMessage(hDialogWnd, WM_NEW_COUNT, i, NULL); 
    } 
} 
1

ही बार में अपने भारी काम करने के लिए कोशिश मत करो। संवाद में स्वयं को OnInitDialog में WM_APP रेंज में एक संदेश पोस्ट करें। डब्लूएम_एपीपी हैंडलर भारी काम का हिस्सा कर सकता है, फिर एक और पोस्ट मैसेज और रिटर्न करें। इस तरह, आप संदेश पंप को प्रसंस्करण के अपने हिस्सों के बीच विंडो संदेशों को संसाधित करने की अनुमति देते हैं।

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

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