MDIChild在MDI Client 区的移动
如何限制MDIChild在MDI Client 区的移动,例如使之不得
超出当前屏幕上的Client区?
关闭后再打开位置就变了,如何控制MDIChild的出现位置?
问题点数:120、回复次数:17Top
1 楼radish()回复于 2000-03-09 21:38:00 得分 0
拦截MDICHILD的窗口移动消息Top
2 楼saxash(还在想)回复于 2000-03-09 21:50:00 得分 0
终于有人回答了:~~)
能不能具体一点点?Top
3 楼radish()回复于 2000-03-09 22:27:00 得分 0
大致如下:
在MDICHILD移动时判断MDICHILD的边缘,不许超出MDI。
打开后再显示拦截WM_SYSCOMMAND消息控制显示位置即可Top
4 楼saxash(还在想)回复于 2000-03-12 15:42:00 得分 0
对呀,理论我也知道,但是要用什么函数确定位置呢……Top
5 楼saxash(还在想)回复于 2000-03-12 18:28:00 得分 0
:-(Top
6 楼radish()回复于 2000-03-12 20:22:00 得分 0
简单示例: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中拦截Top
7 楼radish()回复于 2000-03-12 20:22:00 得分 85
简单示例: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;
}
Top
8 楼saxash(还在想)回复于 2000-03-13 20:38:00 得分 0
我去转成Delphi试一下:)Top
9 楼saxash(还在想)回复于 2000-03-14 20:38:00 得分 0
按照 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. ……有没有更好的办法?
Top
10 楼SMITH()回复于 2000-03-17 21:54:00 得分 15
在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;
Top
11 楼agui(阿贵: 高级图形用户界面)回复于 2000-03-18 02:00:00 得分 5
to saxash:
我认为拦截WM_WINDOWPOSCHANGING是最好的方法了。
我没给你支招,所以不用给分。Top
12 楼saxash(还在想)回复于 2000-03-20 20:18:00 得分 0
感谢几位朋友的热心,我很想解决这个问题,现在我的程序里这个功能基本能用,
但是如我所说,留下个很讨厌的尾巴。所以我想再等几天,看有没有人回答,然后
才给分大家。
To smith:
谢谢你的回答,你的例程看来能实现,不过我不是很喜欢这种方法,难道一定要
用到外部文件?Top
13 楼sunsetyang()回复于 2000-03-23 14:26:00 得分 15
可以使用注册表完成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;Top
14 楼saxash(还在想)回复于 2000-03-24 17:54:00 得分 0
15 楼saxash(还在想)回复于 2000-03-27 20:26:00 得分 0
大家有点钻牛角尖,其实只要设置MDIChild的top和left属性就行了。
看来没人回答,给分了。Top




