Выбор каталога файлов Delphi (из DLL) выводит другое окно перед текущим приложением? - PullRequest
2 голосов
/ 29 апреля 2019

Я поддерживаю устаревшее программное обеспечение Delphi 6, и оно использует следующую функцию выбора каталога файлов из библиотеки Delphi 2009:

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 Explorer или другое приложение) становится активным и остается перед моим текущим приложением Delphi 6, из которого я вызываю функцию выбора каталога.Что происходит и как этого избежать?

Когда я вызываю свою функцию _SelectDirectory из приложения Delphi 2009 (а не из DLL), тогда все в порядке, текущее приложение остается активным.Таким образом, использование DLL вызывает проблемы.Я использую динамическую загрузку моей DLL:

ImpLib:=LoadLibrary(LibraryName);
@TmpSelectDirectory:=GetProcAddress(ImpLib, '_SelectDirectory');
TmpSelectDirectory(ADirPath);

Может быть, я смогу оштрафовать загрузку DLL Delphi 2009 в приложение Delphi 6 таким образом, чтобы текущее приложение Delphi 6 оставалось активным даже после вызова aftarФункция DLL.

1 Ответ

4 голосов
/ 29 апреля 2019

Я не могу использовать функцию выбора каталога файлов Delphi 6, потому что Delphi 6 не имеет такой функции

Да, это так: FileCtrl.SelectDirectory().Обязательно используйте 2-ю перегруженную версию с параметром Root.Эта перегрузка отображает современный системный диалог с использованием функции Win32 SHBrowseForFolder().Другая перегрузка отображает более старый диалог VCL в стиле Win3.1.

В качестве альтернативы, 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);

Когда я вызываю свою функцию _SelectDirectory из приложения Delphi 2009 (а не из DLL), тогда всевсе в порядке, текущее приложение остается активным.

В этой ситуации TFileOpenDialog имеет доступ к TApplication и активным TForm объектам приложения и может выбрать владельца по умолчанию HWNDмежду ними.Но когда вы вызываете TFileOpenDialog из библиотеки DLL, она больше не может этого делать, поэтому вам нужно более четко указать, какого владельца HWND использовать.

...