3

私が見つけることができるすべての GDIPlus デモ コードは、無効化なしで描画されます。では、TScrollbox で TImage を使用して MouseMove で描画するときに、GDIPlus API で四角形を無効にするにはどうすればよいでしょうか?

function NormalizeRect ( R: TRect ): TRect;
begin

  // This routine normalizes a rectangle. It makes sure that the Left,Top
  // coords are always above and to the left of the Bottom,Right coords.

  with R do
  begin

    if Left > Right then
      if Top > Bottom then
        Result := Rect ( Right, Bottom, Left, Top )
      else
        Result := Rect ( Right, Top, Left, Bottom )
    else if Top > Bottom then
      Result := Rect ( Left, Bottom, Right, Top )
    else
      Result := Rect ( Left, Top, Right, Bottom );

  end;

end;

procedure TFormMain.Image1MouseDown ( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer );
begin
  if Line1.Down then
  begin
    GPPointStart := MakePoint ( X, Y );
  end;
end;

procedure TFormMain.Image1MouseMove ( Sender: TObject; Shift: TShiftState; X, Y: Integer );
var
  graphics: TGPGraphics;
  pen: TGPPen;
  SolidBrush: TGPSolidBrush;
  rgbTriple: windows.RGBTRIPLE;
  iRect: TRect;
begin  
  if Line1.Down then
  begin
    if ssLeft in Shift then
    begin
      iRect := NormalizeRect ( Rect ( X, Y, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height ) );
      InvalidateRect ( ScrollBox1.Handle, @iRect, TRUE );
      graphics := TGPGraphics.Create ( Image1.Picture.Bitmap.Canvas.Handle );
      graphics.Flush ( FlushIntentionFlush );
      GPPointEnd := MakePoint ( X, Y );
      rgbTriple := ColorToRGBTriple ( ColorBox1.Selected );
      pen := TGPPen.Create ( MakeColor ( StrToInt ( Alpha1.Text ), rgbTriple.rgbtRed, rgbTriple.rgbtGreen, rgbTriple.rgbtBlue )
        );
      pen.SetWidth ( StrToInt ( Size1.Text ) );
      graphics.DrawLine ( pen, GPPointStart.X, GPPointStart.Y, GPPointEnd.X, GPPointEnd.Y );
      graphics.Free;
      Image1.Refresh;
    end;
   end;
end;

これは次のようになります。 ここに画像の説明を入力

Delphi 2010でhttp://www.progdigy.comのGDIPlus ライブラリを使用します。

4

1 に答える 1

6

このInvalidateRectコマンドは GDI+ とは関係ありません。これは、ウィンドウの特定の部分が無効であり、再描画する必要があることを OS に伝えるコマンドです。次に OS がそのウィンドウを再描画することを決定したとき、プログラムは OS にウィンドウのどれだけを描画する必要があるかを尋ねることができます。

あなたのコードは を呼び出しInvalidateRectており、ウィンドウの同じ部分をペイントしています。ただし、ウィンドウはまだ無効化されているため、後でメッセージを処理するときに、OS はプログラムにその領域を再描画するように要求しwm_Paintます。

画像の外観が異なると予想される理由がわかりません。スクロールボックスを無効にすることとは関係ありません。キャラクターの目をクリックし、マウスを下と右、時計回りにドラッグしたように見えます。

マウスを動かすたびに、元のパイントから現在のマウス位置まで新しい線を引きます。現在表示されているビットマップに直接線を描画し、イメージ コントロールに再描画を依頼します。それはビットマップに従い、描画します — そのビットマップに別の行を追加したばかりです。

あなたが意図したのは、マウスを動かすたびに、汚れていない画像の上に1本の黒い線が表示されることだったと思います. InvalidateRectそれは役に立ちません。前の行の位置に元の画像を再描画し、新しい行を描画する必要があります。InvalidateRect以前のグラフィック操作を「元に戻す」のには役立ちません。ウィンドウの特定の部分をいつか再描画する必要があることをOSに伝えるだけです。無効化されたピクセルをどの色で再描画するかについては述べていません。それwm_Paintがそのためです。

于 2012-04-11T20:46:30.840 に答える