Countdown mit Cancel



  • Hallo,

    ich bin in C++ ein absoluter Neueinsteiger, habe bisher nur Perl / TK gemacht.

    Ich will eine ganz einfache Funktion schreiben:

    Ein Fortschrittsbalken soll nach 5 Sekunden 100 Prozent erreichen.
    Wenn man in diesen 5 Sekunden nicht auf Cancel drückt, wird ein Neustart durchgeführt.
    Also so:
    http://www.pctex.de/reboot.jpg

    Was ganz einfach klingt, macht mich einfach Wahnsinnig:

    1. War das ganze Fenster unsichtbar, bis die 5 Sekunden abgelaufen waren. (Keine Ahung warum, ich musste erst einen Timer einbauen, damit überhaupt das Fenster eingeblendet wird 😕 😕 )
    2. Kann ich nicht auf den Cancel Button drücken, da die ganze Anwendung 5 Sekunden lang "einfriert."

    Vieleicht kann sich bitte mal jemand den Code unten anschauen, was ich da falsch mache...

    Danke im voraus!

    // Reboot.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "Drive Tester.h"
    #include "Reboot.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CReboot dialog
    
    CReboot::CReboot(CWnd* pParent /*=NULL*/)
    	: CDialog(CReboot::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CReboot)
    		// NOTE: the ClassWizard will add member initialization here
    	//}}AFX_DATA_INIT
    }
    
    void CReboot::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CReboot)
    	DDX_Control(pDX, IDC_PROGRESS, m_progress);
    	//}}AFX_DATA_MAP
    }
    
    BEGIN_MESSAGE_MAP(CReboot, CDialog)
    	//{{AFX_MSG_MAP(CReboot)
    	ON_WM_TIMER()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CReboot message handlers
    
    BOOL CReboot::OnInitDialog() 
    {
    	CDialog::OnInitDialog();
    
    	SetTimer(ID_TIMER, 10, NULL);
    
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE
    }
    
    void CReboot::OnOK() 
    {
    	CDialog::OnOK();
    }
    
    void CReboot::OnTimer(UINT nIDEvent) 
    {
    	KillTimer(nIDEvent);
    
    	UpdateData(FALSE);
    
    	int reboot_time = 5;
    	bool reboot = false;
    	int status = 0;
    	int time = 0;
    	int statusadd = 100 / (reboot_time * 10);
    
    	while(!reboot){
    		status = status + statusadd;
    		m_progress.SetPos(status);
    		UpdateData(FALSE);
    		Sleep(100);
    		time = time + 100;
    		if (time > reboot_time *1000){
    			reboot = true;
    		}
    	}
    
    	MessageBox("Reboot");
    	CDialog::OnTimer(nIDEvent);
    }
    

    mfg
    trequ



  • hi, das hab ich mir auch schonmal gebastelt (allerdings zum runterfahren+ausschalten)...
    naja, ein sleep() iss immer nicht so toll in einer single-thread anwendung da dieses den "einzigen" thread blockiert, dh. die anwendung friert ein da auch die nachrichten schleife nicht abgefragt wird.
    der ansatz mit dem timer war nicht schlecht, aber deine lösung leider nicht so gut, da dein proggi in der while-schleife hängt bis diese aufgelöst wird und dann erst der dialog angezeigt werden kann.

    hier mal mein code:
    ( einfacher MFC-Dialog,
    m_Progress = control der progressbar
    button1 = ID_OK = sofort ausschalten, ohne die zeit abzuwarten
    button2 = ID_CANCLE = timer abbrechen und dialog beenden
    )

    #define ZEIT 50 // Zeit in 0.2sec bis zum runterfahren :: 50 == 10sec
    
    BOOL CShutdownDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	SetIcon(m_hIcon, TRUE);
    	SetIcon(m_hIcon, FALSE);
    
    	// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
    	m_Progress.SetRange(0, ZEIT);
    	m_Progress.SetStep(1);
    	m_Progress.SetPos(0);
    	m_iClock = 0;
    
    	m_Timer1 = SetTimer(ID_TIMER1, 200, NULL);
    
    	return TRUE;
    }
    
    void CShutdownDlg::OnTimer(UINT nIDEvent) 
    {
    	switch(nIDEvent)
    	{
    		case ID_TIMER1:
    		{
    			if ( ++m_iClock > ZEIT ) {
    				KillTimer(ID_TIMER1);
    				OnOK();
    			} else
    				m_Progress.StepIt();
    		}
    		break;
    	}	
    
    	CDialog::OnTimer(nIDEvent);
    }
    
    void CShutdownDlg::OnCancel() 
    {
    	KillTimer(ID_TIMER1);
    	CDialog::OnCancel();
    }
    
    void CShutdownDlg::OnOK() 
    {
    	// hier noch den code rein der dann ausschaltet
    	CDialog::OnOK();
    }
    

    ist eigentlich nicht viel dazu... 😉

    grusz



  • Hallo,

    danke für die Antwort, leider erhalte ich immer:

    Reboot.cpp(55) : error C2065: 'm_iClock' : nichtdeklarierter Bezeichner
    Reboot.cpp(57) : error C2065: 'm_Timer1' : nichtdeklarierter Bezeichner

    Danke im voraus.

    mfg
    trequ



  • hi,
    // privat membervariablen:
    UINT m_Timer1;
    int m_iClock;

    dann klappts 😃

    grusz



  • Danke,

    funktioniert wunderbar
    🙂 🙂 🙂 🙂

    mfg
    trequ


Log in to reply