Delphi 如何切换';当前';OnTypeChange处理程序中TopEndDialog的目录?(有可能吗?)

Delphi 如何切换';当前';OnTypeChange处理程序中TopEndDialog的目录?(有可能吗?),delphi,Delphi,根据选择的过滤器,我希望OpenDialog在不同的目录中“查看”。 比如: procedure TForm1.FileOpen1OpenDialogTypeChange(Sender: TObject); // This does not work as intended... var Dialog: TOpenDialog; FilterIndex: Integer; FilterExt: string; Path: string; begin { TForm1.actFil

根据选择的过滤器,我希望OpenDialog在不同的目录中“查看”。 比如:

procedure TForm1.FileOpen1OpenDialogTypeChange(Sender: TObject);
// This does not work as intended...
var
  Dialog: TOpenDialog;
  FilterIndex: Integer;
  FilterExt: string;
  Path: string;
begin { TForm1.actFileOpenOpenDialogTypeChange }
  Dialog := Sender as TOpenDialog;
  FilterIndex := Dialog.FilterIndex;
  FilterExt := ExtFromFilter(Dialog.Filter, FilterIndex);
  GetIniPathForExtension(FilterExt, Path);
  if DirectoryExists(Path) and
     (Path <> IncludeTrailingPathDelimiter(Dialog.InitialDir)) then
  begin
    // those two statements don't have the desired effect
    // but illustrate what is meant to happen:
    Dialog.FileName := Path + '*' + FilterExt;
    Dialog.InitialDir := Path;
  end;
end;  { TForm1.actFileOpenOpenDialogTypeChange }
过程TForm1.fileopen1pendialogtypechange(发送方:TObject);
//这不符合预期。。。
变量
对话框:TopEndDialog;
FilterIndex:整数;
FilterText:字符串;
路径:字符串;
开始{TForm1.actfileopendialogtypechange}
对话框:=作为TopEndDialog的发送方;
FilterIndex:=Dialog.FilterIndex;
FilterText:=ExtFromFilter(Dialog.Filter,FilterIndex);
GetIniPathForExtension(FilterText,路径);
如果目录存在(路径)并且
(路径包括RailingPathDelimiter(Dialog.InitialDir))然后
开始
//这两种说法没有达到预期效果
//但请举例说明将要发生什么:
Dialog.FileName:=Path+'*'+filterText;
Dialog.InitialDir:=路径;
结束;
结束;{TForm1.actfileopendialogtypechange}
我找不到任何方法让对话框自动更新到新目录。
我试着调用OpenDialog.Execute,但这会启动另一个OpenDialog,而不会关闭当前的一个…

不久前,我已经考虑过这类事情,但也找不到解决方案。现在我很高兴无论如何都不实施它,原因如下:

假设用户执行“打开”对话框。他知道在哪里可以找到所需的文件,并导航到该文件夹。现在他看不到文件,意识到过滤器设置错误。他更改了过滤器,自然希望文件夹保持不变

尝试做一些观察:在大多数情况下,用户首先选择文件夹,然后选择文件类型。

一种可能性:

var
  ShowAfterClose: boolean = false;
  MemFilterIndex: integer;

procedure TForm1.Import1Click(Sender: TObject);
begin
//...
  with OpenDialogImport do
  repeat
    if Execute then
    begin
      ReadImportedFile(FileName);                     //Do action
      exit;
    end else begin
      if not ShowAfterClose then                     //Check ShowAfterClose
        exit;
      ShowAfterClose := false;                       //Set ShowAfterClose false
      FilterIndex := MemFilterIndex;                 //Copy MemFilterIndex
    end;
  until false;
//...
end;

procedure TForm1.OpenDialogImportTypeChange(Sender: TObject);
begin
 PostMessage(TOpenDialog(Sender).handle,
   WM_KEYDOWN, VK_ESCAPE , 0);                        //Cancel dialog
 TOpenDialog(Sender).InitialDir := 'C:\';             //Set new directory
 MemFilterIndex := TOpenDialog(Sender).FilterIndex;   //Remember filter index
 ShowAfterClose := True;                              //ShowAfterClose = True
end;

到目前为止,我会同意其他人的意见。。。用户界面设计很糟糕,在不询问用户的情况下更改内容,和/或违背用户的意愿。

虽然下面的内容并不完美,但经过2K、XP、Vista和7的测试,它似乎可以工作。其思想是使用对话框的行为,即当在“文件名”框中输入有效目录时,如果按下“打开”按钮,对话框将切换到该文件夹

它不适用于“Vista风格”对话框,我对它一无所知。因此,在显示对话框之前,必须将
UseLatestCommonDialogs
设置为false。另请注意,对话框初始启动时不会触发
OnTypeChange
事件,可以在显示对话框之前设置
FilterIndex
InitialDir


type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure OpenDialog1TypeChange(Sender: TObject);
    procedure OpenDialog1FolderChange(Sender: TObject);
  private
    FDlgCleanUp: Boolean;
    FDlgFocusCtrl: HWnd;
    FSaveDlgFName: array [0..255] of Char;
  public
  end;

[...]

uses
  CommDlg, Dlgs;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    ShowMessage(OpenDialog1.FileName);
end;


type
  TFileExt = (feText = 1, feRichText, feDocument);

const
  FileExts: array [TFileExt] of string = ('txt', 'rtf', 'doc');
  FileExtDesc: array [TFileExt] of string =
      ('text (*.txt)', 'rich text (*.rtf)', 'document (*.doc)');

procedure TForm1.FormCreate(Sender: TObject);
var
  fe: TFileExt;
begin
  OpenDialog1.Options := OpenDialog1.Options - [ofOldStyleDialog];
  NewStyleControls := True;
  UseLatestCommonDialogs := False;

  OpenDialog1.Filter := '';
  for fe := Low(FileExts) to High(FileExts) do
    OpenDialog1.Filter := OpenDialog1.Filter +
        FileExtDesc[fe] + '|*.' + FileExts[fe] + '|';
end;

function GetIniPathForExtension(const Ext: string): string;
begin
  // Get corresponding path from an ini file....
  Result := ExtractFilePath(Application.ExeName) + Ext;
end;

procedure TForm1.OpenDialog1TypeChange(Sender: TObject);
var
  Dialog: TOpenDialog;
  Dlg: HWnd;
  Path: string;
begin
  Dialog := Sender as TOpenDialog;
  Dlg := GetParent(Dialog.Handle);
  Path := GetIniPathForExtension(FileExts[TFileExt(Dialog.FilterIndex)]);
  ForceDirectories(Path);

  // remember what's in file name, have to put it back later
  GetDlgItemText(Dlg, cmb13, @FSaveDlgFName, 256);
  SendMessage(GetDlgItem(Dlg, cmb13), WM_SETREDRAW, 0, 0); // reduce flicker
  FDlgFocusCtrl := GetFocus;

  // set file name to new folder
  SendMessage(Dlg, CDM_SETCONTROLTEXT, cmb13, Longint(PChar(Path)));

  // weird OS: windows - the below is only necessary for XP. 2K, Vista and 7
  // clicks fine without it, XP does not!
  windows.SetFocus(GetDlgItem(Dlg, IDOK));

  // do not cleanup here, with Vista and 7 folder change seems to happen
  // asynchronously - it might occur later than setting the file name and that
  // clears/reverts the edit box.
  FDlgCleanUp := True;

  // click 'Open' to change to folder
  SendMessage(GetDlgItem(Dlg, IDOK), BM_CLICK, IDOK, 0);
end;

procedure TForm1.OpenDialog1FolderChange(Sender: TObject);
var
  Dlg: HWnd;
begin
  // set the file name and focus back
  if FDlgCleanup then begin   // do not intervene if we didn't cause the change
    Dlg := GetParent((Sender as TOpenDialog).Handle);
    SendMessage(GetDlgItem(Dlg, cmb13), WM_SETREDRAW, 1, 0);
    SetDlgItemText(Dlg, cmb13, @FSaveDlgFName);
    windows.SetFocus(FDlgFocusCtrl);
  end;
  FDlgCleanup := False;
end;

请不要更改我的文件夹,当我只更改我正在寻找的文件类型时。。。根据过滤器类型指向“合适的”文件夹可能会对您有所帮助,但我(和大多数用户)不喜欢从他们手中取出东西。这正是你要做的,只要你“友善”地为他们更改文件夹。你(和Uwe)可能是对的。我只是想尝试一下另一种方法,看看用户(包括我自己)是否喜欢它。其思想是,有相当多的文件类型存储在不同的位置,系统(ini文件)会记住每个文件类型最后使用的位置。因此,当对话框打开时,用户选择要查找的文件类型,对话框应该立即切换到(可能)所需的位置。因此,在大多数情况下根本不需要导航。而且应该有一个“后退”按钮(对于Uwe的用例)。我对更智能的对话框想法很满意,但一定要将其作为一个选项,以便可以关闭。当我测试此功能时,PostMessage调用不会使对话框消失。我也尝试过SendMessage。你自己测试过吗?是的,我是,它在D2007和D5下工作。您是否设置了事件OpenDialogImportTypeChange?现在可以了。Windows7上的D2010。我不知道昨天为什么不起作用。为质疑您是否进行了测试而道歉。