Methode alle X Sekunden aufrufen



  • CStoll schrieb:

    plizer schrieb:

    Ich habe die MSDN zu SetTimer nochmal durchgeschaut. Leider weiss ich einfach nicht, wie ich an die ID für den Timer komme. In den Quelltexten wird immer einfach z.B. IDT_TIMER benutzt, allerdings muss ich doch erst an diese ID kommen bzw. erstellen?!

    Denk dir einfach eine schön aussehende Nummer aus und verwende sie dann (wichtig ist nur, daß jeder verwendete Timer seine eigene ID bekommt).

    Danke! Ich habe in der resource.h jetzt IDT_TIMER gestegelegt mit einer Nummer. Jetzt bekomm ich nur immer die Fehlermeldung

    error C2660: 'SetTimer' : Funktion akzeptiert keine 4 Parameter

    Ich habe folgendes versucht:

    SetTimer(m_ParenthWnd, IDT_TIMER, 5000, 0); // So hab ich das öfter gesehen.
    SetTimer(m_ParenthWnd, IDT_TIMER, 5000, NULL); // Sollte das gleiche sein.
    SetTimer(m_ParenthWnd, IDT_TIMER, 5000, (TIMERPROC) NULL); // Hab ich aus der MSDN übernommen.
    


  • Arbeitest du mit der MFC? Wenn ja, verwendest du SetTimer() in einer Methode deiner Fensterklasse?

    Wenn du beide Fragen mit ja beantworten kannst:
    CWnd hat eine eigene Methode SetTimer(), bei der du den ersten Parameter weglassen kannst (die nimmt das eigene Window-Handle und übergibt es zusammen mit den übrigen Parametern an die globale SetTimer()). Damit hast du die Wahl zwischen:

    SetTimer(IDT_TIMER, 5000, 0);//definiert den Timer für das eigene Fenster
    m_Parent->SetTimer(IDT_TIMER, 5000, 0);//definiert den Timer für das Fenster m_Parent
    ::SetTimer(m_ParenthWnd, IDT_TIMER, 5000, 0);//Direktzugriff auf die globale Funktion
    

    (btw, ob du da 0 oder '(TIMERPROC) NULL' angibst, ist letztlich egal)



  • Leider benutz ich die ATL/WTL. Ändert sich dadurch etwas wenn ich direkt mit der WinAPI arbeite?



  • Hey er compiliert mit ::SetTimer, statt nur SetTimer. Prima. Jetzt muss ich den Timer auch nurnoch richtig benutzen 😉 Mal schauen...



  • Gesetzt ist der Timer ja, aber wie ich ihn anwende weiss ich niocht so recht. In der MSDN findet sich folgende Methode zur Anwendung des Timers und hab mal dazugeschrieben, was ich nicht verstehe.

    LONG APIENTRY MainWndProc( // Warum ein großgeschriebenes LONG?
        HWND hwnd,          // handle to main window 
        UINT message,       // type of message 
        WPARAM  wParam,     // additional information 
        LPARAM  lParam)     // additional information 
    { 
        HDC hdc;        // handle to device context -> device context? Was genau ist gemeint?
        POINT pt;       // current cursor location -> Welcher Cursor, welche Location?
        RECT rc;        // location of minimized window -> Versteh nicht den Zusammenhang zwischen dem Timer und eines minimierten Fensters.
    
        switch (message) 
        { 
            //
            // Process other messages. 
            // 
    
            case WM_TIMER: (( ich denke hier drunter muss ich dann die Methode packen, die ich immer wieder ausgeführt haben soll?
            // If the window is minimized, compare the current 
            // cursor position with the one from 10 seconds 
            // earlier. If the cursor position has not changed, 
            // move the cursor to the icon. 
    
                if (IsIconic(hwnd)) // Keine Ahnung was das ist, sollte ich aber wohl einfach übernehmen
                { 
                    GetCursorPos(&pt); // Sind die folgenden Zeilen alle für mich nötig?
    
                    if ((pt.x == ptOld.x) && (pt.y == ptOld.y)) 
                    { 
                        GetWindowRect(hwnd, &rc); 
                        SetCursorPos(rc.left, rc.top); 
                    } 
                    else 
                    { 
                        ptOld.x = pt.x; 
                        ptOld.y = pt.y; 
                    } 
                } 
    
                return 0; 
    
            case WM_DESTROY: 
    
            // Destroy the timer. 
    
                KillTimer(hwnd, IDT_MOUSETRAP); 
                PostQuitMessage(0); 
                break; 
    
            //
            // Process other messages. 
            // 
    
    }
    


  • Ich würde mal vermuten, daß der kompette Inhalt des 'case WM_TIMER:' Zweiges auf eine konkrete Anwendung zugeschnitten ist (wenn sich seit dem letzten Timer-Durchlauf die Cursor-Position nicht geändert hat, springe auf das Programm-Icon). Du mußt dort anstelle des if(IsIconic(hwnd)){...} die Arbeiten einfügen, die dein Programm in regelmäßigen Abständen erledigen soll.



  • Wenn du dir endlich mal die Referenz angeguckt hättest, und dann auch mal unter WM_TIMER nachgeschlagen hättest, würdest du gemerkt haben, dass die Timer-ID über WPARAM an WM_TIMER gesendet wird. D.h:

    case WM_TIMER:
        switch (wParam)
        {
            case TIMER_ID:    //ID des Timers (2. Parameter von SetTimer ())
                //Hier kommen dann die Funktionen rein, die der Timer immer wieder ausführen soll
            break;
        }
    return 0;
    

    Mfg Ominion



  • Danke euch beiden. Ich bin halt noch Anfänger in C++ und komme mit Nicht-Objekten (ok, primitive Datentypen gehen auch) einfach nicht klar. Woher weiss denn wParam von meinem TIMER, müsste ich ihm über die Parameter doch sicher mitteilen, aber dann weiss ich wiederum nicht, was ich übergeben sollte.



  • Der weiß davon, weil du es ihm mit SetTimer() mitgeteilt hast 😉 (wenn der Timer auslöst, schickt er eine WM_TIMER Nachricht mit der angegebenen ID als wParam an das Zielfenster)



  • CStoll schrieb:

    Der weiß davon, weil du es ihm mit SetTimer() mitgeteilt hast 😉 (wenn der Timer auslöst, schickt er eine WM_TIMER Nachricht mit der angegebenen ID als wParam an das Zielfenster)

    Achja 🙄 👍



  • Ne, ich häng immer noch am WPARAM fest. Irgendwie ist es doch nirgends definiert? Also wo bekomme ich das her?

    ::SetTimer(m_ParenthWnd, IDT_TIMER, 5000, 0);
    

    hat doch nix mit WPARAM zu tun oder?





  • Könnt Ihr von dem Kerl die IP raussuchen und ihn anzeigen? Der spamt das ganze Forum mit jugendgefährdenen Videos zu!



  • plizer schrieb:

    Ne, ich häng immer noch am WPARAM fest. Irgendwie ist es doch nirgends definiert? Also wo bekomme ich das her?

    WPARAM ist ein typ, ein #define oder typedef. wenn du <windows.h> includest, dann hast du den.

    ::SetTimer(m_ParenthWnd, IDT_TIMER, 5000, 0);
    

    hat doch nix mit WPARAM zu tun oder?
    [/quote]
    wenn der window manager die WndProc mit WM_TIMER aufruft, erscheint dein wert 'IDT_TIMER' als WPARAM.
    (ich glaub' aber, das hat schon jemand geschrieben)
    🙂



  • Also pack ich dann mein IDT_TIMER in die Switch-Anweisung? Nur dann überspringt er diese einfach?!



  • plizer schrieb:

    Könnt Ihr von dem Kerl die IP raussuchen und ihn anzeigen? Der spamt das ganze Forum mit jugendgefährdenen Videos zu!

    Die IP haben wir schon - und inzwischen ist wohl die halbe Belegschaft dabei, ihm hinterherzuräumen 😡

    @Topic: Von welchem switch() genau redest du jetzt? Der äußere (große) 'switch(message){...} wird kaum deine IDT_TIMER erhalten (die gesendete Nachricht ist WM_TIMER), aber in deinem 'case WM_TIMER:' Block kannst du einen zweiten switch(wPram) aufbauen, um die vielen Timer deiner Anwendung unterscheiden zu können (wenn du nur einen hast, kannst du dessen ID auch nicht beachten).



  • plizer schrieb:

    Also pack ich dann mein IDT_TIMER in die Switch-Anweisung? Nur dann überspringt er diese einfach?!

    wie viele timer benutzt du?
    wenn du nur einen hast, brauchst du im case-zweig 'WM_TIMER' nichts abzufragen, weil er da nur bei timer messages des einzigen timers landet.
    aber lies dir noch mal den thread durch. ähnliches steht alles schon da...
    🙂



  • Ich benutze nur einen Timer! Man, kann man echt so schlecht in einer Sprache sein plötzlich? Versteh da fast nichts, aber für riesige Java-Projekte und ein Informatik-Studium-Abschluss unter Regelstudienzeit hats gereicht.

    Wenn ich jetzt die switch Anweisung rausnehme, bleibt ja nix mehr über! Irgendwie versteh ich immer noch nicht wie und wo ich jetzt meine Methode starten muss, damit diese mit einem Timer läuft. Und leider versteh ich auch 80% der Kommentare zum Quelltext in der MSDN nicht!



  • plizer schrieb:

    Versteh da fast nichts, aber für riesige Java-Projekte und ein Informatik-Studium-Abschluss unter Regelstudienzeit hats gereicht.

    tja, hättest du mal was vernünftiges studiert 😉
    ne, spass beiseite, hier ein kleines beispiel:

    #include <windows.h>
    #include <stdio.h>
    
    // diese funktion wird einmal pro sekunde von windows aufgerufen
    void __stdcall timerproc (HWND h, UINT msg, UINT id, DWORD time)
    {
        puts ("Tick");
    }
    
    int main()
    {
        // wir starten einen sekunden-timer
        SetTimer (0, 1, 1000, timerproc);
    
        // folgender quatsch muss sein, damit windoofs
        // die timerprozedur auch aufruft
        // in einer GUI anwendung ist sowas irgendwo schon vorhanden.
        for (;;)
        {
            MSG msg;
            GetMessage (&msg, 0, 0, 0);
            DispatchMessage (&msg);
        }
    }
    

    mach 'ne konsolenanwendung und poste den code da rein, dann haste etwas zum experimentieren.
    das mit der 'timerproc' kannst du auch in einer GUI anwendung machen, es muss nicht unbedingt eine message an die WndProc geschickt werden.
    🙂


Anmelden zum Antworten