Programm stürtzt bei UpdateData() ab



  • Ich rufe aus einem Thread folgende Funktion auf:

    void CMeinProgDlg::SysTimeAkt(void)
    {
        m_cTime = CTime::GetCurrentTime();
        UpdateData(TRUE);
        m_strSysTime.Format("%d:%d:%d", m_cTime.GetHour(), m_cTime.GetMinute(), m_cTime.GetSecond());
        UpdateData(FALSE);
    }
    

    Mein Programm stürtz dabei bei UpdateData(TRUE) ab.
    Weiß jemand warum oder wie ich das Prob. löse??

    mfg
    Fink Christoph



  • Debugge das Programm doch einfach *lol*



  • Hi,

    probiere es mal so:

    void CMeinProgDlg::SysTimeAkt(void)
    {
        m_cTime = CTime::GetCurrentTime();
        CString m_strSysTime = m_cTime.Format("%H:%M:%S");
        UpdateData(FALSE); //ich würde hier lieber SetDlgItemText verwenden
    }
    

    Hier noch zu CTime...

    Grüße, Volle.



  • @Debugger: Das habe ich und deshalb weiß ich das es bei UpdateData() abstürtzt.

    @Volle: Es stürzt zwar nicht ab. Aber der Static-Text den ich verändern möchte bleibt gleich wie beim start des Programmes.



  • Ist der Dialog zu diesem Aufrufzeitpunkt überhaupt schon initialisiert? Also war OnInitDialog schon mal da? Denn wenn der Thread sich vorher meldet... dann kann's auch *bumm* machen.



  • Ich rufe den Thread aus der OnInitDialog auf. Dan wartet er mit Sleep() eine Sekunde und will dan mit der SysTimeAkt()-Funktion ein Static-Text in die aktuelle Systemzeit ändern. Dies wiederholt der Thread jede Sekunde. Der Dialog ist beim ersen Aufruf von SysTimeAkt() schon lange aufgebaut.



  • Hi,

    machst du das zur Übung? Ansonsten würde ich hier einen Timer verwenden. Aber das nur nebenbei...

    Ich würde hier auch auf jeden Fall auf DDE verzichten. Damit wird ja dein ganzer Dialog aktualisiert. Das ist ja hier überhaupt ganz und gar nicht sinnvoll.

    Hast du das schon probiert?

    Ansonsten könnte ich mir vorstellen, dass du bei der Thread- Geschichte einen Fehler machst. Code?

    Grüße, Volle.



  • Das mit dem Timer klingt gut.
    Gibt es eine möglichkeit das ein Timer die Uhrzeit hochzählt? Also Sekunden, Minuten und Stunden selbst trennt oder muss ich das manuell machen???



  • Hi,

    mach es doch so:

    In OnInitDlg startest du den Timer. Dann fügst du die OnTimer- Behandlungsroutine ein.

    Etwa so:

    BOOL CTimeDlgDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        // Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
        // IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            CString strAboutMenu;
            strAboutMenu.LoadString(IDS_ABOUTBOX);
            if (!strAboutMenu.IsEmpty())
            {   
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        // Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
        //  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
        SetIcon(m_hIcon, TRUE);         // Großes Symbol verwenden
        SetIcon(m_hIcon, FALSE);        // Kleines Symbol verwenden
    
        // ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
        SetTimer(1, 500, NULL);
    
        return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }
    
    void CTimeDlgDlg::OnTimer(UINT nIDEvent) 
    {
        CTime tm = CTime::GetCurrentTime();
        CString tmStr = tm.Format("%H:%M:%S Uhr");
        SetDlgItemText(IDC_TIME, tmStr);
    
        CDialog::OnTimer(nIDEvent);
    }
    

    Grüße, Volle.

    [ Dieser Beitrag wurde am 25.12.2002 um 13:15 Uhr von Volle editiert. ]



  • Zeige mal den Code des Threads. UpdateData() kann man in einem Thread nicht aufrufen.

    Wie rufst du die Funktion eines Dialogs in einem Thread auf ?



  • BOOL CMeinProgDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        // Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
        // IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            CString strAboutMenu;
            strAboutMenu.LoadString(IDS_ABOUTBOX);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        // Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
        //  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
        SetIcon(m_hIcon, TRUE);         // Großes Symbol verwenden
        SetIcon(m_hIcon, FALSE);        // Kleines Symbol verwenden
    
        // TODO: Hier zusätzliche Initialisierung einfügen
    
        m_cTime = CTime::GetCurrentTime();
        UpdateData(TRUE);
        m_strSysTime.Format("%d:%d:%d", m_cTime.GetHour(), m_cTime.GetMinute(), m_cTime.GetSecond());
        UpdateData(FALSE);
    
        m_Flag = 1;
        CWinThread* pThread = AfxBeginThread (thrFunction, &m_Flag);
    
        return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }
    
     UINT CMeinProgDlg::thrFunction(LPVOID pParam) 
    { 
        int* pFlag = (int*) pParam; 
        while (*pFlag)  
        { 
            Sleep(1000);
            CWinampControllerDlg m_dMain;
            m_dMain.SysTimeAkt();
        } 
        return 0; 
    }
    
    void CMeinProgDlg::SysTimeAkt(void)
    {
        m_cTime = CTime::GetCurrentTime();
        UpdateData(TRUE);
        CString m_strSysTime = m_cTime.Format("%H:%M:%S");
        UpdateData(FALSE);
    }
    

    Habe es aber jetzt mit einem Timer genacht, so wie es Volle es gesagt hat und es funktioniert perfekt.

    mfg
    Fink Christoph

    [ Dieser Beitrag wurde am 25.12.2002 um 13:59 Uhr von Fink Christoph editiert. ]



  • Eine Threadfunktion kann nicht eine Memberfunktion einer Klasse sein außer sie ist von CWinThread abgeleitet.

    Du kannst der Threadfunktion den thisZeiger der Klasse übergeben und dann diese Funktion aufrufen.

    Benutze die Suchfunktion nach dem Wort thread und du bekommst einige Bsp.


Anmelden zum Antworten