在PaintBox上画线遇到的问题(27分)

  • 主题发起人 主题发起人 anndy1999
  • 开始时间 开始时间
A

anndy1999

Unregistered / Unconfirmed
GUEST, unregistred user!
由于其他功能需要,我的这个PaintBox每秒钟要刷新一次(我在一个定时器的
TimeTimer事件调用了PaintBox.Invalidate,这个PaintBox的OnPaint事件中我有许多
画线的代码,多次设置如Pen.Mode,Pen.Color等。)

现在问题就是:
我在这个PaintBox上用鼠标拉动画线(采用pmNotXor的方式,要求Move也能看到线),遇到PaintBox刷新的时
刻这条线就不见了,

我曾想过这样处理,画线在另一个PaintBoxTemp上处理,但是没想到的是,当原来的
PaintBox在定时刷新时,这个新的PaintBoxTemp也在刷新,所以结果还是一样。

大家帮我想想解决办法,谢谢了先!!
 
你用鼠标拉动画线时是不是在OnMousemove上画线?是的话,当然会有问题了,
建议在OnMousemove中将要画线的点存在一个全局变量中,在OnMouseMove的最后也是调用PaintBox.Invalidate,然后将用鼠标拉动画线的代码放到PaintBox的OnPaint的最后,
并在OnMousedown设置鼠标拉动画线标识,在OnMouseUp取消鼠标拉动画线标识
 
其实我现在的方法就和你的差不多。
先在OnMousedown设了画线标志,并记录了点击点的坐标。
再在OnMouseMove过程画线(采用pmNotXor),然后在OnMouseUp时先取消画线标志接着在此调用PaintBox.invaliate,因为我要将画出来的线再画在PaintBox的OnPaint中(这样才可以保留下来)。
但这样子就是遇到PaintBox.invalidate时,OnMouseMove过程中拉动的线就看不见。
 
也许你没看明白我的意思吧,我是说画线的代码不要放在OnMouseMove过程中,
下面我简单写了一个画线程序,你看一下吧

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;

type
PMyLine = ^TMyLine;
TMyLine = record
P1: TPoint;
P2: TPoint;
end;

TForm1 = class(TForm)
PaintBox1: TPaintBox;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
LineList: TList;
CurP1, CurP2: TPoint;
MDown: Boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
LineList := TList.Create;
MDown := False;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
while LineList.Count <> 0 do
begin
Dispose(LineList[0]);
LineList.Delete(0);
end;
LineList.Free;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
i: Integer;
MyLine: PMyLine;
begin
PaintBox1.Canvas.Pen.Mode := pmBlack;
for i := 0 to LineList.Count - 1 do
begin
MyLine := LineList;
PaintBox1.Canvas.MoveTo(MyLine.P1.X, MyLine.P1.Y);
PaintBox1.Canvas.LineTo(MyLine.P2.X, MyLine.P2.Y);
end;

if MDown then
begin
PaintBox1.Canvas.Pen.Mode := pmNotXor;
PaintBox1.Canvas.MoveTo(CurP1.X, CurP1.Y);
PaintBox1.Canvas.LineTo(CurP2.X, CurP2.Y);
end;
end;

procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
MDown := True;

CurP1 := Point(X, Y);
CurP2 := Point(X, Y);
PaintBox1.Invalidate;
end;

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if MDown then
begin
CurP2 := Point(X, Y);
PaintBox1.Invalidate;
end;
end;

procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
MyLine: PMyLine;
begin
MDown := False;

CurP2 := Point(X, Y);
New(MyLine);
MyLine.P1 := CurP1;
MyLine.P2 := CurP2;
LineList.Add(MyLine);

PaintBox1.Invalidate;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
PaintBox1.Invalidate; //这个其实是没有必要的,PaintBox会自动重画
Timer1.Enabled := True;
end;

end.
 
你的答案确实可行,但到实际我的程序还要变动一下。我周一就回去试试。谢谢!
 
后退
顶部