TBaseCustomControl =
class(TCustomControl)
private
FGrid: Boolean;
// Gitter zum einrasten an
FGridWidth: Integer;
// Pixelweite des Gitters
FOldScreenRect : TRect;
// letzte Größe des ClientRect beim moven
MoveOffsetX, MoveOffsetY : Integer;
// komulierte X-, Y-Offsets beim moven
procedure WMSizing(
var AMsg: TMessage);
message WM_SIZING;
procedure WMMoving(
var AMsg: TMessage);
message WM_MOVING;
....
public
property Grid : Boolean
read FGrid
write FGrid;
property GridWidth : Integer
read FGridWidth
write FGridWidth;
...
procedure TBaseCustomControl.WMMoving(
var AMsg: TMessage);
var ARect : PRect;
begin
// am Gitter ausrichten
if Grid
then begin
ARect := PRect(AMsg.lParam);
// Startwert für Left setzen und auf Raster korrigieren
if (FOldScreenRect.Left = 0)
or
((FOldScreenRect.Left
mod FGridWidth) > 0)
then
FOldScreenRect.Left := ARect.Left
div FGridWidth * FGridWidth;
// Startwert für Right setzen und auf Raster korrigieren
if (FOldScreenRect.Right = 0)
or
((FOldScreenRect.Right
mod FGridWidth) > 0)
then
FOldScreenRect.Right := ARect.Right
div FGridWidth * FGridWidth;
// Startwert für Top setzen und auf Raster korrigieren
if (FOldScreenRect.Top = 0)
or
((FOldScreenRect.Top
mod FGridWidth) > 0)
then
FOldScreenRect.Top := ARect.Top
div FGridWidth * FGridWidth;
// Startwert für Bottom setzen und auf Raster korrigieren
if (FOldScreenRect.Bottom = 0)
or
((FOldScreenRect.Bottom
mod FGridWidth) > 0)
then
FOldScreenRect.Bottom := ARect.Bottom
div FGridWidth * FGridWidth;
Dec(MoveOffsetX, (ARect.Left - FOldScreenRect.Left));
Dec(MoveOffsetY, (ARect.Top - FOldScreenRect.Top));
// in X-Richtung verschieben
if Abs(MoveOffsetX) > FGridWidth
then begin
// über das Raster hinaus
Dec(ARect.Left, (FGridWidth*MoveOffsetX
div Abs(MoveOffsetX)));
Dec(ARect.Right, (FGridWidth*MoveOffsetX
div Abs(MoveOffsetX)));
MoveOffsetX := 0;
end else begin
ARect.Left := FOldScreenRect.Left;
ARect.Right := FOldScreenRect.Right;
end;
// in Y-Richtung verschieben
if Abs(MoveOffsetY) > FGridWidth
then begin
// über das Raster hinaus
Dec(ARect.Top, (FGridWidth*MoveOffsetY
div Abs(MoveOffsetY)));
Dec(ARect.Bottom, (FGridWidth*MoveOffsetY
div Abs(MoveOffsetY)));
MoveOffsetY := 0;
end else begin
ARect.Top := FOldScreenRect.Top;
ARect.Bottom := FOldScreenRect.Bottom;
end;
FOldScreenRect := ARect^;
end;
end;