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;

这是它的样子: 在此处输入图像描述

使用来自http://www.progdigy.com的GDIPlus 库和 Delphi 2010。

4

1 回答 1

6

InvalidateRect命令与 GDI+ 无关。这是一个命令,告诉操作系统窗口的某个部分是无效的,应该重新绘制。当操作系统下一次决定重新绘制该窗口时,程序可以询问操作系统需要绘制多少窗口。

您的代码正在调用InvalidateRect,然后它在窗口的同一部分上进行绘制。但是,该窗口仍然无效,因此操作系统会要求您的程序稍后在您下一次处理wm_Paint消息时重新绘制该区域。

我不知道您为什么希望您的图像看起来有任何不同,这与使滚动框无效无关。看起来你点击了角色的眼睛,然后顺时针向右拖动鼠标。

在每次鼠标移动时,您都会从原始品脱到当前鼠标位置绘制一条新线。您直接在当前显示的位图上绘制线条,然后要求图像控件重绘自身。它服从并绘制位图——您刚刚添加了另一行的位图。

我怀疑您打算发生的情况是,每次鼠标移动都会导致一条黑线出现在原本干净的图像上。InvalidateRect对此无济于事。您需要在前一行位置重新绘制原始图像,然后绘制新行。InvalidateRect不能帮助您“撤消”先前的图形操作。它只是告诉操作系统某个窗口的某个部分应该在某个时候重新绘制。它没有说明这些无效像素应该用什么颜色重新绘制。这wm_Paint就是为了。

于 2012-04-11T20:46:30.840 回答