亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? magnetunit.pas

?? 這是一個有 BUG 的磁性窗體的組件/單元
?? PAS
?? 第 1 頁 / 共 2 頁
字號:
{: (C) Copyright 2003 - All rights reserved.
    Company: BCP Software, www.bcp-software.nl
    Author:  Marco Wobben, marco@wobben.com }
unit MagnetUnit;

{ To do

  - If snapped to a screen edge, the resizing of the form using the opposite
    border doesn't snap anymore.
  - How does this work in a MDI application. The mainform's edge may not be
    considering it's border.
  - For multimonitor it now switches to snapmode 'near'. This should only be the
    case for the aligning monitor borders and not for the outermost borders.

  History

  ** 18 September 2003 **
    Fix:
      Thanks to George Boudouris.
    Behaviour:
      Snapping Magnet1 to M2 clustered ok.
      Snapping this new cluster from M1 to M3 didn't cluster M3...
    Routines Changed:
      ClusterSnapList
}

interface

{ $ DEFINE CODESITE}

uses
  Forms, Messages, Windows, Classes, Controls;

type
  TSnapOption = (soInScreen, soMagnet, soInMainForm);
  TSnapOptions = set of TSnapOption;

  TSnapBorder = (sbInner, sbOuter, sbNear);

  TMagnet = class(TComponent)
  private
    FActive: boolean;
    FClientInstance,
      FPrevClientProc: TFarProc;
    FRange: integer;
    FSnapOptions: TSnapOptions;
    FDragStart: TRect;
    FDragging: Boolean;
    FCluster: TList;
    FSnapList: TList;
    FEnableClustering: Boolean;
    FAutoSnap: boolean;
    FClusterSnapping: Boolean;
    FImmediateCluster: boolean;
    FOldArea: TRect;
    FGroupIndex: integer;
    FClusterIndex: integer;
    procedure ClientWndProc(var Message: TMessage);
    procedure SetActive(const Value: boolean);
    procedure SetRange(const Value: integer);
    procedure SetSnapOptions(const Value: TSnapOptions);
    function SnapToRect(var aLeft, aTop: integer; const aWidth, aHeight:
      integer;
      aRect: TRect; aBorder: TSnapBorder): boolean;
    function GetInCluster: Boolean;
    procedure SetEnableClustering(const Value: Boolean);
    procedure UnCluster;
    procedure ReCluster(NewCluster: TList);
    procedure SetAutoSnap(const Value: boolean);
    procedure SetClusterSnapping(const Value: Boolean);
    procedure ClusterSnapList;
    procedure AdjustCluster(Delta: TPoint);
    procedure SetImmediateCluster(const Value: boolean);
    procedure SetGroupIndex(const Value: integer);
    procedure SetClusterIndex(const Value: integer);
  protected
    function Form: TCustomForm;

    function Area: TRect;
    function Center: TPoint;

    procedure WindowPosChanging(var aPos: TPoint; const W, H: integer; Sizing: Boolean = False); virtual;
    procedure WindowSizeChanging(var aRect: TRect); virtual;
    procedure ApplyDeltaPos(aDelta: TPoint);

    procedure AppendCluster(aCluster: TList);
    procedure RemoveFromCluster(aMagnet: TMagnet);
    property Cluster: TList read FCluster;
  public
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;

    {: Returns true if this is the magnet being dragged by a mouse cursor. }
    property Dragging: Boolean read FDragging;
    {: Returns true if this magnet is part of a cluster. }
    property InCluster: Boolean read GetInCluster;

  published
    {: Activate the magnet by setting Active to true. }
    property Active: boolean read FActive write SetActive default false;
    {: This will enable the magnet to snap to objects specified in the
       SnapOptions unless CTRL is pressed. If set to false it requires CTRL
       to be pressed to enable snapping. }
    property AutoSnap: boolean read FAutoSnap write SetAutoSnap default true;
    {: The groupindex is used to let all magnets with the same groupindex
       respond to each other. }
    property GroupIndex: integer read FGroupIndex write SetGroupIndex default 0;
    {: The clusterindex is a number which if clustering is enabled only works
       on magnets with the same clusterindex. }
    property ClusterIndex: integer read FClusterIndex write SetClusterIndex default 0;
    {: The distance to other objects at which this object will snap. }
    property Range: integer read FRange write SetRange default 15;
    {: Specifies at which objects this magnet will snap.
       soInScreen: snap on the screen edge and make sure the magnet remains inside.
       soMagnet: snap to other magnets.
       soInMainForm: similar to soInScreen, but in this case the application mainform sets the edge.
         (soInMainForm allows the magnet to leave the mainform if the mainform is dragged) }
    property SnapOptions: TSnapOptions read FSnapOptions write SetSnapOptions
      default [soInScreen, soMagnet];
    {: Set this to true to maintain the snapped magnets in a cluster while this
       magnet (or other) is being dragged. }
    property EnableClustering: Boolean read FEnableClustering write
      SetEnableClustering default true;
    {: ClusterSnapping exends the snapping behaviour accross all magnet edges in
       the cluster. }
    property ClusterSnapping: Boolean read FClusterSnapping write
      SetClusterSnapping default true;
    {: This option is default false, once set to true the snapping automatically
       clusters the magnets snapped to and does not wait until snapping is
       completed by releasing the mouse. }
    property ImmediateCluster: boolean read FImmediateCluster
      write SetImmediateCluster default false;
  end;

{: This grows or shrinks the rectangle on all sides with the specified number.
   Passing (5,5,10,10) and 1 will result in (4,4,11,11)
   Passing (5,5,10,10) and -1 will result in (6,6,9,9) }
function GrowRect(aRect: TRect; Grow: integer): TRect;
{: This function returns the surface in pixels. }
function RectArea(aRect: TRect): integer;
{: Returns true if the rectangles are aligned
  (meaning not overlapping and not a pixel space in between) }
function RectAligned(R1, R2: TRect): boolean;
{: Returns true if rectangles are overlapping and false if not. }
function RectOverlap(R1, R2: TRect): boolean;

{: Return the magnet instance in the owner component list or return nil if
   not found. }
function FindMagnet(aOwner: TComponent): TMagnet;
{: Return the magnet instance in the owner component list or returns a new
   instance if not found. }
function GetMagnet(aOwner: TComponent): TMagnet;

{: Sets the autosnap property of all magnets with the specified GroupIndex. }
procedure SetAutoSnapAllMagnets(aAutoSnap: boolean; aGroupIndex: integer);

implementation

uses
  {$IFDEF CODESITE} CsIntf, {$ENDIF}
  SysUtils, Types;

var
  ActiveMagnets: TList;
  AllMagnets: TList;

procedure SetAutoSnapAllMagnets(aAutoSnap: boolean; aGroupIndex: integer);
var
  i: integer;
begin
  for i:=0 to AllMagnets.Count-1 do
    with TMagnet(AllMagnets[i]) do
      if (GroupIndex = aGroupIndex) then
        AutoSnap := aAutoSnap;
end;

function FindMagnet(aOwner: TComponent): TMagnet;
var
  i: integer;
begin
  Result := nil;
  for i := 0 to aOwner.ComponentCount - 1 do
    if aOwner.Components[i] is TMagnet then
    begin
      Result := TMagnet(aOwner.Components[i]);
      Exit;
    end;
end;

function GetMagnet(aOwner: TComponent): TMagnet;
begin
  Result := FindMagnet(aOwner);
  if not Assigned(Result) then
    Result := TMagnet.Create(aOwner);
end;

function GrowRect(aRect: TRect; Grow: integer): TRect;
begin
  Result.Left := aRect.Left - Grow;
  Result.Top := aRect.Top - Grow;
  Result.Right := aRect.Right + Grow;
  Result.Bottom := aRect.Bottom + Grow;
  if IsRectEmpty(aRect) then
    FillChar(Result, SizeOf(Result), #0);
end;

function RectArea(aRect: TRect): integer;
begin
  if IsRectEmpty(aRect) then
    Result := 0
  else
    Result := (aRect.Right - aRect.Left) * (aRect.Bottom - aRect.Top);
end;

function RectAligned(R1, R2: TRect): boolean;
var
  Tmp: TRect;
begin
  Result :=
    not IntersectRect(Tmp, R1, R2) and
    IntersectRect(Tmp, GrowRect(R1, 1), R2);
end;

function RectOverlap(R1, R2: TRect): boolean;
var
  Tmp: TRect;
begin
  Result := IntersectRect(Tmp, R1, R2) and not IsRectEmpty(Tmp);
end;

{ TMagnet }

procedure TMagnet.ApplyDeltaPos(aDelta: TPoint);
var
  R: TRect;
begin
  R := Area;
  OffsetRect(R, aDelta.X, aDelta.Y);
  Form.SetBounds(
    R.Left,
    R.Top,
    R.Right - R.Left,
    R.Bottom - R.Top);
end;

procedure TMagnet.ClientWndProc(var Message: TMessage);
var
  R: TRect;
  P: TPoint;
begin
  with Message do
  begin
    case Msg of
      WM_ENTERSIZEMOVE:
        begin
          FOldArea := Area;
          FDragStart := Area;
          FDragging := True;
        end;
      WM_EXITSIZEMOVE:
        begin
          ClusterSnapList;
          FOldArea := Area;
          FDragging := False;
        end;
      WM_WINDOWPOSCHANGING:
        with TWmWindowPosChanging(Message).WindowPos^ do
        begin
          FSnapList.Clear;
          if ((GetKeyState(VK_CONTROL) and $F0 = 0) xor (not AutoSnap)) and
            (Dragging) then
          begin
            if (cx <> Area.Right-Area.Left) or (cy <> Area.Bottom-Area.Top) and
              (flags and SWP_NOSIZE = 0) then
            begin
              R := Rect(x,y,x+cx,y+cy);
              // {$IFDEF CODESITE}CodeSite.SendRect('SIZE',R);{$ENDIF}
              WindowSizeChanging(R);
              FDragStart := R;
              x := R.Left;
              y := R.Top;
              cx := R.Right-R.Left;
              cy := R.Bottom-R.Top;
            end
            else
            if (flags and SWP_NOMOVE = 0) then
            begin
              P := Point(x, y);
              // {$IFDEF CODESITE}CodeSite.SendRect('MOVE',Rect(x,y,x+cx,y+cy));{$ENDIF}
              WindowPosChanging(P, cx, cy);
              AdjustCluster(
                Point(
                  P.X - FDragStart.Left,
                  P.Y - FDragSTart.Top));
              FDragStart := Rect(P.X, P.Y, P.X+cx, P.Y+cy);
              x := P.x;
              y := P.y;
            end;
            if FImmediateCluster then
              ClusterSnapList;
            // the window message is handled
            Result := 1;
          end
          else
          begin
            if Dragging and InCluster then
              UnCluster;
          end;
        end;
      WM_DESTROY:
        Active := False;
    end;

    if (Result = 0) then
      Result := CallWindowProc(FPrevClientProc, Form.Handle, Msg, wParam,
        lParam);
  end;
end;

constructor TMagnet.Create(aOwner: TComponent);
begin
  if not (aOwner is TCustomForm) then
    raise EComponentError.Create(ClassName + '.Owner must be a TForm');

  if Assigned(FindMagnet(aOwner)) then
    raise EComponentError.Create(ClassName +
      ' can occur only once in a TForm');

  inherited Create(aOwner);

  FActive := False;
  FAutoSnap := True;
  FRange := 15;
  FSnapOptions := [soInScreen, soMagnet];
  FDragging := False;

  FCluster := TList.Create;
  FCluster.Add(Self);

  FSnapList := TList.Create;

  FEnableClustering := True;
  FClusterSnapping := True;
  FImmediateCluster := False;

  FGroupIndex := 0;
  FClusterIndex := 0;

  AllMagnets.Add(Self);
end;

destructor TMagnet.Destroy;
begin
  AllMagnets.Extract(Self);

  Active := False;
  FCluster.Free;
  FSnapList.Free;
  inherited;
end;

function TMagnet.Form: TCustomForm;
begin
  Result := TCustomForm(Owner);
end;

function TMagnet.GetInCluster: Boolean;
begin
  Result := (FCluster.Count > 1);
end;

procedure TMagnet.AppendCluster(aCluster: TList);
var
  i: integer;
begin
  if (EnableClustering) then
    for i := 0 to aCluster.Count - 1 do
      if (FCluster.IndexOf(aCluster[i]) < 0) and
        (TMagnet(aCluster[i]).EnableClustering) then
      begin
        FCluster.Add(aCluster[i]);
      end;
end;

procedure TMagnet.SetActive(const Value: boolean);
begin
  if (Active <> Value) then
  begin
    if Value then
    begin
      // hook into the Form to receive the WM_WINDOWPOSCHANGING
      FClientInstance := MakeObjectInstance(ClientWndProc);
      FPrevClientProc := Pointer(GetWindowLong(Form.Handle, GWL_WNDPROC));
      SetWindowLong(Form.Handle, GWL_WNDPROC, Integer(FClientInstance));

      ActiveMagnets.Add(Self);
    end
    else
    begin
      if InCluster then
        UnCluster;

      // unhook from the Form to stop reveiving the WM_WINDOWPOSCHANGING
      SetWindowLong(Form.Handle, GWL_WNDPROC, Integer(FPrevClientProc));
      FreeObjectInstance(FClientInstance);

      ActiveMagnets.Extract(Self);
    end;

    FActive := Value;
  end;
end;

procedure TMagnet.SetRange(const Value: integer);
begin
  FRange := Value;
end;

procedure TMagnet.SetSnapOptions(const Value: TSnapOptions);
begin
  if (soInMainForm in Value) and (Form = Application.MainForm) then
    FSnapOptions := Value - [soInMainForm]
  else
    FSnapOptions := Value;
end;

function TMagnet.SnapToRect(var aLeft, aTop: integer;
  const aWidth, aHeight: integer; aRect: TRect; aBorder:
  TSnapBorder): boolean;
var
  ISect, RangeRect: TRect;
begin
  Result := False;

  if (aBorder = sbInner) then
  begin
    // left edge
    if (aLeft < aRect.Left + Range) then
    begin
      aLeft := aRect.Left;
      Result := True;
    end;
    // right edge
    if (aLeft + aWidth + Range > aRect.Right) then
    begin
      aLeft := aRect.Right - aWidth;
      Result := True;
    end;
    // top edge
    if (aTop < aRect.Top + Range) then

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美videossexotv100| 日韩一区精品视频| 亚洲成人精品一区| 国产成人午夜视频| 91精品国产综合久久国产大片| 26uuu亚洲婷婷狠狠天堂| 亚洲高清视频中文字幕| 不卡的av网站| 久久先锋影音av鲁色资源| 亚洲国产三级在线| 99麻豆久久久国产精品免费| 精品国产一二三| 欧美96一区二区免费视频| 欧美影片第一页| 中文字幕日韩一区二区| 国内精品伊人久久久久影院对白| 欧美日韩免费电影| 亚洲一区二区三区四区在线 | 色老汉av一区二区三区| 久久亚洲精品小早川怜子| 日本一不卡视频| 欧美性大战xxxxx久久久| 日韩美女视频一区| 成人18精品视频| 国产精品久久久久久久久久免费看| 精品夜夜嗨av一区二区三区| 日韩精品一区二区三区在线播放| 日日摸夜夜添夜夜添精品视频| 欧美午夜寂寞影院| 亚洲国产sm捆绑调教视频| 欧洲国内综合视频| 亚洲在线视频网站| 欧美日韩日日摸| 午夜亚洲福利老司机| 在线不卡的av| 免费成人小视频| 精品久久久久久久久久久久包黑料| 蜜臀精品一区二区三区在线观看| 欧美一级黄色大片| 国产一区啦啦啦在线观看| 久久久三级国产网站| 国产·精品毛片| 最新国产精品久久精品| 色欧美片视频在线观看在线视频| 亚洲精品欧美专区| 91精品国产91热久久久做人人| 日本午夜一区二区| 久久久久九九视频| 91蜜桃视频在线| 日韩综合小视频| 精品免费日韩av| av中文字幕亚洲| 亚洲国产成人av网| 日韩精品资源二区在线| 风间由美一区二区av101| 国产精品美女久久久久aⅴ | 福利一区二区在线观看| 中文字幕一区二区三| 欧美午夜电影一区| 久久精品国产精品亚洲综合| 久久嫩草精品久久久精品一| 成人免费看的视频| 天天影视色香欲综合网老头| 久久久久亚洲综合| 欧美无人高清视频在线观看| 精品一区二区av| 亚洲免费观看视频| 欧美成人vr18sexvr| 99久久精品免费看国产免费软件| 五月婷婷激情综合网| 国产亚洲综合在线| 欧美日韩视频在线观看一区二区三区 | 久久综合久久综合久久| 色综合婷婷久久| 激情久久五月天| 亚洲一区二区精品视频| 欧美国产视频在线| 日韩一区二区精品| 色综合一区二区| 国产麻豆日韩欧美久久| 亚洲1区2区3区视频| 国产精品毛片久久久久久久| 欧美大片在线观看| 欧美肥妇free| 色av成人天堂桃色av| 国产suv一区二区三区88区| 午夜精品国产更新| 亚洲美女免费视频| 国产精品妹子av| 精品成人在线观看| 日韩午夜中文字幕| 欧美怡红院视频| 91视频一区二区三区| 国产精品1024久久| 极品少妇xxxx偷拍精品少妇| 亚洲va国产va欧美va观看| 亚洲乱码国产乱码精品精的特点| 国产日韩av一区| 日韩精品一区在线| 4438x亚洲最大成人网| 在线欧美日韩国产| 99精品视频在线免费观看| 国产成人av一区二区三区在线观看| 日韩高清在线电影| 日韩1区2区日韩1区2区| 午夜免费久久看| 午夜精品久久一牛影视| 亚洲电影一级黄| 丝袜美腿亚洲综合| 日韩黄色免费网站| 图片区日韩欧美亚洲| 五月天亚洲婷婷| 日本午夜精品一区二区三区电影| 亚洲午夜激情网页| 亚洲va在线va天堂| 日本在线不卡视频| 久久精品国产精品青草| 蜜桃视频免费观看一区| 久久97超碰色| 国产成人精品aa毛片| 成人爱爱电影网址| 色综合 综合色| 欧美在线免费观看亚洲| 91超碰这里只有精品国产| 91精品久久久久久蜜臀| 日韩欧美一区二区三区在线| 日韩亚洲欧美一区二区三区| 日韩美一区二区三区| 国产视频一区二区在线观看| 国产欧美精品在线观看| 国产精品女上位| 亚洲欧美日韩系列| 日韩精品一级中文字幕精品视频免费观看 | 91精品福利视频| 欧美日本在线观看| 2017欧美狠狠色| 中文字幕一区二区在线播放| 亚洲综合色视频| 老司机一区二区| zzijzzij亚洲日本少妇熟睡| 欧美在线观看你懂的| 精品毛片乱码1区2区3区| 国产精品污网站| 亚洲成人综合在线| 国产一区二区三区不卡在线观看| 成人的网站免费观看| 欧美无人高清视频在线观看| 精品少妇一区二区三区在线播放 | 亚洲另类在线制服丝袜| 肉肉av福利一精品导航| 高清视频一区二区| 欧美午夜电影网| 国产区在线观看成人精品| 亚洲精品国产无天堂网2021| 日韩激情一区二区| 99久久精品免费精品国产| 91精品国产综合久久婷婷香蕉| 国产人伦精品一区二区| 婷婷国产在线综合| 99久久久国产精品免费蜜臀| 日韩亚洲欧美在线| 亚洲精品日韩一| 国产福利一区二区三区视频| 欧美日韩卡一卡二| 亚洲人123区| 国产剧情一区二区| 7777女厕盗摄久久久| 亚洲欧洲99久久| 国产一区二区在线电影| 欧美午夜不卡在线观看免费| 欧美国产1区2区| 精品一区二区三区在线播放| 色域天天综合网| 亚洲国产精品激情在线观看 | 午夜视频在线观看一区| 风间由美一区二区三区在线观看 | 欧美日韩成人综合天天影院| 中文字幕一区二区三区不卡在线| 精品一区二区三区在线播放视频| 欧美日韩国产一级片| 日本午夜精品视频在线观看| 不卡的av中国片| 中文字幕不卡三区| 国产成人精品一区二区三区四区 | 亚洲欧美日韩小说| 成人av综合一区| 国产欧美一区二区精品性色| 久久精品国产色蜜蜜麻豆| 欧美一区二视频| 日韩二区三区四区| 在线观看91精品国产麻豆| 亚洲精品成人天堂一二三| aaa亚洲精品| 亚洲日本va午夜在线影院| 成人h动漫精品| 国产精品国产三级国产有无不卡| 国产高清无密码一区二区三区| 久久久久久久一区| 成人午夜在线播放| 1区2区3区欧美|