Dlg-Pointer übergeben



  • Und wie macht man es dann? Wenn ich eine Variable meines CDialogXYZ von einem Thread aus ändern will, kann ich ja noch mit SendMessage arbeiten (ist aber unschön). Aber wenn ich den Wert einer Variablem auslesen will???

    geht ehendlich nur über PostThreadMessage als sender und

    m_nThreadID=::GetCurrentThreadId(); 
      VERIFY(m_hHook=::SetWindowsHookEx(WH_GETMESSAGE, &CRegDEx::_GetMsgProc, \
                                        NULL, m_nThreadID));
    
    LRESULT CRegDEx::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
      LPMSG lpMsg=(LPMSG)lParam; 
      if ( nCode >= 0 && PM_REMOVE == wParam && lpMsg->hwnd==0)
      {
        switch (lpMsg->message)
        {
          case WM_THREAD_MYSQL:
            TRACE("CRegDEx::GetMsgProc State:%i\n", lpMsg->wParam);
            {
            }
            break;
        }
      }
      return CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }
    
    oder über MFC
    

    als empfänger, synconisation hilft nicht

    volker



  • Wenn ich eine Variable meines

    für variablen greift syncronisation über CCriticalSection und die klasse bzw. pointer übergibst du ganz normal.

    CCriticalSection m_cs;

    {
    CSingleLock cLock(&m_cs, true); //lock
    // jetzt kannst du mit deiner klassse arbeiten

    }
    // unlock da ->} oder cLock.Unlock();



  • Stichwort Threadsynchronisation, dafür gibts mächtig viele Seiten Literatur!
    Man muss andere Threads davon ausschliessen, auf die Variablen zuzugreifen, wenn man sie gerade ändern will.

    Effizient ist hier 'ne Critical Section, da sie feststellt, von welchem Thread aus der Lock() erfolgt und somit einen weiteren Zugriff vom gleichen Thread aus nicht blockiert, während andere Synchronisationsobjekte schon blockieren würden.

    FAQ:
    F:Wie kann ich nun von mehreren Threads auf die gleiche CWnd-Klasse zugreifen?
    A:Einfach den CWnd-Zeiger übergeben.

    F:Wie muss ich Zugriffe auf die Variable synchronisieren?
    A:

    class CMyWnd : public CWnd
    {
      int m_Member;
      CCriticalSection m_cs;
    public:
      void IncMember()
      {
        CSingleLock lock( &m_cs, TRUE);
        if( lock.IsLocked())
        {
          m_Member++;
        }
        // lock.Unlock();  // wird automatisch aufgerufen
      }
    };
    

    [ Dieser Beitrag wurde am 17.04.2003 um 15:14 Uhr von RenéG editiert. ]



  • @RenéG: Wenn ich das so wie in deinem letzten Posting mache, kann ich mit

    m_pDlg = (CDialogXYZ *)CWnd::FromHandle(hwnd);
    BOOL m_pDlg->IsFinished(); // wobei IsFinished() eine CS benutzt
    

    aus jedem Thread auf eine Dialog zugreifen?



  • Nein, wie schon in Frage 1 beantwortet, Du musst den Zeiger auf das CWnd an den Thread übergeben, NICHT das HWND. Dann fällt nämlich auch die Methode CWnd::FromHandle flach!

    + Beispiel:

    CMeinDialog::BeginneThread()
    {
      AfxBeginThread( MeinThread, (LPVOID)this...); // hier wird der Zeiger auf  CMeinDialog an den Thread übergeben
    }
    
    UINT MeinThread( LPVOID pParam)
    {
      CMeinDialog* pDlg = (CMeinDialog*)pParam;
      // Zugriffe auf synchronisierte Memberfunktionen von CMeinDialog
      return 0;
    }
    

    Wenn man sich ganz ganz sicher ist, dass es keine Synchronisationsprobleme geben kann, kann man die Synchronisation auch weglassen, was die Zugriffe sehr beschleunigt.

    [ Dieser Beitrag wurde am 17.04.2003 um 15:24 Uhr von RenéG editiert. ]



  • Danke für das Beispiel. 🙂 seltsam... bei mir wurde auf CMeinDialog-Member immer nur von einem Thread aus zugegriffen und dennoch kam diese Assertion failed.



  • wo und im welchen zusammenhang ??



  • @vdittrich: schau mal in "CAsyncSocket oder ...."



  • Zur letzten Antwort von RenéG:
    SO GEHT ES EBEN NICHT! So habe ich es früher gemacht und da kommt ja genau dieses Assertion failure!

    Ich weiß jetzt warum er bei der static_cast methode auch gecrasht ist: Weil ich der SetParentDlg Funktion der betreffenden Klasse einen ungültigen hwnd gegeben habe... (habe GetSafeHwnd() fatalerweise schon im konstruktor meiner Fensterklasse aufgerufen)

    Mit dieser rauf-Cast-methode gibt er eine weile ruhe mit den asserts, aber wenn ich anschließend wieder irgend wo anders mit diesem pointer arbeite passiert wieder dasselbe.
    Und wisst ihr was: Der kann mich mal! Mittlerweile bin ich mal wieder soweit, dass ich alles einfach unter release kompilliere ... *gg*

    matthias



  • einfach unter release kompilliere ..

    ich will mich ja in deine programmierung nicht einmischen, aber so wie du schreibst solltest du die art und weise deiner arbeit überdenken.

    "man sollte wissen was man tut"

    mfg schönes wochenende



  • SO GEHT ES EBEN NICHT!

    Ich denke mir mal, dass Du noch irgendwo anders Fehler hast, denn ich arbeite schon seit Jahren effizient mit dieser Methode, und zwar sogar auf Multiprozessorsystemen!


Anmelden zum Antworten