Ce qui pourrait causer des problèmes de rafraîchissement sur vista 64 bits, mais pas en 32 bits dans .NET WinForms?
-
23-08-2019 - |
Question
Cela se produit lors de la compilation pour Tout Cpu, ainsi que la compilation à x86. Les sections de l'interface graphique ne redessine pas moins qu'il ne soit redimensionnée, par exemple, si la principale forme est maximisée certaines des commandes ne redimensionner pas, et d'autres ont des sections qui ne retracent et affiche la ce qui était précédemment là.
Cela fonctionne très bien sur les machines 32 bits, XP et Vista, mais sur Vista 64 bits (ne pas x64 XP pour tester avec) le redécoupage juste ne fonctionne pas correctement.
Quelqu'un a des idées sur l'endroit où commencer le suivi de cette baisse?
Edit: Cela se produit sur 2 machines séparées, et au moins celui que je suis actuellement a les derniers pilotes de NVidia.
Edit2: Exécution d'une machine virtuelle XP 32 bits sur ma machine 64 bits et l'application ne présente pas la question de redessiner dans la machine virtuelle
Edit3: Peut-être un problème de pilote, mais nous ne savons pas si ou quand les conducteurs résoudre le problème. Un collègue dit qu'il y a moins de problèmes avec une carte ATI à la maison qu'avec NVidia, mais j'ai été mise à jour mes pilotes vidéo à peu près tous les mois pour les quelques derniers mois et il est toujours pas résolu, nous ne pouvons pas simplement libérer notre produit et juste dire à nos clients un jour les fabricants de pilotes peut se déplacer à fixer cela.
Quelqu'un at-il une idée sur ce que les choses à essayer d'éviter? Nous compilons que x86 et tous nos composants x86. Je ne peux pas semble reproduire ce problème avec l'un des composants dans des projets de test, et je ne l'ai pas entendu quelqu'un d'autre rapport ces questions sur la plupart des forums composants, il est donc assez probable que c'est quelque chose que nous faisons.
La solution
Cela semble horriblement comme ce problème .
Lors du redimensionnement des fenêtres sur Windows, vous obtenez généralement une chaîne où chaque fenêtre reçoit un message WM_SIZE
et appelle ensuite MoveWindow()
(ou similaire) sur ses enfants qui, à son tour recevoir un WM_SIZE
et ainsi de suite. Je suis sûr que .NET fait la même chose sous les couvertures.
Sur x64, Windows limite la profondeur de cette imbrication, et après un certain point (12-15 fenêtres imbriquées), il sera tout simplement pas envoyer les messages WM_SIZE
plus. Cette limitation ne semble pas exister sur x86. Cette limitation affecte à la fois le code x86 et x64 en cours d'exécution sur les versions x64 de Windows.
Cela nous Foxed pour les âges, comme différentes installations x64 montreraient des symptômes différents. L'affichage blog MSDN a surtout des solutions de contournement possibles -. Nous avons fini par un fil secondaire pour faire la taille de la fenêtre de manière asynchrone, ce résolu le problème assez nettement
Autres conseils
Si vous utilisez la fonctionnalité Windows Forms, il pourrait être à voir avec les problèmes de limitation de nidification sur Windows 64 bits.
Détails ici: http://www.feedghost.com/Blogs/ BlogEntry.aspx? ENTRYID = 17829
En résumé ...
De la source MS, en Control.SetBoundsCore:
SafeNativeMethods.SetWindowPos(new HandleRef(window, Handle), NativeMethods.NullHandleRef, x, y, width, height, flags);
// NOTE: SetWindowPos causes a WM_WINDOWPOSCHANGED which is processed
// synchonously so we effectively end up in UpdateBounds immediately following
// SetWindowPos.
//
//UpdateBounds(x, y, width, height);
Et de MSDN:
"Une petite enquête a montré que Windows cesse d'envoyer WM_SIZE quand il atteint un certain certain imbrication niveau. En d'autres termes, il ne sera pas envoyer WM_SIZE à vos fenêtres enfant si vous essayez de les redimensionner lorsque vous traitez WM_SIZE dans les parents. En fonction, dépendemment sur les choses USER / mises à jour / serivice emballe le niveau d'imbrication maximum laquelle il cesse de se propageant WM_SIZE peut varier de 15 à 31 et même beaucoup supérieur (effectivement inaccessible) en vertu dernière XP 32bit / sp2.
Mais il encore trop peu sous XP x64 et encore des choses laides similaires arriver à d'autres messages sous certains construit de Vista.
Il est donc certainement un bug de Windows. "
Vous avez deux choix: soit réduire la profondeur de votre hiérarchie de contrôle (la solution plus idéale), ou bien Dérive « fixe » les contrôles de chacun de ceux du système que vous utilisez, comme suit:
public class FixedPanel : Panel
{
protected override void SetBoundsCore( int x, int y, int width, int height, BoundsSpecified specified )
{
base.SetBoundsCore( x, y, width, height, specified );
if( specified != BoundsSpecified.None )
{
if( ( specified & BoundsSpecified.X ) == BoundsSpecified.None )
{
x = Left;
}
if( ( specified & BoundsSpecified.Y ) == BoundsSpecified.None )
{
y = Top;
}
if( ( specified & BoundsSpecified.Width ) == BoundsSpecified.None )
{
width = Width;
}
if( ( specified & BoundsSpecified.Height ) == BoundsSpecified.None )
{
height = Height;
}
}
if( x != Left || y != Top || width != Width || height != Height )
{
UpdateBounds( x, y, width, height );
}
}
}
Je pense que la cause la plus probable de ce problème est un problème de redessiner dans votre application. Il est possible qu'il y ait une fenêtre subtile différence un message de commande sur 64 bits qui expose cette question dans votre code.
Vous pouvez expérimenter cela en procédant comme suit.
- Ajoutez une minuterie à votre application.
- Dans le gestionnaire d'événements appel flakyControl.Update ()
Je régler la minuterie à quelque chose de long comme 5 secondes. Ensuite, exécutez l'application sur Win64 et voir si cela résout le problème. Si oui, alors est l'un de vos contrôles la cause la plus probable est pas correctement la signalisation qu'il a été invalidée.
Je commencerais avec des contrôles personnalisés dans l'application. Systématiquement ajouter un appel de mise à jour à chaque méthode et surchargée gestionnaire d'événements dans le code. Finalement, vous trouverez celui qui résout le problème et vous saurez où le bug est en réalité.
Si vous utilisez la solution BeginInvoke () décrite sur le MSDN
Sons comme un problème pilote d'affichage pour moi ... Essayez de mettre à jour les derniers pilotes et voir si cela résout le problème? La différence de bit 64/32 est probablement un hareng saur ...
Je suis d'accord avec Gordon. J'ai vu des questions où la marque de nouvelles machines 64 bits ont des problèmes d'affichage avec des programmes qui avaient l'air bien en 32 bits, mais présenteraient des questions bizarres sur les machines 64 bits. Mise à jour de la dernière / pilotes recommandés presque toujours résolu le problème.
Le fait que vous pouvez exécuter le programme sur un système d'exploitation virtuel sans problème suggère qu'il est un problème de pilote, parce que (au moins en VirtualPC) la carte graphique est émulé. Cela signifie que certaines choses que la carte graphique gère habituellement se fait maintenant par la CPU, et donc pas en interaction avec le pilote graphique. Rappelez-vous que je ne suis pas un expert en virtualisation et je suppose que la couche de virtualisation pourrait affecter la question d'une autre manière.
Je crois que cela est lié à celui du nombre imbriqué HWND dans l'arborescence. Je ne connais pas les détails spécifiques, mais il y avait des restrictions imposées à HWNDs imbriquées avec 64bit. Les temps que je l'ai vu se produire, je travaille autour de lui en se laissant glisser de la vue plein thème de base (ou aéro), aux fenêtres classiques. À ce stade, les problèmes disparaissent.
Essayez de passer au classique, et si cela résout, voyez si vous pouvez réduire le nombre de HWNDs imbriqués.