Thread erstellen



  • Hallo.

    Kennt jemand ein gutes Tut wo super gut beschrieben ist, wie ich einen Thread in der MFC erstelle? Hab davon noch keine Ahnung. Hab in der MSDN schon gelesen und auch so ausprobiert, aber irgendwie kommt er mir da mit Fehlern zurück.

    Bei google hab ich auch nicht wirklich was gefunden und in den FAQ's steht auch nichts leider. (Hab ich zumindest nichts gesehen).

    Wäre lieb von euch.

    Danke schonmal.



  • Hallo - Threads sind ganz einfach.
    Ich gehe jetzt einfach mal davon aus, dass du schon etwas Plan von der Sache hast.
    Ich glaube aber, dass ich das hier schon mal geschrieben habe - durchsuch das Forum auch mal nach meinem Namen - da findest du was zu MFC-Threads.

    Ich gehe davon aus, dass du dich etwas ausskennst - darum werde ich's dir mit viel Code zeigen - aber Achtung - es kommen auch Klassenpointer drin vor; wir wollen unsere Daten doch gut kapseln, oder?

    Ok, hier mal ein kurzer Überblick

    CDlg.h

    class CDlg::CDialog(IDD_DLG) {
    private:
      void process();
      static UINT THREAD(LPVIOD);
    
      typedef void(CDlg::*f)(void);
    
      struct t_data {
        t_data(CDlg* pDlg_, f pFunc_)
          : pDlg(pDlg_), pFunc(pFunc_) {}
    
        ~t_data() {
          pDlg = 0;
          pFunc = 0;
        }
    
        void operator() () {
          if(pDlf && pFunc)
            (pDlg->*pFunc)();
        }
        private:
          CDlg* pDlg;
          f pFunc;
      };
    }
    

    CDlg.cpp

    void CDlg::process() {
      // mach was..
    }
    
    BOOL CDlg::OnInitDialog() {
      AfxBeginThread(THREAD, new t_data(this, process));
      return TRUE;
    }
    
    UINT CDlg::THREAD(LPVOID param) {
      t_data *data = static_cast<t_data*>(param);
      (*data)(); // hier wird eignentliche Funktion deiner Klasse aufgerufen.
      delete data;
      return 0;
    }
    

    Das ganze hat den Vorteil, dass alle Funktionen Member deiner Klasse sind.
    Du brauchst keine public-Methoden die du aus dem Thread aufrufen kannst.
    Durch die Übergabe der Klasseninstanz wird das alles auch noch ein bisschen sicherer.

    Viel Spaß.

    Das mag jetzt zwar etwas kompliziert wirken - aber es macht durchaus Sinn.
    Da die Threads leider static und public sein müssen, müssten alle anderen Methoden aus deiner Klasse auf die du zugreifen möchtest auch zumindest public sein → ein offenes Tor.

    Da du jetzt aber einen Klassenpointer übergibst, kann bestimmt werden von welcher Klasseninstanz die Funktion aufgerufen werden soll.
    Denk's dir einfach ein bisschen durch!



  • im FAQ zur MFC hier im Forum gibts auch was zu Threads



  • danke schonmal an euch 2

    ich bekomm hier aber folgenden fehler:

    irgendwie will der die member nicht kennen:

    pDlf nicht deklarierter Bezeichner



  • Ich tippe auf einen Tippfehler 🙂 (das kommt davon, wenn man den Code blind abschreibt, ohne nachzudenken)



  • ich hab das jetzt so gemacht:

    CZeichnen.h

    void Anzeigen();
    static UINT DialogAnzeigen (LPVOID pParam);
    

    CZeichnen.cpp

    UINT CZeichnen::DialogAnzeigen(LPVOID pParam)
    {
    	CZeichnen* pDlg = (CZeichnen*) pParam;
    	pDlg->Anzeigen();
    	return 0; 
    
    }
    
    void CZeichnen::Anzeigen()
    {
    	Aufbereitung = new CDatenaufbereitung2;
    	Aufbereitung->Create(IDD_Aufbereitung2);
    	Aufbereitung->ShowWindow(SW_SHOW);
    }
    

    CZeichnen.cpp //Buttonklick

    AfxBeginThread (DialogAnzeigen, this, THREAD_PRIORITY_NORMAL);
    ......... //Nun kommen eine Menge Zeichenroutinen
    

    Sinn der Sache soll sein, dass während des Zeichnens, was ein bissl länger dauert auf Grund von riesigen Datenmengen, ein Dialogfeld angezeigt wird, wo "Daten werden aufbereitet..." drinsteht.

    Hab das vorher mit DoModal() gemacht ohne Thread. Da aber dann der Focus dort war, ging die Zeichenroutine logischerweise nicht. Desshalb mach ich das jetzt mit der ShowWindow Version. Problem dabei ist: Mache ich das nicht im Thread, wird mir zwar der Dialog aber ohne Inhalt angezeigt und ich habe keine Lust, da noch irgendwie was "rumzupfuschen".

    Desshalb soll ein Thread her. In der Version, wie es jetzt aber ist, zeigt er den gar nicht an. Wenn ich unter der Funktion Anzeigen() aber noch ne MessageBox packe, zeigt er beides an, aber erst dann, wenn die Zeichnungsroutine abgearbeitet ist, obwohl der Thread vorher gestartet wird.


Anmelden zum Antworten