[WM_TIMER] Der will nicht..
-
Was genau passiert bei KillTimer?
-
Meldung:
Assert, file: ../afxwin2.inl, line 185Wenn ich dann unterbreche, lande ich allerdings in afxtls.cpp bei folgender Zeile:
inline void* CThreadSlotData::GetThreadValue(int nSlot) { EnterCriticalSection(&m_sect); ASSERT(nSlot != 0 && nSlot < m_nMax); ASSERT(m_pSlotData != NULL); // die nächste Zeile ist es wohl.. ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED); ASSERT(m_tlsIndex != (DWORD)-1); if( nSlot <= 0 || nSlot >= m_nMax ) // check for retail builds. { LeaveCriticalSection(&m_sect); return NULL; } CThreadData* pData = (CThreadData*)TlsGetValue(m_tlsIndex); if (pData == NULL || nSlot >= pData->nCount) { LeaveCriticalSection(&m_sect); return NULL; } void* pRetVal = pData->pData[nSlot]; LeaveCriticalSection(&m_sect); return pRetVal; }
Das hilft mir allerdings nicht viel weiter ..
-
Nur mal so..
Wenn ich bei:ASSERT(m_nTimer!=0);
in OnInitDialog() einen Breakpoint setze, dann wird OnTimer() aufgerufen, aber nur einmal.
<edit>
Und setze ich noch einen Breakpoint in OnTimer(), wird OnTimer() 3x aufgerufen..
Eigentlich sollte es mind. 100x aufgerufen werden..
</edit>
-
Passiert in diesem Programm sonst noch etwas?
Falls ja, ist das Verhalten bei einem ansonsten leeren Projekt genauso?Was steht in afxwin2.inl, Zeile 185? Die Datei sollte in einem Unterverzeichnis des Visual C++-Ordners zu finden sein.
-
(1.) In dem Programm bzw. diesem Dlg passiert noch OpenGL-Kram.
(2.) Hab mal ein neues Projekt aufgemacht, und in dem funzt es prima mit dem Timer. Da fällt mir ein, das ich Klassen- und Dateinamen von Hand mal geändert hab, hat aber alles bis auf den Timer gefunzt. Kann's daran liegen?
(3.) Hab folgendes gefunden, was vermutlich bedeutet, dass das Fenster-Handle aschon freigegeben wurde._AFXWIN_INLINE BOOL CWnd::KillTimer(UINT_PTR nIDEvent) { ASSERT(::IsWindow(m_hWnd)); return ::KillTimer(m_hWnd, nIDEvent); }
<edit> KillTimer() steht jetzt in der OnOK()-Funktion, der Assert hat sich damit erledigt.
</edit>
-
don_basto schrieb:
(1.) In dem Programm bzw. diesem Dlg passiert noch OpenGL-Kram.
Kann es sein, dass da sehr viel OpenGL-Kram passiert? Liegt die Prozessorauslastung in der Nähe von 100%, weil dein Fenster andauernd neu gezeichnet wird?
Dann ist es normal, dass dein Timer nicht regelmäßig ausgelöst wird. Timernachrichten werden nur dann überhaupt abgearbeitet, wenn sonst nichts zu tun ist. Wenn dein Programm ständig damit beschäftigt ist, andere Nachrichten zu verarbeiten, kommt der Timer nicht durch. Du musst dir ein anderes Verfahren für zeitgesteuerte Ereignisse einfallen lassen.
-
Da passiert soviel Kram, wie eben Zeit ist. Hab gerade festgestellt, dass der Timer prima funzt, solange ich das OGL-Control rauskommentiere. Das OGL-Control überschreibt die OnPaint()-Funktion, welche vermutlich immer aufgerufen wird, wenn Zeit ist, da die Frameraten des Controls von dessen Grösse abhängen(klein schnelle Rate, gross langsam).
Hab aber keine Ahnung, von der internen MFC-Struktur. Ich stelle eine OGL-Szene dar und wollte mit der OnTimer()-Funktion die abgespielte Zeit in einem Textfeld darstellen. Wie kann ich das ohne OnTimer() anstellen?
In der OnPaint()-Funktion des OGL-Controls will ich das Textfeld nicht aktualiseren, weil es dem Dialog (mit dem Textfeld) untergeordnet ist und ich Aufrufen entgegen der Hierarchie gern vermeide, wenn es möglich ist.
-
don_basto schrieb:
Hab aber keine Ahnung, von der internen MFC-Struktur.
Das hat mit MFC nichts zu tun, das ist ganz allgemein unter Windows so.
Wie kann ich das ohne OnTimer() anstellen?
Du könntest einen weiteren Thread benutzen, der hin und wieder deinem Hauptfenster eine benutzerdefinierte Nachricht schickt. Die Behandlungsfunktion im Hauptfenster ermittelt die verstrichene Zeit und aktualisiert das Textfeld.
In der OnPaint()-Funktion des OGL-Controls will ich das Textfeld nicht aktualiseren, weil es dem Dialog (mit dem Textfeld) untergeordnet ist und ich Aufrufen entgegen der Hierarchie gern vermeide, wenn es möglich ist.
Da würde ich mir keine allzu großen Gedanken machen. Dass ein Fenster seinem Elternfenstern eine Nachricht schickt, ist sehr verbreitet. Alle Notify-Nachrichten funktionieren so.
-
Das ist Neuland fur mich. Ich bin nicht sicher, ob ich dich richtig verstanden hab:
- das OGL-Ctrl schickt jede Sekunden eine benutzerdefinierte Nachricht (WM_MYMSG)
- der Dialog fängt diese Nachricht und aktualisiert dann sein Textfeld
Das klingt machbar. Muss ich mir jetzt erstmal zusammensuchen, kann dauern.Noch eine Frage: Wie baue ich eine Framebremse in mein OGL-Ctrl ein, ohne den Rechner lahm zu legen? So dass Luft für die OnTimer()-Funktion wäre?
(Im Grafik-Forum nix gefunden.)<edit> Wie wäre der Thread-Ansatz? </edit>
-
Hab's jetzt mit GetParent()->SendMessage() im OGLCtrl implementiert. Funzt prima.
Tausend Dank an MFK für die Tipps!Eine Frage noch zum Schluss: Wie sage ich der OnPaint()-Methoden des OGLCtrl, dass die OGL-Scene nicht ständig neu geteichnet werden soll?
Grüsse,
don_basto.