web-dev-qa-db-fra.com

Différence entre InvalidateRect et RedrawWindow

Lorsque je souhaite redessiner une fenêtre, existe-t-il une fonction préférée à appeler entre InvalidateRect et RedrawWindow?

Par exemple, ces deux appels sont-ils égaux: (gagner serait un HWND)
RedrawWindow(win, NULL, NULL, RDW_INVALIDATE);
InvalidateRect(win, NULL, NULL);

La ou les principales questions: Quand dois-je utiliser l'un ou l'autre? Y a-t-il des différences qui se produisent en arrière-plan? (différents messages WM/focus/ordre/priorités ..)

La raison pour laquelle je veux redessiner la fenêtre est parce que je lui envoie une nouvelle image que je veux qu'elle affiche, ce qui signifie que le contenu de la fenêtre n'est plus valide.

39
Default

InvalidateRect ne redessine pas immédiatement la fenêtre. Il "planifie" simplement un futur redessin pour une zone rectangulaire spécifique de la fenêtre. En utilisant InvalidateRect, vous pouvez planifier autant de zones que vous le souhaitez, en les faisant accumuler dans un tampon interne. Le redessin réel pour toutes les zones programmées accumulées aura lieu plus tard, lorsque la fenêtre n'aura rien d'autre à faire. (Bien sûr, si la fenêtre est inactive au moment où vous lancez l'appel InvalidateRect, le redessin aura lieu immédiatement).

Vous pouvez également forcer un rafraîchissement immédiat pour toutes les zones invalidées actuellement accumulées en appelant UpdateWindow. Mais, encore une fois, si vous n'êtes pas pressé, appeler explicitement UpdateWindow n'est pas nécessaire, car une fois que la fenêtre est inactive, elle effectuera automatiquement un nouveau dessin pour toutes les zones actuellement invalidées.

RedrawWindow, d'autre part, est une fonction avec un ensemble de capacités beaucoup plus large et flexible. Il peut être utilisé pour effectuer une planification d'invalidation (c'est-à-dire la même chose que InvalidateRect) ou il peut être utilisé pour effectuer avec force un redessin immédiat de la zone spécifiée, sans faire de "planification". Dans ce dernier cas, appeler RedrawWindow est pratiquement équivalent à appeler InvalidateRect, puis appeler immédiatement UpdateWindow.

54
AnT

RedrawWindow(win, NULL, NULL, RDW_INVALIDATE); et InvalidateRect(win, NULL, NULL); sont équivalents. Les deux fonctions invalident la fenêtre. Le WM_Paint Se produit à l'heure normale (aucun autre message dans la file d'attente d'application) dans les deux cas.

Si vous voulez que le Paint soit fait immédiatement, alors appelez RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW) ou InvalidateRect suivi d'un UpdateWindow le fera.

RedrawWindow donne simplement plus d'options avec les bits RDW_ *. Si tout ce que vous voulez, c'est invalider la fenêtre sans Paint immédiat, alors appeler InvalidateRect semble plus propre.

19
Mike T

Je n'aime pas simplement donner des liens, mais le MSDN vous donne toutes les informations dont vous avez besoin et ce serait une perte de temps de tout retaper ici.

RedrawWindow

InvalidateRect

Bref, oui il y a des différences. La question est, pourquoi voulez-vous redessiner la fenêtre? Est-ce parce que le contenu n'est plus valable? Si c'est le cas, utilisez InvalidateRect, sinon utilisez RedrawWindow.

1
Peter Alexander

RedrawWindow repeint la fenêtre immédiatement. InvalidateRect marque uniquement la fenêtre à repeindre sur le prochain message WM_Paint. Mais les messages WM_Paint ont une priorité plus faible que les autres messages, donc la repeinture ne sera pas immédiatement si votre application est occupée à gérer d'autres messages.

1
Stefan