Точно так же, с той лишь оговоркой, что при возникновении события OnMouseDown/OnMouseMove координаты курсора будут относительно верхнего левого угла компонента, а не формы.
Например, вот для панельки:
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
with Panel1 do
begin
Left := 23;
Top := 47;
Width := 278;
Height := 138;
end;
FMouseAction := maNone;
FGridX := 10;
FGridY := 10;
FSnapToGrid := True;
end;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FMoveStart := Point(X + Panel1.Left, Y + Panel1.Top);
if (X >= 0) and (X <= Panel1.Width) and
(Y >= 0) and (Y <= Panel1.Height) then
FMouseAction := maMove;
Form1.Invalidate;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
MX, MY, GX, GY: Integer;
begin
if FMouseAction = maMove then
begin
MX := Panel1.Left shl 1 - FMoveStart.X + X;
MY := Panel1.Top shl 1 - FMoveStart.Y + Y;
if FSnapToGrid then
begin
GX := Round(MX / FGridX) * FGridX;
GY := Round(MY / FGridY) * FGridY;
FMoveStart := Point(GX - Panel1.Left + FMoveStart.X,
GY - Panel1.Top + FMoveStart.Y);
Panel1.Left := GX;
Panel1.Top := GY;
end
else
begin
Panel1.Left := MX;
Panel1.Top := MY;
FMoveStart := Point(X + Panel1.Left, Y + Panel1.Top);
end;
end;
Form1.Invalidate;
end;
procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FMouseAction := maNone;
end;