TBrowseForFolder 是 Delphi / C++ Builder 中自带的一个浏览目录的对话框,位于 StdActns 单元(后期为 Vcl.StdActns 单元),不幸的是,这个动作代码天生残疾(从诞生到现在一直没改过这个问题),要让其好用,有两种解决办法:
第一种:刮骨疗毒=>修改 StdActns 单元的代码
- 将 StdActns 单元复制到你工程目录下;
- 打开这个单元,并在 TBrowseForFolder.ExecuteTarget 实现中,找到下面这段代码:
with BrowseInfo do begin hwndOwner := Application.Handle; pidlRoot := RootItemIDList; ....
将 hwndOwner 的值由 Application.Handle 改为:
if Assigned(Screen.ActiveForm) then hwndOwner:=Screen.ActiveForm.Handle else hwndOwner:=Application.Handle;
然后分别使用 Release/Debug 模式编译这个单元。
- 复制 Release/Debug 两种模式下的相应 StdActns 的 dcu 到 Delphi/C++ Builder 的安装目录中对应的位置,覆盖原来的 dcu 文件。
第二种:投机取巧=>既然你设置的 hwndOwner 是 Application.Handle,那我在调用这个动作前,先把 Application.Handle 窗口置前就好了,这样子,弹出的浏览目录对话框就不会跑到其它窗口后面了。所以,此时正确的姿势就成了:
SetForegroundWindow(Application.Handle); BrowseForFolder.Execute;
注意此时,你就不能将动作绑定到一个控件上了,而要在控件的 OnClick 一类的事件中,手动调用。
好了,比较一下两个的优劣:
- 第一种唯一的问题就是每次升级 Delphi 你都需要处理一遍,直到官方修改这个问题;
- 第二种唯一的问题是你要多写两行代码,不需要管 Delphi 升级的问题。
如何取舍,在于你而不在于我。同样的问题,在 FMX 中依然存在,同样的办法解决。