2009-11-03 7 views
9

मेरे एप्लिकेशन को डेटाबेस से कनेक्ट करने में कुछ समय लग सकता है। यह कनेक्शन एक लाइब्रेरी फ़ंक्शन कॉल के साथ बनाया गया है, यानी मैं वहां प्रगति अद्यतन नहीं डाल सकता और कॉलबैक या कुछ समान बना सकता हूं।एक अलग थ्रेड में प्रगति पट्टी के साथ एक एमएफसी संवाद कैसे बनाएँ?

मेरा विचार डीबी से कनेक्ट करने से पहले एक अलग थ्रेड में प्रगति पट्टी के साथ एक संवाद बनाना था। यह संवाद CProgressCtrl::StepIt() के साथ प्रगति की स्थिति को लगातार बदल देगा ताकि उपयोगकर्ता कुछ हो रहा हो।
उस संवाद के बाद और इसकी बात करने के बाद मैं मुख्य थ्रेड से डीबी कनेक्शन फ़ंक्शन को कॉल करना चाहता हूं। कनेक्शन फ़ंक्शन पूरा होने के बाद, मैं प्रगति पट्टी थ्रेड को रोकना चाहता हूं।

CMyApp::  ProgressThread 
InitInstance()  . 
    |    . 
    |    . 
    +-Create Dialog-+ 
    |    | 
    |    Animate 
Connect   Progress 
    to    Bar 
    DB    | 
    |    | 
    +-Destroy Dlg---+ 
    |    . 
    |    . 

संभव है कि है:

मुझे एक तस्वीर पेंट करते हैं? यदि हां, तो कैसे?

शायद पूरी बात टाइमर का उपयोग करके भी काम करेगी। शायद अधिक आसान होगा लेकिन मैं इसे काम करने के लिए नहीं मिल सका।

  1. मैं CProgressCtrl::SetMarquee() जो कर सकते हैं मैं वास्तव में क्या जरूरत के बारे में पता कर रहा हूँ, लेकिन मैं इसका इस्तेमाल नहीं कर सकते क्योंकि आवेदन यूनिकोड समर्थन नहीं है।
  2. मैं डीबी कनेक्शन कॉल को एक अलग धागे में ले जा सकता हूं लेकिन इस तरह यह कोड में बहुत सारे बदलाव और कनेक्शन त्रुटियों के अतिरिक्त हैंडलिंग की तरह दिखता है।

अद्यतन 2
मैं जिस तरह से AlexEzh और जेवियर डी पेड्रो सुझाव काम कर समझ लिया: अपनी ही धागे में डीबी stuf रखो।
शुरुआत में मुझे चिंता थी कि त्रुटि प्रबंधन कैसे किया जा सकता है लेकिन वास्तव में यह वास्तव में इसी तरह के समान था।

  1. मुख्य धागे में मैं कनेक्शन पैरामीटर, परिणाम ध्वज और थ्रेड-चलने-ध्वज के साथ एक संरचना बना देता हूं। उत्तरार्द्ध प्रारंभ में true पर सेट किया गया है।
  2. मैं एक थ्रेड बनाता हूं और उस संरचना को पैरामीटर के रूप में पास करता हूं।
  3. मैं एक संवाद बनाता हूं जो मुख्य धागे में प्रगति पट्टी प्रदर्शित करता है।
  4. इसके अलावा मुख्य धागे में एक लूप होता है जो थ्रेड-चलने वाला ध्वज सेट होता है। यह CMyDialog::Animate() पर कॉल करता है जो CProgressCtrl::StepIt() पर कॉल करता है और फिर Sleep() थोड़ा सा कॉल करता है।
  5. धागा डीबी-कनेक्शन कोड निष्पादित करता है और चलने पर चलने वाले ध्वज को false पर सेट करता है।
  6. जब मुख्य थ्रेड लूप से बाहर निकलता है तो यह त्रुटियों को ठीक से संभाल सकता है जैसा कि पहले किया गया था।

नुकसान: बढ़ते खिड़की पर माउस काम नहीं करता। यह अदृश्य है। इस प्रकार कोई रद्द-बटन या अन्य इंटरैक्टिव संवाद तत्वों का उपयोग नहीं किया जा सकता है। हालांकि, मैं इसके साथ रह सकता हूं।

CMyApp::  WorkerThread 
InitInstance()  . 
    |    . 
    |    . 
Create Dialog  . 
    |    . 
    +-Start Thread--+ 
    |    | 
    |    Connect 
Animate   to 
Progress   DB 
    Bar    | 
    |    | 
    +-Thread Ends---+ 
    |    . 
Destroy Dlg  . 
    |    . 
+3

आरेख –

+0

आप एक एएनएसआई आवेदन में SetMarquee() कॉल कर सकते हैं, लेकिन यह टाइमर कि प्रगति बार एनिमेट होने के बाद से आप की मदद नहीं करेगा के लिए +1 मुख्य थ्रेड भी –

+0

मेरी afxcmn में पर कहा जाता है।एच यह इस तरह दिखता है: ** यदि (_WIN32_WINNT> = 0x0501) && परिभाषित (यूनिकोड) \ n बूल सेटमार्की (_In_ BOOL fMarqueeMode, _In_ int nInterval); \ n #endif \t // _WIN32_WINNT> = 0x0501 && परिभाषित (यूनिकोड) \ n ** और इसलिए मैं इसे कॉल नहीं कर सकता। – foraidt

उत्तर

2

डीबी कनेक्शन तर्क को अलग थ्रेड पर ले जाना अभी भी सुरक्षित होगा। संवाद धागे पर डीबी के साथ, आप प्रगति पट्टी को फिर से तैयार करने में सक्षम होंगे लेकिन संवाद में अन्य नियंत्रण नहीं।

+0

मैं RedrawWindow() को कॉल करके पूरे संवाद को पुन: पेश कर सकता हूं। अगर मैं ऐसा नहीं करता, केवल प्रगति पट्टी एनिमेटेड है। – foraidt

7

मुझे आशा है कि प्रगति बार के साथ खुद का धागा स्प्लैश स्क्रीन बनाने में मददगार हो सकता है के बारे में this लेख:

जब से तुम चित्र पसंद आया, तो यहां आपको अब ऐसा लगता है कि है। एमएफसी संदेश कतार स्तर पर थ्रेड लॉकिंग के साथ समस्या को हल करते समय मैंने इसे लिखा था।

2
  1. AfxBeginThread का उपयोग कर कार्यकर्ता धागा बनाएं।
  2. उस थ्रेड में CProgressCtrl बनाएं और Create पर कॉल करें, संवाद को CProgressCtrl के अभिभावक के रूप में पास करें, प्रगति नियंत्रण के लिए मार्की शैली का उपयोग करें।
  3. थ्रेड में एक संदेश प्रतीक्षा लूप बनाएं:

    MSG msg;
    जबकि (GetMessage (& संदेश, शून्य, 0, 0))
    {
    TranslateMessage (& संदेश);
    डिस्पैच मैसेज (& msg);
    }

  4. संदेश लूप को लूप से बाहर निकलने के लिए यह देखने के लिए वैश्विक ध्वज की जांच करने की आवश्यकता है।

+0

यह काम नहीं करेगा। मेरा जवाब पढ़ें। –

+1

@ किरील यह मेरे लिए काम करता है, मेरी परियोजना पर, वास्तव में काम करने का अनुमान नहीं लगाता है? –

+0

एमएफसी थ्रेड को फ़ंक्शन बनाने में deadlocked किया जा सकता है। इससे बचने के लिए आपको गैर-एमएफसी धागे का उपयोग करना चाहिए। –

1

क्या आपने के बजाय PBM_SETMARQUEE के साथ SendMessage का उपयोग करने का प्रयास किया है। मैंने कभी कोशिश नहीं की है लेकिन इसे काम करना चाहिए।

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

वैसे भी, मैं एलेक्सएज़ से सहमत हूं कि ऐसा करने का सबसे अच्छा तरीका काम करने वाले धागे में पूरा गैर-यूआई काम कर रहा है।

+0

जब मैंने कोशिश की तो संदेश भेजना कोई प्रभाव नहीं पड़ा। – foraidt

1

रूप

CProgressCtrl m_progress; 

एक सदस्य चर बनाएं प्रगति बार आईडी

साथ DoDataExcchange में DDX_Control में m_progress जोड़ें बटन पर क्लिक समारोह के अंतर्गत निम्नलिखित कोड जोड़ें।

m_progress.setRange(0,100); 
m_progress.SetPos(1); 
+0

यह केवल बहुत ही बुनियादी जानकारी है जिसे न तो पूछा गया था और न ही बहु-थ्रेड समस्या का समाधान है। – foraidt

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