如何创建一个图标到windows的状态栏上?(200分)

  • 主题发起人 主题发起人 MicroZeng
  • 开始时间 开始时间
M

MicroZeng

Unregistered / Unconfirmed
GUEST, unregistred user!
如Foxmail, 编辑邮件时,会自动在windows状态栏上创建一个图标。<br><br>我现在使用的方法是:<br>procedure TEditForm.CreateParams(VAR Params: TCreateParams);<br>begin<br>&nbsp; Inherited CreateParams(Params);<br>&nbsp; Params.WndParent := GetDesktopWindow;<br>end;<br><br>但是这样的方法会引起一个问题, 就是EditForm的Handle不是Application的<br>了,从别的程序中,点击EditForm后,显示在最前端却是变成这个应用程序的<br>MainForm. 另外还引发了一些关于Handle的问题, 可以参照这个:<br>http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=140165<br><br>存在这个问题的一个程序的例子是在:<br>http://www.soim.com/soimexpress.zip
 
呵呵,我也很想知道哦。
 
TStatusBar支持自画,在OnDrawPanel事件中加入画图标的语句即可。
 
是要在windows的taskbar上添加一个按钮,就象另外一个程序启动了一样。<br>不是自己程序的statusbar上。
 
也许就是启动了另外一个程序呢? 把主程序关闭后它在吗?<br><br>
 
你可以将该程序做成COM,这样他就能在任务栏上有图标了,<br>而且这个图标也能随你需要而改变
 
Crane,能不能说的详细点,最好举个例子,多谢多谢!
 
没看明白, 其实不就是一个tray icon吗?
 
其实这在VC中是很容易的,只需改变子窗口的风格(复选system关键字),然后<br>把窗口作成非模态的即可,估计在delphi中也能通过Api来完成。<br>我现在所能告诉你的就是将自窗口作成COM,比如foxmail可以这么做:<br>主程序是foxmail.exe的邮件管理部分。<br>然后newmail.exe管写新邮件(具有自己的图标)<br>sendingmail.exe是收发邮件时的窗口(具有自己的图标<br>现在将后两个程序(其实这两个程序单独运行是没有意义的)作成COM,<br>赋予它们属性,比如帐号,地址等等,给予它们方法比如以非模态的形式<br>"show"出来等等,然后在foxmail中适时的生成这两个COM的实例,<br>将他们当作foxmail的一部分(当然属性得赋全),这时,newmail或<br>sendingmail即以foxmail外部窗口的形式出现,任务兰里有其自己的图标<br>但因为它是子进程(也可能是线程,惭愧这地方还没搞懂呢),所以当父进程<br>消失后它也一样消失.<br>我个人建议你用后一种方法,COM是趋势,速度快,集成在系统里,比较稳定<br>又省资源.<br>
 
抱歉,我实在是没有看懂, 到底你们说的是哪一个图标? 我也在用foxmail, 只有一个<br>system trayicon呀?
 
cAKK:不是tray icon,是taskbar,应该每个程序自动生成一个图标的。<br>
 
cAkk,你到考试时也是这样审题的吗?<br>:-)开个玩笑,以报一剑之仇:=)<br>microZeng的意思是:程序开一窗口,就在taskbar上生成这个窗口的button
 
阿非: 已经明白意思了,的确一直没注意到这个.. :-)<br>&nbsp; &nbsp; &nbsp;
 
to Crane:<br>&nbsp; 很有可能向你说的那样使用了COM或EXE外部文件。然后有主程序调用。其他办法可能没有了。
 
不过我用spy++看了一下,好像两个窗口的processhandle一样的,说明不是外部调用的.<br><br>另外,用spy++可以看到,"编辑邮件"的那个窗口的owner是"(none)",而我们通常<br>show出来的form的owner都是tapplication,不管你create的时候是否create(nil).<br><br>我测试了一下,delphi不知道是怎么实现的,反正,即使你是用的create(nil),但是<br>用spy++看,它的owner还是tapplication. 可是foxmail的那个的owner就是none.<br><br>看来,只要把窗口的owner去掉就可以了,问题是不知道怎样"真正"去掉?
 
COM应为具有系统集成的性质,所以它肯定与父进程属于同一processHandle;<br>否则我们调用的所有Api也属于外部调用了。<br>前面忘说一点:<br>&nbsp;在com的方法中要先application.Createform(form1,Tform);<br>这个application 和主程序的application不同,可能是由com<br>自己动态生成的(得看书恶补了!)。
 
to microzeng<br><br>不明白你的意思,按你的方法,应该没问题了呀?不会出现<br>"点击EditForm后,显示在最前端却是变成这个应用程序的MainForm."<br><br>我觉得你自己的方法就可行,cakk的测试不也证明了其parent为0么,<br>只有重载createparam才能使它的parent为0
 
我觉得foxmail不是用的COM,没这么麻烦的.<br><br>VB做出来的程序都是这个效果,想让他图标不出现在任务栏还不行呢!
 
我发现,无论是用<br>&nbsp; Params.WndParent := GetDesktopWindow;<br>还是<br>&nbsp; Params.WndParent := 0;<br>在这样产生的EditForm上,如果使用了TOpenDialog以后,这个TOpenDialog的<br>窗口还是在MainForm上。我改写了TOpenDialog的源码,存成TMyOpenDialog,<br>可以设置OpenDialog1.ParentHandle := Self.Handle;,这样,opendialog<br>打开的时候就是在EditForm上。问题是:当打开OpenDialog1的时候,MainForm<br>会失去响应。也就是说,可以切换到MainForm,但MainForm上所有按钮都失去<br>响应。对于这个现象,我疑惑不解。<br>
 
后退
顶部