Ce qui pourrait causer des problèmes de rafraîchissement sur vista 64 bits, mais pas en 32 bits dans .NET WinForms?

StackOverflow https://stackoverflow.com/questions/386826

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.

Était-ce utile?

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:

http: //social.msdn.microsoft.com/forums/en-US/windowsuidevelopment/thread/25181bd5-394d-4b94-a6ef-06e3e4287527/

  

"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.

  1. Ajoutez une minuterie à votre application.
  2. 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é.

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.

scroll top