1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
| unit GrabHandleMainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ExtCtrls;
type
TGrapSide = (gsNone, gsTop, gsLeft, gsBottom, gsRight);
TGrab = class(TObject)
private
FRect: TRect;
FDown: Boolean;
FSide: TGrapSide;
public
constructor Create();
function EstimateSide(const P: TPoint; E: Integer): TGrapSide;
property SelectionRect: TRect read FRect;
property SelectionTopLeft: TPoint read FRect.TopLeft write FRect.TopLeft;
property SelectionBottomRight: TPoint read FRect.BottomRight write FRect.BottomRight;
property SelectionLeft: Integer read FRect.Left write FRect.Left;
property SelectionRight: Integer read FRect.Right write FRect.Right;
property SelectionTop: Integer read FRect.Top write FRect.Top;
property SelectionBottom: Integer read FRect.Bottom write FRect.Bottom;
property Down: Boolean read FDown write FDown;
property Side: TGrapSide read FSide write FSide;
end;
type
TForm1 = class(TForm)
PaintBoxImage: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBoxImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure PaintBoxImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure PaintBoxImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure PaintBoxImagePaint(Sender: TObject);
public
{ Déclarations publiques }
FGrab: TGrab;
FBitmap: TBitmap;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FGrab := TGrab.Create();
FBitmap := TBitmap.Create();
FBitmap.LoadFromFile('SPAM.BMP');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(FBitmap);
FreeAndNil(FGrab);
end;
procedure TForm1.PaintBoxImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (FGrab.SelectionTopLeft.X >= 0) and (FGrab.SelectionTopLeft.Y >= 0) then
begin
FGrab.Side := FGrab.EstimateSide(Point(X, Y), 1);
PaintBoxImage.Cursor := crHandPoint;
end
else
begin
FGrab.Down := True;
FGrab.SelectionTopLeft := Point(X, Y);
end;
end;
procedure TForm1.PaintBoxImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (FGrab.SelectionTopLeft.X >= 0) and (FGrab.SelectionTopLeft.Y >= 0) then
begin
if FGrab.Down then
begin
FGrab.SelectionBottomRight := Point(X, Y);
PaintBoxImage.Invalidate;
end
else
begin
if FGrab.Side = gsNone then
begin
case FGrab.EstimateSide(Point(X, Y), 1) of
gsTop, gsBottom: PaintBoxImage.Cursor := crSizeNS;
gsLeft, gsRight: PaintBoxImage.Cursor := crSizeWE;
else
PaintBoxImage.Cursor := crDefault;
end;
end
else
begin
case FGrab.Side of
gsTop : if (Y < FGrab.SelectionBottom) and (Y > 0) then FGrab.SelectionTop := Y;
gsBottom : if (Y > FGrab.SelectionTop) and (Y < PaintBoxImage.Height) then FGrab.SelectionBottom := Y;
gsLeft : if (X < FGrab.SelectionRight) and (X > 0) then FGrab.SelectionLeft := X;
gsRight : if (X > FGrab.SelectionLeft) and (X < PaintBoxImage.Width) then FGrab.SelectionRight := X;
end;
PaintBoxImage.Invalidate;
end;
end;
end;
end;
procedure TForm1.PaintBoxImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FGrab.Down := False;
FGrab.Side := gsNone;
PaintBoxImage.Cursor := crDefault;
end;
procedure TForm1.PaintBoxImagePaint(Sender: TObject);
begin
PaintBoxImage.Canvas.Draw(0, 0, FBitmap);
PaintBoxImage.Canvas.Brush.Color := clRed;
PaintBoxImage.Canvas.FrameRect(FGrab.SelectionRect);
PaintBoxImage.Canvas.Pen.Color := clBlue;
PaintBoxImage.Canvas.Brush.Color := clBlue;
PaintBoxImage.Canvas.Rectangle(Rect((FGrab.SelectionLeft + FGrab.SelectionRight) div 2 - 2, FGrab.SelectionTop - 2, (FGrab.SelectionLeft + FGrab.SelectionRight) div 2 + 2, FGrab.SelectionTop + 2));
PaintBoxImage.Canvas.Rectangle(Rect((FGrab.SelectionLeft + FGrab.SelectionRight) div 2 - 2, FGrab.SelectionBottom - 2, (FGrab.SelectionLeft + FGrab.SelectionRight) div 2 + 2, FGrab.SelectionBottom + 2));
PaintBoxImage.Canvas.Rectangle(Rect(FGrab.SelectionLeft - 2, (FGrab.SelectionTop + FGrab.SelectionBottom) div 2 - 2, FGrab.SelectionLeft + 2, (FGrab.SelectionTop + FGrab.SelectionBottom) div 2 + 2));
PaintBoxImage.Canvas.Rectangle(Rect(FGrab.SelectionRight - 2, (FGrab.SelectionTop + FGrab.SelectionBottom) div 2 - 2, FGrab.SelectionRight + 2, (FGrab.SelectionTop + FGrab.SelectionBottom) div 2 + 2));
end;
{ TGrab }
constructor TGrab.Create;
begin
FRect := Rect(-1, -1, -1, -1);
end;
function TGrab.EstimateSide(const P: TPoint; E: Integer): TGrapSide;
function SameValue(const A, B: Integer; Epsilon: Integer): Boolean;
begin
if A > B then
Result := (A - B) <= Epsilon
else
Result := (B - A) <= Epsilon;
end;
var
InLeft, InRight, InTop, InBottom: Boolean;
begin
Result := gsNone;
InLeft := SameValue(P.X, FRect.Left, E);
InRight := not InLeft and SameValue(P.X, FRect.Right, E);
if InLeft or InRight then
begin
if (P.Y >= FRect.Top - E) and (P.Y < FRect.Bottom + E) then
if InLeft then
Result := gsLeft
else
Result := gsRight;
end
else
begin
InTop := SameValue(P.Y, FRect.Top, E);
InBottom := not InTop and SameValue(P.Y, FRect.Bottom, E);
if InTop or InBottom then
begin
if (P.X >= FRect.Left - E) and (P.X < FRect.Right + E) then
if InTop then
Result := gsTop
else
Result := gsBottom;
end;
end
end;
end. |
Partager