64 ビット Vista では再描画の問題が発生するが、.NET WInForms では 32 ビットでは発生しない原因は何ですか?

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

質問

これは、x86 にコンパイルするときだけでなく、Any CPU 用にコンパイルするときにも発生します。GUI のセクションは、サイズを変更しない限り再描画されません。たとえば、メイン フォームが最大化されている場合、一部のコントロールはそれに伴ってサイズ変更されません。また、再描画されず、以前に存在していたものを表示するセクションがあるものもあります。

これは、XP と Vista の両方の 32 ビット マシンでは正常に動作しますが、64 ビット Vista (テスト用の x64 XP がない) では再描画が正しく動作しません。

どこから追跡を開始すればよいか考えている人はいますか?

編集:これは 2 台の別々のマシンで発生しますが、少なくとも現在使用しているマシンには NVidia の最新ドライバーがインストールされています。

編集2:64 ビット マシン上で 32 ビット XP 仮想マシンを実行すると、アプリケーションでは VM での再描画の問題が発生しません。

編集3:これはドライバーの問題である可能性がありますが、ドライバーが問題を修正するかどうか、いつ修正するかはわかりません。同僚は、自宅の ATI カードは NVidia よりも問題が少ないと言っていますが、私はここ数か月間ほぼ毎月ビデオ ドライバーを更新していますが、まだ解決されていないため、そのまま製品をリリースするわけにはいきません。そして、いつかドライバーのメーカーがこの問題を修正してくれるかもしれないとお客様に伝えてください。

どのようなことを避けるべきかについて何か洞察を持っている人はいますか?x86 としてコンパイルしており、すべてのコンポーネントは x86 です。テスト プロジェクトのどのコンポーネントでもこの問題を再現することはできないようです。また、ほとんどのコンポーネント フォーラムでこれらの問題を他の人が報告しているのを聞いたことがありません。そのため、これは私たちがやっている問題である可能性がかなり高いです。

役に立ちましたか?

解決

これ恐ろしく<のhref = "http://blogs.msdn.com/alejacma/archive/2008/11/20/controls-won-t-get-resized-once-the-nesting-hierarchy-のように聞こえます窓が-超える-特定-深さx64.aspxを」REL = "noreferrer">これで問題がを。

Windows上でウィンドウのサイズを変更するときは、典型的には、各ウィンドウがWM_SIZEメッセージを受信チェーンを取得し、順番にようにMoveWindow()を受け取り、その子にWM_SIZE(または類似)を呼び出します。私は、.NETは、カバーの下に同じことをしていることを確信してます。

x64では、Windowsは、このネストの深さを制限し、特定のポイント(12-15ネストされたウィンドウ)の後に、それだけでもうWM_SIZEメッセージを送信しません。この制限は、x86上に存在する表示されません。この制限は、Windowsのx64バージョンで実行されている両方のx86とx64のコードに影響を与えます。

異なるのx64インストールは異なる症状を示すと同じように

これは、年齢のために私たちをfoxed。上記のMSDNのブログ投稿は、いくつかの回避策を持っている - 私たちは、非同期的にウィンドウサイズを行うには、二次スレッドを使用して終了、これはかなりきちんと問題を解決した。

他のヒント

あなたがWindowsフォームを使用している場合は、

は、64ビットWindows上で営巣制限の問題をどうすることもできます。

ここで、

詳細: http://www.feedghost.com/Blogs/ BlogEntry.aspx?ENTRYID = 17829

要約すると...

MSソースから、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);

そしてMSDNから:

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

  

「少し調査は、WindowsがWM_SIZEの送信を停止したことを示しました   それはいくつかの特定のネストに到達したとき   レベル。言い換えれば、それは送信されません   あなたの子ウィンドウにWM_SIZEあなたの場合   あなたが処理するときにそれらのサイズを変更してみてください   親のものでWM_SIZE。によって   USERもの/アップデート/ seriviceに   最大ネスティングレベルでパック   それはWM_SIZE月を伝播停止します   でも、多くの15から31に変わると   高い(効果的に到達不能)の下で   最新のXPの32ビット/ SP2ます。

     XP x64およびまだいくつかの類似した醜いものの下に

しかし、それはまだあまりにも少ないです   いくつかの下で他のメッセージに起こります   ビスタのビルドます。

     

だから、それは確かWindowsのバグである。 "

あなたのコントロール階層(より理想的なソリューション)の深さを減らすか、あるいは次のように、あなたが使用するシステムのもののそれぞれからのコントロールを「固定」導き出す次のいずれか:

この次の2つの選択肢があり

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 );
    }
  }
}

と思うのがこの問題は再描画の問題です。でも存在する可能性があること、微妙なwindowsメールを差64ビットのある露この問題がコードです。

できる実験をするには、次のようにします。

  1. 追加タイマーアプリケーションに対応し、
  2. のイベントハンドラを呼flakyControl.Update()

私はタイマーの設定も長のインの5秒です。そして実際にアプリを立ち上げにWin64とを確認してくださいこの問題です。その場合その原因は一つの制御が必要となる場合がありシグナル伝達するか無効となります。

いずカスタムコントロール。体系的に追加-更新を呼べてのオーバーライド法は、イベントハンドラのコードです。れんの修正のしょうがわのバグを実現する

MSDN で説明されている BeginInvoke() ソリューションを使用する場合 ブログ OnSizeChanged() をオーバーライドするコントロールの子のドッキングを必ず無効にしてください。Dock = DockStyle.Fill だったため、修正を機能させるには DockStyle.None に変更する必要がありました。

私にはディスプレイドライバの問題のようですね...

最新のドライバに更新してみて、それが問題を修正するかどうかを確認? 64/32ビットの差は、おそらく赤ニシンです...

私はゴードンに同意するだろう。私は、ブランドの新しい64ビットマシンが32ビットの下で罰金に見えたプログラムで表示の問題があった問題を見てきましたが、64ビットマシン上で奇妙な問題を示すであろう。最新のものに更新/推奨ドライバはほとんどの場合、問題を修正します。

あなたは問題なく、仮想OS上でプログラムを実行することができるという事実は、(少なくとものVirtualPCで)グラフィックスカードがエミュレートされているので、それは、ドライバの問題であることを示唆しています。これは、グラフィックスカードが正常に扱うだろういくつかのものは、今CPUによって行われ、したがって、グラフィックドライバと相互作用していないことを意味します。私は、仮想化の専門家ではないことを断っておくが、私は、仮想化層が他の方法で問題に影響を与える可能性があると仮定します。

私は、これはHWNDのは、ツリー内のネストされた数に関係していると信じています。私は具体的な詳細を知らないが、64ビットとネストされたのHWNDに配置され、いくつかの制限がありました。私はそれが起こる見てきた時間が、私は窓classicに、フルVistaの基本(またはエアロ)のテーマからバックドロップして、それを回避します。この時点で、問題が消えます。

古典的に切り替えてみてください、それはそれを解決する場合は、ネストされたのHWNDの数を減らすことができるかどうか、見ています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top