2012-04-26 110 views
0

我有一个画布,我想像MS画图一样绘制它。在画布上绘图 - 如何检查鼠标左键是否关闭?

我曾尝试以下方法,但没有成功:

(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个矩形*,我该如何让它逐步绘制?

+1

为什么你会期望它做任何其他的绘图?您显示的唯一代码是当您首次按下鼠标按钮时绘制单个矩形的位置。 'GetAsyncKeyState'确实会告诉你鼠标按钮是否关闭。这就是你问的问题的答案。但你问错了问题。如果你想知道如何用钢笔画一个表面,那么问一下,而不是如何检测鼠标按钮是否被按下,因为只知道你显然没有得到你想要的东西。 – 2012-04-27 15:25:36

+0

Rob是对的,问题标题没有描述你写的实际问题。您应该更具体地了解您实际要求的内容。 – 2012-04-27 16:39:35

回答

3

在MouseDown中,设置一个布尔值来表示它的下降并存储鼠标的位置。 InMouseMove如果鼠标关闭,从上一个位置绘制到当前位置,存储当前位置。 在MouseUp中重置布尔值

反正是一种方法。

+0

我只是想说完全一样的东西。 +1。 – Pateman 2012-04-26 22:14:22

6

你需要跟踪你是否在拖动鼠标(左键是down),保存起点的位置,并在事件中绘制你的线。 (这不会完全达到你想要的效果,因为它不会显示你的线条将出现在哪里,也不会清除你以前绘制的任何线条,你需要跟踪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. 
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事件将跟踪画布上的移动。显然你只需要画画,如果你开始。为了解决这个问题,你可以设置一个简单的布尔标志,正如我已经演示的IsDrawing - 当你在画布上MouseDown时,它被设置为True,当你在画布上MouseUp时设置为False。

使用IsDrawing标志以及GetAsyncKeyState您现在可以确定是否继续在画布上绘图。由于MSDN文章中介绍,你需要知道GetAsyncKeyState只跟踪物理按键布局,而不是逻辑的:

的GetAsyncKeyState功能可与鼠标按钮。但是,它 检查物理鼠标按钮的状态,而不检查物理按钮映射到的逻辑 鼠标按钮。例如, 调用GetAsyncKeyState(VK_LBUTTON)总是返回 左侧物理鼠标按钮的状态,无论它是否映射到 左侧或右侧的逻辑鼠标按钮。您可以通过调用GetSystemMetrics(SM_SWAPBUTTON) 来确定系统的 当前物理鼠标按钮到逻辑鼠标按钮的映射。

如果鼠标按钮已被交换,则返回TRUE。

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;