mirror of
https://github.com/fadden/ciderpress.git
synced 2026-04-22 09:17:01 +00:00
File selection dialog update, part 1
This adds a replacement for the SelectFilesDialog class. It has been updated to use Explorer-style dialogs, which are a bit nicer than the old-style dialogs. Hopefully this will eliminate some of the brain damage, like the disappearing Accept button. This change only updates MDC. A second change will update the main app and remove the old code. Also, updated the MDC version to 3.0.0, and changed the web site linked in the Help menu from faddensoft.com to a2ciderpress.com.
This commit is contained in:
+389
-61
@@ -3,49 +3,6 @@
|
||||
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
||||
* See the file LICENSE for distribution terms.
|
||||
*/
|
||||
/*
|
||||
* Support for file selection dialog.
|
||||
*
|
||||
* What we want to do is get the full set of selected files out of the dialog.
|
||||
* However, Windows does not provide a way to do that. There are various
|
||||
* slightly awkward approaches:
|
||||
*
|
||||
* - Get the IShellView pointer via the IShellBrowser pointer via the
|
||||
* undocumented WM_GETISHELLBROWSER message. You can then play with the
|
||||
* shellview window, select items with SelectItem(), and get an object
|
||||
* representing the selected items with another call. What form the
|
||||
* object takes is frustratingly unspecified.
|
||||
* http://www.codeproject.com/dialog/select_all_button.asp
|
||||
* - Get the CListView so you can play with its members. This is done by
|
||||
* GetParent --> GetItem(lst2) --> GetItem(1), which is probably
|
||||
* somewhat fragile, but seems to work on 98 through XP. Standard LVN
|
||||
* stuff applies.
|
||||
* http://www.codeguru.com/mfc/comments/10216.shtml
|
||||
* - Using a window hook (not an OFN hook), get the class name and strcmp()
|
||||
* it for the class we're looking for ("syslistview32"). Once we have
|
||||
* it, proceed as above.
|
||||
* http://www.codeproject.com/dialog/customize_dialog.asp
|
||||
*
|
||||
* Care must be taken with the ListView because it doesn't contain file names,
|
||||
* but rather display names (potentially without filename extensions). The
|
||||
* next big assumptive leap is that the ItemData pointer is a shell PIDL that
|
||||
* can be used directly.
|
||||
*
|
||||
* The PIDL stored is, of course, relative to the IShellFolder currently being
|
||||
* displayed. There's no easy way to get that, but if we just go ahead and
|
||||
* call SHGetPathFromIDList anyway we get the right file name with the wrong
|
||||
* path (it appears to be the desktop folder). We can strip the path off and
|
||||
* prepend the value from the undocumented GetFolderPath() call (which just
|
||||
* issues a CDM_GETFOLDERPATH message).
|
||||
*
|
||||
* To make matters even more interesting, it is necessary to provide a "hook"
|
||||
* function to prevent double-clicking from closing the dialog while side-
|
||||
* stepping our additions. Of course, adding an OFN hook renders all of the
|
||||
* existing message map and initialization stuff inoperable. You can stuff
|
||||
* things through various "user data" pointers and end up with access to your
|
||||
* object, and if you cram the hook procedure's hDlg into the object's m_hWnd
|
||||
* you can treat "this" like a window instead of passing HWNDs around.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "SelectFilesDialog.h"
|
||||
#include "PathName.h"
|
||||
@@ -53,6 +10,374 @@
|
||||
#include <dlgs.h>
|
||||
|
||||
|
||||
void SelectFilesDialog2::OnInitDone()
|
||||
{
|
||||
// Tweak the controls
|
||||
SetControlText(IDOK, L"Accept");
|
||||
|
||||
HideControl(stc2); // "Files of type"
|
||||
HideControl(cmb1); // (file type combo)
|
||||
|
||||
// Configure a window proc to intercept events. We need to do it this
|
||||
// way, rather than using m_ofn.lpfnHook, because the CFileDialog hook
|
||||
// does not receive messages intended for the standard controls of the
|
||||
// default dialog box. Since our goal is to intercept the "OK" button,
|
||||
// we need to set a proc for the whole window.
|
||||
CWnd* pParent = GetParent();
|
||||
fPrevWndProc = (WNDPROC) ::SetWindowLongPtr(pParent->m_hWnd, GWL_WNDPROC,
|
||||
(LONG_PTR) MyWindowProc);
|
||||
|
||||
// Stuff a pointer to this object into the userdata field.
|
||||
::SetWindowLongPtr(pParent->m_hWnd, GWL_USERDATA, (LONG_PTR) this);
|
||||
}
|
||||
|
||||
void SelectFilesDialog2::OnFolderChange()
|
||||
{
|
||||
// We get one of these shortly after OnInitDone. We can't do this in
|
||||
// OnInitDone because the dialog isn't ready yet.
|
||||
//
|
||||
// Ideally we'd just call GetFolderPath(), but for some reason that
|
||||
// returns an empty string for places like Desktop or My Documents
|
||||
// (which, unlike Computer or Libraries, do have filesystem paths).
|
||||
// You actually get the path in the string returned from the multi-select
|
||||
// file dialog, but apparently you have to use a semi-hidden method
|
||||
// to get at it from OnFolderChange.
|
||||
//
|
||||
// In other words, par for the course in Windows file dialogs.
|
||||
|
||||
fCurrentDirectory = L"";
|
||||
CWnd* pParent = GetParent();
|
||||
LRESULT len = pParent->SendMessage(CDM_GETFOLDERIDLIST, 0, NULL);
|
||||
if (len <= 0) {
|
||||
LOGW("Can't get folder ID list, len is %d", len);
|
||||
} else {
|
||||
LPCITEMIDLIST pidlFolder = (LPCITEMIDLIST) CoTaskMemAlloc(len);
|
||||
len = pParent->SendMessage(CDM_GETFOLDERIDLIST, len,
|
||||
(LPARAM) pidlFolder);
|
||||
ASSERT(len > 0); // should fail earlier, or not at all
|
||||
|
||||
WCHAR buf[MAX_PATH];
|
||||
BOOL result = SHGetPathFromIDList(pidlFolder, buf);
|
||||
if (result) {
|
||||
fCurrentDirectory = buf;
|
||||
} else {
|
||||
fCurrentDirectory = L"";
|
||||
}
|
||||
CoTaskMemFree((LPVOID) pidlFolder);
|
||||
}
|
||||
|
||||
LOGD("OnFolderChange: '%ls'", (LPCWSTR) fCurrentDirectory);
|
||||
}
|
||||
|
||||
BOOL SelectFilesDialog2::OnFileNameOK()
|
||||
{
|
||||
// This function provides "custom validation of filenames that are
|
||||
// entered into a common file dialog box". We don't need to validate
|
||||
// filenames here, but we do require it for another reason: if the user
|
||||
// double-clicks a file, the dialog will accept the name and close
|
||||
// without our WindowProc getting a WM_COMMAND.
|
||||
//
|
||||
// This function doesn't get called if we select a file or files and
|
||||
// hit the OK button or enter key, because we intercept that before
|
||||
// the dialog can get to it. It also doesn't get called if you
|
||||
// double-click directory, as directory traversal is handled internally
|
||||
// by the dialog.
|
||||
//
|
||||
// It's possible to click then shift-double-click to select a range,
|
||||
// so we can have content in both the list and the text box. This is
|
||||
// really just another way to hit "OK".
|
||||
|
||||
LOGD("OnFileNameOK");
|
||||
CFileDialog* pDialog = (CFileDialog*) GetParent();
|
||||
FPResult fpr = OKButtonClicked(pDialog);
|
||||
switch (fpr) {
|
||||
case kFPDone:
|
||||
return 0; // success, let the dialog exit
|
||||
case kFPPassThru:
|
||||
LOGW("WEIRD: got OK_PASSTHRU from double click");
|
||||
return 1;
|
||||
case kFPNoFiles:
|
||||
LOGW("WEIRD: got OK_NOFILES from double click");
|
||||
return 1;
|
||||
case kFPError:
|
||||
return 1;
|
||||
default:
|
||||
assert(false);
|
||||
return 1;
|
||||
}
|
||||
// not reached
|
||||
}
|
||||
|
||||
/*static*/ LRESULT CALLBACK SelectFilesDialog2::MyWindowProc(HWND hwnd,
|
||||
UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
SelectFilesDialog2* pSFD =
|
||||
(SelectFilesDialog2*) ::GetWindowLong(hwnd, GWL_USERDATA);
|
||||
|
||||
if (uMsg == WM_COMMAND) {
|
||||
// React to a click on the OK button (also triggered by hitting return
|
||||
// in the filename text box).
|
||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) {
|
||||
// Obtain a CFileDialog pointer from the window handle. The
|
||||
// SelectFilesDialog pointer only gets us to a child window
|
||||
// (the one used to implement the templated custom stuff).
|
||||
CFileDialog* pDialog = (CFileDialog*) CWnd::FromHandle(hwnd);
|
||||
FPResult fpr = pSFD->OKButtonClicked(pDialog);
|
||||
switch (fpr) {
|
||||
case kFPDone:
|
||||
// Success; close the dialog with IDOK as the return.
|
||||
LOGD("Calling EndDialog");
|
||||
pDialog->EndDialog(IDOK);
|
||||
return 0;
|
||||
case kFPPassThru:
|
||||
LOGD("passing through");
|
||||
// User typed a single name that didn't resolve to a
|
||||
// simple file. Let the CFileDialog have it so it can
|
||||
// do a directory change. (We don't just want to return
|
||||
// nonzero -- fall through to call prior window proc.)
|
||||
break;
|
||||
case kFPNoFiles:
|
||||
// No files have been selected. We popped up a message box.
|
||||
// Discontinue processing.
|
||||
return 0;
|
||||
case kFPError:
|
||||
// Something failed internally. Don't let the parent dialog
|
||||
// continue on.
|
||||
return 0;
|
||||
default:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ::CallWindowProc(pSFD->fPrevWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
SelectFilesDialog2::FPResult SelectFilesDialog2::OKButtonClicked(CFileDialog* pDialog)
|
||||
{
|
||||
// There are two not-quite-independent sources of filenames. As
|
||||
// ordinary (non-directory) files are selected, they are added to the
|
||||
// edit control. The user is free to edit the text in the box. This is
|
||||
// then what would be returned to the user of the file dialog. With
|
||||
// OFN_FILEMUSTEXIST, the dialog would even confirm that the files exist.
|
||||
//
|
||||
// It is possible to select a bunch of files, delete the text, type
|
||||
// some more names, and hit OK. In that case you would get a completely
|
||||
// disjoint set of names in the list control and edit control.
|
||||
//
|
||||
// Complicating matters somewhat is the "hide extensions for known file
|
||||
// types" feature, which strips the filename extensions from the entries
|
||||
// in the list control. As the files are selected, the names -- with
|
||||
// extensions -- are added to the edit box. So we'd really like to get
|
||||
// the names from the edit control.
|
||||
//
|
||||
// (Win7: Control Panel, Appearance and Personalization, Folder Options,
|
||||
// View tab, scroll down, "Hide extensions for known file types" checkbox.)
|
||||
//
|
||||
// So we need to get the directory names out of the list control, because
|
||||
// that's the only place we can find them, and we need to get the file
|
||||
// names out of the edit control, because that's the only way to get the
|
||||
// full file name (not to mention any names the user typed).
|
||||
//
|
||||
// We have a special case: we want to be able to type a path into
|
||||
// the filename field to go directly there (e.g. "C:\src\test", or a
|
||||
// network path like "\\webby\fadden"). If the text edit field contains
|
||||
// a single name, and the name isn't a simple file, we want to let the
|
||||
// selection dialog exercise its default behavior.
|
||||
|
||||
LOGV("OKButtonClicked");
|
||||
|
||||
// reset array in case we had a previous partially-successful attempt
|
||||
fFileNameArray.RemoveAll();
|
||||
|
||||
// add a slash to the directory name, unless it's e.g. "C:\"
|
||||
CString curDirSlash = fCurrentDirectory;
|
||||
if (curDirSlash.GetAt(curDirSlash.GetLength() - 1) != '\\') {
|
||||
curDirSlash += '\\';
|
||||
}
|
||||
|
||||
// Get the contents of the text edit control.
|
||||
CString editStr;
|
||||
LRESULT editLen = pDialog->SendMessage(CDM_GETSPEC, 0, NULL);
|
||||
if (editLen > 0) {
|
||||
LPTSTR buf = editStr.GetBuffer(editLen);
|
||||
pDialog->SendMessage(CDM_GETSPEC, editLen, (LPARAM) buf);
|
||||
editStr.ReleaseBuffer();
|
||||
}
|
||||
LOGV("textedit has '%ls'", (LPCWSTR) editStr);
|
||||
|
||||
// Parse the contents into fFileNameArray.
|
||||
int fileCount = ParseFileNames(editStr);
|
||||
if (fileCount < 0) {
|
||||
::MessageBeep(MB_ICONERROR);
|
||||
return kFPError;
|
||||
}
|
||||
|
||||
// find the ShellView control
|
||||
CWnd* pListWrapper = pDialog->GetDlgItem(lst2);
|
||||
if (pListWrapper == NULL) {
|
||||
LOGE("Unable to find ShellView (lst2=%d) in file dialog", lst2);
|
||||
return kFPError;
|
||||
}
|
||||
|
||||
// get the list control, with voodoo
|
||||
CListCtrl* pList = (CListCtrl*) pListWrapper->GetDlgItem(1);
|
||||
if (pList == NULL) {
|
||||
LOGE("Unable to find list control");
|
||||
return kFPError;
|
||||
}
|
||||
|
||||
// Check to see if nothing is selected, or exactly one directory has
|
||||
// been found in the text box.
|
||||
int listCount = pList->GetSelectedCount();
|
||||
LOGD("Found %d selected items", listCount);
|
||||
if (listCount + fileCount == 0) {
|
||||
MessageBox(L"Please select one or more files and directories.",
|
||||
m_ofn.lpstrTitle, MB_OK | MB_ICONWARNING);
|
||||
return kFPNoFiles;
|
||||
} else if (fileCount == 1 && listCount == 0) {
|
||||
CString file(fFileNameArray[0]);
|
||||
CString path;
|
||||
if (file.Find('\\') == -1) {
|
||||
// just the filename, prepend the current dir
|
||||
path = curDirSlash + file;
|
||||
} else {
|
||||
// full (?) path, don't alter it
|
||||
path = file;
|
||||
}
|
||||
DWORD attr = GetFileAttributes(path);
|
||||
LOGV("Checking to see if '%ls' is a directory: 0x%08lx",
|
||||
(LPCWSTR) path, attr);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
(attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
return kFPPassThru;
|
||||
}
|
||||
}
|
||||
|
||||
// Run through the list, looking for directories. We have to prepend the
|
||||
// current directory to each entry and check the filesystem.
|
||||
int index = pList->GetNextItem(-1, LVNI_SELECTED);
|
||||
int dirCount = 0;
|
||||
while (listCount--) {
|
||||
CString itemText(pList->GetItemText(index, 0));
|
||||
CString path(curDirSlash + itemText);
|
||||
DWORD attr = GetFileAttributes(path);
|
||||
LOGV(" %d: 0x%08lx '%ls'", index, attr, (LPCWSTR) itemText);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
(attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
fFileNameArray.Add(itemText);
|
||||
dirCount++;
|
||||
}
|
||||
|
||||
index = pList->GetNextItem(index, LVNI_SELECTED);
|
||||
}
|
||||
LOGV(" added %d directories", dirCount);
|
||||
|
||||
return kFPDone;
|
||||
}
|
||||
|
||||
int SelectFilesDialog2::ParseFileNames(const CString& str)
|
||||
{
|
||||
// The filename string can come in two forms. If only one filename was
|
||||
// selected, the entire string will be the filename (spaces and all). If
|
||||
// more than one file was selected, the individual filenames will be
|
||||
// surrounded by double quotes. All of this assumes that the names were
|
||||
// put there by the dialog -- if the user just types a bunch of
|
||||
// space-separated filenames without quotes, we can't tell that from a
|
||||
// single long name with spaces.
|
||||
//
|
||||
// Double quotes aren't legal in Windows filenames, so we don't have
|
||||
// to worry about embedded quotes.
|
||||
//
|
||||
// So: if the string contains any double quotes, we assume that a series
|
||||
// of quoted names follows. Anything outside quotes is accepted as a
|
||||
// single space-separated name. If the string does not have any '"',
|
||||
// we just grab the whole thing as a single entry.
|
||||
//
|
||||
// It's possible to see a full path here -- we allow a special case
|
||||
// where the user can type a path into the text box to change directories.
|
||||
// We only expect to see one of those, though, so it must not be quoted.
|
||||
//
|
||||
// The dialog seems to leave an extra space at the end of multi-file
|
||||
// strings.
|
||||
|
||||
LOGD("ParseFileNames '%ls'", (LPCWSTR) str);
|
||||
if (str.GetLength() == 0) {
|
||||
// empty string
|
||||
return 0;
|
||||
} else if (str.Find('\"') == -1) {
|
||||
// no quotes, single filename, possibly with spaces
|
||||
fFileNameArray.Add(str);
|
||||
return 1;
|
||||
} else if (str.Find('\\') != -1) {
|
||||
// should not be multiple full/partial paths, string is invalid
|
||||
LOGW("Found multiple paths in '%ls'", (LPCWSTR) str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const WCHAR* cp = str;
|
||||
const WCHAR* start;
|
||||
while (*cp != '\0') {
|
||||
// consume whitespace, which should only be spaces
|
||||
while (*cp == ' ') {
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (*cp == '\0') {
|
||||
// reached end of string
|
||||
break;
|
||||
} else if (*cp == '\"') {
|
||||
// grab quoted item
|
||||
cp++;
|
||||
start = cp;
|
||||
while (*cp != '\"' && *cp != '\0') {
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (cp == start) {
|
||||
// empty quoted string; ignore
|
||||
LOGV(" found empty string in '%ls'", (LPCWSTR) str);
|
||||
} else {
|
||||
CString name(start, cp - start);
|
||||
LOGV(" got quoted '%ls'", (LPCWSTR) name);
|
||||
fFileNameArray.Add(name);
|
||||
}
|
||||
if (*cp != '\0') {
|
||||
cp++; // advance past closing quote
|
||||
} else {
|
||||
LOGV(" (missing closing quote)");
|
||||
}
|
||||
} else {
|
||||
// found unquoted characters
|
||||
start = cp;
|
||||
cp++;
|
||||
while (*cp != ' ' && *cp != '\"' && *cp != '\0') {
|
||||
cp++;
|
||||
}
|
||||
CString name(start, cp - start);
|
||||
LOGV(" got unquoted '%ls'", (LPCWSTR) name);
|
||||
fFileNameArray.Add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Our CFileDialog "hook" function.
|
||||
*
|
||||
@@ -85,7 +410,7 @@
|
||||
|
||||
switch (uiMsg) {
|
||||
case WM_INITDIALOG:
|
||||
LOGI("WM_INITDIALOG, OFN=0x%08lx", lParam);
|
||||
LOGD("WM_INITDIALOG, OFN=0x%08lx", lParam);
|
||||
SetWindowLong(hDlg, GWL_USERDATA, lParam);
|
||||
break;
|
||||
case WM_NOTIFY: // 0x4e
|
||||
@@ -101,9 +426,9 @@
|
||||
ASSERT(pSFD != NULL);
|
||||
return pSFD->HandleHelp(hDlg, (LPHELPINFO) lParam);
|
||||
default:
|
||||
//LOGI("OFNHookProc: hDlg=0x%08lx uiMsg=0x%08lx "
|
||||
// "wParam=0x%08lx lParam=0x%08lx",
|
||||
// hDlg, uiMsg, wParam, lParam);
|
||||
LOGV("OFNHookProc: hDlg=0x%08lx uiMsg=0x%08lx "
|
||||
"wParam=0x%08lx lParam=0x%08lx",
|
||||
hDlg, uiMsg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -173,7 +498,7 @@ UINT SelectFilesDialog::HandleNotify(HWND hDlg, LPOFNOTIFY pofn)
|
||||
*/
|
||||
UINT SelectFilesDialog::HandleCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LOGI(" HandleCommand wParam=%d lParam=0x%08lx", wParam, lParam);
|
||||
LOGD(" HandleCommand wParam=%d lParam=0x%08lx", wParam, lParam);
|
||||
|
||||
if ((int) wParam == fAcceptButtonID) {
|
||||
MyOnAccept();
|
||||
@@ -191,9 +516,9 @@ UINT SelectFilesDialog::HandleCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
|
||||
*/
|
||||
UINT SelectFilesDialog::HandleSize(HWND hDlg, UINT nType, int cx, int cy)
|
||||
{
|
||||
//LOGI("Dialog: old size %d,%d (ready=%d)",
|
||||
// fLastWinSize.Width(), fLastWinSize.Height(), fReady);
|
||||
//LOGI("Dialog: new size %d,%d", cx, cy);
|
||||
LOGD("Dialog: old size %d,%d (ready=%d)",
|
||||
fLastWinSize.Width(), fLastWinSize.Height(), fReady);
|
||||
LOGD("Dialog: new size %d,%d", cx, cy);
|
||||
|
||||
// we get called once before we have a chance to initialize
|
||||
if (!fReady)
|
||||
@@ -202,10 +527,11 @@ UINT SelectFilesDialog::HandleSize(HWND hDlg, UINT nType, int cx, int cy)
|
||||
int deltaX, deltaY;
|
||||
deltaX = cx - fLastWinSize.Width();
|
||||
deltaY = cy - fLastWinSize.Height();
|
||||
//LOGI("Delta is %d,%d", deltaX, deltaY);
|
||||
LOGD("Delta is %d,%d", deltaX, deltaY);
|
||||
|
||||
ShiftControls(deltaX, 0 /*deltaY*/);
|
||||
|
||||
// TODO: this is wrong
|
||||
GetParent()->GetWindowRect(&fLastWinSize);
|
||||
|
||||
return 1;
|
||||
@@ -229,7 +555,6 @@ UINT SelectFilesDialog::HandleHelp(HWND hDlg, LPHELPINFO lpHelpInfo)
|
||||
return TRUE; // yes, we handled it
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* When the CFileDialog finishes doing its thing, we "fix" stuff a bit.
|
||||
* We can't really do this earlier, because we'd be destroying windows that
|
||||
@@ -259,7 +584,7 @@ void SelectFilesDialog::MyOnInitDone(void)
|
||||
pWnd->GetWindowRect(&cancelRect);
|
||||
|
||||
vertDiff = acceptRect.top - okRect.top;
|
||||
LOGI("vertDiff = %d (horizDiff=%d)", vertDiff,
|
||||
LOGD("vertDiff = %d (horizDiff=%d)", vertDiff,
|
||||
acceptRect.left - okRect.left);
|
||||
|
||||
ShiftControls(0, -vertDiff);
|
||||
@@ -303,7 +628,6 @@ void SelectFilesDialog::ShiftControls(int deltaX, int deltaY)
|
||||
Invalidate(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the list view control out of the common file dialog.
|
||||
*
|
||||
@@ -357,7 +681,7 @@ void SelectFilesDialog::MyOnFileNameChange(void)
|
||||
*/
|
||||
void SelectFilesDialog::MyOnAccept(void)
|
||||
{
|
||||
//LOGI("OnAccept!");
|
||||
LOGD("OnAccept!");
|
||||
PrepEndDialog();
|
||||
}
|
||||
|
||||
@@ -375,7 +699,7 @@ bool SelectFilesDialog::PrepEndDialog(void)
|
||||
|
||||
// let sub-classes copy data out
|
||||
if (!MyDataExchange(true)) {
|
||||
LOGI("MyDataExchange failed!");
|
||||
LOGW("MyDataExchange failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -395,14 +719,15 @@ bool SelectFilesDialog::PrepEndDialog(void)
|
||||
* Fortunately I believe the world is divided into "typers" and
|
||||
* "clickers", and so long as their paths don't cross we're fine.
|
||||
*/
|
||||
LOGI("PrepEndDialog: got max=%d off=%d", m_ofn.nMaxFile, m_ofn.nFileOffset);
|
||||
LOGD("PrepEndDialog: got max=%d off=%d str='%ls'",
|
||||
m_ofn.nMaxFile, m_ofn.nFileOffset, m_ofn.lpstrFile);
|
||||
if (m_ofn.nFileOffset != 0) {
|
||||
WCHAR* buf = m_ofn.lpstrFile;
|
||||
buf += m_ofn.nFileOffset;
|
||||
while (*buf != '\0') {
|
||||
if (buf > m_ofn.lpstrFile)
|
||||
*(buf-1) = '\\';
|
||||
LOGI(" File '%ls'", buf);
|
||||
LOGD(" File '%ls'", buf);
|
||||
buf += wcslen(buf) +1;
|
||||
}
|
||||
//Sleep(1000);
|
||||
@@ -413,7 +738,7 @@ bool SelectFilesDialog::PrepEndDialog(void)
|
||||
/* stick a '\' on the very end, so we get double-null action later */
|
||||
*(m_ofn.lpstrFile + nextSpot) = '\\';
|
||||
}
|
||||
LOGI("Last offset was %d", nextSpot);
|
||||
LOGD("Last offset was %d", nextSpot);
|
||||
|
||||
#if 0
|
||||
/* make it clear that they're only getting one */
|
||||
@@ -435,7 +760,7 @@ bool SelectFilesDialog::PrepEndDialog(void)
|
||||
*/
|
||||
pList = (CListCtrl*) GetListCtrl();
|
||||
if (pList == NULL) {
|
||||
LOGI("GLITCH: could not get list control");
|
||||
LOGW("GLITCH: could not get list control");
|
||||
return false;
|
||||
}
|
||||
ASSERT(pList != NULL);
|
||||
@@ -443,6 +768,7 @@ bool SelectFilesDialog::PrepEndDialog(void)
|
||||
CString fileNames;
|
||||
|
||||
int count = pList->GetSelectedCount();
|
||||
LOGD("List control has %d items; nextSpot=%d", count, nextSpot);
|
||||
if (count == 0) {
|
||||
if (nextSpot == 0) {
|
||||
MessageBox(L"Please select one or more files and directories.",
|
||||
@@ -453,12 +779,14 @@ bool SelectFilesDialog::PrepEndDialog(void)
|
||||
}
|
||||
|
||||
/* nothing but typed-in names */
|
||||
LOGD("Using typed-in names");
|
||||
fileNames = m_ofn.lpstrFile;
|
||||
fFileNameOffset = m_ofn.nFileOffset;
|
||||
} else {
|
||||
bool compare;
|
||||
if (nextSpot == 0) {
|
||||
fileNames = GetFolderPath();
|
||||
LOGD("set filenames to folder path (%ls)", (LPCWSTR) fileNames);
|
||||
/* add a trailing '\', which gets stomped to '\0' later on */
|
||||
if (fileNames.Right(1) != L"\\")
|
||||
fileNames += L"\\";
|
||||
|
||||
Reference in New Issue
Block a user