PB TIMER en MFC

valdeub
PB TIMER en MFC

Bonjour,
je rencontre actuellement un phénomène étrange dans une application MFC (type Doc/View). En gros, les traitements lancés à l'expiration de différents Timers dans ma CView viennent interrompre le traitement de ma fonction OnDraw() ...
Est-ce que quelqu'un aurait une explication voire une parade !!!
D'avance merci !!!
Stéphan

fredericmazue

Normalement ça ne devrait pas se produire je pense.
Tel que tu décris, on dirait que les tick des timers ne sont pas traités par ta procédure de fenêtre. Concrètement en MFC cela peut vouloir dire que tes timers n'ont pas été initialisés correctement et/ou au bon endroit
Tu dois normalement appeler SetTimer (alias CWnd::SetTimer) dans la portée de ta CView, avec NULL en troisième paramètre pour que la procédure de fenêtre par défaut de la CView soit utilisée. Et ton code qui répond au timer, tu dois le mettre dans la méthode OnTimer de ta CView
Moyennant quoi, l'effet que tu décris ne devait plus se produire

valdeub

Je précise un peu plus ...
J'initialise mes Timers (SetTimer( ..., ..., NULL)) dans OnInitialUpdate() de CMyView.
Dans OnTimer pour chacun des Timers je lis des données et appelle Invalidate(FALSE) donc indirectement la OnDraw() de CMyView.
J'ai mis des traces dans OnDraw et dans OnTimer et il se trouve que les traces de OnTimer apparaissent au milieu de l'execution de la procédure d'affichage contenue dans OnDraw ...
Voilà donc mon problème ...

fredericmazue

Quote:
J'initialise mes Timers (SetTimer( ..., ..., NULL)) dans OnInitialUpdate() de CMyView.
Dans OnTimer pour chacun des Timers je lis des données et appelle Invalidate(FALSE) donc indirectement la OnDraw() de CMyView.

C'est correct. Mais c'était le premier point à vérifier.

Bon le comportement que tu décris est un comportement préemptif. Ce qui n'arrive pas quand une seule WndProc est en jeu. Je veux dire que si tu es dans un événement WM_PAINT (i.e tu es dans OnDraw appelé depuis la WndProc), un évémenent WM_TIMER ne peut préempter pour que le flux d'exécution saute dans OnTimer.
On a ça uniquement dans une application multithread. Je pense que ce n'est pas le cas (volontairement) de ton application car sinon ça serait évident et tu ne poserais pas la question.
Alors quoi :?:
J'avoue que je n'ai pas eu le désagrément de faire du MFC depuis un bon moment, aussi je ne me souviens plus très bien.
Mais nous devons forcément regarder 2 threads puisqu'il y a préemption. Le premier est celui de la procédure de fenêtre, la WndProc. Normalement on y touche pas.
Le second est celui de l'application. Ca ne peut être que lui. La classe CWinApp descend de CWinThread si je me souviens bien, ce qui veut dire que la boucle de pompe des messages (pas la WndProc hein ?) de l'application tourne dans un thread séparé, ce qui est d'ailleurs normal dans une appli Win32.
Mais peut être que ta boucle des messages n'est pas standard. Normalement ça se résume à GetMessage TranslateMessage et DistpachMessage. Si en amont il y a un appel supplémentaire à PeekMessage, ça peut permette à un message WM_TIMER de préempter une WndProc.
Il me semble me souvenir avoir déjà vu ça...

En espérant que ça t'aide.