views:

211

answers:

4

A user can manually sort files in a standard Windows Open Dialog (in "Details" view mode) by Name, Date or Size by clicking on the corresponding column header. How to set a sorting mode in Open Dialog (TOpenDialog class in Delphi) programmatically in application so that the dialog opens with a preferred sorting?

+1  A: 

TFileOpenDialog (D2009) internally uses the IFileDialog interface from Windows. That interface doesn't offer any way in which to set the sorting of the files. However it does have SetClientGuid and ClearClientData. These are used by TFileOpenDialog through its ClientGUID property. Setting a ClientGuid for your particular instance instructs windows to persist the dialog's state. Windows will then remember things as the last folder opened, the way the files are listed and the sorting.

So, if you just want to accommodate your users by remembering the last way they had the dialog set up when opening a file, all you have to do is set the ClientGUID of the FileOpenDialog.

To get a GUID, press Ctrl-Shft-G in the code editor. Just remember to leave off the square brackets when pasting this into the ClientGUID property.

Marjan Venema
+1  A: 

The GetOpenFileName() API and the Vista IFileDialog interface have no support for this. You can hack the dialog as demonstrated in this magazine article. Beware that the article is quite dated. And that hacks like these are brittle, they may well stop working on the next version of Windows.

Hans Passant
A: 

You could roll your own using a component like DexExpress' TcxShellListView. It allows for sorting of files.

yozey
A: 

After googling the subject I found some "magic numbers" and have come to the following solution (TOpenDialog.OnFolderChange event handler):

procedure TDM.OpenDlgFolderChange(Sender: TObject);
const
  FCIDM_SHVIEW_LARGEICON = $7029;
  FCIDM_SHVIEW_SMALLICON = $702A;
  FCIDM_SHVIEW_LIST = $702B;
  FCIDM_SHVIEW_REPORT = $702C;
  FCIDM_SHVIEW_THUMBNAIL = $702D;
  FCIDM_SHVIEW_TILE = $702E;

  ByName = $7602;
  BySize = $7603;
  ByType = $7604;
  ByModified = $7605;
  ByAttributes = $7608;

var
  Handle: THandle;

begin
  Handle:= FindWindowEx(GetParent(OpenDlg.Handle), 0, 'SHELLDLL_DefView', nil);
  SendMessage(Handle, WM_COMMAND, FCIDM_SHVIEW_REPORT, 0);
  SendMessage(Handle, WM_COMMAND, ByAttributes, 0);
  SendMessage(Handle, WM_COMMAND, ByName, 0);
end;

First message sets "Details" view mode, the second sets sorting "By Attributes" and the third "By Name"; the two different 'sorting' messages are required two guaranty that the final sorting is ascending.

The above code works fine on Win XP, but the sorting part does not work on Win 2000 SP4; on Win 7 the "sorting magic numbers" are shifted, i.e. "ByName = $7603", etc.

Serg