Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Aktualisierung der Gui

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
17.07.2003, 19:50 Uhr
Dirk22



Hi,

ich habe mir ein kleines MFC-Programm, welches von CFormView abgeleitet ist, angelegt.
Dann habe ich eine Stoppuhr programmiert. Die Anzeige der Stoppuhr findet in der Statusleiste statt. Diese Stoppuhr funktioniert auch wunderbar. Doch wenn ich irgendwo im Menü rumspiele und z.B. den Hilfedialog öffne, dann wird die Anzeige in der Statusleiste nicht aktualisiert und zeigt immer noch den alten Wert an, bis ich eben nichts mehr am Menü mache, welches ja zur MainFrame gehört. Und die Statusleiste halt auch. Und diese Update_Command Funktion wird ja nur aufgerufen, wenn sich das Programm im Leerlauf befindet. Und wenn ich im Menü bin, dann ist das Programm ja nicht im Leerlauf.
Ich denke ansich schon, dass ein Thread die Lösung hierfür ist. Leider weiss ich nicht wie ich ihn hier ansetzen soll. Denn so eine Update_Command Funktion zur Aktualisierung von z.B. der Statusleiste kann ich ja nicht so einfach in einen Thread stecken und aufrufen. Ich kenne bisher eben nur Worker Threads. Wahrscheinlich wird dann hier die andere Variante von Threads benötigt.

Was kann ich hier tun? Falls die Fragestellung unklar ist, kann ich gerne meinen Code hier posten. Ich habe nur die Dateien MainFrm.cpp und MainFrm.h bearbeitet.

Vielen Dank im Voraus

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.07.2003, 19:53 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hallo,
ich würde eher einen Timer benutzen, ist für so eine Funktion sinnvoller...
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.07.2003, 19:53 Uhr
Dirk22



Ich poste den Code doch gleich. Dann könnt ihr mir wahrscheinlich besser helfen.

MainFrm.h:


C++:
// MainFrm.h : Schnittstelle der Klasse CMainFrame
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__C2E513DA_FB00_40F4_87CA_3383E4B4C921__INCLUDED_)
#define AFX_MAINFRM_H__C2E513DA_FB00_40F4_87CA_3383E4B4C921__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMainFrame : public CFrameWnd
{
    
protected: // Nur aus Serialisierung erzeugen
    CMainFrame();
    DECLARE_DYNCREATE(CMainFrame)

// Attribute
public:

// Operationen
public:

private:
    char m_stoppuhr[20];
    int sec;
    int min;
    int hour;
    int total_sec;

// Überladungen
    // Vom Klassenassistenten generierte Überladungen virtueller Funktionen
    //{{AFX_VIRTUAL(CMainFrame)
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    //}}AFX_VIRTUAL

// Implementierung
public:
    virtual ~CMainFrame();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // Eingebundene Elemente der Steuerleiste
    CStatusBar  m_wndStatusBar;
    CToolBar    m_wndToolBar;

// Generierte Message-Map-Funktionen
protected:
    //{{AFX_MSG(CMainFrame)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnUpdateStoppuhrPane(CCmdUI* pCmdUI);
    afx_msg void OnButtonStop();
    afx_msg void OnButtonStart();
    afx_msg void OnTimer(UINT nIDEvent);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.

#endif // !defined(AFX_MAINFRM_H__C2E513DA_FB00_40F4_87CA_3383E4B4C921__INCLUDED_)



MainFrm.cpp:


C++:
// MainFrm.cpp : Implementierung der Klasse CMainFrame
//

#include "stdafx.h"
#include "Stoppuhr.h"

#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    //{{AFX_MSG_MAP(CMainFrame)
        ON_WM_CREATE()
        ON_UPDATE_COMMAND_UI(ID_STOPPUHR, OnUpdateStoppuhrPane)
    ON_COMMAND(ID_BUTTON_STOP, OnButtonStop)
    ON_COMMAND(ID_BUTTON_START, OnButtonStart)
    ON_WM_TIMER()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
    ID_SEPARATOR,           // Statusleistenanzeige
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
    ID_STOPPUHR,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame Konstruktion/Zerstörung

CMainFrame::CMainFrame()
{
    sec = 0;
    min = 0;
    hour = 0;
    total_sec = 0;
    strcpy(m_stoppuhr,"");
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Symbolleiste konnte nicht erstellt werden\n");
        return -1;      // Fehler bei Erstellung
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Statusleiste konnte nicht erstellt werden\n");
        return -1;      // Fehler bei Erstellung
    }

    // ZU ERLEDIGEN: Löschen Sie diese drei Zeilen, wenn Sie nicht wollen, dass die Symbolleiste
    //  andockbar ist.
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // ZU ERLEDIGEN: Ändern Sie hier die Fensterklasse oder das Erscheinungsbild, indem Sie
    //  CREATESTRUCT cs modifizieren.

    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame Diagnose

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
    CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
    CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame Nachrichten-Handler

void CMainFrame::OnButtonStart()
{
    SetTimer(ID_TIMER_STOPPUHR,1000,NULL);
}

void CMainFrame::OnButtonStop()
{
    sec = 0;
    min = 0;
    hour = 0;
    total_sec = 0;
    strcpy(m_stoppuhr,"");

    KillTimer(ID_TIMER_STOPPUHR);
}


/////////////////////////////////////////////////////////////////////////////
// UpdateFunktionen

void CMainFrame::OnUpdateStoppuhrPane(CCmdUI *pCmdUI)
{
    pCmdUI->Enable(true);
    pCmdUI->SetText(m_stoppuhr);
}


/////////////////////////////////////////////////////////////////////////////
// TimerFunktionen


void CMainFrame::OnTimer(UINT nIDEvent)
{
    switch(nIDEvent)
    {
    case ID_TIMER_STOPPUHR:    
        
        total_sec++;
        sec++;
        
        if (sec==60)
        {
            min++;
            sec=0;
        }
        if (min==60)
        {
            hour++;
            sec=0;
            min=0;
        }
        
        if (total_sec < 60) sprintf(m_stoppuhr,"%d s",sec);
        else if (total_sec < 3600)
        {
            if (sec < 10) sprintf(m_stoppuhr, "%d:0%d min",min,sec);
            else sprintf(m_stoppuhr, "%d:%d min",min,sec);
        }
        else    
        {
            if (sec < 10 && min < 10) sprintf(m_stoppuhr, "%d:0%d:0%d h",hour,min,sec);
            if (sec < 10 && min >= 10) sprintf(m_stoppuhr, "%d:%d:0%d h",hour,min,sec);
            if (sec >= 10 && min < 10) sprintf(m_stoppuhr, "%d:0%d:%d h",hour,min,sec);
            if (sec >=10 && min >= 10) sprintf(m_stoppuhr,"%d:%d:%d h",hour,min,sec);    
        }
        break;
    }
    
    CFrameWnd::OnTimer(nIDEvent);
}



mfg

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
17.07.2003, 20:06 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hallo, mach es halt einfach so das du in der OnTimerfunktion


C++:
m_wndStatusBar.SetDlgItemText(ID_STOPUHR,m_stoppuhr);



am Ende aufrufst
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
17.07.2003, 20:19 Uhr
Dirk22



Hi FloSoft,

leider hat diese Zeile überhaupt keine Auswirkung. Es wird wegen dieser Zeile nichts in der Statusleiste angezeigt. Sie bringt aber auch keine Fehlermeldung.
Ich habe die Zeilen der Updatefunktion auskommentiert. Denn diese bräuchte ich ja dann theoretisch nicht mehr. Und deine Zeile habe ich direkt vor das break in der OnTimer Funktion gesteckt.

mfg

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
17.07.2003, 23:35 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo Dirk,
hast Du mal einen Haltepunkt in OnButtonStart() gesetzt, ob der Timer überhaupt gestartet wird?
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
18.07.2003, 08:20 Uhr
Dirk22



Ja, der Timer wird gestartet. Es hat ja auch mit meinem hier geposteten Code funktioniert. Nur wenn ich mir einen Menüpunkt auswähle oder eben irgendetwas im Menü mache, dann wird die Statusleiste solange nicht mehr aktualisiert, bis ich nichts mehr im Menü mache.
Ich muss auch sagen, dass ich mir die Form der Aktualisierung der Mainframe-Elemente anders wünschen würde als mit diesem UPDATE_COMMAND_UI Makro. Denn die Updatefunktionen werden ja immer nur ausgeführt, wenn sich das Programm im Leerlauf befindet. Warum kann man nicht einfach in irgendeiner beliebigen Funktion sagen, dass man nun einen Wert in die Statusleiste schreiben will. Nein, man muss immer diese Updatefunktionen verwenden. Und wenn man dann im Menü irgendetwas macht, dann befindet sich das Programm nicht mehr im Leerlauf und die Updatefunktion wird nicht mehr aufgerufen. Oder verstehe ich das falsch?
Naja, um wieder auf mein Problem zurückzukommen. Was kann man da machen, dass die Statusleiste immer aktualisiert wird, egal ob der Benutzer geraden ein Menü offen hat oder nicht.

Vielen Dank im Voraus

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: