Delphi 文件目录选择(来自DLL)将其他window 带到当前应用程序前面?

Delphi file directory selection (from DLL) brings other window in front of the current application?

我正在维护 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;

我不能使用文件目录选择Delphi6功能,因为Delphi6没有这样的功能,如果有的话,它已经过时且无法使用了。所以 - 我正在使用 DLL 中的函数。但是调用此函数后,另一个 window(可能是 Windows Explorer 或其他应用程序)变为活动状态并停留在我当前的 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函数。

I can not use file directory selection Delphi 6 function because Delphi 6 has not such function

是的,它有:FileCtrl.SelectDirectory(). Just be sure to use the 2nd overloaded version that has a Root parameter. That overload displays a modern system dialog using the Win32 SHBrowseForFolder() 功能。另一个重载显示一个旧的 Win3.1 风格的 VCL 对话框。

或者,TFileOpenDialog.Execute() 有一个可选的 HWND 参数来指定对话框的所有者 window。让您的调用 D6 代码在 window.

的活动 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);

When I call my _SelectDirectory function from Delphi 2009 application (and not from DLL), then all is OK, the current application remains the active one.

在这种情况下,TFileOpenDialog 可以访问应用程序的 TApplication 和活动的 TForm 对象,并可以从它们之间选择一个默认所有者 HWND。但是当您从 DLL 内部调用 TFileOpenDialog 时,它就不能再这样做了,因此您必须更明确地说明要使用哪个所有者 HWND