mirror of
https://github.com/fadden/ciderpress.git
synced 2024-06-07 17:29:27 +00:00
File selection dialog update, part 2
This updates the main app to use the new dialog, and removes the old code.
This commit is contained in:
parent
2f136fd5ab
commit
94beec0639
|
@ -189,8 +189,8 @@ void MainWindow::OnActionsAddFiles(void)
|
||||||
|
|
||||||
addFiles.m_ofn.lpstrInitialDir = fPreferences.GetPrefString(kPrAddFileFolder);
|
addFiles.m_ofn.lpstrInitialDir = fPreferences.GetPrefString(kPrAddFileFolder);
|
||||||
|
|
||||||
addFiles.DoModal();
|
LRESULT addResult = addFiles.DoModal();
|
||||||
if (addFiles.GetExitStatus() == IDOK) {
|
if (addResult == IDOK) {
|
||||||
fPreferences.SetPrefBool(kPrAddIncludeSubFolders,
|
fPreferences.SetPrefBool(kPrAddIncludeSubFolders,
|
||||||
addFiles.fIncludeSubfolders != 0);
|
addFiles.fIncludeSubfolders != 0);
|
||||||
if (addFiles.fStripFolderNamesEnable) {
|
if (addFiles.fStripFolderNamesEnable) {
|
||||||
|
@ -206,8 +206,7 @@ void MainWindow::OnActionsAddFiles(void)
|
||||||
fPreferences.SetPrefLong(kPrAddConvEOL,
|
fPreferences.SetPrefLong(kPrAddConvEOL,
|
||||||
addFiles.fConvEOL);
|
addFiles.fConvEOL);
|
||||||
|
|
||||||
CString saveFolder = addFiles.GetFileNames();
|
CString saveFolder = addFiles.GetDirectory();
|
||||||
saveFolder = saveFolder.Left(addFiles.GetFileNameOffset());
|
|
||||||
fPreferences.SetPrefString(kPrAddFileFolder, saveFolder);
|
fPreferences.SetPrefString(kPrAddFileFolder, saveFolder);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -401,15 +400,14 @@ void MainWindow::OnActionsAddDisks(void)
|
||||||
/*
|
/*
|
||||||
* Set up an AddFilesDialog, but don't actually use it as a dialog.
|
* Set up an AddFilesDialog, but don't actually use it as a dialog.
|
||||||
* Instead, we just configure the various options appropriately.
|
* Instead, we just configure the various options appropriately.
|
||||||
*
|
|
||||||
* To conform to multi-file-selection semantics, we need to drop a
|
|
||||||
* null byte in right after the pathname.
|
|
||||||
*/
|
*/
|
||||||
ASSERT(dlg.m_ofn.nFileOffset > 0);
|
ASSERT(dlg.m_ofn.nFileOffset > 0);
|
||||||
int len;
|
{
|
||||||
len = wcslen(dlg.m_ofn.lpstrFile) + 2;
|
CString directory(dlg.m_ofn.lpstrFile, dlg.m_ofn.nFileOffset - 1);
|
||||||
dlg.m_ofn.lpstrFile[dlg.m_ofn.nFileOffset-1] = '\0';
|
CString file(dlg.m_ofn.lpstrFile + dlg.m_ofn.nFileOffset);
|
||||||
addOpts.SetFileNames(dlg.m_ofn.lpstrFile, len, dlg.m_ofn.nFileOffset);
|
LOGD("Stuffing '%ls' '%ls'", (LPCWSTR) directory, (LPCWSTR) file);
|
||||||
|
addOpts.StuffSingleFilename(directory, file);
|
||||||
|
}
|
||||||
addOpts.fStoragePrefix = "";
|
addOpts.fStoragePrefix = "";
|
||||||
addOpts.fIncludeSubfolders = false;
|
addOpts.fIncludeSubfolders = false;
|
||||||
addOpts.fStripFolderNames = false;
|
addOpts.fStripFolderNames = false;
|
||||||
|
|
|
@ -24,6 +24,7 @@ bool AddFilesDialog::MyDataExchange(bool saveAndValidate)
|
||||||
{
|
{
|
||||||
CWnd* pWnd;
|
CWnd* pWnd;
|
||||||
|
|
||||||
|
LOGD("AddFilesDialog MyDataExchange(%d)", saveAndValidate);
|
||||||
if (saveAndValidate) {
|
if (saveAndValidate) {
|
||||||
if (GetDlgButtonCheck(this, IDC_ADDFILES_NOPRESERVE) == BST_CHECKED)
|
if (GetDlgButtonCheck(this, IDC_ADDFILES_NOPRESERVE) == BST_CHECKED)
|
||||||
fTypePreservation = kPreserveNone;
|
fTypePreservation = kPreserveNone;
|
||||||
|
@ -126,56 +127,9 @@ bool AddFilesDialog::ValidateStoragePrefix(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddFilesDialog::HandleHelp()
|
||||||
UINT AddFilesDialog::MyOnCommand(WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch (wParam) {
|
|
||||||
case IDHELP:
|
|
||||||
OnIDHelp();
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return SelectFilesDialog::MyOnCommand(wParam, lParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddFilesDialog::ShiftControls(int deltaX, int deltaY)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* These only need to be here so that the initial move puts them
|
|
||||||
* where they belong. Once the dialog has been created, the
|
|
||||||
* CFileDialog will move things where they need to go.
|
|
||||||
*/
|
|
||||||
MoveControl(this, IDC_ADDFILES_STATIC1, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_NOPRESERVE, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_PRESERVE, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_PRESERVEPLUS, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_STATIC2, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_STRIP_FOLDER, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_INCLUDE_SUBFOLDERS, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_OVERWRITE, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_STATIC3, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_PREFIX, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_STATIC4, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_CONVEOLNONE, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_CONVEOLTYPE, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_CONVEOLTEXT, 0, deltaY, false);
|
|
||||||
MoveControl(this, IDC_ADDFILES_CONVEOLALL, 0, deltaY, false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These actively move.
|
|
||||||
*/
|
|
||||||
MoveControl(this, IDHELP, deltaX, deltaY, false);
|
|
||||||
StretchControl(this, IDC_ADDFILES_PREFIX, deltaX, 0, false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* It's important that the base class be called last, because it calls
|
|
||||||
* Invalidate to redraw the dialog.
|
|
||||||
*/
|
|
||||||
SelectFilesDialog::ShiftControls(deltaX, deltaY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddFilesDialog::OnIDHelp(void)
|
|
||||||
{
|
{
|
||||||
|
LOGD("AddFilesDialog HandleHelp");
|
||||||
CWnd* pWndMain = ::AfxGetMainWnd();
|
CWnd* pWndMain = ::AfxGetMainWnd();
|
||||||
CWinApp* pAppMain = ::AfxGetApp();
|
CWinApp* pAppMain = ::AfxGetApp();
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
class AddFilesDialog : public SelectFilesDialog {
|
class AddFilesDialog : public SelectFilesDialog {
|
||||||
public:
|
public:
|
||||||
AddFilesDialog(CWnd* pParentWnd = NULL) :
|
AddFilesDialog(CWnd* pParentWnd = NULL) :
|
||||||
SelectFilesDialog(L"IDD_ADD_FILES", pParentWnd)
|
SelectFilesDialog(L"IDD_ADD_FILES", true, pParentWnd)
|
||||||
{
|
{
|
||||||
SetWindowTitle(L"Add Files...");
|
SetWindowTitle(L"Add Files...");
|
||||||
fStoragePrefix = "";
|
fStoragePrefix = "";
|
||||||
|
@ -36,8 +36,6 @@ public:
|
||||||
fConvEOL = 0;
|
fConvEOL = 0;
|
||||||
fConvEOLEnable = true;
|
fConvEOLEnable = true;
|
||||||
|
|
||||||
fAcceptButtonID = IDC_SELECT_ACCEPT;
|
|
||||||
|
|
||||||
fpTargetDiskFS = NULL;
|
fpTargetDiskFS = NULL;
|
||||||
//fpTargetSubdir = NULL;
|
//fpTargetSubdir = NULL;
|
||||||
fpDiskImg = NULL;
|
fpDiskImg = NULL;
|
||||||
|
@ -69,21 +67,11 @@ public:
|
||||||
private:
|
private:
|
||||||
virtual bool MyDataExchange(bool saveAndValidate) override;
|
virtual bool MyDataExchange(bool saveAndValidate) override;
|
||||||
|
|
||||||
/*
|
|
||||||
* Overrides base class version so we can move our stuff around.
|
|
||||||
*/
|
|
||||||
virtual void ShiftControls(int deltaX, int deltaY) override;
|
|
||||||
|
|
||||||
// Grabs OnIDHelp; otherwise forwards to base class.
|
|
||||||
virtual UINT MyOnCommand(WPARAM wParam, LPARAM lParam) override;
|
|
||||||
|
|
||||||
// User hit the Help button.
|
// User hit the Help button.
|
||||||
void OnIDHelp(void);
|
virtual void HandleHelp() override;
|
||||||
|
|
||||||
/*
|
// Make sure the storage prefix they entered is valid.
|
||||||
* Make sure the storage prefix they entered is valid.
|
bool ValidateStoragePrefix();
|
||||||
*/
|
|
||||||
bool ValidateStoragePrefix(void);
|
|
||||||
|
|
||||||
//DECLARE_MESSAGE_MAP()
|
//DECLARE_MESSAGE_MAP()
|
||||||
};
|
};
|
||||||
|
|
|
@ -589,10 +589,7 @@ IDD_ADD_FILES DIALOGEX 0, 0, 292, 231
|
||||||
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | DS_CONTEXTHELP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
|
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | DS_CONTEXTHELP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
|
||||||
FONT 8, "MS Sans Serif", 0, 0, 0x1
|
FONT 8, "MS Sans Serif", 0, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "",1119,0,0,291,87,NOT WS_GROUP,WS_EX_STATICEDGE
|
LTEXT "",1119,0,0,291,105,NOT WS_GROUP
|
||||||
PUSHBUTTON "&Accept",IDC_SELECT_ACCEPT,241,88,50,14
|
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,241,106,50,14
|
|
||||||
PUSHBUTTON "Help",IDHELP,241,124,50,14
|
|
||||||
GROUPBOX "File attribute preservation",IDC_ADDFILES_STATIC1,4,112,169,47
|
GROUPBOX "File attribute preservation",IDC_ADDFILES_STATIC1,4,112,169,47
|
||||||
CONTROL "&Ignore file attribute preservation tags",IDC_ADDFILES_NOPRESERVE,
|
CONTROL "&Ignore file attribute preservation tags",IDC_ADDFILES_NOPRESERVE,
|
||||||
"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,122,157,10
|
"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,122,157,10
|
||||||
|
@ -608,14 +605,14 @@ BEGIN
|
||||||
CONTROL "Auto-detect && &convert files with text",IDC_ADDFILES_CONVEOLTEXT,
|
CONTROL "Auto-detect && &convert files with text",IDC_ADDFILES_CONVEOLTEXT,
|
||||||
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,200,148,10
|
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,200,148,10
|
||||||
CONTROL "Convert &ALL files",IDC_ADDFILES_CONVEOLALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,211,141,10
|
CONTROL "Convert &ALL files",IDC_ADDFILES_CONVEOLALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,211,141,10
|
||||||
GROUPBOX "Miscellaneous",IDC_ADDFILES_STATIC2,176,145,115,47
|
GROUPBOX "Miscellaneous",IDC_ADDFILES_STATIC2,175,112,116,47
|
||||||
CONTROL "&Include subfolders",IDC_ADDFILES_INCLUDE_SUBFOLDERS,
|
CONTROL "&Include subfolders",IDC_ADDFILES_INCLUDE_SUBFOLDERS,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,180,155,88,10
|
"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,179,122,88,10
|
||||||
CONTROL "&Strip folder names",IDC_ADDFILES_STRIP_FOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,166,88,10
|
CONTROL "&Strip folder names",IDC_ADDFILES_STRIP_FOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,179,133,88,10
|
||||||
CONTROL "&Overwrite existing files",IDC_ADDFILES_OVERWRITE,
|
CONTROL "&Overwrite existing files",IDC_ADDFILES_OVERWRITE,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,180,177,85,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,179,144,85,10
|
||||||
LTEXT "Storage prefix (optional):",IDC_ADDFILES_STATIC3,177,198,77,8
|
LTEXT "Storage prefix (optional):",IDC_ADDFILES_STATIC3,178,168,77,8
|
||||||
EDITTEXT IDC_ADDFILES_PREFIX,176,210,102,14,ES_AUTOHSCROLL
|
EDITTEXT IDC_ADDFILES_PREFIX,176,179,116,14,ES_AUTOHSCROLL
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_USE_SELECTION DIALOG 0, 0, 139, 79
|
IDD_USE_SELECTION DIALOG 0, 0, 139, 79
|
||||||
|
@ -1473,6 +1470,8 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VERTGUIDE, 8
|
VERTGUIDE, 8
|
||||||
BOTTOMMARGIN, 224
|
BOTTOMMARGIN, 224
|
||||||
|
HORZGUIDE, 112
|
||||||
|
HORZGUIDE, 168
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_USE_SELECTION, DIALOG
|
IDD_USE_SELECTION, DIALOG
|
||||||
|
|
|
@ -1180,38 +1180,37 @@ bool DiskArchive::BulkAdd(ActionProgressDialog* pActionProgress,
|
||||||
/*
|
/*
|
||||||
* Save the current directory and change to the one from the file dialog.
|
* Save the current directory and change to the one from the file dialog.
|
||||||
*/
|
*/
|
||||||
const WCHAR* buf = pAddOpts->GetFileNames();
|
const CString& directory = pAddOpts->GetDirectory();
|
||||||
LOGI("Selected path = '%ls' (offset=%d)", buf,
|
LOGI("Selected path = '%ls'", (LPCWSTR) directory);
|
||||||
pAddOpts->GetFileNameOffset());
|
|
||||||
|
|
||||||
if (GetCurrentDirectory(NELEM(curDir), curDir) == 0) {
|
if (GetCurrentDirectory(NELEM(curDir), curDir) == 0) {
|
||||||
errMsg = L"Unable to get current directory.\n";
|
errMsg = L"Unable to get current directory.\n";
|
||||||
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (SetCurrentDirectory(buf) == false) {
|
if (SetCurrentDirectory(directory) == false) {
|
||||||
errMsg.Format(L"Unable to set current directory to '%ls'.\n", buf);
|
errMsg.Format(L"Unable to set current directory to '%ls'.\n",
|
||||||
|
(LPCWSTR) directory);
|
||||||
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += pAddOpts->GetFileNameOffset();
|
const CStringArray& fileNames = pAddOpts->GetFileNames();
|
||||||
while (*buf != '\0') {
|
for (int i = 0; i < fileNames.GetCount(); i++) {
|
||||||
LOGI(" file '%ls'", buf);
|
const CString& name = fileNames.GetAt(i);
|
||||||
|
LOGI(" file '%ls'", (LPCWSTR) name);
|
||||||
|
|
||||||
/* add the file, calling DoAddFile via the generic AddFile */
|
/* add the file, calling DoAddFile via the generic AddFile */
|
||||||
nerr = AddFile(pAddOpts, buf, &errMsg);
|
nerr = AddFile(pAddOpts, name, &errMsg);
|
||||||
if (nerr != kNuErrNone) {
|
if (nerr != kNuErrNone) {
|
||||||
if (errMsg.IsEmpty())
|
if (errMsg.IsEmpty())
|
||||||
errMsg.Format(L"Failed while adding file '%ls': %hs.",
|
errMsg.Format(L"Failed while adding file '%ls': %hs.",
|
||||||
(LPCWSTR) buf, NuStrError(nerr));
|
(LPCWSTR) name, NuStrError(nerr));
|
||||||
if (nerr != kNuErrAborted) {
|
if (nerr != kNuErrAborted) {
|
||||||
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
||||||
}
|
}
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += wcslen(buf)+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fpAddDataHead == NULL) {
|
if (fpAddDataHead == NULL) {
|
||||||
|
@ -1239,7 +1238,7 @@ bool DiskArchive::BulkAdd(ActionProgressDialog* pActionProgress,
|
||||||
bail:
|
bail:
|
||||||
FreeAddDataList();
|
FreeAddDataList();
|
||||||
if (SetCurrentDirectory(curDir) == false) {
|
if (SetCurrentDirectory(curDir) == false) {
|
||||||
errMsg.Format(L"Unable to reset current directory to '%ls'.\n", buf);
|
errMsg.Format(L"Unable to reset current directory to '%ls'.\n", curDir);
|
||||||
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
ShowFailureMsg(pActionProgress, errMsg, IDS_FAILED);
|
||||||
// bummer, but don't signal failure
|
// bummer, but don't signal failure
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,38 +908,37 @@ bool NufxArchive::BulkAdd(ActionProgressDialog* pActionProgress,
|
||||||
/* initialize count */
|
/* initialize count */
|
||||||
fNumAdded = 0;
|
fNumAdded = 0;
|
||||||
|
|
||||||
const WCHAR* buf = pAddOpts->GetFileNames();
|
const CString& directory = pAddOpts->GetDirectory();
|
||||||
LOGI("Selected path = '%ls' (offset=%d)", buf,
|
LOGI("Selected path = '%ls'", (LPCWSTR) directory);
|
||||||
pAddOpts->GetFileNameOffset());
|
|
||||||
|
|
||||||
if (GetCurrentDirectory(NELEM(curDir), curDir) == 0) {
|
if (GetCurrentDirectory(NELEM(curDir), curDir) == 0) {
|
||||||
errMsg = L"Unable to get current directory.\n";
|
errMsg = L"Unable to get current directory.\n";
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (SetCurrentDirectory(buf) == false) {
|
if (SetCurrentDirectory(directory) == false) {
|
||||||
errMsg.Format(L"Unable to set current directory to '%ls'.\n", buf);
|
errMsg.Format(L"Unable to set current directory to '%ls'.\n",
|
||||||
|
(LPCWSTR) directory);
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += pAddOpts->GetFileNameOffset();
|
const CStringArray& fileNames = pAddOpts->GetFileNames();
|
||||||
while (*buf != '\0') {
|
for (int i = 0; i < fileNames.GetCount(); i++) {
|
||||||
LOGI(" file '%ls'", buf);
|
const CString& name = fileNames.GetAt(i);
|
||||||
|
LOGI(" file '%ls'", (LPCWSTR) name);
|
||||||
|
|
||||||
/* this just provides the list of files to NufxLib */
|
/* this just provides the list of files to NufxLib */
|
||||||
nerr = AddFile(pAddOpts, buf, &errMsg);
|
nerr = AddFile(pAddOpts, name, &errMsg);
|
||||||
if (nerr != kNuErrNone) {
|
if (nerr != kNuErrNone) {
|
||||||
if (errMsg.IsEmpty())
|
if (errMsg.IsEmpty())
|
||||||
errMsg.Format(L"Failed while adding file '%ls': %hs.",
|
errMsg.Format(L"Failed while adding file '%ls': %hs.",
|
||||||
buf, NuStrError(nerr));
|
name, NuStrError(nerr));
|
||||||
if (nerr != kNuErrAborted) {
|
if (nerr != kNuErrAborted) {
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
}
|
}
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += wcslen(buf)+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* actually do the work */
|
/* actually do the work */
|
||||||
|
@ -970,7 +969,7 @@ bool NufxArchive::BulkAdd(ActionProgressDialog* pActionProgress,
|
||||||
bail:
|
bail:
|
||||||
NuAbort(fpArchive); // abort anything that didn't get flushed
|
NuAbort(fpArchive); // abort anything that didn't get flushed
|
||||||
if (SetCurrentDirectory(curDir) == false) {
|
if (SetCurrentDirectory(curDir) == false) {
|
||||||
errMsg.Format(L"Unable to reset current directory to '%ls'.\n", buf);
|
errMsg.Format(L"Unable to reset current directory to '%ls'.\n", curDir);
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
// bummer, but don't signal failure
|
// bummer, but don't signal failure
|
||||||
}
|
}
|
||||||
|
@ -993,14 +992,20 @@ bool NufxArchive::AddDisk(ActionProgressDialog* pActionProgress,
|
||||||
bool retVal = false;
|
bool retVal = false;
|
||||||
CStringA storageNameA, origNameA;
|
CStringA storageNameA, origNameA;
|
||||||
|
|
||||||
LOGI("AddDisk: '%ls' %d", pAddOpts->GetFileNames(),
|
LOGI("AddDisk: '%ls' (count=%d)", (LPCWSTR) pAddOpts->GetDirectory(),
|
||||||
pAddOpts->GetFileNameOffset());
|
pAddOpts->GetFileNames().GetCount());
|
||||||
LOGI("Opts: '%ls' type=%d", (LPCWSTR) pAddOpts->fStoragePrefix,
|
LOGI("Opts: stpfx='%ls' pres=%d", (LPCWSTR) pAddOpts->fStoragePrefix,
|
||||||
pAddOpts->fTypePreservation);
|
pAddOpts->fTypePreservation);
|
||||||
LOGI(" sub=%d strip=%d ovwr=%d",
|
LOGI(" sub=%d strip=%d ovwr=%d",
|
||||||
pAddOpts->fIncludeSubfolders, pAddOpts->fStripFolderNames,
|
pAddOpts->fIncludeSubfolders, pAddOpts->fStripFolderNames,
|
||||||
pAddOpts->fOverwriteExisting);
|
pAddOpts->fOverwriteExisting);
|
||||||
|
|
||||||
|
if (pAddOpts->GetFileNames().GetCount() != 1) {
|
||||||
|
LOGW("GLITCH: expected only one filename, found %d",
|
||||||
|
pAddOpts->GetFileNames().GetCount());
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
pDiskImg = pAddOpts->fpDiskImg;
|
pDiskImg = pAddOpts->fpDiskImg;
|
||||||
ASSERT(pDiskImg != NULL);
|
ASSERT(pDiskImg != NULL);
|
||||||
|
|
||||||
|
@ -1016,27 +1021,27 @@ bool NufxArchive::AddDisk(ActionProgressDialog* pActionProgress,
|
||||||
/* prepare to add */
|
/* prepare to add */
|
||||||
AddPrep(pActionProgress, pAddOpts);
|
AddPrep(pActionProgress, pAddOpts);
|
||||||
|
|
||||||
const WCHAR* buf;
|
const CString& directory = pAddOpts->GetDirectory();
|
||||||
buf = pAddOpts->GetFileNames();
|
const CStringArray& fileNames = pAddOpts->GetFileNames();
|
||||||
LOGI("Selected path = '%ls' (offset=%d)", buf,
|
LOGD("Selected path = '%ls'", (LPCWSTR) directory);
|
||||||
pAddOpts->GetFileNameOffset());
|
|
||||||
|
|
||||||
if (GetCurrentDirectory(NELEM(curDir), curDir) == 0) {
|
if (GetCurrentDirectory(NELEM(curDir), curDir) == 0) {
|
||||||
errMsg = L"Unable to get current directory.\n";
|
errMsg = L"Unable to get current directory.\n";
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (SetCurrentDirectory(buf) == false) {
|
if (SetCurrentDirectory(directory) == false) {
|
||||||
errMsg.Format(L"Unable to set current directory to '%ls'.\n", buf);
|
errMsg.Format(L"Unable to set current directory to '%ls'.\n",
|
||||||
|
(LPCWSTR) directory);
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf += pAddOpts->GetFileNameOffset();
|
const CString& fileName = pAddOpts->GetFileNames().GetAt(0);
|
||||||
LOGI(" file '%ls'", buf);
|
LOGI(" file '%ls'", (LPCWSTR) fileName);
|
||||||
|
|
||||||
/* strip off preservation stuff, and ignore it */
|
/* strip off preservation stuff, and ignore it */
|
||||||
pathProp.Init(buf);
|
pathProp.Init(fileName);
|
||||||
pathProp.fStripDiskImageSuffix = true;
|
pathProp.fStripDiskImageSuffix = true;
|
||||||
pathProp.LocalToArchive(pAddOpts);
|
pathProp.LocalToArchive(pAddOpts);
|
||||||
|
|
||||||
|
@ -1047,7 +1052,7 @@ bool NufxArchive::AddDisk(ActionProgressDialog* pActionProgress,
|
||||||
details.storageType = kBlockSize;
|
details.storageType = kBlockSize;
|
||||||
details.access = kNuAccessUnlocked;
|
details.access = kNuAccessUnlocked;
|
||||||
details.extraType = pAddOpts->fpDiskImg->GetNumBlocks();
|
details.extraType = pAddOpts->fpDiskImg->GetNumBlocks();
|
||||||
origNameA = buf;
|
origNameA = fileName; // narrowing conversion
|
||||||
storageNameA = pathProp.fStoredPathName;
|
storageNameA = pathProp.fStoredPathName;
|
||||||
details.origName = origNameA;
|
details.origName = origNameA;
|
||||||
details.storageName = storageNameA;
|
details.storageName = storageNameA;
|
||||||
|
@ -1056,7 +1061,7 @@ bool NufxArchive::AddDisk(ActionProgressDialog* pActionProgress,
|
||||||
|
|
||||||
time_t now, then;
|
time_t now, then;
|
||||||
|
|
||||||
pathName = buf;
|
pathName.SetPathName(fileName);
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
then = pathName.GetModWhen();
|
then = pathName.GetModWhen();
|
||||||
UNIXTimeToDateTime(&now, &details.archiveWhen);
|
UNIXTimeToDateTime(&now, &details.archiveWhen);
|
||||||
|
@ -1065,7 +1070,7 @@ bool NufxArchive::AddDisk(ActionProgressDialog* pActionProgress,
|
||||||
|
|
||||||
/* set up the progress updater */
|
/* set up the progress updater */
|
||||||
pActionProgress->SetArcName(pathProp.fStoredPathName);
|
pActionProgress->SetArcName(pathProp.fStoredPathName);
|
||||||
pActionProgress->SetFileName(buf);
|
pActionProgress->SetFileName(fileName);
|
||||||
|
|
||||||
/* read the disk now that we have progress update titles in place */
|
/* read the disk now that we have progress update titles in place */
|
||||||
int block, numBadBlocks;
|
int block, numBadBlocks;
|
||||||
|
@ -1142,7 +1147,7 @@ bail:
|
||||||
NuAbort(fpArchive); // abort anything that didn't get flushed
|
NuAbort(fpArchive); // abort anything that didn't get flushed
|
||||||
NuFreeDataSource(pSource);
|
NuFreeDataSource(pSource);
|
||||||
if (SetCurrentDirectory(curDir) == false) {
|
if (SetCurrentDirectory(curDir) == false) {
|
||||||
errMsg.Format(L"Unable to reset current directory to '%ls'.\n", buf);
|
errMsg.Format(L"Unable to reset current directory to '%ls'.\n", curDir);
|
||||||
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
ShowFailureMsg(fpMsgWnd, errMsg, IDS_FAILED);
|
||||||
// bummer
|
// bummer
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ void MainWindow::ScanFiles(void)
|
||||||
memset(&scanOpts, 0, sizeof(scanOpts));
|
memset(&scanOpts, 0, sizeof(scanOpts));
|
||||||
|
|
||||||
// choose input files
|
// choose input files
|
||||||
SelectFilesDialog2 chooseFiles(L"IDD_CHOOSE_FILES", this);
|
SelectFilesDialog chooseFiles(L"IDD_CHOOSE_FILES", false, this);
|
||||||
chooseFiles.SetWindowTitle(L"Choose Files...");
|
chooseFiles.SetWindowTitle(L"Choose Files...");
|
||||||
INT_PTR retval = chooseFiles.DoModal();
|
INT_PTR retval = chooseFiles.DoModal();
|
||||||
if (retval != IDOK) {
|
if (retval != IDOK) {
|
||||||
|
|
|
@ -128,6 +128,8 @@ public:
|
||||||
static const WCHAR* FilenameOnly(const WCHAR* pathname, WCHAR fssep);
|
static const WCHAR* FilenameOnly(const WCHAR* pathname, WCHAR fssep);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
DECLARE_COPY_AND_OPEQ(PathName)
|
||||||
|
|
||||||
void SplitIFN(void) {
|
void SplitIFN(void) {
|
||||||
if (!fSplit) {
|
if (!fSplit) {
|
||||||
_wsplitpath(fPathName, fDrive, fDir, fFileName, fExt);
|
_wsplitpath(fPathName, fDrive, fDir, fFileName, fExt);
|
||||||
|
|
|
@ -10,14 +10,18 @@
|
||||||
#include <dlgs.h>
|
#include <dlgs.h>
|
||||||
|
|
||||||
|
|
||||||
void SelectFilesDialog2::OnInitDone()
|
void SelectFilesDialog::OnInitDone()
|
||||||
{
|
{
|
||||||
// Tweak the controls
|
// Tweak the controls
|
||||||
SetControlText(IDOK, L"Accept");
|
SetControlText(IDOK, L"Accept");
|
||||||
|
|
||||||
|
// we don't take a "files of type" arg, so there's nothing in this combo box
|
||||||
HideControl(stc2); // "Files of type"
|
HideControl(stc2); // "Files of type"
|
||||||
HideControl(cmb1); // (file type combo)
|
HideControl(cmb1); // (file type combo)
|
||||||
|
|
||||||
|
// Let the subclass do control configuration and data exchange.
|
||||||
|
(void) MyDataExchange(false);
|
||||||
|
|
||||||
// Configure a window proc to intercept events. We need to do it this
|
// Configure a window proc to intercept events. We need to do it this
|
||||||
// way, rather than using m_ofn.lpfnHook, because the CFileDialog hook
|
// way, rather than using m_ofn.lpfnHook, because the CFileDialog hook
|
||||||
// does not receive messages intended for the standard controls of the
|
// does not receive messages intended for the standard controls of the
|
||||||
|
@ -31,7 +35,7 @@ void SelectFilesDialog2::OnInitDone()
|
||||||
::SetWindowLongPtr(pParent->m_hWnd, GWL_USERDATA, (LONG_PTR) this);
|
::SetWindowLongPtr(pParent->m_hWnd, GWL_USERDATA, (LONG_PTR) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectFilesDialog2::OnFolderChange()
|
void SelectFilesDialog::OnFolderChange()
|
||||||
{
|
{
|
||||||
// We get one of these shortly after OnInitDone. We can't do this in
|
// We get one of these shortly after OnInitDone. We can't do this in
|
||||||
// OnInitDone because the dialog isn't ready yet.
|
// OnInitDone because the dialog isn't ready yet.
|
||||||
|
@ -73,7 +77,7 @@ void SelectFilesDialog2::OnFolderChange()
|
||||||
LOGD("OnFolderChange: '%ls'", (LPCWSTR) fCurrentDirectory);
|
LOGD("OnFolderChange: '%ls'", (LPCWSTR) fCurrentDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL SelectFilesDialog2::OnFileNameOK()
|
BOOL SelectFilesDialog::OnFileNameOK()
|
||||||
{
|
{
|
||||||
// This function provides "custom validation of filenames that are
|
// This function provides "custom validation of filenames that are
|
||||||
// entered into a common file dialog box". We don't need to validate
|
// entered into a common file dialog box". We don't need to validate
|
||||||
|
@ -112,16 +116,17 @@ BOOL SelectFilesDialog2::OnFileNameOK()
|
||||||
// not reached
|
// not reached
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ LRESULT CALLBACK SelectFilesDialog2::MyWindowProc(HWND hwnd,
|
/*static*/ LRESULT CALLBACK SelectFilesDialog::MyWindowProc(HWND hwnd,
|
||||||
UINT uMsg, WPARAM wParam, LPARAM lParam)
|
UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
SelectFilesDialog2* pSFD =
|
SelectFilesDialog* pSFD =
|
||||||
(SelectFilesDialog2*) ::GetWindowLong(hwnd, GWL_USERDATA);
|
(SelectFilesDialog*) ::GetWindowLong(hwnd, GWL_USERDATA);
|
||||||
|
|
||||||
if (uMsg == WM_COMMAND) {
|
if (uMsg == WM_COMMAND) {
|
||||||
// React to a click on the OK button (also triggered by hitting return
|
// React to a click on the OK button (also triggered by hitting return
|
||||||
// in the filename text box).
|
// in the filename text box).
|
||||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) {
|
if (HIWORD(wParam) == BN_CLICKED) {
|
||||||
|
if (LOWORD(wParam) == IDOK) {
|
||||||
// Obtain a CFileDialog pointer from the window handle. The
|
// Obtain a CFileDialog pointer from the window handle. The
|
||||||
// SelectFilesDialog pointer only gets us to a child window
|
// SelectFilesDialog pointer only gets us to a child window
|
||||||
// (the one used to implement the templated custom stuff).
|
// (the one used to implement the templated custom stuff).
|
||||||
|
@ -152,13 +157,16 @@ BOOL SelectFilesDialog2::OnFileNameOK()
|
||||||
assert(false);
|
assert(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else if (LOWORD(wParam) == pshHelp) {
|
||||||
|
pSFD->HandleHelp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ::CallWindowProc(pSFD->fPrevWndProc, hwnd, uMsg, wParam, lParam);
|
return ::CallWindowProc(pSFD->fPrevWndProc, hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectFilesDialog2::FPResult SelectFilesDialog2::OKButtonClicked(CFileDialog* pDialog)
|
SelectFilesDialog::FPResult SelectFilesDialog::OKButtonClicked(CFileDialog* pDialog)
|
||||||
{
|
{
|
||||||
// There are two not-quite-independent sources of filenames. As
|
// There are two not-quite-independent sources of filenames. As
|
||||||
// ordinary (non-directory) files are selected, they are added to the
|
// ordinary (non-directory) files are selected, they are added to the
|
||||||
|
@ -280,10 +288,16 @@ SelectFilesDialog2::FPResult SelectFilesDialog2::OKButtonClicked(CFileDialog* pD
|
||||||
}
|
}
|
||||||
LOGV(" added %d directories", dirCount);
|
LOGV(" added %d directories", dirCount);
|
||||||
|
|
||||||
|
// let sub-classes copy data out, and have an opportunity to reject values
|
||||||
|
if (!MyDataExchange(true)) {
|
||||||
|
LOGW("MyDataExchange failed!");
|
||||||
|
return kFPError;
|
||||||
|
}
|
||||||
|
|
||||||
return kFPDone;
|
return kFPDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SelectFilesDialog2::ParseFileNames(const CString& str)
|
int SelectFilesDialog::ParseFileNames(const CString& str)
|
||||||
{
|
{
|
||||||
// The filename string can come in two forms. If only one filename was
|
// 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
|
// selected, the entire string will be the filename (spaces and all). If
|
||||||
|
@ -369,540 +383,3 @@ int SelectFilesDialog2::ParseFileNames(const CString& str)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Our CFileDialog "hook" function.
|
|
||||||
*
|
|
||||||
* "hdlg" is a handle to the child dialog box. Use the GetParent() function
|
|
||||||
* to get the handle of the dialog box window.
|
|
||||||
*
|
|
||||||
* uiMsg identifies the message being received. If it's WM_INITDIALOG, then
|
|
||||||
* lParam points to the OPENFILENAME structure.
|
|
||||||
*
|
|
||||||
* Do not call EndDialog from here. Instead, PostMessage a WM_COMMAND with
|
|
||||||
* IDABORT. (Looks like you can EndDialog on the parent and have it work, at
|
|
||||||
* least for IDCANCEL.)
|
|
||||||
*
|
|
||||||
* Return zero to enable standard processing, nonzero to claim ownership of
|
|
||||||
* the message.
|
|
||||||
*/
|
|
||||||
/*static*/ UINT CALLBACK SelectFilesDialog::OFNHookProc(HWND hDlg, UINT uiMsg,
|
|
||||||
WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
OPENFILENAME* pOfn;
|
|
||||||
SelectFilesDialog* pSFD = NULL;
|
|
||||||
pOfn = (OPENFILENAME*) GetWindowLong(hDlg, GWL_USERDATA);
|
|
||||||
if (pOfn != NULL) {
|
|
||||||
pSFD = (SelectFilesDialog*) pOfn->lCustData;
|
|
||||||
/* allow our "this" pointer to play with the window */
|
|
||||||
/* [does not seem to cause double-frees on cleanup] */
|
|
||||||
if (pSFD->m_hWnd == NULL)
|
|
||||||
pSFD->m_hWnd = hDlg;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (uiMsg) {
|
|
||||||
case WM_INITDIALOG:
|
|
||||||
LOGD("WM_INITDIALOG, OFN=0x%08lx", lParam);
|
|
||||||
SetWindowLong(hDlg, GWL_USERDATA, lParam);
|
|
||||||
break;
|
|
||||||
case WM_NOTIFY: // 0x4e
|
|
||||||
ASSERT(pSFD != NULL);
|
|
||||||
return pSFD->HandleNotify(hDlg, (LPOFNOTIFY)lParam);
|
|
||||||
case WM_COMMAND:
|
|
||||||
ASSERT(pSFD != NULL);
|
|
||||||
return pSFD->HandleCommand(hDlg, wParam, lParam);
|
|
||||||
case WM_SIZE:
|
|
||||||
ASSERT(pSFD != NULL);
|
|
||||||
return pSFD->HandleSize(hDlg, wParam, LOWORD(lParam), HIWORD(lParam));
|
|
||||||
case WM_HELP:
|
|
||||||
ASSERT(pSFD != NULL);
|
|
||||||
return pSFD->HandleHelp(hDlg, (LPHELPINFO) lParam);
|
|
||||||
default:
|
|
||||||
LOGV("OFNHookProc: hDlg=0x%p uiMsg=0x%08lx "
|
|
||||||
"wParam=0x%08lx lParam=0x%08lx",
|
|
||||||
hDlg, uiMsg, wParam, lParam);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle WM_NOTIFY messages.
|
|
||||||
*
|
|
||||||
* You can indicate displeasure with the CDN_* messages by using SetWindowLong
|
|
||||||
* to alter the DWL_MSGRESULT value.
|
|
||||||
*/
|
|
||||||
UINT SelectFilesDialog::HandleNotify(HWND hDlg, LPOFNOTIFY pofn)
|
|
||||||
{
|
|
||||||
// int count;
|
|
||||||
|
|
||||||
switch (pofn->hdr.code) {
|
|
||||||
case CDN_INITDONE:
|
|
||||||
MyOnInitDone();
|
|
||||||
return 1;
|
|
||||||
case CDN_SELCHANGE:
|
|
||||||
LOGI(" CDN_SELCHANGE");
|
|
||||||
MyOnFileNameChange(/*&count*/);
|
|
||||||
//ClearFileName();
|
|
||||||
return 1;
|
|
||||||
case CDN_FOLDERCHANGE:
|
|
||||||
LOGI(" CDN_FOLDERCHANGE");
|
|
||||||
break;
|
|
||||||
case CDN_SHAREVIOLATION:
|
|
||||||
LOGI(" CDN_SHAREVIOLATION");
|
|
||||||
break;
|
|
||||||
case CDN_HELP:
|
|
||||||
LOGI(" CDN_HELP!");
|
|
||||||
break;
|
|
||||||
case CDN_FILEOK:
|
|
||||||
LOGI(" CDN_FILEOK");
|
|
||||||
/* act like they hit the Accept button */
|
|
||||||
// MyOnFileNameChange(&count);
|
|
||||||
//ClearFileName();
|
|
||||||
// if (count != 0) {
|
|
||||||
// LOGI("Count = %d, accepting CDN_FILEOK", count);
|
|
||||||
// MyOnAccept();
|
|
||||||
// } else {
|
|
||||||
// OPENFILENAME* pOfn;
|
|
||||||
// pOfn = (OPENFILENAME*) GetWindowLong(hDlg, GWL_USERDATA);
|
|
||||||
// LOGI("Count=0, name='%ls'", pOfn->lpstrFile);
|
|
||||||
// }
|
|
||||||
PrepEndDialog();
|
|
||||||
/* must do this every time, or it fails in funky ways */
|
|
||||||
SetWindowLong(hDlg, DWL_MSGRESULT, 1);
|
|
||||||
return 1;
|
|
||||||
case CDN_TYPECHANGE:
|
|
||||||
LOGI(" CDN_TYPECHANGE");
|
|
||||||
break;
|
|
||||||
case CDN_INCLUDEITEM:
|
|
||||||
LOGI(" CDN_INCLUDEITEM");
|
|
||||||
default:
|
|
||||||
LOGI(" HandleNotify, code=%d, pOfn=0x%p", pofn->hdr.code, pofn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle WM_COMMAND messages.
|
|
||||||
*/
|
|
||||||
UINT SelectFilesDialog::HandleCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
LOGD(" HandleCommand wParam=%d lParam=0x%08lx", wParam, lParam);
|
|
||||||
|
|
||||||
if ((int) wParam == fAcceptButtonID) {
|
|
||||||
MyOnAccept();
|
|
||||||
return 1;
|
|
||||||
} else if (wParam == IDCANCEL) {
|
|
||||||
MyOnCancel();
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return MyOnCommand(wParam, lParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle WM_SIZE.
|
|
||||||
*/
|
|
||||||
UINT SelectFilesDialog::HandleSize(HWND hDlg, UINT nType, int cx, int 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)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int deltaX, deltaY;
|
|
||||||
deltaX = cx - fLastWinSize.Width();
|
|
||||||
deltaY = cy - fLastWinSize.Height();
|
|
||||||
LOGD("Delta is %d,%d", deltaX, deltaY);
|
|
||||||
|
|
||||||
ShiftControls(deltaX, 0 /*deltaY*/);
|
|
||||||
|
|
||||||
// TODO: this is wrong
|
|
||||||
GetParent()->GetWindowRect(&fLastWinSize);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User hit F1 or applied the '?' button to something. Our heritage is
|
|
||||||
* dubious, so use global functions to access the help file.
|
|
||||||
*/
|
|
||||||
UINT SelectFilesDialog::HandleHelp(HWND hDlg, LPHELPINFO lpHelpInfo)
|
|
||||||
{
|
|
||||||
CWnd* pWndMain = ::AfxGetMainWnd();
|
|
||||||
CWinApp* pAppMain = ::AfxGetApp();
|
|
||||||
DWORD context = lpHelpInfo->iCtrlId;
|
|
||||||
BOOL result;
|
|
||||||
|
|
||||||
//LOGI("Handling help with context %ld", context);
|
|
||||||
result = ::WinHelp(pWndMain->m_hWnd, pAppMain->m_pszHelpFilePath,
|
|
||||||
HELP_CONTEXTPOPUP, context);
|
|
||||||
//LOGI("SFD WinHelp returned %d", result);
|
|
||||||
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
|
|
||||||
* the parent dialog wants to move.
|
|
||||||
*
|
|
||||||
* We need to shift everything up by the difference between the IDOK button
|
|
||||||
* and our "accept" button.
|
|
||||||
*/
|
|
||||||
void SelectFilesDialog::MyOnInitDone(void)
|
|
||||||
{
|
|
||||||
LOGI("OnInitDone!");
|
|
||||||
CWnd* pParent = GetParent();
|
|
||||||
CWnd* pWnd;
|
|
||||||
CRect okRect, cancelRect, acceptRect;
|
|
||||||
int vertDiff;
|
|
||||||
|
|
||||||
ASSERT(pParent != NULL);
|
|
||||||
pWnd = GetDlgItem(fAcceptButtonID);
|
|
||||||
ASSERT(pWnd != NULL);
|
|
||||||
pWnd->GetWindowRect(&acceptRect);
|
|
||||||
|
|
||||||
pWnd = pParent->GetDlgItem(IDOK);
|
|
||||||
ASSERT(pWnd != NULL);
|
|
||||||
pWnd->GetWindowRect(&okRect);
|
|
||||||
pWnd = pParent->GetDlgItem(IDCANCEL);
|
|
||||||
ASSERT(pWnd != NULL);
|
|
||||||
pWnd->GetWindowRect(&cancelRect);
|
|
||||||
|
|
||||||
vertDiff = acceptRect.top - okRect.top;
|
|
||||||
LOGD("vertDiff = %d (horizDiff=%d)", vertDiff,
|
|
||||||
acceptRect.left - okRect.left);
|
|
||||||
|
|
||||||
ShiftControls(0, -vertDiff);
|
|
||||||
|
|
||||||
// DestroyItem(pParent, stc3); // "File name"
|
|
||||||
// DestroyItem(pParent, edt1); // (file name edit)
|
|
||||||
DestroyItem(pParent, stc2); // "Files of type"
|
|
||||||
DestroyItem(pParent, cmb1); // (file type combo)
|
|
||||||
DestroyItem(pParent, IDOK); // "Open"/"Save"
|
|
||||||
DestroyItem(pParent, IDCANCEL); // "Cancel"
|
|
||||||
DestroyItem(this, stc32); // our placeholder
|
|
||||||
|
|
||||||
pParent->GetWindowRect(&fLastWinSize);
|
|
||||||
fLastWinSize.bottom -= vertDiff;
|
|
||||||
pParent->MoveWindow(&fLastWinSize);
|
|
||||||
|
|
||||||
// let sub-classes initialize the data fields
|
|
||||||
MyDataExchange(false);
|
|
||||||
|
|
||||||
fReady = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Shift the controls when the window size changes. This is a bit tricky
|
|
||||||
* because the CFileDialog is also moving the controls, though it doesn't
|
|
||||||
* move them in quite the way we want.
|
|
||||||
*/
|
|
||||||
void SelectFilesDialog::ShiftControls(int deltaX, int deltaY)
|
|
||||||
{
|
|
||||||
if (deltaX == 0 && deltaY == 0) {
|
|
||||||
LOGI("SFD OnSize: no meaningful change");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
LOGI("ShiftControls x=%d y=%d", deltaX, deltaY);
|
|
||||||
}
|
|
||||||
MoveControl(this, fAcceptButtonID, deltaX, deltaY, false);
|
|
||||||
MoveControl(this, IDCANCEL, deltaX, deltaY, false);
|
|
||||||
//StretchControl(this, IDC_FVIEW_EDITBOX, deltaX, deltaY);
|
|
||||||
|
|
||||||
// erase & redraw
|
|
||||||
Invalidate(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the list view control out of the common file dialog.
|
|
||||||
*
|
|
||||||
* Returns "NULL" if it can't find it.
|
|
||||||
*/
|
|
||||||
CWnd* SelectFilesDialog::GetListCtrl(void)
|
|
||||||
{
|
|
||||||
CWnd* pItem;
|
|
||||||
CWnd* pList;
|
|
||||||
|
|
||||||
/* our dialog is a child; get our parent, then grab the shellview */
|
|
||||||
pItem = GetParent()->GetDlgItem(lst2);
|
|
||||||
ASSERT(pItem != NULL);
|
|
||||||
if (pItem == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* pull the listview out of the shellview */
|
|
||||||
pList = pItem->GetDlgItem( 1);
|
|
||||||
ASSERT(pList != NULL);
|
|
||||||
|
|
||||||
return pList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When the selection changes, update our dialog.
|
|
||||||
*/
|
|
||||||
void SelectFilesDialog::MyOnFileNameChange(void)
|
|
||||||
{
|
|
||||||
//LOGI("OnFileNameChange");
|
|
||||||
|
|
||||||
CListCtrl* pList;
|
|
||||||
|
|
||||||
pList = (CListCtrl*) GetListCtrl();
|
|
||||||
if (pList == NULL) {
|
|
||||||
LOGI("GLITCH: could not get list control");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ASSERT(pList != NULL);
|
|
||||||
|
|
||||||
//LOGI("Selected count=%d", pList->GetSelectedCount());
|
|
||||||
//*pCount = pList->GetSelectedCount();
|
|
||||||
|
|
||||||
//CWnd* pItem;
|
|
||||||
//pItem = GetDlgItem(IDC_SELECT_ACCEPT);
|
|
||||||
//ASSERT(pItem != NULL);
|
|
||||||
//pItem->EnableWindow(*pCount != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The user hit the "Accept" button. Package up the file selection.
|
|
||||||
*/
|
|
||||||
void SelectFilesDialog::MyOnAccept(void)
|
|
||||||
{
|
|
||||||
LOGD("OnAccept!");
|
|
||||||
PrepEndDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Either the user hit the "Accept" button or the OFN dialog has indicated
|
|
||||||
* that it wants to close.
|
|
||||||
*
|
|
||||||
* Returns "true" if all went well, "false" if it failed (e.g. because the
|
|
||||||
* user hasn't selected any files).
|
|
||||||
*/
|
|
||||||
bool SelectFilesDialog::PrepEndDialog(void)
|
|
||||||
{
|
|
||||||
CListCtrl* pList;
|
|
||||||
int nextSpot = 0;
|
|
||||||
|
|
||||||
// let sub-classes copy data out
|
|
||||||
if (!MyDataExchange(true)) {
|
|
||||||
LOGW("MyDataExchange failed!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start with the set of stuff that the window wants to tell us about.
|
|
||||||
* Run through the list, converting all '\0' to '\\'. Later on we
|
|
||||||
* convert them back.
|
|
||||||
*
|
|
||||||
* nFileOffset will be zero if they click on "accept" instead of hitting
|
|
||||||
* return in the edit box or double-clicking on files. This can make it
|
|
||||||
* tricky to have names in the text field and files selected, because
|
|
||||||
* clicking rather than hitting "enter" will yield different results.
|
|
||||||
*
|
|
||||||
* The OFN dialog does add names to the box as they are selected, which
|
|
||||||
* makes it awkward to do anything reasonable.
|
|
||||||
*
|
|
||||||
* Fortunately I believe the world is divided into "typers" and
|
|
||||||
* "clickers", and so long as their paths don't cross we're fine.
|
|
||||||
*/
|
|
||||||
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) = '\\';
|
|
||||||
LOGD(" File '%ls'", buf);
|
|
||||||
buf += wcslen(buf) +1;
|
|
||||||
}
|
|
||||||
//Sleep(1000);
|
|
||||||
nextSpot = (buf - m_ofn.lpstrFile) -1;
|
|
||||||
ASSERT(*(m_ofn.lpstrFile + nextSpot) == '\0');
|
|
||||||
ASSERT(*(m_ofn.lpstrFile + nextSpot+1) == '\0');
|
|
||||||
|
|
||||||
/* stick a '\' on the very end, so we get double-null action later */
|
|
||||||
*(m_ofn.lpstrFile + nextSpot) = '\\';
|
|
||||||
}
|
|
||||||
LOGD("Last offset was %d", nextSpot);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* make it clear that they're only getting one */
|
|
||||||
/* (bad case: click on some files and hit "Accept") */
|
|
||||||
if (nextSpot == 0) {
|
|
||||||
CWnd* pEditWnd;
|
|
||||||
CString editText;
|
|
||||||
pEditWnd = GetParent()->GetDlgItem(edt1);
|
|
||||||
pEditWnd->GetWindowText(editText);
|
|
||||||
if (!editText.IsEmpty()) {
|
|
||||||
pEditWnd->SetWindowText("");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now merge in the selected files.
|
|
||||||
*/
|
|
||||||
pList = (CListCtrl*) GetListCtrl();
|
|
||||||
if (pList == NULL) {
|
|
||||||
LOGW("GLITCH: could not get list control");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ASSERT(pList != NULL);
|
|
||||||
|
|
||||||
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.",
|
|
||||||
m_ofn.lpstrTitle, MB_OK | MB_ICONWARNING);
|
|
||||||
/* make it clear that we're ignoring the names they typed */
|
|
||||||
ClearFileName();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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"\\";
|
|
||||||
fFileNameOffset = fileNames.GetLength();
|
|
||||||
compare = false;
|
|
||||||
} else {
|
|
||||||
fileNames = m_ofn.lpstrFile;
|
|
||||||
ASSERT(fileNames.Right(1) == L"\\");
|
|
||||||
fFileNameOffset = m_ofn.nFileOffset;
|
|
||||||
compare = true;
|
|
||||||
}
|
|
||||||
ASSERT(fFileNameOffset > 0);
|
|
||||||
|
|
||||||
POSITION posn;
|
|
||||||
posn = pList->GetFirstSelectedItemPosition();
|
|
||||||
if (posn == NULL) {
|
|
||||||
/* shouldn't happen -- Accept button should be dimmed */
|
|
||||||
ASSERT(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
while (posn != NULL) {
|
|
||||||
/* do this every time, because "fileNames" can be reallocated */
|
|
||||||
const WCHAR* tailStr = fileNames;
|
|
||||||
tailStr += fFileNameOffset-1;
|
|
||||||
|
|
||||||
int num = pList->GetNextSelectedItem(posn); // posn is updated
|
|
||||||
|
|
||||||
/* here we make a big assumption: that GetItemData returns a PIDL */
|
|
||||||
LPITEMIDLIST pidl;
|
|
||||||
WCHAR buf[MAX_PATH];
|
|
||||||
pidl = (LPITEMIDLIST) pList->GetItemData(num);
|
|
||||||
if (SHGetPathFromIDList(pidl, buf)) {
|
|
||||||
/* it's a relative PIDL but SHGetPathFromIDList wants a full
|
|
||||||
one, so it returns CWD + filename... strip bogus path off */
|
|
||||||
CString compareName(L"\\");
|
|
||||||
PathName path(buf);
|
|
||||||
compareName += path.GetFileName();
|
|
||||||
compareName += L"\\";
|
|
||||||
//LOGI(" Checking name='%ls'", compareName);
|
|
||||||
|
|
||||||
if (compare && Stristr(tailStr, compareName) != NULL) {
|
|
||||||
LOGI(" Matched '%ls', not adding", (LPCWSTR) compareName);
|
|
||||||
} else {
|
|
||||||
if (compare) {
|
|
||||||
LOGI(" No match on '%ls', adding", (LPCWSTR) compareName);
|
|
||||||
} else {
|
|
||||||
LOGI(" Found '%ls', adding", (LPCWSTR) compareName);
|
|
||||||
}
|
|
||||||
fileNames += path.GetFileName();
|
|
||||||
fileNames += L"\\";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* expected, for things like "Control Panels" or "My Network" */
|
|
||||||
LOGI(" No path for '%ls'",
|
|
||||||
(LPCWSTR) pList->GetItemText(num, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileNames.GetLength() >= (int)m_ofn.nMaxFile) {
|
|
||||||
LOGW("GLITCH: excessively long file name list");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGI("Final result: names at %d, len=%d, str='%ls'",
|
|
||||||
fFileNameOffset, wcslen(fileNames), (LPCWSTR) fileNames);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Null-terminate with extreme prejudice. Every filename should be
|
|
||||||
* separated with a null, and the last filename should be followed by
|
|
||||||
* two. Every component was followed by '\\', and the last one
|
|
||||||
* naturally has a null, so we should be in great shape after this.
|
|
||||||
*
|
|
||||||
* Could probably have done it entirely with CString, but I'm not sure
|
|
||||||
* how CStrings react to buffers with multiple null-terminated
|
|
||||||
* sub-strings.
|
|
||||||
*/
|
|
||||||
ASSERT(fFileNames != m_ofn.lpstrFile);
|
|
||||||
delete[] fFileNames;
|
|
||||||
fFileNames = wcsdup(fileNames);
|
|
||||||
WCHAR* cp = fFileNames;
|
|
||||||
cp += fFileNameOffset-1;
|
|
||||||
while (*cp != '\0') {
|
|
||||||
if (*cp == '\\')
|
|
||||||
*cp = '\0';
|
|
||||||
cp++;
|
|
||||||
}
|
|
||||||
//fileNames.ReleaseBuffer(-1);
|
|
||||||
|
|
||||||
fExitStatus = IDOK;
|
|
||||||
CDialog* pDialog = (CDialog*) GetParent();
|
|
||||||
pDialog->EndDialog(IDCANCEL);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User hit our cancel button.
|
|
||||||
*/
|
|
||||||
void SelectFilesDialog::MyOnCancel(void)
|
|
||||||
{
|
|
||||||
fExitStatus = IDCANCEL;
|
|
||||||
CDialog* pDialog = (CDialog*) GetParent();
|
|
||||||
pDialog->EndDialog(IDCANCEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clear the filename field.
|
|
||||||
*/
|
|
||||||
void SelectFilesDialog::ClearFileName(void)
|
|
||||||
{
|
|
||||||
CWnd* pWnd = GetParent()->GetDlgItem(edt1);
|
|
||||||
if (pWnd != NULL)
|
|
||||||
pWnd->SetWindowText(L"");
|
|
||||||
}
|
|
||||||
|
|
|
@ -40,129 +40,11 @@
|
||||||
#define UTIL_SELECTFILESDIALOG_H
|
#define UTIL_SELECTFILESDIALOG_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* File selection, based on an "open" file dialog.
|
* File selection, based on an "open" common file dialog.
|
||||||
*
|
|
||||||
* DoModal will return with IDCANCEL to indicate that the standard fields
|
|
||||||
* (like lpstrFile) are not actually filled in. Use the provided fields
|
|
||||||
* to get exit status and filename info.
|
|
||||||
*
|
|
||||||
* Defer any dialog initialization to MyDataExchange.
|
|
||||||
*/
|
*/
|
||||||
class SelectFilesDialog : public CFileDialog {
|
class SelectFilesDialog : public CFileDialog {
|
||||||
public:
|
public:
|
||||||
enum { kFileNameBufSize = 32768 };
|
SelectFilesDialog(const WCHAR* rctmpl, bool showHelp, CWnd* pParentWnd = NULL) :
|
||||||
SelectFilesDialog(const WCHAR* rctmpl, CWnd* pParentWnd = NULL) :
|
|
||||||
CFileDialog(true, NULL, NULL, OFN_HIDEREADONLY, NULL, pParentWnd,
|
|
||||||
0, FALSE /*disable Vista style*/)
|
|
||||||
{
|
|
||||||
m_ofn.Flags |= OFN_ENABLETEMPLATE | OFN_ALLOWMULTISELECT |
|
|
||||||
OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING;
|
|
||||||
m_ofn.lpTemplateName = rctmpl;
|
|
||||||
m_ofn.hInstance = AfxGetInstanceHandle();
|
|
||||||
m_ofn.lpstrFile = new WCHAR[kFileNameBufSize];
|
|
||||||
m_ofn.lpstrFile[0] = m_ofn.lpstrFile[1] = '\0';
|
|
||||||
m_ofn.nMaxFile = kFileNameBufSize;
|
|
||||||
m_ofn.nFileOffset = -1;
|
|
||||||
m_ofn.Flags |= OFN_ENABLEHOOK;
|
|
||||||
m_ofn.lpfnHook = OFNHookProc;
|
|
||||||
m_ofn.lCustData = (LPARAM) this;
|
|
||||||
|
|
||||||
fExitStatus = IDABORT;
|
|
||||||
fFileNames = new WCHAR[2];
|
|
||||||
fFileNames[0] = fFileNames[1] = '\0';
|
|
||||||
fFileNameOffset = 0;
|
|
||||||
|
|
||||||
fAcceptButtonID = IDOK;
|
|
||||||
|
|
||||||
fReady = false; // used by WM_SIZE handler
|
|
||||||
}
|
|
||||||
virtual ~SelectFilesDialog(void) {
|
|
||||||
delete[] m_ofn.lpstrFile;
|
|
||||||
delete[] fFileNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetExitStatus(void) const { return fExitStatus; }
|
|
||||||
const WCHAR* GetFileNames(void) const { return fFileNames; }
|
|
||||||
int GetFileNameOffset(void) const { return fFileNameOffset; }
|
|
||||||
|
|
||||||
// set the window title; must be called before DoModal
|
|
||||||
void SetWindowTitle(const WCHAR* title) {
|
|
||||||
m_ofn.lpstrTitle = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stuff values into our filename holder
|
|
||||||
void SetFileNames(const WCHAR* fileNames, size_t len, int fileNameOffset) {
|
|
||||||
ASSERT(len > wcslen(fileNames));
|
|
||||||
ASSERT(fileNames[len] == '\0');
|
|
||||||
ASSERT(fileNames[len-1] == '\0');
|
|
||||||
LOGD("SetFileNames '%ls' %d %d", fileNames, len, fileNameOffset);
|
|
||||||
delete[] fFileNames;
|
|
||||||
fFileNames = new WCHAR[len];
|
|
||||||
memcpy(fFileNames, fileNames, len * sizeof(WCHAR));
|
|
||||||
fFileNameOffset = fileNameOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// would be overrides
|
|
||||||
virtual void MyOnInitDone(void);
|
|
||||||
virtual void MyOnFileNameChange(void);
|
|
||||||
// like DoDataExchange, but ret val replaces pDX->Fail()
|
|
||||||
virtual bool MyDataExchange(bool saveAndValidate) { return true; }
|
|
||||||
|
|
||||||
// would be message handlers
|
|
||||||
virtual UINT HandleNotify(HWND hDlg, LPOFNOTIFY pofn);
|
|
||||||
virtual UINT HandleCommand(HWND hDlg, WPARAM wParam, LPARAM lParam);
|
|
||||||
virtual UINT HandleSize(HWND hDlg, UINT nType, int cx, int cy);
|
|
||||||
virtual UINT HandleHelp(HWND hDlg, LPHELPINFO lpHelp);
|
|
||||||
virtual UINT MyOnCommand(WPARAM wParam, LPARAM lParam) { return 0; }
|
|
||||||
|
|
||||||
virtual void MyOnAccept(void);
|
|
||||||
virtual void MyOnCancel(void);
|
|
||||||
|
|
||||||
// utility functions
|
|
||||||
virtual CWnd* GetListCtrl(void);
|
|
||||||
virtual void ShiftControls(int deltaX, int deltaY);
|
|
||||||
virtual void DestroyItem(CWnd* pDlg, int id) {
|
|
||||||
CWnd* pWnd = pDlg->GetDlgItem(id);
|
|
||||||
if (pWnd == NULL) {
|
|
||||||
LOGW("Could not find item %p %d", pDlg, id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pWnd->DestroyWindow();
|
|
||||||
}
|
|
||||||
virtual bool PrepEndDialog(void);
|
|
||||||
|
|
||||||
// make this a little easier
|
|
||||||
int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL,
|
|
||||||
UINT nType = MB_OK)
|
|
||||||
{
|
|
||||||
return GetParent()->MessageBox(lpszText, lpszCaption, nType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're in a library, so the app resources have to tell us this
|
|
||||||
int fAcceptButtonID;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static UINT CALLBACK OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam,
|
|
||||||
LPARAM lParam);
|
|
||||||
void ClearFileName(void);
|
|
||||||
|
|
||||||
bool fReady;
|
|
||||||
int fExitStatus;
|
|
||||||
int fFileNameOffset;
|
|
||||||
WCHAR* fFileNames;
|
|
||||||
CRect fLastWinSize;
|
|
||||||
|
|
||||||
//DECLARE_MESSAGE_MAP()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* File selection, based on an "open" common file dialog.
|
|
||||||
*/
|
|
||||||
class SelectFilesDialog2 : public CFileDialog {
|
|
||||||
public:
|
|
||||||
SelectFilesDialog2(const WCHAR* rctmpl, CWnd* pParentWnd = NULL) :
|
|
||||||
CFileDialog(true, NULL, NULL, OFN_HIDEREADONLY, NULL, pParentWnd,
|
CFileDialog(true, NULL, NULL, OFN_HIDEREADONLY, NULL, pParentWnd,
|
||||||
0, FALSE /*disable Vista style*/)
|
0, FALSE /*disable Vista style*/)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +52,8 @@ public:
|
||||||
// we want the multi-select behavior but we don't want to return
|
// we want the multi-select behavior but we don't want to return
|
||||||
// the filenames in the filename buf.
|
// the filenames in the filename buf.
|
||||||
m_ofn.Flags |= OFN_ENABLETEMPLATE | OFN_ALLOWMULTISELECT |
|
m_ofn.Flags |= OFN_ENABLETEMPLATE | OFN_ALLOWMULTISELECT |
|
||||||
OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING;
|
OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING |
|
||||||
|
(showHelp ? OFN_SHOWHELP : 0);
|
||||||
|
|
||||||
// Configure use of a template. The dialog template must have
|
// Configure use of a template. The dialog template must have
|
||||||
// WS_CHILD and WS_CLIPSIBLINGS set, and should have DS_3DLOOK and
|
// WS_CHILD and WS_CLIPSIBLINGS set, and should have DS_3DLOOK and
|
||||||
|
@ -179,7 +62,7 @@ public:
|
||||||
m_ofn.hInstance = AfxGetInstanceHandle();
|
m_ofn.hInstance = AfxGetInstanceHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SelectFilesDialog2(void) {}
|
virtual ~SelectFilesDialog(void) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets the directory name where the files live. This is a full path.
|
* Gets the directory name where the files live. This is a full path.
|
||||||
|
@ -200,14 +83,40 @@ public:
|
||||||
m_ofn.lpstrTitle = (LPCWSTR) fCustomTitle;
|
m_ofn.lpstrTitle = (LPCWSTR) fCustomTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
/*
|
/*
|
||||||
* Finish configuring the file dialog.
|
* 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:
|
||||||
|
/*
|
||||||
|
* Finishes configuring the file dialog.
|
||||||
*/
|
*/
|
||||||
virtual void OnInitDone() override;
|
virtual void OnInitDone() override;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Track changes to the current directory.
|
* Tracks changes to the current directory.
|
||||||
*
|
*
|
||||||
* Updates fCurrentDirectory with the path currently being used by the
|
* Updates fCurrentDirectory with the path currently being used by the
|
||||||
* dialog. For items with no path (e.g. Computer or Libraries), this
|
* dialog. For items with no path (e.g. Computer or Libraries), this
|
||||||
|
@ -215,7 +124,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void OnFolderChange() override;
|
virtual void OnFolderChange() override;
|
||||||
|
|
||||||
private:
|
|
||||||
/*
|
/*
|
||||||
* Custom filename validation; in our case, it's a double-click trap.
|
* Custom filename validation; in our case, it's a double-click trap.
|
||||||
*
|
*
|
||||||
|
@ -266,7 +174,7 @@ private:
|
||||||
CString fCustomTitle;
|
CString fCustomTitle;
|
||||||
|
|
||||||
// Directory the dialog is currently accessing. Prepend this to the
|
// Directory the dialog is currently accessing. Prepend this to the
|
||||||
// entries in fFileNameArray to get the full path.
|
// entries in fFileNameArray to get full paths.
|
||||||
CString fCurrentDirectory;
|
CString fCurrentDirectory;
|
||||||
|
|
||||||
// File names of selected files.
|
// File names of selected files.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user