我有一个Canvas,我想像MS Paint那样绘制它。
我尝试过以下方法,但没有成功:
(1)
Canvas.OnMouseDown
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
//Draw something (Lets say a rect for example*)
Image1.Canvas.Rectangle(x,y,x+4,y+4);
end;
(2)
我尝试了Canvas.OnMouseDown和Canvas.OnMouseUp的组合,如本网站的示例所示:
http://www.delphipages.com/forum/showthread.php?t=142153
(3)
GetAsyncKeyState:
http://msdn.microsoft.com/en-us/library/ms646293%28VS.85%29.aspx检测鼠标按下
(4)
Mouse.IsDraging功能。
我尝试过的上述方法仍然无法取得任何成功。
每次当我想拖动光标并绘制它时,只需将1 Rect *放在我第一次点击的位置,我该如何逐渐绘制它?
答案 0 :(得分:6)
您需要跟踪是否要拖动鼠标(左按钮已关闭),保存起点,并在OnMouseUp
事件中绘制您的线。 (这不会完全按照您的意愿行事,因为它不会显示您的线条的显示位置,也不会清除您之前绘制的任何线条。您需要跟踪这些线条。 OnMouseMove
。但它应该让你开始。)
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Vcl.Graphics,
Controls, Forms, Dialogs;
type
TForm2 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
Drawing: Boolean;
mX, mY: Integer;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if [ssLeft] = Shift then
begin
Drawing := True;
mX := X;
mY := Y;
end;
end;
procedure TForm2.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Drawing and not (ssLeft in Shift) then // Left button released
begin
Canvas.MoveTo(mX, mY);
Canvas.LineTo(X, Y);
Drawing := False;
end;
end;
end.
答案 1 :(得分:3)
在MouseDown中,设置一个布尔值来表示它的向下并存储鼠标的位置。 InMouseMove如果鼠标从最后位置向下绘制到当前位置,则存储当前位置。 在MouseUp中重置布尔值
无论如何,一种方式。
答案 2 :(得分:2)
我这样做的方式是这样的:
var
Form1: TForm1;
IsDrawing: Boolean; // flag to determine if drawing or not
implementation
{$R *.dfm}
procedure DoPaint(ACanvas: TCanvas; X, Y: Integer; AColor: TColor;
ASize: Integer; AStyle: TPenStyle; Persistent: Boolean);
begin
with ACanvas do
begin
Pen.Color := AColor;
Pen.Style := AStyle;
Pen.Width := ASize;
if not Persistent then
MoveTo(X, Y);
LineTo(X, Y);
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case Button of
mbLeft:
begin
IsDrawing := True;
DoPaint(Form1.Canvas, X, Y, clBlue, 10, psSolid, False);
end;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (GetAsyncKeyState(VK_LBUTTON) <> 0) and
(IsDrawing) then
begin
DoPaint(Form1.Canvas, X, Y, clBlue, 10, psSolid, True);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsDrawing := False;
end;
这里要注意的两件事是MouseMove事件和GetAsyncKeyState。您使用了MouseDown和MouseUp,但是继续绘图需要MouseMove。
MouseMove事件将跟踪画布上的移动。显然你只需要画画,如果你开始。要处理这个问题,你可以设置一个简单的布尔标志,正如我在{0}上演示的那样 - 当你在画布上使用MouseDown时设置为True,当你在画布上设置MouseUp时设置为False。
使用IsDrawing
标记和IsDrawing
,您现在可以确定是否继续在画布上绘图。如MSDN文章中所述,您需要注意GetAsyncKeyState
仅跟踪物理按钮布局,而不是逻辑按钮布局:
GetAsyncKeyState函数适用于鼠标按钮。但是,它 检查物理鼠标按钮的状态,而不是逻辑上的 物理按钮映射到的鼠标按钮。例如, 调用GetAsyncKeyState(VK_LBUTTON)始终返回的状态 离开物理鼠标按钮,无论它是否映射到 左或右逻辑鼠标按钮。您可以确定系统 物理鼠标按钮到逻辑鼠标按钮的当前映射 调用GetSystemMetrics(SM_SWAPBUTTON)。
如果已交换鼠标按钮,则返回TRUE。
答案 3 :(得分:0)
如果您需要类似代码的行:
procedure TForm1.img1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
(Sender as TImage).Canvas.MoveTo(X, Y);
end;
procedure TForm1.img1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
(Sender as TImage).Canvas.LineTo(X, Y);
end;
或者,如果您需要免费使用抽奖:
procedure TForm1.img1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
with (Sender as TImage) do begin
if Shift = [ssLeft] then
Canvas.LineTo(X, Y);
Canvas.MoveTo(X, Y);
end;
end;