如何让子窗口随着住窗口移动而移动。

yypp 2001-05-17 09:29:00
如何在程序里实现子窗口随着主窗口的拖动而一起移动?两者的相对位置保持不变。
就好象WINAMP一样。
谢谢
...全文
246 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
yypp 2001-05-17
  • 打赏
  • 举报
回复
有没有Delphi的代码?
sundayboys 2001-05-17
  • 打赏
  • 举报
回复
bcb的,转贴:
一.首先,在单元文件Private段加入如下代码:
void __fastcall LinkWindow(TWMWindowPosChanged &Msg) ;

BEGIN_MESSAGE_MAP

MESSAGE_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 Form3

if(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一起动不?


yypp 2001-05-17
  • 打赏
  • 举报
回复
OK

写些大家的回复
canna 2001-05-17
  • 打赏
  • 举报
回复
重载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;
}
sweihua 2001-05-17
  • 打赏
  • 举报
回复
my god!
cobi 2001-05-17
  • 打赏
  • 举报
回复
我根据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)

5,391

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧