![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Здравствуйте. Следующая задача:
Создайте приложение, в котором можно рисовать прямоугольники мышью прямо на форме, при перемещении мыши с нажатой левой кнопкой должен прорисовываться прямоугольник и как резиновый изменяться то в большую, то в меньшую сторону, при отпускании кнопки мыши прямоугольник должен фиксироваться на форме. Перемещение мыши с не нажатой кнопкой не должно приводить к рисованию. Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = 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 }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssLeft in Shift then Canvas.MoveTo(X,Y);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
Canvas.Brush.Color:=Color;
Canvas.FillRect(Canvas.ClipRect);
Canvas.Rectangle(Canvas.PenPos.X,Canvas.PenPos.Y,X,Y);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then Canvas.Rectangle(Canvas.PenPos.X,Canvas.PenPos.Y,X,Y);
end;
end.Как этого избежать? Возможно, что в процедуре FillRect нужно другие параметры указать? Если да, то какие? |
|
#2
|
||||
|
||||
|
Надо сохранять созданные прямоугольники (координаты) и при перерисовке - все сохраненные рисовать по новой.
|
|
#3
|
|||
|
|||
|
Как-то слишком объемно получится, не? Может можно как-то проще?
|
|
#4
|
||||
|
||||
|
А чего объемного? Хранить - динамический массив пар координат, 4 числа - 16 байт. Даже если нарисовать 1000 прямоугольников (а это крыша съедет рисовать руками) получится дополнительно 16 кб памяти.
Можно конечно запоминать предыдущую картинку. То есть рисовать прямоугольники не только на форму, но и в битмап в памяти, при рисовании новых прямоугольников обновлять экран с этого битмапа, а не FillRect'ом. При большом числе прямоугольников это будет и лучше по памяти, и по скорости. Но руками такого количества прямоугольников не нарисовать. |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Drodis (13.05.2013)
| ||
|
#5
|
|||
|
|||
|
Надо примерно так
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
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
MovedCanvas:TCanvas;
MovedPoint1,MovedPoint2:TPoint;
procedure DrawRectangle();
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DrawRectangle();
begin
if MovedCanvas = Nil then Exit;
with MovedCanvas do begin
Pen.Color:= clRed; // можно другой;
Pen.Mode := pmXor; // а вот это важно!;
MoveTo(MovedPoint1.X,MovedPoint1.Y);
LineTo(MovedPoint1.X,MovedPoint2.Y);
LineTo(MovedPoint2.X,MovedPoint2.Y);
LineTo(MovedPoint2.X,MovedPoint1.Y);
LineTo(MovedPoint1.X,MovedPoint1.Y);
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if not (ssLeft in Shift) then Exit;
MovedCanvas := Canvas;
MovedPoint1.X:=X;
MovedPoint1.Y:=Y;
MovedPoint2.X:=X;
MovedPoint2.Y:=Y;
DrawRectangle(true);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if MovedCanvas = Nil then Exit;
DrawRectangle(true);
MovedPoint2.X:=X;
MovedPoint2.Y:=Y;
DrawRectangle(true);
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if MovedCanvas = Nil then Exit;
DrawRectangle(true);
MovedCanvas := nil;
// а вот тут можно что нибудь нарисовать
Canvas.Pen.Color := clBlack;
Canvas.Pen.Mode := pmCopy;
Canvas.Brush.Color:=clYellow;
//Canvas.FillRect(Canvas.ClipRect); вот это не нужно
Canvas.Rectangle(MovedPoint1.X,MovedPoint1.Y,MovedPoint2.X,MovedPoint2.Y);
end;
end. |
| Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
Drodis (14.05.2013)
| ||