2

is it possible to open TOpenDialog, TSaveDialog with focus set to the file list view instead of file name edit box ?

Thanks a lot

Regards

  • As usual for those kinds of questions: any particular reason you'd like to change the *default* behavior? – Cosmin Prund Apr 04 '11 at 10:39
  • You could probably do it with a hack. You'd be better off using the standard behaviour as Cosmin intimates. – David Heffernan Apr 04 '11 at 10:50
  • The application I'm writing now is already unusual with its GUI and because the users will mostly browse the files (not by entering file names) I would prefer this feature. –  Apr 04 '11 at 10:57
  • Then hack the dialog. Send it messages to change focus. Make sure you deal with the fact that XP and Vista/7 have different dialogs that no doubt need different hacks. – David Heffernan Apr 04 '11 at 11:08
  • OK, but how :) ? I would do it by finding list view handle and sending SetFocus API function, but I can't find the way how to get the dialog handle. –  Apr 04 '11 at 11:11
  • That's the bit that's the hack. – David Heffernan Apr 04 '11 at 11:32
  • 2
    You start by calling the [GetOpenFileName Function](http://msdn.microsoft.com/en-us/library/ms646927(v=vs.85).aspx) yourself, so you can provide set up the `lpfnHook` parameter with your own [OFNHookProc Callback Function](http://msdn.microsoft.com/en-us/library/ms646931(v=vs.85).aspx). Not sure if it would work, don't have the time to test this (hence this is a comment, not an answer) – Cosmin Prund Apr 04 '11 at 11:44
  • @Cosmin When you do that you end up with the revolting legacy dialogs on Vista/7. The cure is worse than the disease. – David Heffernan Apr 04 '11 at 12:10

1 Answers1

4

You can put the focus to the control you like but the dialog should be ready when you do that. The 'OnShow' event is early for that. You can use 'OnFolderChange' event for instance, together with a flag in order to not to change the focus every time the folder is changed:

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure OpenDialog1FolderChange(Sender: TObject);
  private
    FDlgSetFocus: Boolean;

uses
  dlgs;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FDlgSetFocus := False;
  OpenDialog1.Execute;
end;

procedure TForm1.OpenDialog1FolderChange(Sender: TObject);
begin
  if not FDlgSetFocus then
    windows.SetFocus(GetDlgItem(GetParent((Sender as TOpenDialog).Handle), lst2));
  FDlgSetFocus := True;
end;
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • 1
    +1; I just started writing a small demo of how to hook `TFileOpenDialog.CreateFileDialog: IFileDialog` in order to register own `IFileDialogEvents` in order to respond to the `OnFolderChange` event. Never crossed my mind the VCL would surface the same event itself! But it's kind of obvious it would... Also OnFolderChange looks like exactly the place to do this (ie: not *inelegant*) because it's called once before the dialog shows on screen. – Cosmin Prund Apr 04 '11 at 12:42
  • @Cosmin - Heh!, I once fell for the same with the OnCanClose event.. I removed the last paragraph in light of your assessment, thanks! – Sertac Akyuz Apr 04 '11 at 13:18
  • What do people do if they want code that runs on Vista/7 and XP? Does everybody write their own wrappers around the two dialogs and switch between them depending on the underlying OS? – David Heffernan Apr 04 '11 at 13:26
  • @David - The VCL does that, so no need for that regarding this case. I tested the above in 2K and W7, seems to work OK. But I guess that could be necessary on some circumstances. – Sertac Akyuz Apr 04 '11 at 13:36
  • @Sertac OK, I see that now, `TFileDialogWrapper`. I'm not familiar with it because I have my own wrapper that's a bit more versatile (and pre-dates the VCL wrapper). – David Heffernan Apr 04 '11 at 13:41