2012-02-03 19 views
6

GDI +を使用して画面に描画するカスタム(winforms)コンポーネントがいくつかあります。 ダブルバッファリングによってアプリケーションが強制終了される原因は何ですか?

が再描画のちらつきを防止するために、私はダブルバッファリングを有効にすることを決めたので、私は私のコンストラクタに行を追加しました:

このコンポーネント(ColourWheel)上で正常に動作
public ColourWheel() 
{ 
    InitializeComponent(); 
    this.DoubleBuffered = true; 
} 

  1. 私は上のコンポーネントでフォームを実行しようとすると、私が手に:私は私の他の2つ(同様に構造化された)のコンポーネントのいずれかのコンストラクタに同じ行を追加すると、私は奇妙な症状のカップルを取得します引数例外はApplication.Run(new Form());です。
  2. デザインモードに切り替えると、パラメータを使用して処理されない例外が発生したコンポーネントに関するエラーが発生します。私が1またはそれらの全てにダブルバッファリングを有効にするかどうかは関係していないよう

が、それはまだ他の人をColourWheelに動作しますが、ありません。

記録のために、いくつかの他の方法も試しました。doublebuffering技術

ダブルバッファリングが1つのコンポーネント上で動作する原因になる可能性はありますか?


EDIT:ここでは、実行時の症状から、例外の詳細があります:

System.ArgumentExceptionの未処理メッセージ=パラメータが有効 ではありませんでした。ソース= System.DrawingのStackTrace:System.WindowsでSystem.Drawing.BufferedGraphics.Render() でSystem.Drawing.BufferedGraphics.RenderInternalでSystem.Drawing.Graphics.GetHdc() (HandleRef refTargetDC、BufferedGraphicsバッファ) でSystem.Windows.Formsで.Forms.Control.WmPaint System.Windows.Forms.Control.WndProc(メッセージ& M)System.Windows.Forms.ScrollableControl.WndProcで (メッセージ& M)に(メッセージ& M) .UserControl.WndProc(メッセージ& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(メッセージ&m) at System.Windows.Forms.Co System.Windows.Forms.UnsafeNativeMethods.DispatchMessageWでntrol.ControlNativeWindow.WndProc System.Windows.Forms.NativeWindow.DebuggableCallbackで(メッセージ& M) (のIntPtr hWndは、MSGのInt32、のIntPtr WPARAM、LPARAMのIntPtr) (MSG & MSG) System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop System.Windows.Forms.Application.ThreadContext.RunMessageLoopInnerで(のIntPtr dwComponentID、のInt32理由、のInt32 pvLoopData) (のInt32 で理由、ApplicationContextコンテキスト) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 理由、ApplicationContextコンテキスト) TestForm.Programのystem.Windows.Forms.Application.Run(フォームmainForm) 。System.AppDomain._nExecuteAssembly(RuntimeAssemblyアセンブリ、String [] args)のD:¥Documents and Settings¥Tom Wright¥My Documents¥Visual Studioのメイン()( 2010 \ Projects \ ColourPicker \ TestForm \ Program.cs:line 18 ) System.ThreadingでSystem.Threading.ThreadHelper.ThreadStart_Context(オブジェクトの状態) でSystem.AppDomain.ExecuteAssembly(文字列assemblyFile、証拠assemblySecurity、文字列[]引数)Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() で で(ExecutionContext executionContext、ContextCallbackコールバック、オブジェクト状態) ignoreSyncCtx) System.Threading.ThreadHelper.ThreadStartで()のInnerException:


EDIT 2:

private void ValueSlider_Paint(object sender, PaintEventArgs e) 
{ 
     using (Graphics g = e.Graphics) 
     { 
      g.DrawImage(this.gradientImage, new Rectangle(0, 0, paintArea.Width, paintArea.Height)); 
      if (this.showmarker) 
      { 
       ColourHandler.HSV alt = ColourHandler.RGBtoHSV(new ColourHandler.RGB(this.SelectedColour.R, this.SelectedColour.G, this.SelectedColour.B)); 
       alt.Saturation = 0; 
       alt.value = 255 - alt.value; 
       using (Pen pen = new Pen(ColourHandler.HSVtoColour(alt))) 
       { 
        pen.Width = (float)MARKERWIDTH; 
        g.DrawRectangle(pen, 0 - pen.Width, this.brightnessPoint.Y - MARKERWIDTH, this.paintArea.Width + (pen.Width * 2), MARKERWIDTH * 2); 
       } 
      } 
     } 
} 
のOnPaintハンドラの問題を引き起こしている二つの成分の一方(より複雑な)から
+0

例外を通知してください。 – roken

+1

@rokenすべてあなたの友人。 –

+0

問題のコントロールでOnPaint()をオーバーライドしていますか?もしそうなら、それはどのように見えますか? – roken

答えて

8

Paintイベント中に貸し出されたGraphicsオブジェクトを処分することは想定されていません。それはあなたのusingブロックが不適切にブロックするものです。

症状が次回Paintイベント火災は、あなたが戻って同じGraphicsオブジェクトを取得することはありませんが、それはもはやにバインドされているメモリ内のあなたのスタックトレースに見られるようGraphics.GetHdc()が失敗する原因HDC、。

  1. それは(CS_OWNDCウィンドウスタイルが設定されている場合、それは、シングルバッファリングでも可能ですが、これは、非常に可能性の高いダブルバッファリングの場合である)の単一Paintイベントをoutlivesいる可能性があります。

  2. Paintイベントのハンドラは複数存在することがあります。

ので、イベントハンドラはGraphicsオブジェクト上Disposeを呼び出したり、usingブロックがそうすることを許してはなりません。代わりに、Paintイベントの処理が完了した後、.NETフレームワークが適切にリソースをクリーンアップします。

+1

これは1年以上働いていて、ユーザーコントロールクラスを独自のファイルに移動したときにエラーOPを投げ始めました。あなたが何を提案したか - C#は時々本当に奇妙なことがあります! –

1

別のマシンでこれをテストして、自分のコンピュータであるかどうかを確認する必要があります。ほとんどの場合、これはダブルバッファリングの結果として起こるべきではありませんが、ペイントイベントに含めてはいけない要素を破棄しているかどうかを確認してください。

+2

'Paint'イベント中にあなたに与えられた' Graphics'オブジェクトを処分するはずがないと思います。 –

+0

@benが正しいです。 'g'で 'using'をしないでください。これは、そのスコープを終了するときにGraphicsオブジェクトを破棄しますが、そのオブジェクトの所有者ではありません。 –

+0

ありがとうございました。私は '(Graphics g = e.Graphics){}'を使っていました。これを削除することが鍵でした。 –

関連する問題