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 Rect *を配置するだけですが、徐々に描画するにはどうすればよいですか?

4

4 に答える 4

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.
于 2012-04-26T22:19:28.690 に答える
3

MouseDownで、ブール値を設定してダウンと言い、マウスの位置を保存します。InMouseMoveマウスが最後の位置から現在の位置に下向きに描画されている場合は、現在の位置を保存します。MouseUpでブール値をリセットします

とにかく、一方通行。

于 2012-04-26T22:13:45.590 に答える
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;

ここで注意すべき2つのことは、MouseMoveイベントとGetAsyncKeyStateです。MouseDownとMouseUpを使用しましたが、描画を続行するために必要なMouseMoveです。

MouseMoveイベントは、キャンバス上の動きを追跡します。明らかに、あなたが最初から描く必要があるのはあなただけです。これを処理するために、私が使用して示したように単純なブールフラグを設定できますIsDrawing-これは、キャンバス上でMouseDownを実行する場合はTrueに設定され、キャンバス上でMouseUpを実行する場合はFalseに設定されます。

IsDrawingフラグを一緒に使用するGetAsyncKeyStateと、キャンバスに描画を続行するかどうかを決定できるようになりました。GetAsyncKeyStateMSDNの記事で説明されているように、論理的なボタンレイアウトではなく、物理的なボタンレイアウトのみを追跡することに注意する必要があります。

GetAsyncKeyState関数は、マウスボタンで機能します。ただし、物理ボタンがマップされている論理マウスボタンではなく、物理マウスボタンの状態をチェックします。たとえば、GetAsyncKeyState(VK_LBUTTON)を呼び出すと、論理マウスの左ボタンと右ボタンのどちらにマップされているかに関係なく、常に左の物理マウスボタンの状態が返されます。GetSystemMetrics(SM_SWAPBUTTON)を呼び出すことにより、物理マウスボタンから論理マウスボタンへのシステムの現在のマッピングを判別できます。

これは、マウスボタンが交換された場合にTRUEを返します。

于 2012-04-27T10:39:12.940 に答える
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;
于 2012-04-29T19:55:46.113 に答える