7
votes

Détecter le changement de thème du système dans WPF

J'ai besoin, pour que mon application WPF, de détecter lorsque le DWM est allumé / éteint ou lorsque le thème du système change.
Il y a un tel événement dans Winforms, mais je ne peux voir aucun dans WPF.


4 commentaires

Quand ont-ils ajouté cet événement à Winforms? Pour autant que je sache, cela n'échange aucun événement que ce soit lorsque la composition DWM est activée / désactivée.


Ce n'est pas un événement Winforms, c'est un Message de la fenêtre .


@Bolt: Les messages de fenêtre sont disponibles dans WPF tout aussi facilement qu'ils sont dans Winforms. Je sais sur wm_dwmcompositionChanged , mais la question me conduit à croire qu'il y a un événement pour cela dans Winforms. Je n'ai pas encore trouvé ça ... (Modifier: On dirait que la première partie est ce que votre réponse se termine. Si je n'étais pas hors de voix, j'avais +1.)


L'événement s'appelle stylechanged et fonctionne à 100% avec les thèmes et le DWM.


3 Réponses :


9
votes

Je n'ai pas entendu parler d'un événement WinForms qui déclenche lorsqu'une fenêtre WinForms reçoit des messages du système, mais elle possède sa propre méthode wndProc () que vous pouvez remplacer. Vous êtes probablement confondre des messages de fenêtres pour des événements de formulaire. ah, donc c'est l'événement stylechanged invoqué dans WinForms Windows. Le reste de ma réponse reste toujours cependant.

WPF n'est pas étroitement lié à l'API Windows, que ce soit une technologie de haut niveau qui investit beaucoup d'abstraction à l'écart des internes. Pour un, il dessine tout dans une fenêtre par elle-même et ne demande pas au système de faire le dessin ( éditer: C'est pourquoi WPF manque de telle < Code> Stylechaged événement). Cela dit, Windows envoie des messages à toutes les fenêtres lorsque le DWM est basculé et lorsque le thème change, et vous pouvez toujours expliquer au niveau bas de la couche WPF pour accéder à ces messages et manipuler vos commandes WPF en conséquence. < P> Joindre une procédure de fenêtre sur la HWND (Poignée de fenêtre) de votre fenêtre WPF dans le cadre de l'événement SourceInitialized's de votre fenêtre. Dans votre procédure de fenêtre, gérer le Wm_dwmcompositionChanged et WM_THEMECHANGED Messages de fenêtre respectivement.

Voici un exemple rapide (avec le code de la chaudron adapté de Cette question de la mine ): xxx


3 commentaires

Jusqu'à ce que la modification soit acceptée: veuillez noter que les messagesides sont mélangés (comme Pierre indiquée dans sa réponse: WM_THEMECHANGED = 0x31a et WM_DWMCompositionChanged = 0x31e)


@ATHANVIEL: Crier interne J'étais complètement inconscient de la réponse de Peter jusqu'à ce que vous soyez arrivé. J'ai approuvé votre édition. Merci!


Les remerciements vont à Pierre, car il m'a sauvé beaucoup de temps, ce qui a mal tourné. Non, moins vous êtes les bienvenus :)



3
votes

L'événement SystemEvents.userprefeferencéraGanged aussi le tour. userPreFerenCeChanged (à JapAense)


0 commentaires

3
votes

Malheureusement, la solution acceptée ne fonctionne pas avec les changements de thème de couleur Aero et les numéros hexagonaux de message WM sont mélangés - mais je suis d'accord pour que cela soit très utile si vous souhaitez attraper des messages WM dans WPF. J'ai essayé de trouver une solution à ce problème pendant un moment, et je pense que je l'ai résolu pour tous les cas possibles (pour les thèmes Aero et classique).

Le changement de couleur Aero déclenche le message WM_DWMColorizeColorchanged. < / p>

Pour détecter lorsque les modifications du thème de la couleur, vous devez utiliser plusieurs méthodes. L'événement Form.STylechanged va détecter tous les changements thématiques, sauf pour les changements de couleur Aero . Voici une solution alternative à stylechanged. (OK, je sais que c'est des winforms, mais vous avez l'idée. L'équivalent WPF est dans la réponse acceptée quand même.) xxx

pour les thèmes de couleur Aero, les SystemEvents .USERPREFERENCECANGED Evénement fonctionne aussi (merci voit!): xxx

Comme vous pouvez le voir ci-dessus, il est loin d'être intuitif. Aero Color Change déclenche un événement de préférence «général», même s'il y a beaucoup plus approprié pour cela, comme «VisualStyle», etc.

Si vous voulez être approfondi, vous devez comparer le Couleur DWM enregistrée sur la couleur actuelle DWM, pour vous assurer qu'il s'agissait d'un thème de couleur Aero qui a déclenché cet événement (à l'aide de l'appel de l'API DwMetColorizorizedParamètres), et pas autre chose. Voir ces réponses sur la manière dont les couleurs AERO peuvent être récupérées: Obtenez la couleur active de Windows 8 Theme de couleur automatique


0 commentaires