MDIChild在MDI Client 区的移动

saxash 2000-03-09 09:28:00
如何限制MDIChild在MDI Client 区的移动,例如使之不得
超出当前屏幕上的Client区?
关闭后再打开位置就变了,如何控制MDIChild的出现位置?
...全文
293 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
saxash 2000-03-27
  • 打赏
  • 举报
回复
大家有点钻牛角尖,其实只要设置MDIChild的top和left属性就行了。
看来没人回答,给分了。
saxash 2000-03-24
  • 打赏
  • 举报
回复
sunsetyang 2000-03-23
  • 打赏
  • 举报
回复
可以使用注册表完成Smith所说的功能:
try
reg:=TRegistry.Create;
reg.RootKey:=HKEY_CURRENT_USER;
if reg.OpenKey('\SoftWare\XXX\XXX',true)
begin
//Get Or Set Values you need
reg.ReadXXXX(...);
or
reg.WriteXXXX(...);
end;
reg.closekey;
finally
reg.Free;
end;
saxash 2000-03-20
  • 打赏
  • 举报
回复
感谢几位朋友的热心,我很想解决这个问题,现在我的程序里这个功能基本能用,
但是如我所说,留下个很讨厌的尾巴。所以我想再等几天,看有没有人回答,然后
才给分大家。

To smith:
谢谢你的回答,你的例程看来能实现,不过我不是很喜欢这种方法,难道一定要
用到外部文件?
光明山人 2000-03-18
  • 打赏
  • 举报
回复
to saxash:
我认为拦截WM_WINDOWPOSCHANGING是最好的方法了。

我没给你支招,所以不用给分。
SMITH 2000-03-17
  • 打赏
  • 举报
回复
在MDIForm创建的时候调用LoadFormStatus过程,在MDIForm关闭的时候调用SaveFormStatus过程即可,过程如下:

procedure LoadFormStatus(form : TForm);
var
inif : Tinifile;
fn : string;
begin
fn := copy(application.exeName,1,pos('.',application.exeName)-1) + '.ini';
inif := Tinifile.Create(fn);
form.Position := poDesigned;
form.top := inif.ReadInteger(form.name,'TOP',form.top);
form.left := inif.ReadInteger(form.name,'LEFT',form.left);
inif.Free;
end;


procedure SaveFormStatus(form : TForm);
var
inif : Tinifile;
fn : string;
begin
fn := copy(application.exeName,1,pos('.',application.exeName)-1) + '.ini';
inif := Tinifile.Create(fn);
inif.WriteString(form.name,'Title',form.caption);
inif.WriteInteger(form.name,'TOP',form.top);
inif.WriteInteger(form.name,'LEFT',form.left);
inif.Free;
end;
saxash 2000-03-14
  • 打赏
  • 举报
回复
按照 radish的方法,改成Delphi是这个样子的:
0. 基本上成功了。
1. 其实不需要 Public的Client_Width, 因为每个窗体都有该属性。
2. 在 MDIChild的 Private下加入
procedure OnWindowsMove(var Msg: TMessage);
message WM_WINDOWPOSCHANGING;
3.
procedure TMDIChild.OnWindowsMove(var Msg: TMessage);
var
CurPos: WINDOWPOS;
begin
CurPos := ptr(msg.lparam);

if CurPos.x < 0 then CurPos.x := 0;
if CurPos.y < 0 then CurPos.y := 0;
if CurPos.x > Form1.ClientWidth - self.width then
CurPos.x := Form1.ClientWidth - self.width - 4; //***
if CurPos.y > Form1.ClientHeight - self.height then
CurPos.y := Form1.ClientHeight - self.height -
Form1.Statusbar.height - 34; //***
end;

4. 注意上面的***,后面的 4和 34 是我加上去的,因为这样才不会出现
滚动条…… x轴还好办,4这个值基本可以不要变;y轴就麻烦啦,不同
的主 Form会有不同的值!
5. ……有没有更好的办法?
saxash 2000-03-13
  • 打赏
  • 举报
回复
我去转成Delphi试一下:)
radish 2000-03-12
  • 打赏
  • 举报
回复
简单示例:FORM1为主,FORM2为CHILD
在FORM1中加入PUBLIC 属性 Client_Width
void __fastcall TForm1::FormResize(TObject *Sender)
{
TRect CRect=this->GetClientRect();
this->Client_Width=CRect.right - CRect.left;
}

在FORM2中拦截
radish 2000-03-12
  • 打赏
  • 举报
回复
简单示例:FORM1为主,FORM2为CHILD
在FORM1中加入PUBLIC 属性 Client_Width
void __fastcall TForm1::FormResize(TObject *Sender)
{
TRect CRect=this->GetClientRect();
this->Client_Width=CRect.right - CRect.left;
}

在FORM2中拦截WM_WINDOWPOSCHANGING
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_WINDOWPOSCHANGING,TMessage,OnWindowsMove);
END_MESSAGE_MAP(TForm);


void __fastcall TForm2::OnWindowsMove(TMessage &Msg)
{
WINDOWPOS * CurPos=(WINDOWPOS *)Msg.LParam;
if (CurPos->x<0)
CurPos->x=0;
Edit2->Text=Form1->Caption;
Edit3->Text=Form1->Client_Width;
if (CurPos->x + this->Width >Form1->Client_Width)
CurPos->x=Form1->Client_Width-this->Width;// - CRect.left;

if (CurPos->y<0)
CurPos->y=0;

}

saxash 2000-03-12
  • 打赏
  • 举报
回复
:-(
saxash 2000-03-12
  • 打赏
  • 举报
回复
对呀,理论我也知道,但是要用什么函数确定位置呢……
radish 2000-03-09
  • 打赏
  • 举报
回复
大致如下:
在MDICHILD移动时判断MDICHILD的边缘,不许超出MDI。
打开后再显示拦截WM_SYSCOMMAND消息控制显示位置即可
saxash 2000-03-09
  • 打赏
  • 举报
回复
终于有人回答了:~~)
能不能具体一点点?
radish 2000-03-09
  • 打赏
  • 举报
回复
拦截MDICHILD的窗口移动消息

5,385

社区成员

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

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