Debug Assertion Failed | wincore.cpp | Line: 883



  • Hallo,
    ich habe folgendes Problem.

    Eine Funktion soll Daten aus einer csv-Datei einlesen und parallel wird ein Dialog angezeigt, in dem eine Fortschrittsanzeige läuft.

    Wenn ich nun aus einem zweiten Thread den Dialog mit der Fortschrittsanzeige aufrufe, dann kommt der Fehler aus dem Titel dieses Threads.

    Hier mein Code:

    class CTestDlg : public CDialog
    	{
    	public:
    		CHSIDepotmanagerDlg(CWnd* pParent = NULL);
    		CProgress m_progress_dialog;
    [...]
    
    BOOL CTestDlg::OnInitDialog()
    {
    m_progress_dialog.Create(IDD_Progress, this);
    m_progress_dialog.CenterWindow();
    
    CWinThread* stockdata_thread = AfxBeginThread(load_stockdata_thread, this);
    [...]
    
    UINT CTestDlg::load_stockdata_thread(LPVOID pParam)
    	{
    		CHSIDepotmanagerDlg* pDlg = (CHSIDepotmanagerDlg*) pParam;
    		pDlg->TEST();
    
    		return true;
    	}
    [...]
    
    void CTestDlg::TEST() 
    {
    	m_progress_dialog.init();
    	m_progress_dialog.show(); 
    
    	m_progress_dialog.setText("Das ist ein TEST");
    	m_progress_dialog.say_hello();
    
    	m_progress_dialog.hide();
    }
    
    void CProgress::show()
    {
    	this->ShowWindow(SW_SHOWNOACTIVATE);
    }
    
    void CProgress::hide()
    {
    	this->ShowWindow(SW_HIDE);
    }
    
    BOOL CProgress::say_hello()
    {	
    //	m_progress_dialog.ShowWindow(); 
    
    	for(int i=0; i<=100;i++)
        {
          Sleep(20);
          m_ctlProgress.SetPos(i);
    
    //		  if(i==50)
    //		setText("Das hier auch!");
        }
    
    	return true;
    }
    


  • Du darfst UI-Elemente nur aus dem Thread direkt ansprechen, aus welchem diese erzeugt wurden. Wenn Du aus dem anderen Thread was in der Oberfläche verändern willst, dann sende (oder poste) eine WM_APP+x Nachricht, welche dann die entsprechende Aktion ausführt.



  • Hallo Svetkata,

    zweiter Anlauf( "Kyrill" hat meinen Rechner während des ersten Versuchs ausgeschalten 😞 )

    Eine WM_xx Messge posten, wie Jochen es vorgeschlagen hat, ist eine Möglichkeit. Alternativ dazu kannst Du aber in CTestDlg::OnInitDialog() statt des this Pointers den WIndow Handle des Dialoges m_hWnd an AfxBeginThread(..) übergeben. In der Thread Funktion CTestDlg::load_stockdata_thread(LPVOID pParam) dann CHSIDepotmanagerDlg pDlg = (CHSIDepotmanagerDlg*)CWnd::FromHandle(HWND(pParam));, und ansonsten, wie implementiert.

    Der Grund dafür ist, dass CWnd (und abgeleitete Klassen, wie eben auch CDialog) nicht "Thread-Safe" sind (siehe auch die Dokumentation von Microsoft :)). CWnd Pointer können temporär verwendbar sein. In der OnInitDialog() ist natürlich der this Pointer für das Dialogfenster gültig (vorausgesetzt Du hast die Basisimplementierung aufgerufen). Aber bis der Thread started, kann der Zeiger schon wieder ins Nirwana zeigen. m_hWnd ist der Handle des Dialoges, und der ist gültig, solange der Dialog existiert.

    Gruss, Gio



  • Gemacht wie von Geo beschrieben. Vielen Dank!



  • Gio wollte ich natürlich sagen. Sorry!



  • Und, geht??


Anmelden zum Antworten