bcb的,转贴:
一.首先,在单元文件Private段加入如下代码: 
void __fastcall LinkWindow(TWMWindowPosChanged &Msg) ;BEGIN_MESSAGE_MAPMESSAGE_HANDLER(WM_WINDOWPOSCHANGED,TWMWindowPosChanged,LinkWindow)END_MESSAGE_MAP(TForm); //消息映射,//其中WM_WINDOWPOSCHANGED为位置发生变化的消息二.然后,在单元实现的文件头中加入如下声明: const flag=SWP_NOACTIVATE||SWP_NOZORDER||SWP_NOMOVE||SWP_NOSIZE;//其中大写的都为显示窗口位置的消息,记录窗口是否会发生变化.三.最后,在单元实现中加入如下代码:void __fastcall TForm1::changed(TWMWindowPosChanged &Msg){//连动了俩个窗口TRect *Rect2,*Rect3;int x2,y2,cx2,cy2;int x3,y3,cx3,cy3;UINT flag2,flag3;// Link Form2;if(Form2!=NULL){Rect2=new TRect;GetWindowRect(Form2->Handle,Rect2);x2=Msg.WindowPos->x+Msg.WindowPos->cx;y2=Msg.WindowPos->y;cx2=Form2->Width;cy2=Msg.WindowPos->cy;flag2=flag;if(Rect2->Left!=x2||Rect2->Top!=y2)flag2=flag2&&!SWP_NOMOVE;if(Rect2->Right-Rect2->Left!=cx2||Rect2->Bottom-Rect2->Top!=cy2)flag2=flag2&&!SWP_NOSIZE;if(flag2!=flag)SetWindowPos(Form2->Handle,0,x2,y2,cx2,cy2,flag2);}//Link Form3if(Form3!=NULL){Rect3=new TRect;GetWindowRect(Form3->Handle,Rect3);x3=Msg.WindowPos->x-Form3->Width;y3=Msg.WindowPos->y;cx3=Form3->Width;cy3=Msg.WindowPos->cy;flag3=flag;if(Rect3->Left!=x3||Rect3->Top!=y3)flag3=flag3&&!SWP_NOMOVE;if(Rect3->Right-Rect3->Left!=cx3||Rect3->Bottom-Rect3->Top!=cy3)flag3=flag3&&!SWP_NOMOVE;if(flag3!=flag)SetWindowPos(Form3->Handle,0,x3,y3,cx3,cy3,flag3);}}四.别忘了把Form2,Form3包含进来.#include "unit2.h"#include "unit3.h"五.最后在Form2和Form3的OnClose事件中加入如下代码:Form2=NULL;delete Form2;//释放Form2占的内存空间Form3=NULL;delete Form3;//释放Form3所占用空间六.Form1能带Form2,Form3一起动不?
 

解决方案 »

  1.   

    我根据sundayboys提供的代码在DELPHI中进行了实现,效果还可以。但是要做到WINAMP的效果,则还有距离。因为窗体的重画在移动过程中没有得到解决,只是在移动结束后才响应。所以还是希望高手能做进一步的指点。代码如下(我只控制了一个窗体)
    ......
      private
        procedure FormLink(var Msg:TWMWindowPosChanged);message WM_WindowPoschanged;
    ......
    uses Unit2;const
      flag = swp_noactivate or swp_nozorder or swp_nomove or swp_nosize;{$R *.DFM}{ TForm1 }procedure TForm1.FormLink(var Msg: TWMWindowPosChanged);
    var
      rect2 : Trect;
      x2,y2,cx2,cy2 : integer;
      flag2 : integer;
    begin
      if (form2 <> nil) then
      begin
        GetWindowRect(form2.handle,rect2);
        x2 := msg.windowpos.x + msg.windowpos.cx;
        y2 := msg.windowpos.y;
        cx2 := FORM2.width;
        cy2 := Msg.windowpos.cy;
        flag2 := flag;    if (rect2.left <> x2) or (rect2.top <> y2) then
          flag2 := flag2 and (not swp_nomove);    if ((rect2.Right - rect2.left) <> cx2) or ((rect2.bottom - rect2.top) <>cy2) then
          flag2 := flag2 and (not swp_nosize);    if (flag2 <> flag) then
          SetWindowPos(form2.handle,0,x2,y2,cx2,cy2,flag2);
      end;
    end;我已经编译成功并运行(WIN98)
      

  2.   

    重载CreateParams()
      让主窗体控制从属窗体,需要将主窗体设为从窗体的“父”,这可以通过重载CreateParams()方法来完成。
    CreateParams()在VCL创建与窗体联系的窗口时调用,CreateParams()的声明如下:
    void __fastcall CreateParams(TCreateParams& Params);
    CreateParams()的唯一参数是对一个TCreateParams结构体的引用。在VCL中TCreateParams定义如下:
    struct TCreateParams
    {
    char *Caption;
    int Style;
    int ExStyle;
    int X;
    int Y;
    int Width;
    int Height;
    HWND WndParent;
    void *Param;
    tagWNDCLASSA WindowClass;
    char WinClassName[64];
    };
      此结构包含了Windows创建一个窗口所需的所有信息(如果你曾用API进行Windows编程,你一定能意识到TCreateParams的成员对Windows CREATESTRUCT结构的映射)。在重载CreateParams()时,首先调用基类的CreateParams()方法,然后修改TCreateParams结构的个别成员变量。一个重载过的CreateParams()方法看起来大致如下:TchartForm是一个子窗口
    MianForm是主窗口void __fastcall TChartForm::CreateParams(TCreateParams& Params)
    {
    TForm::CreateParams(Params);
    Params.Style=WS_CHILD|WS_CLIPSIBLINGS;
    Params.WndParent=MainForm->Handle;
    Params.X=0;
    Params.Y=0;
    Params.Width=MainForm->ClientRect.Right;
    Params.Height=MainForm->ClientRect.Bottom;
    }