6
votes

Sur Win32, puis-je désactiver la peinture d'une fenêtre pendant une période de temps?

Y a-t-il une fonction qui va geler la fenêtre repeindre pendant un certain temps, alors que je modifie la mise en page de ma boîte de dialogue?


2 commentaires

Je doute sérieusement que vous devez faire cela. Avez-vous essayé et déterminé que vous êtes réellement d'une inondation de wm_paint lorsque vous ajustez la mise en page de votre boîte de dialogue? Windows n'enverra pas un message wm_paint à la fenêtre de la fenêtre, sauf s'il n'y ait aucun autre message disponible pour le traitement.


@Cody, je suis sûr que vous le savez, mais Windows n'envoie pas wm_paint , plutôt qu'il les pose. Une distinction tout à fait importante.


3 Réponses :


2
votes

La manière dont Windows peint est que le système publie votre fenêtre wm_paint messages vous instructant de peindre. Vous pouvez choisir d'ignorer ces messages si vous le souhaitez, tandis que vous modifiez la mise en page, puis forcez un cycle de peinture une fois que vous avez fini de modifier la mise en page.

Cependant, mon expérience d'écriture de l'interface utilisateur sous Windows est que vous n'avez généralement pas besoin de prendre de telles étapes. Depuis que vous êtes responsable de la pompe de votre file d'attente de messages, si la fenêtre est en cours de rafraîchissement tandis que vous êtes au milieu de la modification de la mise en page, vous devez avoir pris des mesures qui ont conduit à la file d'attente de message étant pompée.

Mettez simplement, arrêtez de pomper la file d'attente tout en modifiant la mise en page et vos problèmes disparaîtront.


0 commentaires

4
votes

Vous devriez faire le repositionnement dans un seul swoop; Utilisez BegindeferwindowPos et al.


0 commentaires

17
votes

Si vous constatez que vous devez réellement faire cela, vous devez envoyer la fenêtre A wm_sedredraw message avec le wparam défini sur false. Cela indique que la fenêtre ne doit pas être redessinée une fois que son contenu est modifié.

Lorsque vous souhaitez réactiver le dessin, envoyez un autre message wm_sedraw , cette fois avec le wparam Définissez sur true.

code d'exemple: xxx

pour plus d'informations, L'article de blog de Raymond Chen sur le sujet est une excellente lecture.


10 commentaires

@Cody Grey, merci, je dois le faire car l'application est à la peau de SkinCrafter, et parce que nous avons eu des problèmes de pages de propriété, j'ai essentiellement quelques boutons d'image qui agissent comme des onglets, et lorsque l'utilisateur appuie sur l'un d'entre eux. onglet en montrant / masquant / déplaçant tous les widgets.


@satuon: Ugh. Il y a votre problème. Vous utilisez une merde hideuse comme des bibliothèques de peau. Cela ne devrait pas être surprenant que les choses ne regardent pas et ne travaillent pas exactement comme prévu.


@ Cody-Grey Cela fonctionne-t-il pour les fenêtres enfants, ou dois-je envoyer ces messages à chacune des fenêtres de l'enfant?


@Satuon: Oui, cela fonctionne pour les fenêtres enfants, tant que vous leur envoyez le message. Ils repeignent séparément de leur parent.


Il y avait un problème mineur lorsque j'ai ajouté ce code à ma fonction de mise en page, l'icône de la barre des tâches n'a pas montré (je suis sur Windows 7), mais je l'ai résolu en veillant à ce que le message WM_STREDRAW n'est pas utilisé. Première fois que la fonction est appelée, qui était avant l'affichage de la boîte de dialogue pour la première fois.


@Satuon: Oui, si vous ne laissez jamais la fenêtre à être dessinée, cela ne sera jamais tiré sur la barre des tâches non plus. Heureux que vous ayez trouvé quelque chose qui a fonctionné pour vous.


Je ne pense pas que vous ayez besoin d'envoyer séparément wm_sedredraw à des fenêtres enfants. WM_SetReDraw semble fonctionner en se soulevant la visibilité des fenêtres et les fenêtres enfants sont toujours invisibles lorsque leur parent est.


@Chris: Cela pourrait être le cas; Honnêtement, je ne sais pas. Mais il y a quelques problèmes de cette approche, tous deux discutés dans l'article que j'ai lié à. Premièrement, c'est que c'est purement un détail de mise en œuvre et que vous ne devriez pas compter sur. Le comportement pourrait transformer théoriquement dans une future version de Windows, comme wm_sedreraw n'est pas documenté comme faisant la fenêtre pseudo-invisible et / ou ayant des effets sur les vitres enfants. Deuxièmement, il suppose la mise en œuvre par défaut , qui est une erreur car vous devriez généralement fournir un gestionnaire personnalisé pour wm_sedreraw qui pourrait fonctionner différemment.


1. Je pense que la propagation des États, comme les états indiquées et les états activés, et SetReReRaw State, aux fenêtres enfants est toujours à l'avance. 2. Vous ne pouvez pas implémenter SetReDraw aussi efficacement que la mise en œuvre par défaut, car la mise en œuvre par défaut signifie qu'aucun appel à GetDC récupérera une garantie d'affichage, une garantie beaucoup plus forte qu'une implémentation de l'utilisateur qui ne peut se promettre de ne pas appeler GETDC.


Dans VS2019 Débogage, laissant wm_sedreraw FALSE peut quitter l'application avec les commandes NC qui ne répondent pas. Donc, oui, vérifiez toutes les routines où il est nécessaire d'être réellement true, ou mieux, il suffit d'ajouter des conditions pertinentes dans wm_paint .