Delphi文件目录选择(来自DLL)在当前应用程序前面引入了其他窗口?

问题描述 投票:2回答:1

我是维护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 dll directory delphi-7
1个回答
4
投票

我不能使用文件目录选择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

© www.soinside.com 2019 - 2024. All rights reserved.