2010-03-27 6 views
2

je dessine directement à l'écran à l'aide BitBlt et GetDC(IntPtr.Zero). Est-il possible d'appeler Refresh ou Invalidate sur l'ensemble de l'écran lorsque j'ai terminé, pour ne pas laisser de gros morceaux de peinture partout (numériquement parlant)? Lorsque vous dessinez directement sur l'écran comme je le fais, tout ce que vous dessinez reste là jusqu'à ce que la fenêtre en dessous se repeigne (et, ce faisant, repeigne la partie de l'écran qu'il couvre).Comment nettoyer après moi-même quand dessiner directement à l'écran

Le problème est que certaines parties du bureau Windows ne se repeignent pas pendant de longues périodes. Par exemple, si je dessine au-dessus de la barre des tâches, les tâches réelles se repeignent assez rapidement (avec le bouton Démarrer, etc.), mais la barre des tâches elle-même conserve ce que j'ai dessiné pendant quelques minutes.

Si mon application avait une fenêtre qui couvrait tout l'écran, j'appellerais simplement Invalidate() sur ce formulaire qui le ferait se repeindre et donc l'écran entier. Ce dont j'ai besoin, c'est d'un moyen d'appeler Invalidate ou Refresh sur l'ensemble de l'écran lui-même.

+0

Pouvez-vous être plus précis? Où/que dessinez-vous, et quels domaines voulez-vous invalider exactement? (c'est-à-dire voulez-vous que certaines fenêtres soient repeintes? Si oui, quelles fenêtres? etc.) – vladr

+0

Vous voulez probablement faire GetWindowDC (GetDesktopWindow()) pour rendre votre code plus évident et pour assurer votre utilisation non supportée d'une valeur magique. faites en sorte que votre application tombe en panne. –

Répondre

3

InvalidateRect(NULL, NULL, TRUE) devrait invalider et redessiner toutes les fenêtres. Bien que ce sera une opération coûteuse.

Une autre approche serait de se rappeler où vous avez dessiné et essayer d'énumérer toutes les fenêtres dans ce rectangle et invalider seulement eux.

Vous pouvez également essayer de créer une fenêtre transparente sur la zone que vous avez peint quand vous voulez invalider les fenêtres là. Notez que vous voulez faire une fenêtre en couches alpha-mélangée, pas une fenêtre WS_TRANSPARENT. Si vous le faites avec 99% de transparence, le DWM devrait repeindre toutes les fenêtres en dessous une fois qu'il est détruit. Bien sûr, cela pourrait conduire à un scintillement à peine perceptible sur la région cible en raison de l'alphablending de la fenêtre avant que vous le détruisiez.

+0

On dirait que cela va fonctionner. Peu importe que ça coûte cher, puisque je n'appellerai ça qu'une seule fois. Ce que je fais est de rendre une animation en plein écran, donc je n'ai besoin de repeindre l'écran entier qu'une seule fois, une fois l'animation terminée. – MusiGenesis

1

Le « écran » se compose d'un ensemble de fenêtres qui sont sur le bureau parented fenêtre. J'imagine que vous pourriez simplement invalider la fenêtre du bureau, même si vous devrez peut-être recourrir à travers ses fenêtres enfants (les fenêtres de l'application de niveau supérieur) et les invalider aussi. (Il peut aussi y avoir des problèmes avec les moniteurs mutliple, mais cela devrait vous donner un point de départ)

Voir GetDesktopWindow().

Vous pouvez également créer un formulaire qui couvre l'intégralité de l'écran et utiliser un dessin transparent. Ensuite, fermez simplement la fenêtre quand vous avez terminé.

+0

Il devra probablement énumérer toutes les fenêtres et invalider le rectangle de nettoyage dans chacune d'entre elles. La diffusion de "WM_PAINT" a également fonctionné dans l'ancien temps, mais c'est presque certainement exagéré. – vladr

Questions connexes