如果您是MDI高手,则请进!如果您不是就不要来浪费时间了,我知道各位时间宝贵!这在里面作了详细说明,我也不是无中生有拿大家开心,市面上老早就有这样的例子了!我决

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

Ccmake

Unregistered / Unconfirmed
GUEST, unregistred user!
如果您是MDI高手,则请进!如果您不是就不要来浪费时间了,我知道各位时间宝贵!这在里面作了详细说明,我也不是无中生有拿大家开心,市面上老早就有这样的例子了!我决定再加100分! (50分)<br />客户要求软件采用MDI窗体形式,我建立一个主窗口及多个MDI窗口及多个Normal窗口。
问题是窗口内部构件之间的互访非常难以控制,请各位谈谈。通过变量的方式就不要说了!
我试着通过下列方式:
Mainform1.edit.Text := edit1.Text ; //这种方式是行不通的
Application.MainForm.MDIChildren[0].Edit1.Text := edit1.Text ; //这种方式无法通过编译
(Application.MainForm.MDIChildren[0].Controls[0] as Tedit).Text := edit1.Text ; // 这种方式运行出错
……
不知道各位有什么好的方法,请用代码说明!

 
为什么用APPlication啊,
直接用MainForm.MDIChildren[0].Edit1.Text := edit1.Text ;
不可以吗
另外,你这种访问的方法不出错的话,程序能编写完,
我服了你啦,你还是用变量吧,这样是不行的
 
用变量可以实现为什么不用?
是不是要把问题复杂化?
 
窗体之间传值最好有主从、单向:
都从主向从传值,不要从从向主传值,多个从窗体之间传值应由主窗体过度,这样条理
清楚,否则你的代码将变得难以维护,甚至写不完成
 
在Mainform1的implementation后加入:Uses form2的单元文件,然后在Mainform1中就可以
用Mainform1.Edit.Text := Form2.edit1.Text
 
在主窗体编写两个子窗体控件间的赋值的函数(消息方式)
然后在子窗体中向主窗体发送消息去驱动主窗体中的函数
:)
 
设置一些全局变量,用其传值
 
把要共享的变量放到Public中,或定义一个对外的接口实现窗体的封装,
比如上面的问题用一个函数GetText什么的实现
 
''在Mainform1的implementation后加入:Uses form2的单元文件,然后在Mainform1中就可以
用Mainform1.Edit.Text := Form2.edit1.Text '' 比较赞同gaohua21,不过,在子窗体中也要引用
引用主窗体,即在子窗体中use fom1,这样才可以正确将子窗体的信息返回主窗体.
 
&gt;&gt;Application.MainForm.MDIChildren[0].Edit1.Text := edit1.Text ;
TMainForm1(Application.MainForm.MDIChildren[0]).Edit1.Text := edit1.Text ;
 
唉!给个实质性的回答吧!
我举个例子:
有一个Mdichild的窗口(如公司操作员信息)我称之为1窗口,
有一个normal的窗口(增加修改操作员)我称之为2窗口,
现在要做的是当执行1窗口中的增加操作员铵纽后,以showmodal方式调出2窗口,
问题是当点击2窗口中的增加按纽成功之后,如果就退出2窗口这时窗口1中的数据就可刷新了,
但如果此时不退出2窗口,让用户继续增加操作员,问题在这里,如何发送一个信息给1窗口,
让其将则才的数据刷新且在1窗口中显示出来.
成功的案例有速达软件,其mdichild的类型窗口数据可任意调用,且各窗口数据自动更新,
其实这不难,难就难在如何给一个信息其它窗口,有了它一切都OK了!这样的软件才叫棒!
在坐的各位总不会让我建立一些变量再搞个timer来不断的检查吧!
 
&gt;&gt;Application.MainForm.MDIChildren[0].Edit1.Text := edit1.Text ;
由于MDIChildren[0]是不确定的,当然编译器就无法确定里面的对象。
 
这个问题我是这样解决的:
主窗口(如公司操作员信息)直接与Tzble1连接,而从窗口(如增加修改操作员)也直接也
Table1连接,这样就可以同时更新,不用写什么代码。我在帮别人做员工档案管理时就
这样处理,用了三年没有出问题。
 
&gt;.. 如何发送一个信息给1窗口,让其将则才的数据刷新且在1窗口中显示出来.
速达软件没有用过,但从你的描述上可以看出它的窗体是数据敏感的(DataAwared)。
你可以在主窗体上放置数据敏感控件,当在子窗体进行对象修改时,就能及时反应到主窗体上了。
(如果您只是为了满足用户的这个需求的话,请试试MVC(Model View Controller )构架吧!)

 
同意'太阳河上'
 
建一个stringlist用于传递数据就行了。
 
楼上各位富翁得罪了,就这样的问题也那么费你们的事?
全它M的扯蛋。用CopyData !
 
to 太阳河上,道明德
方法还好,但我从来不用delphi的data controls,我都用stringgrid!所有对我无用!
to mazhayang,小雨哥,mazhayang
请说具体一些!

 
我以前对这个问题回答过,结果被高手嗤之以鼻。呵呵。我给你看一件作品的部分内容:
IPC_GETVERSION = 0;
(*
** int version = SendMessage(hwnd,WM_WA_IPC,0,IPC_GETVERSION);
**
** Version will be 0x20yx for Applica 2.yx. versions previous to Applica 2.0
** typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know.
**
** The basic format for sending messages to Applica is:
** int Result=SendMessage(hwnd,WM_WA_IPC,command_data,command);
** (for the version check, command_data is 0).
*)

IPC_DELETE = 101;
(*
** SendMessage(hwnd,WM_WA_IPC,0,IPC_DELETE);
**
** You can use IPC_DELETE to clear Applica's internal playlist.
*)

IPC_STARTPLAY = 102;
(*
** SendMessage(hwnd,WM_WA_IPC,0,IPC_STARTPLAY);
**
** Using IPC_STARTPLAY is like hitting 'Play' in Applica, mostly.
*)

IPC_ISPLAYING = 104;
(*
** int res = SendMessage(hwnd,WM_WA_IPC,0,IPC_ISPLAYING);
**
** IPC_ISPLAYING returns the status of playback.
** if it returns 1, it is playing. if it returns 3, it is paused,
** if it returns 0, it is not playing.
*)

IPC_GETOUTPUTTime = 105;
(*
** int res = SendMessage(hwnd,WM_WA_IPC,mode,IPC_GETOUTPUTTime);
**
** IPC_GETOUTPUTTime returns the position in milliseconds of the
** current song (mode = 0), or the song Length, in seconds (mode = 1).
** Returns -1 if not playing or error.
*)

IPC_JUMPTOTIME = 106;
(* (requires Applica 1.60+)
** SendMessage(hwnd,WM_WA_IPC,ms,IPC_JUMPTOTIME);
** IPC_JUMPTOTIME sets the position in milliseconds of the
** current song (approximately).
** Returns -1 if not playing, 1 on eof, or 0 if successful
*)

IPC_WRITEPLAYLIST = 120;
(* (requires Applica 1.666+)
** SendMessage(hwnd,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
**
** IPC_WRITEPLAYLIST writes the current playlist to &lt;Applicadir&gt;//Applica.msd,
** and returns the current playlist position.
** Kinda obsoleted by some of the 2.x new stuff, but still good for when
** using a front-end (instead of a plug-in)
*)

IPC_SETPLAYLISTPOS = 121;
(* (requires Applica 2.0+)
** SendMessage(hwnd,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
**
** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'.
*)

IPC_SETVOLUME = 122;
(* (requires Applica 2.0+)
** SendMessage(hwnd,WM_WA_IPC,volume,IPC_SETVOLUME);
**
** IPC_SETVOLUME sets the volume of Applica (from 0-255).
*)

IPC_SETPANNING = 123;
(* (requires Applica 2.0+)
** SendMessage(hwnd,WM_WA_IPC,panning,IPC_SETPANNING);
**
** IPC_SETPANNING sets the panning of Applica (from 0 (Left) to 255 (Right)).
*)

IPC_GETLISTLENGTH = 124;
(* (requires Applica 2.0+)
** int Length = SendMessage(hwnd,WM_WA_IPC,0,IPC_GETLISTLENGTH);
**
** IPC_GETLISTLENGTH returns the Length of the current playlist, in
** tracks.
*)

IPC_SETSKIN = 200;
(* (requires Applica 2.04+, only usable from plug-ins (not external apps))
** SendMessage(hwnd,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
**
** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
** can be the name of a skin, a skin .zip file, with or without path.
** if path isn't specified, the default search path is the Applica skins
** directory.
*)
上面是一个定义自己的消息的公共单元,他们都对应一个 CopyData 数据,看 Delphi
Windows API 帮助 COPYDATASTRUCT 和 WM_COPYDATA 对它的说明。上例是一个复杂程序
的内容,你的相对简单,定义结构后直接 SendMessage(HWND,Msg_Type,wParam,lParam)
就可以使用消息来变相多线程。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部