Compared to the XP style in Vista:
Windows 7′s native dialog (for fun purpose):
A file dialog with a custom resource template under Vista (note the extra combo box at the bottom). The dialog is automatically reverted back to the old style:
AFAIK, there is no way to make the old template method work with the Vista’s native dialog. The only way is to make use of the IFileDialogCustomize interface.
The corresponding MSDN documentation is here.
The major drawback of the new method is the extraordinary limitation/restriction. Firstly, the IFileDialogCustomize interface only works with Vista or above. Second, the choice of controls are very limited and no user-defined controls are allowed.
The provided controls are:
- Menu
- Button
- Combo box
- Radio button list
- Check button (check box)
- Edit
- Separator
- Label
Delphi 2009 introduced a new TFileOpenDialog component for Vista. The new class implements the IFileDialog interface, so it ONLY works with Vista or above. The IFileDialogCustomize can be queried from the TFileOpenDialog.Dialog property. Note that TFileOpenDialog.Dialog is always nil unless the dialog is being shown. To get the IFileDialogCustomize interface, do some coding inside the TFileOpenDialog.OnExecute() event:
var
c: IFileDialogCustomize;
begin
if FileOpenDialog1.Dialog.QueryInterface(IFileDialogCustomize, c) = S_OK then
begin
c.StartVisualGroup(0, ‘It is a group’);
c.AddComboBox(1);
c.AddControlItem(1, 1, ‘item 1′);
c.AddControlItem(1, 2, ‘item 2′);
c.EndVisualGroup;
c.MakeProminent(0);
end;
The above code adds a combo box control to the dialog. The "Visual Group" provides a container to group several controls. AddControlItem() method is for adding string item into the combo box. Every control (combo box, edit box etc) or item has a unique id, control’s manipulation and their events are based on the unique ID. For the combo box, an unselected box will return a 0 item ID, so remember to start with index 1 for an item. The MakeProminent() method is to put a group/control AFTER the default filename edit box (the doc reads put it near to the open/save button). The result will look like this:
Why is the method named "Make Prominent" anyway??? The doc reads "Places a control in the dialog so that it stands out compared to other added controls". WTF are they thinking? "STAND OUT"?? hahahaha.
Anyway, controls are pretty useless unless you can interact with them. There are IFileDialogEvents and IFileDialogControlEvents interfaces to deal with the controls. To implement it, simply declare a class:
TTestEvent = class(TInterfacedObject, IFileDialogEvents, IFileDialogControlEvents)
…..
end;
And the complete code for the OnExecute :
procedure TForm1.FileOpenDialog1Execute(Sender: TObject);
var
c: IFileDialogCustomize;
TmpDialogEvents : IFileDialogEvents;
TmpEvents : TTestEvent;
TmpCookie : cardinal;
begin
if FileOpenDialog1.Dialog.QueryInterface(IFileDialogCustomize, c) = S_OK then
begin
c.StartVisualGroup(0, ‘It is a group’);
c.AddComboBox(2);
c.AddControlItem(2, 1, ‘item 1′);
c.AddControlItem(2, 2, ‘item 2′);
c.EndVisualGroup;
c.MakeProminent(0);
TmpEvents := TTestEvent.Create;
TmpEvents.QueryInterface(IFileDialogEvents, TmpDialogEvents);
//remember to UnAdvise it later on
FileOpenDialog1.Dialog.Advise(TmpDialogEvents, TmpCookie);
end;
end;
The link here is the Advise() method. It takes a IFileDialogEvents, but will trigger control’s events if IFileDialogControlEvents is also supported. e.g. to receive an "OnItemSelect" event for the combo box whenever the box item is being selected:
function TTestEvent.OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl,
dwIDItem: DWORD): HResult;
begin
Form1.Caption := Format(‘%d:%d’, [dwIDCtl, dwIDItem]);
result := s_OK;
end;
Actually I am only interested in the final result, so the above helper class can be omitted. Write some code for the TFileOpenDialog.OnOKClick() event:
procedure TForm1.FileOpenDialog1FileOkClick(Sender: TObject;
var CanClose: Boolean);
var
c: IFileDialogCustomize;
n : cardinal;
begin
if FileOpenDialog1.Dialog.QueryInterface(IFileDialogCustomize, c) = S_OK then
begin
c.GetSelectedControlItem(2, n);
showmessage(inttostr(n));
end;
end;
Now I can get the combo’s ItemIndex!
What’s the fuss all about then? Probably I will keep away from the custom file dialog until there is a better solution to put custom controls onto the dialog. There is no simple way to migrate those previous custom common dialog to Vista yet.


Just a note that the docs say you don\’t have to call MakeProminent if you are only adding one item. Also the docs seem to indicate that the argument for MakeProminent is the ControlID, not the VisualGroupID. I\’m guessing that your code works fine because the call isn\’t necessary due to just adding one item. It may be worth mentioning that SetSelectedControlItem can be used to set the initial selection of the added combobox. Thanks for this article, it was extremely helpful!!