这个方法的最明显的问题有两个:1、鼠标在窗体上的控件上按下时,不能收到窗体的MOUSEDOWN和MOUSEUP事件,如果同时监控各个控件的事件,麻烦是相当大的。2、窗口标题栏的鼠标事件难以正常处理。
其实,同上一段落类似,处理窗体的WM_MOVING事件是比较好的方法。即在WM_MOVING事件中同步移动其它窗体。
移动其它窗体的方法也有多种,有人采用发送消息的方式,具体如下:
// dx和dy是当前窗体移动的距离
// hMove是要移动的窗体
// WM_MOVEFORM是自定义的消息
PostMessage(hMove, WM_MOVEFORM,dx,dy);
被移动的窗体处理WM_MOVEFORM消息时,移动自己到新的位置。
如果是VB、Delphi一类的语言,可以直接设置其Left和Top属性。我采用的方法是使用API函数SetWindowPos,该函数重新设置指定窗口的位置。我的参考代码如下:
// 移动被粘贴在一起的其它窗体
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;iFormCount;i++) { TForm *Form=Screen->Forms[i]; if(Form!=My) { // 调整被吸附的窗口位置 UnionOtherForm(My,Form,dx,dy); } } } // 处理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=0; // 通知系统,消息已经处理 }
(编辑:aniston)
|