Updated/Revamped a bit: 17 Jan 2015
Attached is a working example of using the IFileDialog interface introduced in Vista. It is the replacement for the common dialog used for opening/saving files and browsing for folders. This code is not compatible with XP and lower. You should ensure your project has needed logic to verify system is Vista or better. This version does not currently support enhancements provided by Win7 and above. I do plan on adding them in the near future. This class-only solution is based off of my project: Creating COM Interfaces without TLBs
The classes are plug & play. No TLB references are required. The main class is the IFileDialog class and can be used-as is. The optional IFileDialogEvents class is provided so that you can receive callbacks while the IFileDialog is displayed. Before Vista, this would have required subclassing the dialog, but Vista provided a way to do this through simple callback events. This optional events class is not required to display the dialog. But that class is required if you want callbacks, wish to filter what is displayed in the dialog, or want to add your own controls to the dialog. That class must be implemented if used. This means adding a line of code in your declarations section: Implements IFileDialogEvents. Lets talk about the three types of events. You can opt to have any of them or none of them.
Each event sent from the class includes a reference to the Dialog, a user-defined key for the instance of the Dialog, and appropriate event-driven parameters. Some events expect an answer back from you. Though all events will be added when you Implement the class, you only have to code for the ones you asked for & want to respond to.
1. Standard Callback Events. The IFileDialog can forward events to whatever is displaying the dialog. The most common events are: DialogOnInit, OnFolderChanging, OnSelectionChange, OnFieOk. The OnFileOk event occurs just before the user is about to close the dialog and offers you a chance to prevent closing the dialog and/or cache any custom control properties set by the user while the dialog was displayed. The OnFolderChanging event offers you a way to prevent the user from navigating to what they clicked on. There are a few other events that are forwarded and can be reviewed on MSDN. Note: DialogOnInit is a custom event the class sends. It is intended for you to finalize any custom controls you may have added, i.e., setting an option button, selecting a combobox item, etc, before the dialog is displayed. Any actions you take will not be forwarded back through events until DialogOnInit returns. Should you need to actually subclass the dialog, you can do it at this time since the hWnd of the dialog is known.
2. Filter Events. We all know we can assign filters to a file dialog like *.exe, *.txt, *.dll, etc. The dialog offers a more advanced filter where you can individually choose whether what is returned during navigation is actually displayed. When the filter is active, Windows sends you, one by one, every item that would be displayed. You can opt to say yes or no. Note: This was deprecated in Win7 & may not be added back.
3. Custom Control Events. You have the option to add controls to the dialog. These include combo/check/text boxes, option/command buttons, labels, & menu-like controls. There is little point in adding controls if you have no way of knowing if the user is clicking on them. So the dialog can send you some events. However, these events are lacking in my opinion. They do offer basic stuff, like something was clicked, something was selected, but little else. Any added textbox controls, for example, have no events passed. There are no got/lost focus events for the controls. Locating these controls for manual subclassing will be a challenge.
Here's the gotcha. As mentioned, this is not compatible with anything lower than Vista. But you also must get outside of your comfort zone a bit too. Where the older common dialog returned file & folder names, this new version returns objects as IShellItems and IShellItemArrays (when multi-selecting items). That's really not a bad thing. Not only can you have these items give you the file/folder name and 'display' name, you can ask it to give you that name as plain text or as a URL or a few other formats. You can have it give you file attributes of the object. Since no TLBs are used, the IFileDialog class has methods that will allow you to query the returned object for those things.
What I don't like about this new implementation of the dialog? The folder browsing is too limited in my opinion. The older version allowed several flags to restrict what was displayed. This new version has very little options for folders. Win7 added the ability to restrict browsing to the local domain, but other than that, not much. The lack of options from previous version lends to possibility of needing custom filters (#2 above). Additionally, the previous version allowed files to be displayed with folders when browsing for folders. The new version doesn't have that ability. Matter of learning to adjust I guess, but I feel code for the older version of folder browsing may still be worth keeping around.
These classes don't have all the dummy-proofing I tend to add in. It's a work-in-progress. But it is important you become familiar with it before attempting to use it for any serious projects. And come back occasionally to look for updates.
What advantage does this have over TLBs? Only one I can think of: can create a class that can be added to any project without needing to carry over TLBs into the target application.
The sample project does not touch all the properties the IFileDialog class offers. Explore a bit.
Attached is a working example of using the IFileDialog interface introduced in Vista. It is the replacement for the common dialog used for opening/saving files and browsing for folders. This code is not compatible with XP and lower. You should ensure your project has needed logic to verify system is Vista or better. This version does not currently support enhancements provided by Win7 and above. I do plan on adding them in the near future. This class-only solution is based off of my project: Creating COM Interfaces without TLBs
The classes are plug & play. No TLB references are required. The main class is the IFileDialog class and can be used-as is. The optional IFileDialogEvents class is provided so that you can receive callbacks while the IFileDialog is displayed. Before Vista, this would have required subclassing the dialog, but Vista provided a way to do this through simple callback events. This optional events class is not required to display the dialog. But that class is required if you want callbacks, wish to filter what is displayed in the dialog, or want to add your own controls to the dialog. That class must be implemented if used. This means adding a line of code in your declarations section: Implements IFileDialogEvents. Lets talk about the three types of events. You can opt to have any of them or none of them.
Each event sent from the class includes a reference to the Dialog, a user-defined key for the instance of the Dialog, and appropriate event-driven parameters. Some events expect an answer back from you. Though all events will be added when you Implement the class, you only have to code for the ones you asked for & want to respond to.
1. Standard Callback Events. The IFileDialog can forward events to whatever is displaying the dialog. The most common events are: DialogOnInit, OnFolderChanging, OnSelectionChange, OnFieOk. The OnFileOk event occurs just before the user is about to close the dialog and offers you a chance to prevent closing the dialog and/or cache any custom control properties set by the user while the dialog was displayed. The OnFolderChanging event offers you a way to prevent the user from navigating to what they clicked on. There are a few other events that are forwarded and can be reviewed on MSDN. Note: DialogOnInit is a custom event the class sends. It is intended for you to finalize any custom controls you may have added, i.e., setting an option button, selecting a combobox item, etc, before the dialog is displayed. Any actions you take will not be forwarded back through events until DialogOnInit returns. Should you need to actually subclass the dialog, you can do it at this time since the hWnd of the dialog is known.
2. Filter Events. We all know we can assign filters to a file dialog like *.exe, *.txt, *.dll, etc. The dialog offers a more advanced filter where you can individually choose whether what is returned during navigation is actually displayed. When the filter is active, Windows sends you, one by one, every item that would be displayed. You can opt to say yes or no. Note: This was deprecated in Win7 & may not be added back.
3. Custom Control Events. You have the option to add controls to the dialog. These include combo/check/text boxes, option/command buttons, labels, & menu-like controls. There is little point in adding controls if you have no way of knowing if the user is clicking on them. So the dialog can send you some events. However, these events are lacking in my opinion. They do offer basic stuff, like something was clicked, something was selected, but little else. Any added textbox controls, for example, have no events passed. There are no got/lost focus events for the controls. Locating these controls for manual subclassing will be a challenge.
Here's the gotcha. As mentioned, this is not compatible with anything lower than Vista. But you also must get outside of your comfort zone a bit too. Where the older common dialog returned file & folder names, this new version returns objects as IShellItems and IShellItemArrays (when multi-selecting items). That's really not a bad thing. Not only can you have these items give you the file/folder name and 'display' name, you can ask it to give you that name as plain text or as a URL or a few other formats. You can have it give you file attributes of the object. Since no TLBs are used, the IFileDialog class has methods that will allow you to query the returned object for those things.
What I don't like about this new implementation of the dialog? The folder browsing is too limited in my opinion. The older version allowed several flags to restrict what was displayed. This new version has very little options for folders. Win7 added the ability to restrict browsing to the local domain, but other than that, not much. The lack of options from previous version lends to possibility of needing custom filters (#2 above). Additionally, the previous version allowed files to be displayed with folders when browsing for folders. The new version doesn't have that ability. Matter of learning to adjust I guess, but I feel code for the older version of folder browsing may still be worth keeping around.
These classes don't have all the dummy-proofing I tend to add in. It's a work-in-progress. But it is important you become familiar with it before attempting to use it for any serious projects. And come back occasionally to look for updates.
What advantage does this have over TLBs? Only one I can think of: can create a class that can be added to any project without needing to carry over TLBs into the target application.
The sample project does not touch all the properties the IFileDialog class offers. Explore a bit.