ciderpress/util/SelectFilesDialog.h

188 lines
6.7 KiB
C
Raw Permalink Normal View History

2007-03-27 17:47:10 +00:00
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* File selection dialog, a sub-class of "Open" that allows multiple selection
* of both files and directories.
*
* This is something of a nightmare to work through. The standard Windows
* dialog will return multiple selected files, but omits the directories,
* leaving the developer to find alternative means of acquiring the complete
* list of files. The most popular approach is to dig into the CListView
* object (lst2) and peruse the set of selected files from the control itself.
*
* Complicating this is the existence of three very different dialog
* implementations, known as "old style", "explorer" and "vista". Since
* we are currently targeting WinXP as a minimum OS level, and I would
* prefer not to have multiple implementations, this code targets the
* explorer-style dialogs.
*
* The API follows the standard file dialog multi-select pattern, which
* returned a directory name followed by a series of files in that directory.
* We simplify things a bit by returning the pathname separately and the
* filenames in a string array.
*
* The current implementation owes a debt to Hojjat Bohlooli's
* SelectDialog sample (http://www.codeproject.com/Articles/28015/).
*
* Other relevant links:
* http://www.codeproject.com/dialog/select_all_button.asp
* http://www.codeproject.com/dialog/select_all_button.asp
* http://www.codeproject.com/dialog/customize_dialog.asp
* http://stackoverflow.com/questions/31059/
*
* I wish I could say all this nonsense was fixed in the "vista" dialogs,
* but it isn't (e.g. http://stackoverflow.com/questions/8269696/ ).
2007-03-27 17:47:10 +00:00
*/
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
#ifndef UTIL_SELECTFILESDIALOG_H
#define UTIL_SELECTFILESDIALOG_H
2007-03-27 17:47:10 +00:00
/*
* File selection, based on an "open" common file dialog.
*/
class SelectFilesDialog : public CFileDialog {
public:
SelectFilesDialog(const WCHAR* rctmpl, bool showHelp, CWnd* pParentWnd = NULL) :
CFileDialog(true, NULL, NULL, OFN_HIDEREADONLY, NULL, pParentWnd,
0, FALSE /*disable Vista style*/),
fPrevWndProc(NULL)
{
// Set flags. We specify ALLOWMULTISELECT but no filename buffer;
// we want the multi-select behavior but we don't want to return
// the filenames in the filename buf.
m_ofn.Flags |= OFN_ENABLETEMPLATE | OFN_ALLOWMULTISELECT |
OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING |
(showHelp ? OFN_SHOWHELP : 0);
// Configure use of a template. The dialog template must have
// WS_CHILD and WS_CLIPSIBLINGS set, and should have DS_3DLOOK and
// DS_CONTROL set as well.
m_ofn.lpTemplateName = rctmpl;
m_ofn.hInstance = AfxGetInstanceHandle();
}
virtual ~SelectFilesDialog(void) {}
/*
* Gets the directory name where the files live. This is a full path.
*/
const CString& GetDirectory(void) const { return fCurrentDirectory; }
/*
* Gets the file name array. This is only valid if the dialog exited
* successfully (DoModal returned IDOK).
*/
const CStringArray& GetFileNames(void) const { return fFileNameArray; }
/*
* Sets the window title; must be called before DoModal.
*/
void SetWindowTitle(const WCHAR* title) {
fCustomTitle = title;
m_ofn.lpstrTitle = (LPCWSTR) fCustomTitle;
}
/*
* Stuffs a single file/directory into the return value fields. This is
* (mis-)used by code that treats AddFilesDialog as a way to pass data
* around.
*
* TODO: don't do this -- change the callers to pass data around differently
*/
void StuffSingleFilename(const CString& directory, const CString& filename) {
fCurrentDirectory = directory;
fFileNameArray.RemoveAll();
fFileNameArray.Add(filename);
}
protected:
// This is much like DoDataExchange, but ret val replaces pDX->Fail().
// This will be called with saveAndValidate==true during OnInitDialog,
// and with false when we've extracted the filenames and are about to
// close the dialog.
//
// Return true on success, false if something failed and we want to keep
// the dialog open.
virtual bool MyDataExchange(bool saveAndValidate) { return true; }
// Handles a click on the "help" button.
virtual void HandleHelp() {}
private:
DECLARE_COPY_AND_OPEQ(SelectFilesDialog)
/*
* Finishes configuring the file dialog.
*/
virtual void OnInitDone() override;
/*
* Tracks changes to the current directory.
*
* Updates fCurrentDirectory with the path currently being used by the
* dialog. For items with no path (e.g. Computer or Libraries), this
* will set an empty string.
*/
virtual void OnFolderChange() override;
/*
* Custom filename validation; in our case, it's a double-click trap.
*
* Returns 0 if the name looks good, 1 otherwise. If we return 1, the
* dialog will not close.
*/
virtual BOOL OnFileNameOK() override;
/*
* Our WindowProc callback function. Watches for the OK button.
*/
static LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
// filename parse result
enum FPResult { kFPDone, kFPPassThru, kFPNoFiles, kFPError };
/*
* The "OK" (actually "Open" or "Accept") button was clicked. Extract
* the filenames from the list control.
*
* Possible return values:
* OK_DONE
* We have successfully obtained the list of files and folders.
* OK_PASSTHRU
* Let the parent dialog process the event. This is done when the
* edit box contains a directory name -- we want the dialog to
* change to that directory.
* OK_NOFILES
* No files were selected. Keep the dialog open.
* OK_ERROR
* Something went wrong.
*/
FPResult OKButtonClicked(CFileDialog* pDialog);
/*
* Parses the file name string returned by the dialog. Adds them to
* fPathNameArray. Returns the number of names found, or -1 if the
* string appears to be invalid.
*/
int ParseFileNames(const CString& str);
/*
* Previous WindowProc. Most messages will be forwarded to this.
*/
WNDPROC fPrevWndProc;
CString fCustomTitle;
// Directory the dialog is currently accessing. Prepend this to the
// entries in fFileNameArray to get full paths.
CString fCurrentDirectory;
// File names of selected files.
CStringArray fFileNameArray;
};
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
#endif /*UTIL_SELECTFILESDIALOG_H*/