原贴号为1369113现重新开贴总分250分。如果您是MDI高手,则请进!如果您不是就不要来浪费时间了,我知道各位时间宝贵!这在里面作了详细说明,我也不是无中生

  • 主题发起人 主题发起人 Ccmake
  • 开始时间 开始时间
C

Ccmake

Unregistered / Unconfirmed
GUEST, unregistred user!
原贴号为1369113现重新开贴总分250分。如果您是MDI高手,则请进!如果您不是就不要来浪费时间了,我知道各位时间宝贵!这在里面作了详细说明,我也不是无中生有拿大家开心,市面上老早就有这样的例子了! (200分)<br />客户要求软件采用MDI窗体形式,我建立一个主窗口及多个MDI窗口及多个Normal窗口。
问题是窗口内部构件之间的互访非常难以控制,请各位谈谈。通过变量的方式就不要说了!

我举个例子:
有一个Mdichild的窗口(如公司操作员信息)我称之为1窗口,
有一个normal的窗口(增加修改操作员)我称之为2窗口,
现在要做的是当执行1窗口中的增加操作员铵纽后,以showmodal方式调出2窗口,
问题是当点击2窗口中的增加按纽成功之后,如果就退出2窗口这时窗口1中的数据就可刷新了,
但如果此时不退出2窗口,让用户继续增加操作员,问题在这里,如何发送一个信息给1窗口,
让其将则才的数据刷新且在1窗口中显示出来.
成功的案例有速达软件,其mdichild的类型窗口数据可任意调用,且各窗口数据自动更新,
其实这不难,难就难在如何给一个信息其它窗口,有了它一切都OK了!这样的软件才叫棒!
在坐的各位总不会让我建立一些变量再搞个timer来不断的检查吧!
 
从1369113贴中转过来
to 太阳河上,道明德
方法还好,但我从来不用delphi的data controls,我都用stringgrid!所有对我无用!
to mazhayang,小雨哥,mazhayang
请说具体一些!

 
可以在datamodule 的数据表(或Tquery ) 的 onafterscroll 写事件,将目前的窗口遍历一边,如果是你要的子窗口,即写更新代码,不过这样可能效率很低.
如:
for j := 0 to Screen.FormCount - 1 do
if (Screen.Forms[j].ClassType = TRuku_Form_only_show) then
begin
(Screen.Forms[j] as TRuku_Form_only_show).panel_gb.visible := ruku_QueryBDEDesigner4.AsString ='xxx';//写你的更新数据
Break;
end;
 
,,你的什么问题
我有例子要吗??
 
这个问题似乎不是那么复杂吧,随便数数都有好几种方法:

在以下的程序中Form1(Unit1)是主Form,Form2(Unit2)是MDIChild,Form3(Unit3)是Normal窗体。
Form1和Form2是在应用程序启动时自动创建,且自动显示。
Form3是Form2上的按钮单击时创建并显示(以ShowModal方式)。
1、直接访问:
procedure TForm3.Button2Click(Sender: TObject);
begin
if Assigned(Form2) then
//这是一种习惯而已,先判断一下Form2是否初创建,在这个例子中实际上不需要,因为Form2是在程序启动时创建。
Form2.Edit1.Text:=Edit1.Text;
end;

2、在Form2中定义一个属性并定义其相应的读写接口:
type
TForm2 = class(TForm)
...
public
Property Edit1Text:String Read GetEdit1Text Write SetEdit1Text;
end;

implementation
....
function TForm2.GetEdit1Text: String;
begin
Result:=Edit1.Text;
end;

procedure TForm2.SetEdit1Text(const Value: String);
begin
Edit1.Text:=Value;
end;

在Form3中通过直接访问Form2的属性来访问Form2的Edit1。

procedure TForm3.Button2Click(Sender: TObject);
begin
if Assigned(Form2) then
Form2.Edit1Text:=Edit1.Text;
//在给Form2.Edit1Text属性赋值时会自动调相写接口函数SetEdit1Text为Form2的Edit1的Text属性赋值。
end;

以上两种方法需要在Unit3的implementation段或者interface段引用Unit2。
3、在Form3中定义一个属性MyForm2,类型为TForm2,在Form2中ShowModal前把Form2自身赋给这个属性,
在Form3中访问题Form2时并不直接访问全局变量Form2而是问题Form3的属性MyForm2,实际上它不再
关心TForm2的实例名是Form2还是F2o2r2m2。
type
TForm3 = class(TForm)
...
private
FForm2: TForm2;
procedure SetForm2(const Value: TForm2);
public
Property MyForm2:TForm2 Read FForm2 Write SetForm2;
end;

var
Form3: TForm3;

implementation
...
procedure TForm3.SetForm2(const Value: TForm2);
begin
FForm2 := Value;
end;


在Form3中访问题Form2的Edit1时的代码如下:
procedure TForm3.Button3Click(Sender: TObject);
begin
if Assigned(FMyForm2) then
FMyForm2.Edit1.Text:=Edit1.Text;
end;

在Form2中ShowModal前加这样一句:
Form3.MyForm2:=Self;
如果用With语句:
procedure TForm2.Button1Click(Sender: TObject);
begin
With TForm3.Create(Application) do
begin
try
MyForm2:=Self;
ShowModal;
finally
Free;
end;
end;
end;
其实这种方法最科学,最能体现Delphi的OOP思想。

4、通过Message通知Form2,其实不过是让Form2来访问Form3,与Form3直接访问Form2没有什么不同。
5、通过CopyData消息来发送修改后的数据到Form2,这种方法最能体现Windows消息机制的特点,
但是CopyData消息的使用相对麻烦些,这的主页上有一个这样的例子:
“28、利用DLL和简单的Hook技术获取Windows密码输入框的密码的程序,并可得到输入框的Class等相关信息(源码)。 Download! ”
主页地址:http://www.aidelphi.com
6、把第二种和第三种方法结合起来,更加完整:
在Form3中访问题Form2的Edit1时的代码如下:
procedure TForm3.Button3Click(Sender: TObject);
begin
if Assigned(FMyForm2) then
FMyForm2.Edit1Text:=Edit1.Text;
end;
 
其实还有上面的朋友介绍的通过Screen.Forms来访问,在这里也简单的说一下:
for j := 0 to Screen.FormCount - 1 do
if (Screen.Forms[j] is TForm2) then
begin
(Screen.Forms[j] as TForm2).Edit1.Text := Edit1.Text;
Break;
end;
 
又是一个跟我遇到同一种情况的人!
你一定是在Mdichild(form1)及normal(Form2)上分别放置
dataset(from1.query1,form2.query1)控件的!


有一种最好的解决方法!
把你程序中所有用到的数据组件都放在一个DATAMODULE中,并在程序一开始就加载他,
Mdichild(form1)及normal(form2)中的数据控件(dbgrid/dbedit/...)的datasource
属性都指向datamodule中的query(操作员table)对应的datasource控件

这样一来,你在normal中的修改就自然通过数据集控件自动传递到Mdichild中显示出了,
不再需要任何额外代码!何乐而不为呢!
 
to ylm0101 请给出例子,谢谢!
to aizb 谢谢,你的分我会给!
to luckywzy 效果是不错,但我不用data controls!
to TMXYB 如果需要的界面不多,则是个方法,但我的界面太多了,这样的话工作量太大!
 
TO Ccmake
你这一说,我有些奇怪了,能讲一讲原因吗?

//不过我去台湾的论坛上看到另一种方法,但我没有试过,等有了结果再发出来
 
应该自己做一个类,放在主窗口,专门用来做各个子窗口通信用,
其中做一个onupdate事件,当数据改变的时候,就刷新各个子窗口的数据。
其实还是用的变量,只不过封装一下,增加一个方法。
 
to luckywzy
这是个人习性吧!
to sung_001
是个较好的方法!,我的分你也有份!当然还有aizb

各位好好谈谈吧!
 
后退
顶部