Threadsynchronisierung



  • Hi,

    könnte mir jemand helfen.

    habe folgendes Problem:

    Ein hauptddialog startet einen Workerthread. Dieser soll bei einem bestimmten Wert eine Nachricht an den Hauptdialog senden und dabei mit Waitforsingelobjekt pausieren bis der Haupdialog den Workerthread wieder aufweckt.d.h Während Worker pausiert gibt Hauptdialog den übergebenen Wert aus und weckt anschliessend den Worker

    Klappt aber irgendwie nicht. Kann meine selbstdefinierte Onmymessage nicht aufrufen. Bzw. die Meldung der eigenen nachrichtenbehanldungsmethode erscheint nicht auf dem Debugfenster.

    Wo ist der Fehler ?

    .h

    // Inside_visual_eigene_NachrichtDlg.h : Headerdatei
    //

    #pragma once

    // CInside_visual_eigene_NachrichtDlg Dialogfeld
    class CInside_visual_eigene_NachrichtDlg : public CDialog
    {
    // Konstruktion
    public:
    CInside_visual_eigene_NachrichtDlg(CWnd* pParent = NULL); // Standardkonstruktor

    // Dialogfelddaten
    enum { IDD = IDD_INSIDE_VISUAL_EIGENE_NACHRICHT_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung

    // Implementierung
    protected:
    HICON m_hIcon;
    CWnd * pWnd;
    HANDLE *hWnd;

    // Generierte Funktionen für die Meldungstabellen
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    --------------1. Im Header der Empfängerklasse den Msghandler deklariert--------
    afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
    DECLARE_MESSAGE_MAP()
    public:
    afx_msg void OnBnClickedButton1();
    int m_ausgabe;
    afx_msg void OnBnClickedButton4();

    };

    .cpp

    .cpp

    #include "stdafx.h"
    #include "Inside_visual_eigene_Nachricht.h"
    #include "Inside_visual_eigene_NachrichtDlg.h"
    #include ".\inside_visual_eigene_nachrichtdlg.h"
    #include "afxmt.h" // Wichtig für CEvent klasse

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif

    -------------------------------2. Message definieren---------------------------
    #define WM_THREADFINISHED WM_USER+1

    --------------------------------3.Workerthread prototyp
    UINT Workerthread(LPVOID pParam);

    ------------------------------4. Events prototyp
    CEvent g_eventContinue; //erzeugt event mit automatisch

    // CInside_visual_eigene_NachrichtDlg Dialogfeld

    CInside_visual_eigene_NachrichtDlg::CInside_visual_eigene_NachrichtDlg(CWnd* pParent /=NULL/)
    : CDialog(CInside_visual_eigene_NachrichtDlg::IDD, pParent)
    , m_ausgabe(0)
    {
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }

    void CInside_visual_eigene_NachrichtDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_AUSGABE, m_ausgabe);
    }

    BEGIN_MESSAGE_MAP(CInside_visual_eigene_NachrichtDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)

    ---------------------------------5. in cpp file empfängerklasseliste ergänzen
    ON_MESSAGE(WM_THREADFINISHED,OnMyMessage)
    ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton4)
    END_MESSAGE_MAP()

    //Button 1 soll workerthread aktivieren
    void CInside_visual_eigene_NachrichtDlg::OnBnClickedButton1()
    {

    int hwnd =GetDlgCtrlID();

    ------------------ -------------- 6. Starte Workerthread übergebe Handler auf Dlg
    CWinThread * pThread = AfxBeginThread(Workerthread,&hwnd);

    }

    UINT Workerthread(LPVOID pParam){

    CWnd* pWindow= (CWnd*) pParam;

    TRACE("HIER IN WORKERTHREAD , WARTE AUF EREIGNIS \n\n\n");
    TRACE("\nDIE BERECHNUNG WIRD GESTARTET");
    for(int count=0;count<100;count++){
    TRACE("Hier im workerthread %i \n",count);
    if(count==50) {
    TRACE("Hier count = 50, Nachricht wird versendet\n");
    ::PostMessage((HWND)pParam,WM_THREADFINISHED,(WPARAM)count,0);
    ::WaitForSingleObject(g_eventContinue,INFINITE);
    }
    }
    return 0;

    }

    //Diese Methode sollte die Nachricht vom Workerthread empfangen und Zwischenergebniss im Fenster des Hauptdialoges ausgeben ,anschliessend soll der Workerthread weiterlaufen

    LRESULT CInside_visual_eigene_NachrichtDlg::OnMyMessage(WPARAM wParam, LPARAM lParam){
    TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!Nachricht erhalten!!!!!!!%i!!!!!!!!!!!!!!!!!!!!!!!!\n");
    g_eventContinue.SetEvent(); //Workerthread soll weitermachen
    return 0;

    }

    OnMyMessage wird aber nicht ausgeführt, Weiss jemand vielleicht warum ?



  • Der cast von pParam einmal auf CWnd* und weiter unten auf HWND ist nicht konsistent (in der ThreadFunc).
    Aber das nur auf den ersten Blick 😉

    ...

    Edit: d.h. ich guck mal noch ein bisschen...


  • Administrator

    Ich finde es immer wieder schön, wie die Leute Funktionen benutzen ohne eine Ahnung zu haben, was diese Funktion eigentlich überhaupt tut. Und sogar, wenn dann alles nicht übereinstimmt in der Funktion die Rückgabewerte und so weiter nicht stimmen, dann wird halt einfach gemorgst.

    GetDlgCtrlID() liefert dir die ID zurück und kein HWND. Um an das HWND zu kommen musst du GetSafeHwnd() aufrufen. Zudem ist HWND ungleich einem Zeiger auf CWnd.

    Ob sonst noch was falsch ist weiss ich nicht. Solange keine CPP-Tags hinsetzt werde ich auch nicht schauen.

    Grüssli



  • Kann es sein, dass GetDlgCtrlId nicht den HWND liefert? Versuchs doch mal mit CWnd::GetSafeHwnd().
    Also :

    int hwnd = this->GetSafeHwnd() //obwohl mir das mit dem int nich ganz geheuer ist
    

    nochmal zu dem int, warum nimmst du nicht HWND?

    edit: too late 🙄



  • Hi,

    habe das Problem gelöst.

    1. AfxBeginThread(Workerthread,(LPVOID)this->m_hWnd)

    this->m_hWnd ist ein vordefinierter Zeiger auf das Hauptfenster

    2. Postmessage((HWND)pParam,WM_Threadfinished,0,0);

    Dann läuft das Ganze auch

    vielen Dank Jungs 🙂


Anmelden zum Antworten