我可以找到的所有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。
答案 0 :(得分:6)
InvalidateRect
命令与GDI +无关。这是一个命令告诉操作系统窗口的某个部分是无效的,应该重新绘制。当操作系统下一步决定重新绘制该窗口时,程序可以询问操作系统需要绘制多少窗口。
您的代码正在调用InvalidateRect
,然后它正在绘制窗口的相同部分。但是,窗口仍然无效,因此当您下次处理wm_Paint
消息时,操作系统会要求您的程序重新绘制该区域。
我不知道为什么你会期望你的图像看起来有任何不同,它与使滚动框无效无关。看起来你点击了角色的眼睛,然后顺时针将鼠标向下拖动,向右拖动。
在每次鼠标移动时,您将从原始品脱到当前鼠标位置绘制一条新线。您直接在当前显示的位图上绘制线条,然后您要求图像控件重绘自己。它服从并绘制位图 - 你刚刚添加了另一行的位图。
我怀疑你想要发生什么发生的事情是每次鼠标移动导致一条黑线出现在其他未被污染的图像上。 InvalidateRect
无济于事。您需要在上一个行位置上重绘原始图像,然后绘制新行。 InvalidateRect
无法帮助您“撤消”之前的图形操作。它只是告诉操作系统,窗口的某个部分应该在某个时候重新绘制。它没有说明那些无效像素应该用重新绘制的颜色。这就是wm_Paint
的用途。