//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "CDefines.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// 整数i1和i2的差的绝对值小于i3
bool DistanceIn(unsigned int i1,unsigned int i2,unsigned int i3)
{
if(i1>i2)
{ // 确保i2>=i1;
int t=i1;
i1=i2;
i2=t;
}
return i2-i1<=i3;
}
//---------------------------------------------------------------------------
// i1<=i2<i3
bool Mid(unsigned int i1,unsigned int i2,unsigned int i3)
{
return ((i1<=i2) && (i2<i3));
}
//---------------------------------------------------------------------------
// 把窗体My粘到Form窗体
bool AttachToForm(TForm *My,TForm *Form,RECT *r,int space)
{
// 只能粘贴到主窗体
// 可以在这里处理为可以粘贴到任意窗口
Form = Application->MainForm;
CFormAttachStyle *FormStyle=(CFormAttachStyle *)Form->Tag;
CFormAttachStyle *MyStyle=(CFormAttachStyle *)My->Tag;
if(MyStyle==NULL)return false; // 这个不能粘贴
// 检查Form是否粘贴到了My
if(FormStyle)
{
if(FormStyle->AttachTo==My)return false; // 不能循环粘贴
}
// 主窗体的位置
RECT rMain;
GetWindowRect(Form->Handle,&rMain);
MyStyle->AttachTo=NULL;
MyStyle->yPos=r->top;
MyStyle->xPos=r->left;
// 上下方向判断
MyStyle->YStyle=AS_NONE;
if(Mid(rMain.left,r->left,rMain.right) || Mid(r->left,rMain.left,r->right) || (MyStyle->XStyle!=AS_NONE))
{
if(DistanceIn(r->top,rMain.bottom,space))
{
MyStyle->YStyle=AS_BOTTOM;
MyStyle->yPos=rMain.bottom;
}else if(DistanceIn(r->top,rMain.top,space))
{
MyStyle->YStyle=AS_TOP;
MyStyle->yPos=rMain.top;
}else if(DistanceIn(r->bottom,rMain.top,space))
{
MyStyle->YStyle=AS_T_TOP;
MyStyle->yPos=rMain.top-(r->bottom-r->top);
}
}
// 左右方向判断
MyStyle->XStyle=AS_NONE;
if(Mid(rMain.top,r->top,rMain.bottom) || Mid(r->top,rMain.top,r->bottom) || (MyStyle->YStyle!=AS_NONE))
{
if(DistanceIn(r->left,rMain.left,space))
{
MyStyle->XStyle=AS_LEFT;
MyStyle->xPos=rMain.left;
}else if(DistanceIn(r->left,rMain.right,space))
{
MyStyle->XStyle=AS_RIGHT;
MyStyle->xPos=rMain.right;
}else if(DistanceIn(r->right,rMain.left,space))
{
MyStyle->XStyle=AS_L_LEFT;
MyStyle->xPos=rMain.left-(r->right-r->left);
}
}
My->Left=MyStyle->xPos;
My->Top=MyStyle->yPos;
if(MyStyle->XStyle!=AS_NONE || MyStyle->YStyle!=AS_NONE)
{ // 吸附完成
MyStyle->AttachTo=Form;
}
return bool(MyStyle->AttachTo);
}
//---------------------------------------------------------------------------
// 实现窗体粘贴
// space 可以粘贴的距离
bool AttachForm(TForm *My,RECT *r,int space)
{
CFormAttachStyle *MyStyle=(CFormAttachStyle *)(My->Tag);
if(MyStyle)
{
for(int i=0;i<Screen->FormCount;i++)
{
TForm *Form=Screen->Forms[i];
if(Form!=My) // 不同窗体
{
if(AttachToForm(My,Form,r,space))return true;
}
}
}
return false;
}
//---------------------------------------------------------------------------
// 移动被粘贴在一起的其它窗体
void UnionOtherForm(TForm *My,TForm *Form,int dx,int dy)
{
if(Form==NULL)return;
CFormAttachStyle *MyStyle=(CFormAttachStyle *)(Form->Tag);
if(MyStyle)
{
if(MyStyle->Enabled && MyStyle->AttachTo==My)
{
MyStyle->Enabled=false;
int X1=Form->Left;
int Y1=Form->Top;
SetWindowPos(Form->Handle,My->Handle,X1+dx,Y1+dy,Form->Width,Form->Height,SWP_NOSIZE|SWP_NOACTIVATE);
MyStyle->Enabled=true;
}
}
}
//---------------------------------------------------------------------------
// 移动被粘贴在一起的其它窗体
void AdjuctFormPos(TForm *My,RECT *r)
{
// 调整窗口位置
int dy=r->top-My->Top;
int dx=r->left-My->Left;
My->Top=r->top;
My->Left=r->left;
// 调整被吸附的窗口位置
for(int i=0;i<Screen->FormCount;i++)
{
TForm *Form=Screen->Forms[i];
if(Form!=My)
{
UnionOtherForm(My,Form,dx,dy);
}
}
}
//---------------------------------------------------------------------------
// 处理WM_MOVING事件
void Do_WM_MOVING(TForm *My,TMessage &Msg)
{
CFormAttachStyle *MyStyle=(CFormAttachStyle *)My->Tag;
if(MyStyle && MyStyle->Enabled)
{
MyStyle->Enabled=false;
RECT *r=(RECT *)Msg.LParam ;
// 处理粘贴
AttachForm(My,r,12);
MyStyle->Enabled=true;
}
Msg.Result=1; // 通知系统,消息已经处理
}
//---------------------------------------------------------------------------
// 处理WM_MOVE事件
void Do_WM_MOVE(TForm *My,TMessage &Msg)
{
// 处理粘贴成功后的位置调整
CFormAttachStyle *MyStyle=(CFormAttachStyle *)My->Tag;
if(MyStyle && MyStyle->Enabled)
{
if(MyStyle->Enabled && MyStyle->AttachTo)
{ // 粘贴成功
My->Left=MyStyle->xPos;
My->Top=MyStyle->yPos;
}
}
Msg.Result=1; // 通知系统,消息已经处理
}
//---------------------------------------------------------------------------