Tag Archives: CFileDialog

File Open Dialog with Multiple Selection – Part 3: Cutting the Dog Tail

First two articles in this series show how to deal with a large number of selected items, by manipulating the OPENFILENAME::lpstrFile buffer, either for old style or Vista-style Open File dialogs. However, if the target system is Windows Vista or newer, we should prefer getting rid of old stuff and use only Vista-style dialogs.
So, let’s cut the dog’s tail as fast and painless as possible!

Using IFileOpenDialog to collect the results

Example 5

This time, we’ve used Common Item Dialog API (IFileOpenDialog interface and so on) instead of the “classic” CFileDialog::GetStartPosition and CFileDialog::GetNextPathName. That allows to step beyond the old stuff limits without overriding any CFileDialog method and without doing any other type of “dancing on the rope”.

Demo application

Vista File Open Dialog with Multiple Selection - Demo

Vista File Open Dialog with Multiple Selection – Demo

The demo application demonstrates how to grab File Open dialog results by using Common Item Dialog API. For demo/testing purpose it has also a function which uses the old way of CFileDialog::GetNextPathName. Just uncheck “Use IFileOpenDialog”, push “Open…” button, select a large number of items from the open file dialog list, then see the difference.

Demo project download: Vista File Open Dialog with Multiple Selection (591)

Notes

  • Common Item Dialog API is supported on Windows Vista and newer.
  • CFileDialog with Vista style is implemented in Visual Studio 2008 and newer.
  • Of course may be also other solutions. For example, someone still would prefer to derive from CFileDialog in order to put all COM stuff in a single place, for making others’ life easier.
  • For any constructive remark or alternative solution(s), please do not hesitate and leave a comment!

Resources

  • MSDN and Windows Dev Center (see the links in the previous articles).

See also

File Open Dialog with Multiple Selection – Part 2: Vista Style

As told in the previous article, if the Open File dialog has Vista style, it’s not possible to use common dialog box messages like CDM_GETFOLDERPATH and CDM_GETSPEC in order to calculate the necessary buffer size, for multiple selection.
Instead, we can use Common Item Dialog API, in our case IFileOpenDialog interface.

Using IFileOpenDialog interface

Here are the main steps:

  1. call CFileDialog::GetIFileOpenDialog to get ponter to IFileOpenDialog interface;
  2. use IFileOpenDialog::GetSelectedItems; it gets a IShellItemArray* containing currently selected items (an array of IShellItem* elements);
  3. for each item call IShellItem::GetDisplayName; use the name length in order to calculate the necessary buffer size.

Example 4

Further, we can use the returned value to set the OPENFILENAME buffer, if necessary, in CFileDialog::OnFileNameChange overridden function (see the previous article).
Anyway, more implementation details can be found in the attached demo application.

Demo application

File Open Dialog with Multiple Selection - Demo Application

File Open Dialog with Multiple Selection – Demo Application

The demo application contains the complete implementation of a CFileDialog-derived class, that fixes the multiple selection issues described in this article. It can be used either for Vista or old style file dialogs. Also, to see what happens if use the default buffer, just uncheck “Use ext. buffer” then push “Open…” and finally, select a large number of items from the open file dialog list.

Demo project download: File Open Dialog with Multiple Selection (677)

Notes

  • Common Item Dialog API is supported on Windows Vista and newer.
  • CFileDialog with Vista style is implemented in Visual Studio 2008 and newer.

Resources

See also

File Open Dialog with Multiple Selection – Part 1: Old Style

One common beginner’s mistake

Someone may use the following code to show a File Open dialog:

Example 1

Setting OFN_ALLOWMULTISELECT flag tells to Open File dialog to allow multiple file selection. That works fine as log as the user selects a pretty small number of files. Otherwise, it fails with no warning and no file name (or even worse, some garbage) is retrieved.

What is the cause?

If the first parameter of constructor is TRUE, CFileDialog uses GetOpenFileName Windows API function that takes an OPENFILENAME structure. No matter if multiple selection is set, it retrieves all selected (full path and) file names in one single bufffer, which is poited by lpstrFile member of OPENFILENAME. By default, the size of that buffer is set to MAX_PATH (about 260) characters which is pretty small.

Setting a large enough buffer before DoModal

One solution is to make pstrFile member of OPENFILENAME to point to a large enough buffer, able to keep much more file names. Also, the nMaxFile structure member must be set to actual extended buffer size (in characters).

Example 2

It works but is not very ellegant because uses a fixed buffer. Next, well show a method which dynamically estimates and allocate the necessary buffer.

Overriding CFileDialog::OnFileNameChange

CFileDialog::OnFileNameChange is a virtual function that is called as a response to CDN_SELCHANGE notification, sent when the user changes the selection. We can override that function in our own CFileDialog-derived class, then send CDM_GETFOLDERPATH and CDM_GETSPEC mesages in order to estimate the required buffer size.

Example 3

Pretty nice but it works only if CFileDialog has not Vista style. I’ll show how to resolve this, in the next article.

Resources

See also

MFC-extension WIC File Dialogs

A previous article showed how to enumerate WIC (Windows Imaging Component) codecs, that are available in system.
Now, let’s use the codecs list in order to make File Open and File Save As dialogs which are dealing with WIC-compliant image files, i.e. having “File of type” filter list according to available WIC codecs (see the images, below).

WIC Open File Dialog

WIC Open File Dialog

 

WIC Save As File Dialog

WIC Save As File Dialog

CWICFileDialog class

CWICFileDialog is derived from CFileDialog MFC class. It basically overrides CFileDialog::DoModal and constructs the file types filter.

For implementation details, download the demo project attached here.

Demo project

The demo project is just a simple dialog-based MFC application that uses CWICFileDialog. It does nothing else but only shows the file dialogs.
Of course, in practice, you can use CWICFileDialog class in more complex applications like image file viewers, image file converters, and so on.

Resources

See also

Downloads