Reimplement ChooseDirDialog

The previous version was written to work on Win98+, and used the
rather gnarly ShellTree class.  Since we no longer support Win98,
we can now use CShellManager::BrowseForFolder(), which does exactly
what we want without all the ugly code (and it looks nicer, and it
integrates better with the rest of the system).

We can also get rid of NewFolderDialog, which only existed to allow
the user to create a folder when trudging through ShellTree.

This required "upgrading" the main app object from CWinApp to
CWinAppEx, but that appears to be benign.  Tested on WinXP and it
all seems fine.
This commit is contained in:
Andy McFadden 2015-01-13 13:21:43 -08:00
parent 7cd92a7fdd
commit fd37bfd261
19 changed files with 42 additions and 2001 deletions

View File

@ -4,7 +4,7 @@ faddenSoft
http://www.faddensoft.com/
CiderPress
http://a2ciderpress.com/
4.0.0b1
4.0.0b2
42016
C:\DATA\faddenSoft\fs.ico
Copyright © 2015 CiderPress project authors. All rights reserved.
@ -355,7 +355,7 @@ FALSE
4095
Setup400b1.exe
Setup400b2.exe
FALSE

View File

@ -441,7 +441,7 @@ bool AppleSingleArchive::CreateEntry()
}
pNewEntry->SetCompressedLen(dataLen + rsrcLen);
if (rsrcLen > 0) {
if (rsrcLen > 0) { // could do ">=" to preserve empty resource forks
pNewEntry->SetRecordKind(GenericEntry::kRecordKindForkedFile);
} else {
pNewEntry->SetRecordKind(GenericEntry::kRecordKindFile);
@ -460,6 +460,10 @@ bool AppleSingleArchive::CreateEntry()
CStringA fileNameA(fileName);
pNewEntry->SetPathNameMOR(fileNameA);
}
// This doesn't matter, since we only have the file name, but it keeps
// the entry from getting a weird default.
pNewEntry->SetFssep(':');
AddEntry(pNewEntry);
return true;

View File

@ -1,153 +0,0 @@
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
#include "stdafx.h"
#include "ChooseDirDialog.h"
#include "NewFolderDialog.h"
#include "DiskFSTree.h"
BEGIN_MESSAGE_MAP(ChooseDirDialog, CDialog)
ON_NOTIFY(TVN_SELCHANGED, IDC_CHOOSEDIR_TREE, OnSelChanged)
ON_BN_CLICKED(IDC_CHOOSEDIR_EXPAND_TREE, OnExpandTree)
ON_BN_CLICKED(IDC_CHOOSEDIR_NEW_FOLDER, OnNewFolder)
ON_WM_HELPINFO()
//ON_COMMAND(ID_HELP, OnIDHelp)
ON_BN_CLICKED(IDHELP, OnHelp)
END_MESSAGE_MAP()
BOOL ChooseDirDialog::OnInitDialog(void)
{
CDialog::OnInitDialog();
/* set up the "new folder" button */
fNewFolderButton.ReplaceDlgCtrl(this, IDC_CHOOSEDIR_NEW_FOLDER);
fNewFolderButton.SetBitmapID(IDB_NEW_FOLDER);
/* replace the tree control with a ShellTree */
if (fShellTree.ReplaceDlgCtrl(this, IDC_CHOOSEDIR_TREE) != TRUE) {
LOGI("WARNING: ShellTree replacement failed");
ASSERT(false);
}
//enable images
fShellTree.EnableImages();
//populate for the with Shell Folders for the first time
fShellTree.PopulateTree(/*CSIDL_DRIVES*/);
if (fPathName.IsEmpty()) {
// start somewhere reasonable
fShellTree.ExpandMyComputer();
} else {
CString msg("");
fShellTree.TunnelTree(fPathName, &msg);
if (!msg.IsEmpty()) {
/* failed */
LOGI("TunnelTree failed on '%ls' (%ls), using MyComputer instead",
(LPCWSTR) fPathName, (LPCWSTR) msg);
fShellTree.ExpandMyComputer();
}
}
fShellTree.SetFocus();
return FALSE; // leave focus on shell tree
}
BOOL ChooseDirDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN &&
pMsg->wParam == VK_RETURN)
{
//LOGI("RETURN!");
if (GetFocus() == GetDlgItem(IDC_CHOOSEDIR_PATHEDIT)) {
OnExpandTree();
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
void ChooseDirDialog::OnSelChanged(NMHDR* pnmh, LRESULT* pResult)
{
CString path;
CWnd* pWnd = GetDlgItem(IDC_CHOOSEDIR_PATH);
ASSERT(pWnd != NULL);
if (fShellTree.GetFolderPath(&path))
fPathName = path;
else
fPathName = L"";
pWnd->SetWindowText(fPathName);
// disable the "Select" button when there's no path ready
pWnd = GetDlgItem(IDOK);
ASSERT(pWnd != NULL);
pWnd->EnableWindow(!fPathName.IsEmpty());
// It's confusing to have two different paths showing, so wipe out the
// free entry field when the selection changes.
pWnd = GetDlgItem(IDC_CHOOSEDIR_PATHEDIT);
pWnd->SetWindowText(L"");
*pResult = 0;
}
void ChooseDirDialog::OnExpandTree(void)
{
CWnd* pWnd;
CString str;
CString msg;
pWnd = GetDlgItem(IDC_CHOOSEDIR_PATHEDIT);
ASSERT(pWnd != NULL);
pWnd->GetWindowText(str);
if (!str.IsEmpty()) {
fShellTree.TunnelTree(str, &msg);
if (!msg.IsEmpty()) {
CString failed;
CheckedLoadString(&failed, IDS_FAILED);
MessageBox(msg, failed, MB_OK | MB_ICONERROR);
}
}
}
void ChooseDirDialog::OnNewFolder(void)
{
if (fPathName.IsEmpty()) {
MessageBox(L"You can't create a folder in this part of the tree.",
L"Bad Location", MB_OK | MB_ICONERROR);
return;
}
NewFolderDialog newFolderDlg;
newFolderDlg.fCurrentFolder = fPathName;
if (newFolderDlg.DoModal() == IDOK) {
if (newFolderDlg.GetFolderCreated()) {
/*
* They created a new folder. We want to add it to the tree
* and then select it. This is not too hard because we know
* that the folder was created under the currently-selected
* tree node.
*/
if (fShellTree.AddFolderAtSelection(newFolderDlg.fNewFolder)) {
CString msg;
LOGI("Success, tunneling to '%ls'",
(LPCWSTR) newFolderDlg.fNewFullPath);
fShellTree.TunnelTree(newFolderDlg.fNewFullPath, &msg);
if (!msg.IsEmpty()) {
LOGI("TunnelTree failed: %ls", (LPCWSTR) msg);
}
} else {
LOGI("AddFolderAtSelection FAILED");
ASSERT(false);
}
} else {
LOGI("NewFolderDialog returned IDOK but no create");
}
}
}

View File

@ -11,65 +11,47 @@
#include "../util/UtilLib.h"
#include "resource.h"
#include <afxshellmanager.h>
/*
* Choose a directory. This is distinctly different from what the standard
* "Open" and "Save As" dialogs do, because those want to choose normal files
* only, while this wants to select a folder.
*
* TODO: Vista-style dialogs support folder selection. Consider switching
* based on OS version.
* Win2K added the shell "browse for folder" dialog, which does exactly
* what we want.
*/
class ChooseDirDialog : public CDialog {
class ChooseDirDialog {
public:
ChooseDirDialog(CWnd* pParent = NULL, int dialogID = IDD_CHOOSEDIR) :
CDialog(dialogID, pParent)
{
fPathName = L"";
ChooseDirDialog(CWnd* pParent = NULL) {
fpParent = pParent;
}
virtual ~ChooseDirDialog(void) {}
~ChooseDirDialog() {}
const WCHAR* GetPathName(void) const { return fPathName; }
// set the pathname; when DoModal is called this will tunnel in
void SetPathName(const WCHAR* str) { fPathName = str; }
protected:
virtual BOOL OnInitDialog(void) override;
// Special handling for "return" key.
virtual BOOL PreTranslateMessage(MSG* pMsg) override;
/*
* Replace the ShellTree's default SELCHANGED handler with this so we can
* track changes to the edit control.
*/
afx_msg void OnSelChanged(NMHDR* pnmh, LRESULT* pResult);
// User pressed "Expand Tree" button.
afx_msg void OnExpandTree(void);
// User pressed "New Folder" button.
afx_msg void OnNewFolder(void);
// User pressed "Help" button.
afx_msg void OnHelp(void) {
MyApp::HandleHelp(this, HELP_TOPIC_CHOOSE_FOLDER);
// Gets the pathname. Call this after DoModal has updated it.
const CString& GetPathName(void) const {
return fPathName;
}
// F1 key hit, or '?' button in title bar used to select help for an
// item in the dialog. For ON_WM_HELPINFO.
afx_msg BOOL OnHelpInfo(HELPINFO* lpHelpInfo) {
return MyApp::HandleHelpInfo(lpHelpInfo);
// Sets the pathname. Call before DoModal().
void SetPathName(const CString& str) {
fPathName = str;
}
// Returns false if nothing was selected (e.g. the dialog was canceled).
BOOL DoModal() {
CShellManager* pMan = gMyApp.GetShellManager();
CString outFolder;
BOOL result = pMan->BrowseForFolder(outFolder, fpParent, fPathName,
L"Select folder:", BIF_RETURNONLYFSDIRS | BIF_USENEWUI);
fPathName = outFolder;
return result;
}
private:
CString fPathName;
ShellTree fShellTree;
MyBitmapButton fNewFolderButton;
DECLARE_MESSAGE_MAP()
CWnd* fpParent;
CString fPathName;
};
#endif /*APP_CHOOSEDIRDIALOG*/

View File

@ -483,19 +483,6 @@ BEGIN
PUSHBUTTON "Expand Tree",IDC_CHOOSEDIR_EXPAND_TREE,198,208,50,14
END
IDD_NEWFOLDER DIALOG 0, 0, 251, 69
STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Create New Folder"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_NEWFOLDER_NAME,6,47,177,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,193,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,193,24,50,14
LTEXT "Current folder:",IDC_STATIC,6,7,177,8
EDITTEXT IDC_NEWFOLDER_CURDIR,6,16,177,14,ES_AUTOHSCROLL | ES_READONLY
LTEXT "New folder name (will be created in current folder):",IDC_STATIC,6,37,177,8
END
IDD_EXTRACT_FILES DIALOG 0, 0, 299, 242
STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Extract Files"
@ -1439,14 +1426,6 @@ BEGIN
BOTTOMMARGIN, 246
END
IDD_NEWFOLDER, DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 243
TOPMARGIN, 7
BOTTOMMARGIN, 61
END
IDD_EXTRACT_FILES, DIALOG
BEGIN
LEFTMARGIN, 7

View File

@ -26,7 +26,7 @@ DebugLog* gDebugLog;
* This is the closest thing to "main" that we have, but we
* should wait for InitInstance for most things.
*/
MyApp::MyApp(LPCTSTR lpszAppName) : CWinApp(lpszAppName)
MyApp::MyApp(LPCTSTR lpszAppName) : CWinAppEx(true /*lpszAppName*/)
{
gDebugLog = new DebugLog(L"C:\\src\\cplog.txt");
@ -262,8 +262,8 @@ BOOL MyApp::OnIdle(LONG lCount)
IDC_FVIEW_FONT, IDH_FVIEW_FONT,
IDC_FVIEW_NEXT, IDH_FVIEW_NEXT,
IDC_FVIEW_PREV, IDH_FVIEW_PREV,
IDC_NEWFOLDER_CURDIR, IDH_NEWFOLDER_CURDIR,
IDC_NEWFOLDER_NAME, IDH_NEWFOLDER_NAME,
//IDC_NEWFOLDER_CURDIR, IDH_NEWFOLDER_CURDIR, // dialog removed
//IDC_NEWFOLDER_NAME, IDH_NEWFOLDER_NAME, // dialog removed
IDC_EXT_PATH, IDH_EXT_PATH,
IDC_EXT_CONVEOLTEXT, IDH_EXT_CONVEOLTEXT,
IDC_EXT_CONVEOLALL, IDH_EXT_CONVEOLALL,

View File

@ -20,7 +20,7 @@
/*
* Windows application object.
*/
class MyApp: public CWinApp
class MyApp: public CWinAppEx
{
public:
MyApp(LPCTSTR lpszAppName = NULL);

View File

@ -1,68 +0,0 @@
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
#include "stdafx.h"
#include "NewFolderDialog.h"
BEGIN_MESSAGE_MAP(NewFolderDialog, CDialog)
ON_WM_HELPINFO()
END_MESSAGE_MAP()
void NewFolderDialog::DoDataExchange(CDataExchange* pDX)
{
/*
* It is very important to keep '\\' out of the folder path, because it allows
* for all sorts of behavior (like "..\foo" or "D:\ack") that the caller
* might not be expecting. For example, if it's displaying a tree, it
* might assume that the folder goes under the currently selected node.
*
* Under WinNT, '/' is regarded as equivalent to '\', so we have to block
* that as well.
*
* Other characters (':') are also dangerous, but so long as we start with
* a valid path, Windows will prevent them from being used where they are
* inappropriate.
*/
if (!pDX->m_bSaveAndValidate)
DDX_Text(pDX, IDC_NEWFOLDER_CURDIR, fCurrentFolder);
DDX_Text(pDX, IDC_NEWFOLDER_NAME, fNewFolder);
/* validate the new folder by creating it */
if (pDX->m_bSaveAndValidate) {
if (fNewFolder.IsEmpty()) {
MessageBox(L"No name entered, not creating new folder.",
L"CiderPress", MB_OK);
// fall out of DoModal with fFolderCreated==false
} else if (fNewFolder.Find('\\') >= 0 ||
fNewFolder.Find('/') >= 0)
{
MessageBox(L"Folder names may not contain '/' or '\\'.",
L"CiderPress", MB_OK);
pDX->Fail();
} else {
fNewFullPath = fCurrentFolder;
if (fNewFullPath.Right(1) != "\\")
fNewFullPath += "\\";
fNewFullPath += fNewFolder;
LOGI("CREATING '%ls'", (LPCWSTR) fNewFullPath);
if (!::CreateDirectory(fNewFullPath, NULL)) {
/* show the sometimes-bizarre Windows error string */
CString msg, errStr, failed;
DWORD dwerr = ::GetLastError();
GetWin32ErrorString(dwerr, &errStr);
msg.Format(L"Unable to create folder '%ls': %ls",
(LPCWSTR) fNewFolder, (LPCWSTR) errStr);
CheckedLoadString(&failed, IDS_FAILED);
MessageBox(msg, failed, MB_OK | MB_ICONERROR);
pDX->Fail();
} else {
/* success! */
fFolderCreated = true;
}
}
}
}

View File

@ -1,53 +0,0 @@
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* Allow the user to create a new folder.
*/
#ifndef APP_NEWFOLDERDIALOG_H
#define APP_NEWFOLDERDIALOG_H
#include "resource.h"
/*
* Create a new folder in an existing location.
*
* Expects, but does not verify, that "fCurrentFolder" is set to a valid
* path before DoModal is called.
*/
class NewFolderDialog : public CDialog {
public:
NewFolderDialog(CWnd* pParent = NULL) : CDialog(IDD_NEWFOLDER, pParent) {
fCurrentFolder = L"";
fNewFolder = L"";
fFolderCreated = false;
}
virtual ~NewFolderDialog(void) {}
bool GetFolderCreated(void) const { return fFolderCreated; }
// set to CWD before calling DoModal
CString fCurrentFolder;
// filename (NOT pathname) of new folder (DDXed in edit ctrl)
CString fNewFolder;
// full pathname of new folder, valid if fFolderCreated is true
CString fNewFullPath;
protected:
void DoDataExchange(CDataExchange* pDX) override;
afx_msg BOOL OnHelpInfo(HELPINFO* lpHelpInfo) {
return MyApp::HandleHelpInfo(lpHelpInfo);
}
// on exit, set to "true" if we created the folder in "fNewFolder"
bool fFolderCreated;
DECLARE_MESSAGE_MAP()
};
#endif /*APP_NEWFOLDERDIALOG_H*/

View File

@ -24,6 +24,7 @@
#include "targetver.h"
#include <afxwin.h>
#include <afxwinappex.h>
#include <afxcmn.h>
#include <afxdlgs.h>
#include <afxdisp.h>

View File

@ -194,7 +194,6 @@
<ClInclude Include="Main.h" />
<ClInclude Include="MyApp.h" />
<ClInclude Include="NewDiskSize.h" />
<ClInclude Include="NewFolderDialog.h" />
<ClInclude Include="NufxArchive.h" />
<ClInclude Include="OpenVolumeDialog.h" />
<ClInclude Include="PasteSpecialDialog.h" />
@ -266,7 +265,6 @@
<ClCompile Include="CassetteDialog.cpp" />
<ClCompile Include="CassImpTargetDialog.cpp" />
<ClCompile Include="ChooseAddTargetDialog.cpp" />
<ClCompile Include="ChooseDirDialog.cpp" />
<ClCompile Include="Clipboard.cpp" />
<ClCompile Include="ConfirmOverwriteDialog.cpp" />
<ClCompile Include="ContentList.cpp" />
@ -292,7 +290,6 @@
<ClCompile Include="Main.cpp" />
<ClCompile Include="MyApp.cpp" />
<ClCompile Include="NewDiskSize.cpp" />
<ClCompile Include="NewFolderDialog.cpp" />
<ClCompile Include="NufxArchive.cpp" />
<ClCompile Include="OpenVolumeDialog.cpp" />
<ClCompile Include="PasteSpecialDialog.cpp" />

View File

@ -134,9 +134,6 @@
<ClInclude Include="NewDiskSize.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NewFolderDialog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NufxArchive.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -282,9 +279,6 @@
<ClCompile Include="ChooseAddTargetDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ChooseDirDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Clipboard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -360,9 +354,6 @@
<ClCompile Include="NewDiskSize.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NewFolderDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NufxArchive.cpp">
<Filter>Source Files</Filter>
</ClCompile>

View File

@ -25,7 +25,6 @@
#define IDD_CHOOSEDIR 135
#define IDB_NEW_FOLDER 139
#define IDB_CHOOSE_FOLDER 140
#define IDD_NEWFOLDER 141
#define IDD_EXTRACT_FILES 142
#define IDD_ACTION_PROGRESS 143
#define IDD_CONFIRM_OVERWRITE 144
@ -157,8 +156,6 @@
#define IDC_FVIEW_FONT 1129
#define IDC_FVIEW_NEXT 1130
#define IDC_FVIEW_PREV 1131
#define IDC_NEWFOLDER_CURDIR 1132
#define IDC_NEWFOLDER_NAME 1133
#define IDC_EXT_PATH 1136
#define IDC_EXT_CONVEOLTEXT 1137
#define IDC_EXT_CONVEOLALL 1138

View File

@ -24,8 +24,10 @@
#include <stdio.h>
#include <assert.h>
#include <stdint.h>
#include <afxwin.h>
#include <afxcmn.h> // for some stuff in util lib
#include <afxwin.h> // for some stuff in util lib
#include <afxcmn.h>
#include <afxwinappex.h>
#include <afxshellmanager.h>
#include "../util/UtilLib.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,216 +0,0 @@
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* TreeView control containing Windows shell folders.
*
* Originally based on MFCENUM from "Programming the Windows 95 User
* interface". Enhanced by Selom Ofori as "ShellTree" class. Modified
* extensively.
*/
#ifndef UTIL_SHELLTREE_H
#define UTIL_SHELLTREE_H
/*
* ShellTree class.
*/
class ShellTree : public CTreeCtrl {
public:
//enum FindAttribs {type_drive, type_folder};
ShellTree(void) {
fFolderPathValid = false;
}
virtual ~ShellTree(void) {
Detach(); // we don't own the window handle
}
/*
* Replace a CTreeCtrl in a dialog box with us. All of the styles are
* copied from the original dialog window.
*
* Returns TRUE on success, FALSE on failure.
*/
BOOL ReplaceDlgCtrl(CDialog* pDialog, int treeID);
/*
* Populate the tree, starting from "nFolder".
*
* Returns TRUE on success, FALSE on failure.
*/
BOOL PopulateTree(int nFolder = CSIDL_DESKTOP);
/*
* Open up and select My Computer.
*/
void ExpandMyComputer(void);
/*
* Add a new folder to the tree at the currently-selected node. This may
* not actually add a folder if the new folder is at a point in the tree
* below where we have already expanded.
*
* Returns TRUE on success, or FALSE on failure.
*/
BOOL AddFolderAtSelection(const CString& name);
void GetContextMenu(NMHDR* pNMHDR, LRESULT* pResult);
/*
* Gets a handle to the system image list (by just grabbing whatever is
* in place for C:\) and makes it available to the tree control.
*
* The image list should NOT be deleted.
*/
void EnableImages();
/*
* Retrieves the path of the currently selected string.
* Pass a CString object that will hold the folder path.
* If the path is not in the filesystem(eg MyComputer)
* or none is selected it returns false.
*/
BOOL GetSelectedFolderPath(CString &szFolderPath);
/*
* Retrieves the pointer to the ISHELLFOLDER interface
* of the tree node passed as the parameter.
*/
LPSHELLFOLDER GetParentShellFolder(HTREEITEM folderNode);
/*
* Retrieves the Pointer to an ITEMIDLIST structure that
* identifies the subfolder relative to its parent folder.
* see GetParentShellFolder();
*/
LPITEMIDLIST GetRelativeIDLIST(HTREEITEM folderNode);
/*
* Retrieves the Pointer to an ITEMIDLIST
* structure that identifies the subfolder relative to the
* desktop. This is a fully qualified Item Identifier
*/
LPITEMIDLIST GetFullyQualifiedID(HTREEITEM folderNode);
/*
* Tunnel into the tree, finding the node that corresponds to the
* requested pathname.
*
* Sets "resultMsg" to a non-empty string on error.
*/
void TunnelTree(CString path, CString* pResultStr);
// Get the most-recently-set folder path. This will be updated on
// every TVN_SELCHANGED, so add an ON_NOTIFY handler to the parent.
BOOL GetFolderPath(CString* pStr) {
*pStr = fFolderPath;
return fFolderPathValid;
}
protected:
/*
* Respond to TVN_ITEMEXPANDING message.
*
* If the subtree hasn't been expanded yet, dig in.
*/
void OnFolderExpanding(NMHDR* pNMHDR, LRESULT* pResult);
/*
* Handle TVN_DELETEITEM notification by cleaning up our stuff.
*/
void OnDeleteShellItem(NMHDR* pNMHDR, LRESULT* pResult);
/*
* Respond to TVN_SELCHANGED notification.
*/
BOOL OnSelectionChange(NMHDR* pNMHDR, LRESULT* pResult);
/*
* This does the bulk of the work when the selection changes.
*
* The filesystem path (if any) to the object is placed in "szFolderPath".
*/
BOOL OnFolderSelected(NMHDR* pNMHDR, LRESULT* pResult,
CString& szFolderPath);
/*
* Fills a branch of the TreeView control. Given the shell folder (both as
* a shell folder and the fully-qualified item ID list to it) and the parent
* item in the tree (TVI_ROOT to start off), add all the kids to the tree.
*
* Does not try to add the current entry, as a result of which we don't
* have a root "Desktop" node that everything is a child of. This is okay.
*/
void FillTreeView(LPSHELLFOLDER lpsf,LPITEMIDLIST lpifq, HTREEITEM hParent);
/*
* Add a node to the tree.
*
* Returns TRUE on success, FALSE on failure.
*/
BOOL AddNode(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, LPITEMIDLIST lpifq,
unsigned long ulAttrs, HTREEITEM hParent, HTREEITEM* phPrev);
/*
* Sort function callback for TreeView SortChildrenCB.
*/
static int CALLBACK TreeViewCompareProc(LPARAM, LPARAM, LPARAM);
/*
* Set the TreeView normal and selected icons for the specified entry.
*
* "lpifq" is the fully-qualified PIDL, LPTV_ITEM is an item in the tree.
*/
void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTV_ITEM lptvitem);
/*
* Find the tree entry that corresponds to "My Computer".
*
* Returns a handle to the tree item, or NULL if My Computer wasn't found
* or didn't have any children.
*/
HTREEITEM FindMyComputer(void);
/*
* Given a pointer to the My Computer node in the tree, find the node
* corresponding to the requested drive (which should be of the form
* "C:").
*
* Returns a pointer to the drive's node on success, or NULL on failure.
*/
HTREEITEM FindDrive(HTREEITEM myComputer, const CString& drive);
/*
* Given a path, search a subtree following the components.
*
* Pass in the tree's root (it's children will be searched for a
* match with the first path component) and the path to look for
* (which must start and end with '\\').
*/
HTREEITEM SearchTree(HTREEITEM treeNode, const CString& path);
/*
* Tree view element. Each one holds a pointer to the ShellFolder
* object, a pointer to the ItemIDList for the item within the folder,
* and a pointer to the fully-qualified ItemIDList for the item.
*/
typedef struct TVItemData {
LPSHELLFOLDER lpsfParent;
LPITEMIDLIST lpi;
LPITEMIDLIST lpifq;
//bool alphaSort;
} TVItemData;
CString fFolderPath;
BOOL fFolderPathValid;
DECLARE_MESSAGE_MAP()
private:
DECLARE_COPY_AND_OPEQ(ShellTree)
};
#endif /*UTIL_SHELLTREE_H*/

View File

@ -21,7 +21,6 @@
#include "PathName.h"
#include "Pidl.h"
#include "SelectFilesDialog.h"
#include "ShellTree.h"
#include "SoundFile.h"
#include "Modeless.h"

View File

@ -115,7 +115,6 @@
<ClInclude Include="Pidl.h" />
<ClInclude Include="ProgressCancelDialog.h" />
<ClInclude Include="SelectFilesDialog.h" />
<ClInclude Include="ShellTree.h" />
<ClInclude Include="SoundFile.h" />
<ClInclude Include="StdAfx.h" />
<ClInclude Include="Util.h" />
@ -131,7 +130,6 @@
<ClCompile Include="PathName.cpp" />
<ClCompile Include="Pidl.cpp" />
<ClCompile Include="SelectFilesDialog.cpp" />
<ClCompile Include="ShellTree.cpp" />
<ClCompile Include="SoundFile.cpp" />
<ClCompile Include="StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

View File

@ -50,9 +50,6 @@
<ClInclude Include="SelectFilesDialog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShellTree.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SoundFile.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -91,9 +88,6 @@
<ClCompile Include="SelectFilesDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShellTree.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>