Delphi 如何切换';当前';OnTypeChange处理程序中TopEndDialog的目录?(有可能吗?)
根据选择的过滤器,我希望OpenDialog在不同的目录中“查看”。 比如: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
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。我不知道昨天为什么不起作用。为质疑您是否进行了测试而道歉。