4

次のコード スニペットがあるとします。

procedure TPicture.PaintLine(_Canvas: TCanvas; _Left, _Top, _Right, _Bottom: Integer);
begin
  IntersectClipRect(_Canvas.Handle, _Left, _Top, _Right, _Bottom);
  try
    _Canvas.MoveTo(_Left - 10, _Top - 10);
    _Canvas.LineTo(_Right + 10, _Bottom + 10);
    // (This is an example only, the actual drawing is much more complex.)
  finally
    SelectClipRgn(_Canvas.Handle, 0); // This does too much
  end;
end;

IntersectClipRect の呼び出しによって影響を受けたクリッピングを元に戻したいので、以前にアクティブだったクリッピングが再びアクティブになります。上記のコードでは、クリッピングを完全にオフにする SelectClipRgn(...,0) によってこれが行われます。これは機能しますが、その後クリッピングがアクティブにならないため、上記の後に実行される描画は、ペイントされるべきではない領域にペイントされます。

では、IntersectClipRect の効果だけを元に戻す正しい方法は何ですか?

EDIT:Sertacからのコメントを理解した後、不要なCreateRectRgnおよびDeleteObjectコードを削除して、後で遭遇する可能性のある他の人が質問を読みやすくしました。

4

2 に答える 2

7

DC の状態を保存および復元できます。

var
  //  RGN: HRGN;
  SavedDC: Integer;
begin
//  RGN := CreateRectRgn(_Left, _Top, _Right, _Bottom);
  SavedDC := SaveDC(_Canvas.Handle);
  try
    IntersectClipRect(_Canvas.Handle, _Left, _Top, _Right, _Bottom);
    _Canvas.MoveTo(_Left - 10, _Top - 10);
    _Canvas.LineTo(_Right + 10, _Bottom + 10);
    // (This is an example only, the actual drawing is much more complex.)
  finally
    RestoreDC(_Canvas.Handle, SavedDC);
  end;
  ...
于 2013-09-03T16:06:10.460 に答える
3

IIRC、最初に を使用して現在のクリップ領域を保存しGetClipRgn、完了したらSelectClipRgn、保存された領域を再度保存します。

あなたのコードを見ると、次の理由からSelectClipRgn、それで十分なはずです。RGN

IntersectClipRect 関数は、現在のクリッピング領域と指定された四角形の交点から新しいクリッピング領域を作成します。

于 2013-09-03T15:37:13.520 に答える