2011-03-12 10 views
1

OnPaintメソッドで描画するときに1ピクセルを維持します。なぜか分からない。1ピクセル外に - OnPaint - System :: Drawing :: Rectangle rectangle = this-> ClientRectangle;

しかし、私はそれは数え切れないと私は確信していません!

1枚のパネルに1枚のラベルが貼られていますが、それらは正しくカウントされていると思います。私は豊富なトレースをしており、一度に1つずつステップしています絶対にすべて。

私はこれに関連しないいくつかのエラーを見つけました。そのためには明らかに価値がありました。

私は、次のコードは、ClientRectangleに1つの画素の境界線を作成しないことが判明しました: -

System::Drawing::Rectangle rectangle = this->ClientRectangle; 
    rectangle.Inflate(-1,-1); 
    e->Graphics->DrawRectangle(blackPen, rectangle); 

これまでのところは良い

が、すべてでなぜ-1?

とにかく、コードをステップ実行すると私の混乱が深まる。

Iは、(2試行錯誤や色分けによって発見された!)以下で離れて、この1つの画素の境界から矩形の内容全体を埋める: - だから、ClientRectangleが書き込み可能である

System::Drawing::Pen^ violetPen = gcnew System::Drawing::Pen(Brushes::Violet); 
    for(int y=2; y< e->ClipRectangle.Bottom-1; y++) 
    { 
     e->Graphics->DrawLine(violetPen, e->ClipRectangle.Left+2, y, 
      this->ClientRectangle.Right-2, y); 
    } 

領域へのインデックス付けは(1,1)から開始されます。
さて、これは枠なしでパネルで、MSDNによると、以下のようにClientRectangleがある: -

コントロールのクライアント領域がコントロールの境界で、マイナスなスクロールバーなどのクライアント以外の要素を、枠線、タイトルバー、およびメニューがあります。 クライアントの座標はコントロールのクライアント領域の左上隅からの相対値なので、このプロパティから返される矩形の左上隅の座標は(0,0)です。このプロパティを使用して、コントロールのサーフェス上に描画するなどのタスクのコントロールのクライアント領域のサイズと座標を取得できます。

今、私のコントロールには、スクロールバー、ボーダー、タイトルバー、メニューを持っていないので、私は、インデックスは、私はから数えてきたところである(0,0)に開始すべきだと思います。

Panel

Panelコントロールは、任意の境界線なしでデフォルトで表示されます。

私はここで何が欠けているのか理解してもらえますか?

答えて

1

実際、の右下ではなく、問題点が実際にはの角のの角ですか? Windowsによって内部的に使用RECT structureが制御

座標の画素(右、下)が矩形のすぐ外側にあることを意味し、排他あります。あなたが示してきたように、1つのピクセルによってクライアント領域に対応する矩形を収縮させる

は、この問題を解決します。

+0

多くのGDI操作はこのようなものです。たとえば、MoveTo(0,0); LineTo(5,0)はピクセル(0,0)、(1,0)、...、(4.0)を塗りつぶします。それは満たされません(5,0)。 –

+0

@David:そうです。私の心の質問は、.NET Frameworkが 'Rectangle'構造体を返す前に' Inflate(-1、-1) '演算を内部的に行ったかどうかです。時には、このような小さなものが優雅に扱われ、抽象化が漏れてしまうこともあります。 –

+0

WinFormsのユーザーはGDIのような低レベルのWin32 APIにアクセスすることが予想されるので、正しい抽象化を "抽象リーク"にすることが望ましいと思います。もしそうしていなければ、あなたのコードはある抽象と他の抽象との間で永遠に切り替える必要があります。災害のレシピ! –

関連する問題