我是维护Delphi 6遗留软件,它使用Delphi 2009 DLL中的以下文件目录选择功能:
function _SelectDirectory(ADirPath: ShortString): ShortString;
var OpenDlg: TFileOpenDialog;
begin
Result:='';
OpenDlg:=TFileOpenDialog.Create(nil);
try
OpenDlg.Options:=OpenDlg.Options+[fdoPickFolders];
if DirectoryExists(ADirPath) then
OpenDlg.DefaultFolder:=ADirPath;
if OpenDlg.Execute then begin
Result:=OpenDlg.FileName;
end;
finally
OpenDlg.Free;
end;
end;
我不能使用文件目录选择Delphi 6的功能因为Delphi 6没有这样的功能,如果有的话,它已经过时且无法使用。所以 - 我正在使用DLL中的函数。但是在调用此函数之后,另一个窗口(可能是Windows资源管理器或其他应用程序)变为活动状态并停留在我当前的Delphi 6应用程序前面,我从该应用程序调用目录选择功能。发生了什么以及如何避免这种情况?
当我从Delphi 2009应用程序(而不是DLL)调用我的_SelectDirectory函数时,一切正常,当前的应用程序仍然是活动的。因此,使用DLL会导致问题。我使用动态加载我的DLL:
ImpLib:=LoadLibrary(LibraryName);
@TmpSelectDirectory:=GetProcAddress(ImpLib, '_SelectDirectory');
TmpSelectDirectory(ADirPath);
也许我可以很好地将Delphi 2009 DLL加载到Delphi 6应用程序中,这样,当前的Delphi 6应用程序仍然是DLL函数的一个活跃的调用。
我不能使用文件目录选择Delphi 6的功能因为Delphi 6没有这样的功能
是的,它确实:FileCtrl.SelectDirectory()
。请务必使用具有Root
参数的第二个重载版本。该重载使用Win32 SHBrowseForFolder()
函数显示现代系统对话框。另一个重载显示较旧的Win3.1样式的VCL对话框。
或者,TFileOpenDialog.Execute()
有一个可选的HWND
参数来指定对话框的所有者窗口。让你的D6代码调用该窗口的活动TForm.Handle
。
function _SelectDirectory(Owner: HWND; ADirPath: ShortString): ShortString;
var
...
begin
...
if OpenDlg.Execute(Owner) then
...
end;
ImpLib := LoadLibrary(LibraryName);
@TmpSelectDirectory := GetProcAddress(ImpLib, '_SelectDirectory');
TmpSelectDirectory(MyForm.Handle, ADirPath);
当我从Delphi 2009应用程序(而不是DLL)调用我的_SelectDirectory函数时,一切正常,当前的应用程序仍然是活动的。
在这种情况下,TFileOpenDialog
可以访问应用程序的TApplication
和活跃的TForm
对象,并可以从它们之间选择默认所有者HWND
。但是当你从DLL内部调用TFileOpenDialog
时,它不能再这样做了,所以你必须更清楚地知道使用哪个所有者HWND
。