ciderpress/util/ShellTree.cpp

1566 lines
49 KiB
C++
Raw Normal View History

2007-03-27 17:47:10 +00:00
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* ShellTree, a TreeCtrl derivative for displaying the Windows shell namespace.
*/
#include "StdAfx.h"
#include "ShellTree.h"
#include "Pidl.h"
#include "PathName.h"
/*
* ==========================================================================
* ShellTree
2007-03-27 17:47:10 +00:00
* ==========================================================================
*/
BEGIN_MESSAGE_MAP(ShellTree, CTreeCtrl)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnFolderExpanding)
ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteShellItem)
ON_NOTIFY_REFLECT_EX(TVN_SELCHANGED, OnSelectionChange)
2007-03-27 17:47:10 +00:00
END_MESSAGE_MAP()
/*
* 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
ShellTree::ReplaceDlgCtrl(CDialog* pDialog, int treeID)
{
CWnd* pWnd = pDialog->GetDlgItem(treeID);
2014-11-18 05:13:13 +00:00
if (pWnd == NULL)
return FALSE;
2007-03-27 17:47:10 +00:00
#if 0
DWORD styles = pWnd->GetStyle();
DWORD stylesEx = pWnd->GetExStyle();
CRect rect;
pWnd->GetWindowRect(&rect);
pDialog->ScreenToClient(&rect);
pWnd->DestroyWindow();
CreateEx(stylesEx, WC_TREEVIEW, NULL, styles, rect, pDialog, treeID);
2007-03-27 17:47:10 +00:00
#endif
/* latch on to their window handle */
Attach(pWnd->m_hWnd);
2007-03-27 17:47:10 +00:00
return TRUE;
2007-03-27 17:47:10 +00:00
}
/*
* Populate the tree, starting from "nFolder".
*
* Returns TRUE on success, FALSE on failure.
*/
BOOL
ShellTree::PopulateTree(int nFolder)
{
2014-11-18 05:13:13 +00:00
LPSHELLFOLDER lpsf = NULL, lpsf2 = NULL;
LPITEMIDLIST lpi = NULL;
TV_SORTCB tvscb;
2014-11-18 05:13:13 +00:00
LPMALLOC lpMalloc = NULL;
HRESULT hr;
BOOL retval = FALSE;
// Grab a malloc handle.
hr = ::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return FALSE;
// Get a pointer to the desktop folder.
hr = SHGetDesktopFolder(&lpsf);
if (FAILED(hr))
goto bail;
// Initialize the tree view to be empty.
DeleteAllItems();
if (nFolder == CSIDL_DESKTOP) {
// already done
lpsf2 = lpsf;
2014-11-18 05:13:13 +00:00
lpsf = NULL;
ASSERT(lpi == NULL);
} else {
// find the desired special folder
hr = SHGetSpecialFolderLocation(m_hWnd, nFolder, &lpi);
if (FAILED(hr)) {
LOGI("BUG: could not find requested special folder");
goto bail;
}
// bind a ShellFolder to the PIDL.
hr = lpsf->BindToObject(lpi, 0, IID_IShellFolder, (LPVOID *)&lpsf2);
if (FAILED(hr))
goto bail;
}
// fill in the tree starting from this point
FillTreeView(lpsf2, lpi, TVI_ROOT);
// Sort the items in the tree view
tvscb.hParent = TVI_ROOT;
tvscb.lParam = 0;
tvscb.lpfnCompare = TreeViewCompareProc;
SortChildrenCB(&tvscb);
2007-03-27 17:47:10 +00:00
bail:
2014-11-18 05:13:13 +00:00
if (lpsf != NULL)
lpsf->Release();
2014-11-18 05:13:13 +00:00
if (lpsf != NULL)
lpsf2->Release();
lpMalloc->Free(lpi);
2007-03-27 17:47:10 +00:00
return retval;
2007-03-27 17:47:10 +00:00
}
/*
* Open up and select My Computer.
*/
void
ShellTree::ExpandMyComputer(void)
{
HTREEITEM hItem;
hItem = FindMyComputer();
2014-11-18 05:13:13 +00:00
if (hItem == NULL)
hItem = GetRootItem();
Expand(hItem, TVE_EXPAND);
Select(hItem, TVGN_CARET);
2007-03-27 17:47:10 +00:00
}
/*
* 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
ShellTree::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq,
HTREEITEM hParent)
2007-03-27 17:47:10 +00:00
{
CWaitCursor wait;
HTREEITEM hPrev = NULL; // Previous Item Added.
LPENUMIDLIST lpe=NULL;
LPITEMIDLIST lpi=NULL;
LPMALLOC lpMalloc=NULL;
ULONG ulFetched;
HRESULT hr;
HWND hwnd=::GetParent(m_hWnd);
bool gotOne = false;
// Allocate a shell memory object.
hr = ::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return;
// Get the IEnumIDList object for the given folder.
hr = lpsf->EnumObjects(hwnd,
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN,
&lpe);
if (SUCCEEDED(hr))
{
// Enumerate throught the list of folder and non-folder objects.
while (S_OK == lpe->Next(1, &lpi, &ulFetched))
{
//Create a fully qualified path to the current item
//The SH* shell api's take a fully qualified path pidl,
//(see GetIcon above where I call SHGetFileInfo) whereas the
//interface methods take a relative path pidl.
ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER |
SFGAO_FILESYSANCESTOR | SFGAO_DROPTARGET | SFGAO_HIDDEN;
bool goodOne;
// Determine what type of object we have.
lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs);
2007-03-27 17:47:10 +00:00
#if 1
{ /* DEBUG */
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
CString name;
if (Pidl::GetName(lpsf, lpi, SHGDN_NORMAL, &name)) {
LOGD(" Checking '%ls' %08lx", (LPCWSTR) name, ulAttrs);
} else {
LOGD(" Checking <no-name> 0x%08lx", ulAttrs);
}
}
2007-03-27 17:47:10 +00:00
#endif
/*
* (This should be converted to a table and automatically
* scanned when assertions are enabled.)
*
* Win2K folders to show:
* 'My Computer' 0xb0000100 [at root]
* 'My Network Places' 0xb0000100 [at root]
* 'My Documents' 0xb0000100 [at root]
* 'WIN (C:)' 0xb0000100
* 'Compact Disc (H:)' 0xb0000100 <-- SFGAO_REMOVABLE not set
* 'Removable Disk (L:)' 0xb0000100
* 'Documents and Settings' 0xf0400177
* 'Entire Network' 0xb0000000
* 'Microsoft Windows Network' 0xb0000000
* 'Computers Near Me' 0xa0000100
* 'ftp.apple.asimov.net' 0xa0000100
* 'QA-C-Recv on QA' 0xa0000100
* 'BACKUP' 0xf0400177
* 'dudley' 0x70400177
*
* Win2K files, folders, etc. to hide:
* 'gVim 6.1' 0x00000100
* 'Internet Explorer' 0x20000000
* 'Recycle Bin' 0x20000100 (folder + droptarget)
* 'Control Panel' 0xa0000000
* 'Scheduled Tasks on Shiny' 0x20000000
* 'Add Network Place' 0x00000000
* 'ColorBars.jpg' 0x40400177
*
* Win98 folders to show:
* 'My Computer' 0xb0000100 [at root]
* 'My Documents' 0xb0000100 [at root]
* 'Network Neighborhood' 0xb0000100 [at root]
* 'WIN98 (C:)' 0xb0000100
* [C:\]'My Documents' 0xf8000177
* 'Entire Network' 0xb0000000
* 'cpt' 0xe0000177
* 'My eBooks' 0x60000177
*
* Win98 folders and stuff to hide:
* 'Control Panel' 0x20000000
* 'Printers' 0x20000100 (folder + droptarget)
* 'Web Folders' 0xa0000000
* 'BOOTLOG.TXT' 0x40080177
*
* Note that Win98 folders on disk don't have FILESYSANCESTOR
* set. If we check FOLDER && FILESYSTEM (0x60000000), we get
* anything starting with 6/7/E/F, which appears safe. We
* need to do additional tests to pick up some of the A/B items
* that we want while hiding the A items we don't want.
*
* FILESYSANCESTOR is 0x10000000, so that plus FOLDER allows
* 3/7/b/f. These appear to be entirely okay.
*
* DROPTARGET is 0x00000100, and HASSUBFOLDER is 0x80000000.
* Combining with FOLDER yields 0xa00000100, allowing A/B/E/F.
* The only at-risk is A, but combined with DROPTARGET we
* seem to screen out all the bad ones.
*/
2014-11-18 05:13:13 +00:00
if (lpifq == NULL) {
/* dealing with stuff at the root level */
goodOne = ( (ulAttrs & SFGAO_FOLDER) &&
(ulAttrs & SFGAO_HASSUBFOLDER) &&
(ulAttrs & SFGAO_FILESYSANCESTOR) );
} else {
/* deeper down, we're picky in different ways */
bool isFolder = (ulAttrs & SFGAO_FOLDER) != 0;
bool fileSys = (ulAttrs & SFGAO_FILESYSTEM) != 0;
bool hasFSAncestor = (ulAttrs & SFGAO_FILESYSANCESTOR) != 0;
bool dropAndSub = (ulAttrs & SFGAO_DROPTARGET) != 0 &&
(ulAttrs & SFGAO_HASSUBFOLDER) != 0;
goodOne = isFolder &&
(fileSys || hasFSAncestor || dropAndSub);
}
if (goodOne) {
gotOne = true;
if (!AddNode(lpsf, lpi, lpifq, ulAttrs, hParent, &hPrev)) {
LOGI("AddNode failed!");
goto Done;
}
}
lpMalloc->Free(lpi); //Free the pidl that the shell gave us.
lpi=0;
}
}
// Sometimes SFGAO_HASSUBFOLDERS lies, notably in Network Neighborhood.
// When we actually scan the directory we can update the parent node
// if it turns out there's nothing underneath.
if (!gotOne) {
TVITEM tvi;
CString name = GetItemText(hParent);
tvi.hItem = hParent;
tvi.mask = TVIF_CHILDREN;
if (!GetItem(&tvi)) {
LOGW("Could not get TV '%ls'", (LPCWSTR) name);
ASSERT(false);
} else if (tvi.cChildren) {
LOGI("Removing child count (%d) from '%ls'",
tvi.cChildren, (LPCWSTR) name);
tvi.cChildren = 0;
if (!SetItem(&tvi)) {
LOGW("Could not set TV '%ls'", (LPCWSTR) name);
ASSERT(false);
}
}
}
2007-03-27 17:47:10 +00:00
Done:
if (lpe)
lpe->Release();
//The following 2 if statements will only be TRUE if we got here on an
//error condition from the "goto" statement. Otherwise, we free this memory
//at the end of the while loop above.
if (lpi && lpMalloc)
lpMalloc->Free(lpi);
if (lpMalloc)
lpMalloc->Release();
//LOGI("FillTreeView DONE");
2007-03-27 17:47:10 +00:00
}
/*
* Add a node to the tree.
*
* Returns TRUE on success, FALSE on failure.
*/
BOOL
ShellTree::AddNode(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, LPITEMIDLIST lpifq,
unsigned long ulAttrs, HTREEITEM hParent, HTREEITEM* phPrev)
2007-03-27 17:47:10 +00:00
{
TVITEM tvi;
TVINSERTSTRUCT tvins;
2014-11-18 05:13:13 +00:00
LPITEMIDLIST lpifqThisItem = NULL;
TVItemData* lptvid = NULL;
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
WCHAR szBuff[MAX_PATH];
CString name;
2014-11-18 05:13:13 +00:00
LPMALLOC lpMalloc = NULL;
HRESULT hr;
BOOL result = FALSE;
hr = ::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return FALSE;
//Now get the friendly name that we'll put in the treeview.
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
if (!Pidl::GetName(lpsf, lpi, SHGDN_NORMAL, &name)) {
LOGI("HEY: failed getting friendly name");
goto bail; // Error - could not get friendly name.
}
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
wcscpy_s(szBuff, name);
//LOGI("AddNode '%ls' ATTR=0x%08lx", szBuff, ulAttrs);
lptvid = (TVItemData*)lpMalloc->Alloc(sizeof(TVItemData));
if (!lptvid)
goto bail;
tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE |
TVIF_PARAM;
if (ulAttrs & SFGAO_HASSUBFOLDER) {
//This item has sub-folders, so let's put the + in the TreeView.
//The first time the user clicks on the item, we'll populate the
//sub-folders.
tvi.mask |= TVIF_CHILDREN;
tvi.cChildren = 1;
}
tvi.pszText = szBuff;
tvi.cchTextMax = MAX_PATH; // (not needed for InsertItem)
// Allocate a fully-qualified PIDL and stuff it in.
lpifqThisItem = Pidl::ConcatPidls(lpifq, lpi);
// Add the icons.
GetNormalAndSelectedIcons(lpifqThisItem, &tvi);
// Done with lipfqThisItem.
lptvid->lpifq = lpifqThisItem;
2014-11-18 05:13:13 +00:00
lpifqThisItem = NULL;
// Put in a copy of the relative PIDL.
lptvid->lpi = Pidl::CopyITEMID(lpMalloc, lpi);
// Stuff the parent folder's lpsf in.
lptvid->lpsfParent = lpsf;
lpsf->AddRef();
// Done with lptvid.
tvi.lParam = (LPARAM)lptvid;
2014-11-18 05:13:13 +00:00
lptvid = NULL;
// Populate the TreeView Insert Struct
// The item is the one filled above.
// Insert it after the last item inserted at this level.
// And indicate this is a root entry.
tvins.item = tvi;
tvins.hInsertAfter = *phPrev;
tvins.hParent = hParent;
// Add the item to the tree
*phPrev = InsertItem(&tvins);
result = TRUE;
2007-03-27 17:47:10 +00:00
bail:
lpMalloc->Release();
return result;
2007-03-27 17:47:10 +00:00
}
/*
* 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
ShellTree::GetNormalAndSelectedIcons(LPITEMIDLIST lpifq,
LPTV_ITEM lptvitem)
2007-03-27 17:47:10 +00:00
{
//Note that we don't check the return value here because if GetIcon()
//fails, then we're in big trouble...
lptvitem->iImage = Pidl::GetItemIcon(lpifq,
SHGFI_SYSICONINDEX |
SHGFI_SMALLICON);
2007-03-27 17:47:10 +00:00
lptvitem->iSelectedImage = Pidl::GetItemIcon(lpifq,
SHGFI_SYSICONINDEX |
SHGFI_SMALLICON |
SHGFI_OPENICON);
2007-03-27 17:47:10 +00:00
return;
}
/*
* Sort function callback for TreeView SortChildrenCB.
*/
int CALLBACK
ShellTree::TreeViewCompareProc(LPARAM lparam1, LPARAM lparam2, LPARAM)
{
TVItemData* lptvid1 = (TVItemData*)lparam1;
TVItemData* lptvid2 = (TVItemData*)lparam2;
HRESULT hr;
2007-03-27 17:47:10 +00:00
hr = lptvid1->lpsfParent->CompareIDs(0, lptvid1->lpi, lptvid2->lpi);
if (FAILED(hr)) {
ASSERT(false);
return 0;
}
2007-03-27 17:47:10 +00:00
#if 0
if (lptvid1->alphaSort && lptvid2->alphaSort) {
char buf1[MAX_PATH], buf2[MAX_PATH];
if (Pidl::GetName(lptvid1->lpsfParent, lptvid1->lpi, SHGDN_NORMAL, buf1) &&
Pidl::GetName(lptvid2->lpsfParent, lptvid2->lpi, SHGDN_NORMAL, buf2))
{
LOGI("COMPARING '%s' to '%s' (res=%d)", buf1, buf2,
(short) HRESULT_CODE(hr));
return stricmp(buf1, buf2);
} else {
ASSERT(false);
return 0;
}
}
2007-03-27 17:47:10 +00:00
#endif
return (short) HRESULT_CODE(hr);
2007-03-27 17:47:10 +00:00
}
/*
* 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
ShellTree::AddFolderAtSelection(const CString& name)
{
2014-11-18 05:13:13 +00:00
LPSHELLFOLDER lpsf = NULL;
LPITEMIDLIST lpi = NULL;
HTREEITEM hParent;
2014-11-18 05:13:13 +00:00
LPMALLOC lpMalloc = NULL;
LPENUMIDLIST lpe = NULL;
const TVItemData* parentTvid;
2014-11-18 05:13:13 +00:00
TVItemData* newTvid = NULL;
HWND hwnd = ::GetParent(m_hWnd);
2014-11-18 05:13:13 +00:00
HTREEITEM hPrev = NULL;
BOOL result = false;
CString debugName;
HRESULT hr;
LOGI("AddFolderAtSelection '%ls'", (LPCWSTR) name);
// Allocate a shell memory object.
hr = ::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return FALSE;
hParent = GetSelectedItem();
2014-11-18 05:13:13 +00:00
if (hParent == NULL) {
LOGI("Nothing selected!");
goto bail;
}
/*
* Now we either need to create a new node in an existing tree, or if
* we haven't expanded the current node yet then we can just let the
* usual FillTree mechanism do it for us.
*
* If the current node is marked as having children, but has no
* child structures, then it's a folder with sub-folders that hasn't
* been filled in yet. We don't need to do anything.
*
* If the current node doesn't have children, then this is a leaf
* node that has just become a branch. We update its "#of kids" state
* and again let the usual mechanisms do their work.
*
* If the current node has expanded children, then we need to do the
* work ourselves. (It's that, or invalidate the entire subtree,
* which has some UI consequences.)
*/
TVITEM tvi;
debugName = GetItemText(hParent);
tvi.hItem = hParent;
tvi.mask = TVIF_CHILDREN;
if (!GetItem(&tvi)) {
LOGW("Could not get TV '%ls'", (LPCWSTR) debugName);
ASSERT(false);
} else {
HTREEITEM child = GetChildItem(hParent);
2014-11-18 05:13:13 +00:00
if (child == NULL && tvi.cChildren) {
LOGD(" Found unexpanded node, not adding %ls", (LPCWSTR) name);
result = TRUE;
goto bail;
2014-11-18 05:13:13 +00:00
} else if (child == NULL && !tvi.cChildren) {
LOGD(" Found former leaf node, updating kids in %ls",
(LPCWSTR) debugName);
tvi.cChildren = 1;
if (!SetItem(&tvi)) {
LOGW("Could not set TV '%ls'", (LPCWSTR) debugName);
ASSERT(false);
}
result = TRUE;
goto bail;
} else {
2014-11-18 05:13:13 +00:00
ASSERT(child != NULL && tvi.cChildren != 0);
LOGD(" Found expanded branch node '%ls', adding new '%ls'",
(LPCWSTR) debugName, (LPCWSTR) name);
}
}
parentTvid = (TVItemData*)GetItemData(hParent);
2014-11-18 05:13:13 +00:00
ASSERT(parentTvid != NULL);
// Get a handle to the ShellFolder for the currently selected node.
hr = parentTvid->lpsfParent->BindToObject(parentTvid->lpi,
0, IID_IShellFolder, (LPVOID *)&lpsf);
if (FAILED(hr)) {
LOGW("Glitch: unable to get ShellFolder for selected folder");
goto bail;
}
// Get an enumerator for the selected node.
hr = lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN,
&lpe);
if (FAILED(hr)) {
LOGW("Glitch: unable to get enumerator for selected folder");
goto bail;
}
// Enumerate throught the list of folder and non-folder objects.
2014-11-18 05:13:13 +00:00
while (S_OK == lpe->Next(1, &lpi, NULL)) {
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
CString pidlName;
if (Pidl::GetName(lpsf, lpi, SHGDN_NORMAL, &pidlName)) {
if (name.CompareNoCase(pidlName) == 0) {
/* match! */
if (!AddNode(lpsf, lpi, parentTvid->lpifq, 0, hParent, &hPrev)) {
LOGI("AddNode failed!");
goto bail;
}
result = TRUE;
break;
}
}
lpMalloc->Free(lpi); //Free the pidl that the shell gave us.
2014-11-18 05:13:13 +00:00
lpi = NULL;
}
2007-03-27 17:47:10 +00:00
bail:
2014-11-18 05:13:13 +00:00
if (lpi != NULL)
lpMalloc->Free(lpi);
2014-11-18 05:13:13 +00:00
if (lpsf != NULL)
lpsf->Release();
2014-11-18 05:13:13 +00:00
if (lpe != NULL)
lpe->Release();
lpMalloc->Release();
return result;
2007-03-27 17:47:10 +00:00
}
/*
* Respond to TVN_ITEMEXPANDING message.
*
* If the subtree hasn't been expanded yet, dig in.
*/
void ShellTree::OnFolderExpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
TVItemData* lptvid; //Long pointer to TreeView item data
HRESULT hr;
LPSHELLFOLDER lpsf2=NULL;
TV_SORTCB tvscb;
NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE) {
LOGI("Already expanded!");
return;
}
lptvid = (TVItemData*)pnmtv->itemNew.lParam;
if (lptvid) {
hr = lptvid->lpsfParent->BindToObject(lptvid->lpi,
0, IID_IShellFolder,(LPVOID *)&lpsf2);
if (SUCCEEDED(hr))
{
FillTreeView(lpsf2,
lptvid->lpifq,
pnmtv->itemNew.hItem);
}
tvscb.hParent = pnmtv->itemNew.hItem;
tvscb.lParam = 0;
tvscb.lpfnCompare = TreeViewCompareProc;
SortChildrenCB(&tvscb);
}
*pResult = 0;
2007-03-27 17:47:10 +00:00
}
#if 0
/****************************************************************************
*
* FUNCTION: GetContextMenu(NMHDR* pNMHDR, LRESULT* pResult)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Diplays a popup menu for the folder selected. Pass the
* parameters from Rclick() to this function.
2007-03-27 17:47:10 +00:00
*
* MESSAGEMAP: NM_RCLICK;
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
void ShellTree::GetContextMenu(NMHDR*, LRESULT* pResult)
{
POINT pt;
TVItemData* lptvid; //Long pointer to TreeView item data
TV_HITTESTINFO tvhti;
TV_ITEM tvi;
::GetCursorPos((LPPOINT)&pt);
ScreenToClient(&pt);
tvhti.pt=pt;
HitTest(&tvhti);
SelectItem(tvhti.hItem);
if (tvhti.flags & (TVHT_ONITEMLABEL|TVHT_ONITEMICON))
{
ClientToScreen(&pt);
tvi.mask=TVIF_PARAM;
tvi.hItem=tvhti.hItem;
if (!GetItem(&tvi)){
return;
}
lptvid = (TVItemData*)tvi.lParam;
Pidl::DoTheMenuThing(::GetParent(m_hWnd),
lptvid->lpsfParent, lptvid->lpi, &pt);
}
*pResult = 0;
2007-03-27 17:47:10 +00:00
}
#endif
/*
* Respond to TVN_SELCHANGED notification.
*/
BOOL
ShellTree::OnSelectionChange(NMHDR* pnmh, LRESULT* pResult)
{
fFolderPathValid = OnFolderSelected(pnmh, pResult, fFolderPath);
*pResult = 0;
return FALSE; // allow window parent to handle notification
2007-03-27 17:47:10 +00:00
}
/*
* This does the bulk of the work when the selection changes.
*
* The filesystem path (if any) to the object is placed in "szFolderPath".
*/
BOOL
ShellTree::OnFolderSelected(NMHDR* pNMHDR, LRESULT* pResult,
CString &szFolderPath)
2007-03-27 17:47:10 +00:00
{
TVItemData* lptvid;
LPSHELLFOLDER lpsf2=NULL;
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
WCHAR szBuff[MAX_PATH];
HRESULT hr;
BOOL bRet=false;
HTREEITEM hItem=NULL;
hItem = GetSelectedItem();
if (hItem) {
lptvid = (TVItemData*)GetItemData(hItem);
if (lptvid && lptvid->lpsfParent && lptvid->lpi)
{
hr = lptvid->lpsfParent->BindToObject(lptvid->lpi,
0, IID_IShellFolder, (LPVOID *)&lpsf2);
if (SUCCEEDED(hr)) {
ULONG ulAttrs = SFGAO_FILESYSTEM;
// Determine what type of object we have.
lptvid->lpsfParent->GetAttributesOf(1,
(const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
if (ulAttrs & (SFGAO_FILESYSTEM)) {
if (SHGetPathFromIDList(lptvid->lpifq, szBuff)){
szFolderPath = szBuff;
bRet = true;
}
}
if (bRet) {
LOGI("Now selected: '%ls'", szBuff);
} else {
LOGI("Now selected: <no path>");
}
2007-03-27 17:47:10 +00:00
#if 0
// If we're expanding into new territory, load the
// sub-tree. [This makes it expand things that aren't
// necessarily going to be opened, which is very bad for
// empty floppy and CD-ROM drives. Makes little sense.]
TV_SORTCB tvscb;
NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
if ((pnmtv->itemNew.cChildren == 1) &&
!(pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
{
FillTreeView(lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem);
tvscb.hParent = pnmtv->itemNew.hItem;
tvscb.lParam = 0;
tvscb.lpfnCompare = TreeViewCompareProc;
SortChildrenCB(&tvscb);
pnmtv->itemNew.state |= TVIS_EXPANDEDONCE;
pnmtv->itemNew.stateMask |= TVIS_EXPANDEDONCE;
pnmtv->itemNew.mask |= TVIF_STATE;
SetItem(&pnmtv->itemNew);
}
2007-03-27 17:47:10 +00:00
#endif
}
}
if(lpsf2)
lpsf2->Release();
}
*pResult = 0;
return bRet;
2007-03-27 17:47:10 +00:00
}
/*
* Handle TVN_DELETEITEM notification by cleaning up our stuff.
*/
void
ShellTree::OnDeleteShellItem(NMHDR* pNMHDR, LRESULT* pResult)
{
TVItemData* lptvid=NULL;
HRESULT hr;
LPMALLOC lpMalloc;
//LOGI("TVN_DELETEITEM");
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
//Let's free the memory for the TreeView item data...
hr = SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return;
lptvid = (TVItemData*)pNMTreeView->itemOld.lParam;
lptvid->lpsfParent->Release();
lpMalloc->Free(lptvid->lpi);
lpMalloc->Free(lptvid->lpifq);
lpMalloc->Free(lptvid);
lpMalloc->Release();
*pResult = 0;
2007-03-27 17:47:10 +00:00
}
/*
* 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
ShellTree::EnableImages()
{
// Get the handle to the system image list, for our icons
HIMAGELIST hImageList;
SHFILEINFO sfi = { 0 };
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
hImageList = (HIMAGELIST)SHGetFileInfo(L"C:\\",
0, &sfi, sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
// Attach ImageList to TreeView
if (hImageList)
::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM) TVSIL_NORMAL,
(LPARAM)hImageList);
2007-03-27 17:47:10 +00:00
}
/****************************************************************************
*
* FUNCTION: GetSelectedFolderPath(CString &szFolderPath)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: 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.
2007-03-27 17:47:10 +00:00
*
* MESSAGEMAP: NONE
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
BOOL ShellTree::GetSelectedFolderPath(CString &szFolderPath)
{
TVItemData* lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2=NULL;
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
WCHAR szBuff[MAX_PATH];
HTREEITEM hItem=NULL;
HRESULT hr;
BOOL bRet=false;
hItem = GetSelectedItem();
if(hItem)
{
lptvid = (TVItemData*)GetItemData(hItem);
if (lptvid && lptvid->lpsfParent && lptvid->lpi)
{
hr = lptvid->lpsfParent->BindToObject(lptvid->lpi,
0, IID_IShellFolder,(LPVOID *)&lpsf2);
if (SUCCEEDED(hr))
{
ULONG ulAttrs = SFGAO_FILESYSTEM;
// Determine what type of object we have.
lptvid->lpsfParent->GetAttributesOf(1,
(const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
if (ulAttrs & (SFGAO_FILESYSTEM))
{
if(SHGetPathFromIDList(lptvid->lpifq, szBuff)){
szFolderPath = szBuff;
bRet = true;
}
}
}
}
if(lpsf2)
lpsf2->Release();
}
return bRet;
2007-03-27 17:47:10 +00:00
}
/****************************************************************************
*
* FUNCTION: GetParentShellFolder(HTREEITEM folderNode)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Retrieves the pointer to the ISHELLFOLDER interface
* of the tree node passed as the paramter.
2007-03-27 17:47:10 +00:00
*
* MESSAGEMAP: NONE
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
LPSHELLFOLDER ShellTree::GetParentShellFolder(HTREEITEM folderNode)
{
TVItemData* lptvid; //Long pointer to TreeView item data
2007-03-27 17:47:10 +00:00
lptvid = (TVItemData*)GetItemData(folderNode);
if (lptvid)
return lptvid->lpsfParent;
else
return NULL;
2007-03-27 17:47:10 +00:00
}
/****************************************************************************
*
* FUNCTION: GetRelativeIDLIST(HTREEITEM folderNode)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Retrieves the Pointer to an ITEMIDLIST structure that
* identifies the subfolder relative to its parent folder.
* see GetParentShellFolder();
2007-03-27 17:47:10 +00:00
*
* MESSAGEMAP: NONE
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
LPITEMIDLIST ShellTree::GetRelativeIDLIST(HTREEITEM folderNode)
{
TVItemData* lptvid; //Long pointer to TreeView item data
2007-03-27 17:47:10 +00:00
lptvid = (TVItemData*)GetItemData(folderNode);
if (lptvid)
return lptvid->lpifq;
else
return NULL;
2007-03-27 17:47:10 +00:00
}
/****************************************************************************
*
* FUNCTION: GetFullyQualifiedIDLIST(HTREEITEM folderNode)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Retrieves the Pointer to an ITEMIDLIST
* structure that identifies the subfolder relative to the
* desktop. This is a fully qualified Item Identifier
2007-03-27 17:47:10 +00:00
*
* MESSAGEMAP: NONE
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
LPITEMIDLIST ShellTree::GetFullyQualifiedID(HTREEITEM folderNode)
{
TVItemData* lptvid; //Long pointer to TreeView item data
2007-03-27 17:47:10 +00:00
lptvid = (TVItemData*)GetItemData(folderNode);
if (lptvid)
return lptvid->lpifq;
else
return NULL;
2007-03-27 17:47:10 +00:00
}
/*
* Tunnel into the tree, finding the node that corresponds to the
* requested pathname.
*
* Sets "resultMsg" to a non-empty string on error.
*/
void
ShellTree::TunnelTree(CString path, CString* pResultStr)
{
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
const WCHAR* str = path;
int len;
if (str[0] == '\\' && str[1] == '\\') {
*pResultStr = "Can't expand network locations directly.";
return;
}
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
len = path.GetLength();
if (len < 1) {
*pResultStr = "You must enter a folder name.";
return;
}
/* make sure it ends in \ so splitpath knows it's a directory */
if (path[len-1] != '\\')
path += '\\';
/* if it doesn't exist, there's not much point in searching for it */
PathName pathName(path);
if (!pathName.Exists()) {
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
*pResultStr = L"Folder not found.";
return;
}
/*
* Find the folder that corresponds to "My Computer", and then scan
* it for the drive letter.
*/
HTREEITEM myComputer = FindMyComputer();
2014-11-18 05:13:13 +00:00
if (myComputer == NULL) {
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
*pResultStr = L"Unable to locate My Computer in tree.";
return;
}
CString drive = pathName.GetDriveOnly();
LOGI("Searching for drive='%ls'", (LPCWSTR) drive);
HTREEITEM node = FindDrive(myComputer, drive);
2014-11-18 05:13:13 +00:00
if (node == NULL) {
/* unexpected -- couldn't find the drive */
pResultStr->Format(L"Unable to find drive %ls.", (LPCWSTR) drive);
return;
}
/*
* We've got the node for the drive. Now we just need to walk
* through the tree one level at a time, comparing the name in
* the tree against our pathname component.
*/
node = SearchTree(node, pathName.GetPathOnly());
2014-11-18 05:13:13 +00:00
if (node == NULL) {
/* unexpected -- file doesn't exist */
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
pResultStr->Format(L"Unable to find file '%ls'.",
(LPCWSTR) pathName.GetPathOnly());
} else {
Select(node, TVGN_CARET);
EnsureVisible(node);
}
2007-03-27 17:47:10 +00:00
}
/*
* Find the tree entry that corresponds to "My Computer".
*
* This is hampered somewhat by the absence of a way to compare two
* shell folders for equality. The PIDL compare function is meant for
* sorting only (at least as far as it has been documented), and the My
* Computer "folder" has no path to examine.
*
* It helps greatly to assume that My Computer is right under Desktop.
* If it moved, or if we started the tree somewhere other than right at
* the desktop, we'd have to recursively search the tree.
*
2014-11-18 05:13:13 +00:00
* Returns a handle to the tree item, or NULL if My Computer wasn't found
2007-03-27 17:47:10 +00:00
* or didn't have any children.
*/
HTREEITEM
ShellTree::FindMyComputer(void)
{
2014-11-18 05:13:13 +00:00
LPSHELLFOLDER desktop = NULL;
LPITEMIDLIST myComputerPidl = NULL;
LPMALLOC lpMalloc = NULL;
HTREEITEM node;
2014-11-18 05:13:13 +00:00
HTREEITEM result = NULL;
HRESULT hr;
hr = ::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
2014-11-18 05:13:13 +00:00
return NULL;
hr = SHGetDesktopFolder(&desktop);
if (FAILED(hr))
goto bail;
2014-11-18 05:13:13 +00:00
hr = SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &myComputerPidl);
if (FAILED(hr))
goto bail;
node = GetRootItem();
2014-11-18 05:13:13 +00:00
while (node != NULL) {
CString itemText = GetItemText(node);
TVItemData* pData = (TVItemData*) GetItemData(node);
2014-11-18 05:13:13 +00:00
ASSERT(pData != NULL);
hr = desktop->CompareIDs(0, myComputerPidl, pData->lpi);
if (SUCCEEDED(hr) && HRESULT_CODE(hr) == 0) {
LOGD("MATCHED on '%ls'", (LPCWSTR) itemText);
result = node;
break;
}
node = GetNextSiblingItem(node);
}
2014-11-18 05:13:13 +00:00
if (result != NULL && !ItemHasChildren(result)) {
LOGW("Glitch: My Computer has no children");
2014-11-18 05:13:13 +00:00
result = NULL;
}
2007-03-27 17:47:10 +00:00
bail:
2014-11-18 05:13:13 +00:00
if (desktop != NULL)
desktop->Release();
lpMalloc->Free(myComputerPidl);
lpMalloc->Release();
return result;
2007-03-27 17:47:10 +00:00
}
/*
* 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:").
*
2014-11-18 05:13:13 +00:00
* Returns a pointer to the drive's node on success, or NULL on failure.
2007-03-27 17:47:10 +00:00
*/
HTREEITEM
ShellTree::FindDrive(HTREEITEM myComputer, const CString& drive)
{
CString udrive;
/* expand & scan */
Expand(myComputer, TVE_EXPAND);
HTREEITEM node;
node = GetChildItem(myComputer);
2014-11-18 05:13:13 +00:00
if (node == NULL) {
ASSERT(false); // we verified My Computer has kids earlier
2014-11-18 05:13:13 +00:00
return NULL;
}
/*
* Look for the drive letter. It's buried amongst other fluff, so
* we have to rely on Windows preventing the use of a ":" anywhere
* else in the string to avoid false-positives.
*
* We *might* be able to assume it looks like "(C:)", but that's
* probably unwise.
*/
udrive = drive;
udrive.MakeUpper();
2014-11-18 05:13:13 +00:00
while (node != NULL) {
CString itemText = GetItemText(node);
itemText.MakeUpper();
//LOGI("COMPARING '%ls' vs '%ls'", (LPCWSTR) udrive, (LPCWSTR) itemText);
if (itemText.Find(udrive) != -1) {
LOGI("MATCHED '%ls' in '%ls'", (LPCWSTR) udrive, (LPCWSTR) itemText);
break;
}
node = GetNextSiblingItem(node);
}
return node;
2007-03-27 17:47:10 +00:00
}
/*
* 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
ShellTree::SearchTree(HTREEITEM treeNode, const CString& path)
{
LOGI("SearchTree node=0x%p path='%ls'", treeNode, (LPCWSTR) path);
HTREEITEM node;
CString mangle(path);
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
WCHAR* start;
WCHAR* end;
/* make a copy of "path" that we can mess with */
start = mangle.GetBuffer(0);
2014-11-18 05:13:13 +00:00
if (start == NULL || *start != '\\' || *(start + wcslen(start)-1) != '\\')
return NULL;
start++;
node = treeNode;
while (*start != '\0') {
/* grab first node in next level down */
Expand(node, TVE_EXPAND); // need to fill in the tree
node = GetChildItem(node);
Large set of changes to restore CiderPress build. CiderPress and MDC now compile, and execute far enough to open their respective "about" boxes, but I doubt they'll do much more than that. * Switch from MBCS to UNICODE APIs Microsoft switched to UTF-16 (by way of UCS-2) a long time ago, and the support for MBCS seems to be getting phased out. So it's time to switch to wide strings. This is a bit awkward for CiderPress because it works with disk and file archives with 8-bit filenames, and I want NufxLib and DiskImgLib to continue to work on Linux (which has largely taken the UTF-8 approach to Unicode). The libraries will continue to work with 8-bit filenames, with CiderPress/MDC doing the conversion at the appropriate point. There were a couple of places where strings from a structure handed back by one of the libraries were used directly in the UI, or vice-versa, which is a problem because we have nowhere to store the result of the conversion. These currently have fixed place-holder "xyzzy" strings. All UI strings are now wide. Various format strings now use "%ls" and "%hs" to explicitly specify wide and narrow. This doesn't play well with gcc, so only the Windows-specific parts use those. * Various updates to vcxproj files The project-file conversion had some cruft that is now largely gone. The build now has a common output directory for the EXEs and libraries, avoiding the old post-build copy steps. * Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots The old "prebuilts" directory is now gone. The libraries are now built as part of building the apps. I added a minimal set of files for zlib, and a full set for nufxlib. The Linux-specific nufxlib goodies are included for the benefit of the Linux utilities, which are currently broken (don't build). * Replace symbols used for include guards Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
end = wcschr(start, '\\');
2014-11-18 05:13:13 +00:00
if (end == NULL) {
ASSERT(false);
2014-11-18 05:13:13 +00:00
return NULL;
}
*end = '\0';
2014-11-18 05:13:13 +00:00
while (node != NULL) {
CString itemText = GetItemText(node);
//LOGI("COMPARE '%s' '%s'", start, itemText);
if (itemText.CompareNoCase(start) == 0) {
//LOGI("MATCHED '%s' '%s'", itemText, start);
break;
}
node = GetNextSiblingItem(node);
}
2014-11-18 05:13:13 +00:00
if (node == NULL) {
LOGI("NOT FOUND '%ls' '%ls'", (LPCTSTR) path, start);
break;
}
start = end+1;
}
return node;
2007-03-27 17:47:10 +00:00
}
#ifdef USE_OLD
/****************************************************************************
*
* FUNCTION: SearchTree( HTREEITEM treeNode,
* CString szSearchName )
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Too crude to explain, just use it
2007-03-27 17:47:10 +00:00
*
* WARNING: Only works if you use the default PopulateTree()
* Not guaranteed to work on any future or existing
* version of windows. Use with caution. Pretty much
* ok if you're using on local drives
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
bool ShellTree::SearchTree(HTREEITEM treeNode,
CString szSearchName,
FindAttribs attr)
2007-03-27 17:47:10 +00:00
{
TVItemData* lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2=NULL;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
bool bRet=false;
HRESULT hr;
CString szCompare;
szSearchName.MakeUpper();
while(treeNode && bRet==false)
{
lptvid=(TVItemData*)GetItemData(treeNode);
if (lptvid && lptvid->lpsfParent && lptvid->lpi)
{
hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
0,IID_IShellFolder,(LPVOID *)&lpsf2);
if (SUCCEEDED(hr))
{
ULONG ulAttrs = SFGAO_FILESYSTEM;
lptvid->lpsfParent->GetAttributesOf(1,
(const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
if (ulAttrs & (SFGAO_FILESYSTEM))
{
if(SHGetPathFromIDList(lptvid->lpifq,
szCompare.GetBuffer(MAX_PATH)))
{
switch(attr)
{
case type_drive:
_splitpath(szCompare,drive,dir,fname,ext);
szCompare=drive;
break;
case type_folder:
szCompare = GetItemText(treeNode);
break;
}
szCompare.MakeUpper();
if(szCompare == szSearchName)
{
EnsureVisible(treeNode);
SelectItem(treeNode);
bRet=true;
}
}
}
lpsf2->Release();
}
}
treeNode = GetNextSiblingItem(treeNode);
}
return bRet;
2007-03-27 17:47:10 +00:00
}
/****************************************************************************
*
* FUNCTION: TunnelTree(CString szFindPath)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Too crude to explain, just use it
2007-03-27 17:47:10 +00:00
*
* WARNING: Only works if you use the default PopulateTree()
* Not guaranteed to work on any future or existing
* version of windows. Use with caution. Pretty much
* ok if you're using on local drives
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
void ShellTree::TunnelTree(CString szFindPath)
{
HTREEITEM subNode = GetRootItem();
CString szPathHop;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
char delimiter[]="\\";
PathName checkPath(szFindPath);
if(!checkPath.Exists())
{
MessageBox(szFindPath,"Folder not found",MB_ICONERROR);
return;
}
if(szFindPath.ReverseFind('\\') != szFindPath.GetLength()-1)
{
szFindPath += "\\";
}
_splitpath(szFindPath,drive,dir,fname,ext);
//search the drive first
szPathHop=drive;
subNode=GetChildItem(subNode);
if(subNode)
{
if(SearchTree(subNode,szPathHop, ShellTree::type_drive))
{
//break down subfolders and search
char *p=strtok(dir,delimiter);
while(p)
{
subNode = GetSelectedItem();
subNode = GetChildItem(subNode);
if(SearchTree(subNode,p,ShellTree::type_folder))
p=strtok(NULL,delimiter);
else
p=NULL;
}
}
}
2007-03-27 17:47:10 +00:00
}
#endif
#ifdef USE_NEW
// new version for Win2K
/****************************************************************************
*
* FUNCTION: SearchTree( HTREEITEM treeNode,
* CString szSearchName )
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Too crude to explain, just use it
2007-03-27 17:47:10 +00:00
*
* WARNING: Only works if you use the default PopulateTree()
* Not guaranteed to work on any future or existing
* version of windows. Use with caution. Pretty much
* ok if you're using on local drives
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
bool ShellTree::SearchTree(HTREEITEM treeNode,
CString szSearchName,
FindAttribs attr)
2007-03-27 17:47:10 +00:00
{
TVItemData* lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2=NULL;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
bool bRet=false;
HRESULT hr;
CString szCompare;
szSearchName.MakeUpper();
while(treeNode && bRet==false)
{
lptvid=(TVItemData*)GetItemData(treeNode);
if (lptvid && lptvid->lpsfParent && lptvid->lpi)
{
hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
0,IID_IShellFolder,(LPVOID *)&lpsf2);
if (SUCCEEDED(hr))
{
ULONG ulAttrs = SFGAO_FILESYSTEM;
lptvid->lpsfParent->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
if (ulAttrs & (SFGAO_FILESYSTEM))
{
if(SHGetPathFromIDList(lptvid->lpifq,
szCompare.GetBuffer(MAX_PATH)))
{
CString folder;
SHGetSpecialFolderPath(NULL,
folder.GetBuffer(MAX_PATH),
CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
if( szCompare.Find( folder ) != -1 )
if( szSearchName.Find( szCompare ) == -1 ) {
LOGI("Magic match on '%s'", szCompare);
return false;
}
SHGetSpecialFolderPath(NULL,
folder.GetBuffer(MAX_PATH),
CSIDL_DESKTOPDIRECTORY, FALSE );
if( szCompare.Find( folder ) != -1 )
if( szSearchName.Find( szCompare ) == -1 ) {
LOGI("MAGIC '%s'='%s' and '%s'='%s'",
szCompare, folder, szSearchName, szCompare);
return false;
}
SHGetSpecialFolderPath(NULL,
folder.GetBuffer(MAX_PATH),
CSIDL_PERSONAL, FALSE );
if( szCompare.Find( folder ) != -1 )
if( szSearchName.Find( szCompare ) == -1 ) {
LOGI("Magic match on '%s'", szCompare);
return false;
}
switch(attr) {
case type_drive:
_splitpath(szCompare,drive,dir,fname,ext);
szCompare = drive;
break;
case type_folder:
szCompare = GetItemText(treeNode);
break;
}
szCompare.MakeUpper();
if(szCompare == szSearchName)
{
EnsureVisible(treeNode);
SelectItem(treeNode);
bRet=true;
}
}
}
lpsf2->Release();
}
}
treeNode = GetNextSiblingItem(treeNode);
}
return bRet;
2007-03-27 17:47:10 +00:00
}
/****************************************************************************
*
* FUNCTION: TunnelTree(CString szFindPath)
2007-03-27 17:47:10 +00:00
*
* PURPOSE: Too crude to explain, just use it
2007-03-27 17:47:10 +00:00
*
* WARNING: Only works if you use the default PopulateTree()
* Not guaranteed to work on any future or existing
* version of windows. Use with caution. Pretty much
* ok if you're using on local drives
2007-03-27 17:47:10 +00:00
*
****************************************************************************/
void ShellTree::TunnelTree(CString szFindPath)
{
HTREEITEM subNode = GetRootItem();
CString szPathHop;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
char delimiter[]="\\";
PathName checkPath(szFindPath);
if(!checkPath.Exists()) {
MessageBox(szFindPath,"Folder not found",MB_ICONERROR);
return;
}
if(szFindPath.ReverseFind('\\') != szFindPath.GetLength()-1) {
szFindPath += "\\";
}
_splitpath(szFindPath, drive, dir, fname, ext);
HTREEITEM root = subNode;
//search the drive first
szPathHop=drive;
do {
CString currItem = GetItemText( root );
LOGI("Scanning '%s' for drive '%s'", currItem, szPathHop);
if (ItemHasChildren(root))
{
Expand(root, TVE_EXPAND);
subNode = GetChildItem(root);
if(subNode)
{
if(SearchTree(subNode, szPathHop, ShellTree::type_drive))
{
// we have a match on the drive; SearchTree will have
// left it as the selected item
LOGI("Tunnel match '%s' in subnode", szPathHop);
// break down subfolders and search
char* p = strtok(dir, delimiter);
while (p) {
subNode = GetSelectedItem();
subNode = GetChildItem(subNode);
if(SearchTree(subNode, p, ShellTree::type_folder))
p=strtok(NULL,delimiter);
else
p=NULL;
}
return;
}
}
Expand(root, TVE_COLLAPSE);
}
root = GetNextSiblingItem( root );
} while( root );
2007-03-27 17:47:10 +00:00
}
#endif
#if 0 // quick test
2014-11-18 05:13:13 +00:00
LPMALLOC g_pMalloc = NULL;
2007-03-27 17:47:10 +00:00
// Main_OnBrowse - browses for a program folder.
// hwnd - handle to the application's main window.
//
// Uses the global variable g_pMalloc, which is assumed to point
// to the shell's IMalloc interface.
void Main_OnBrowse(HWND hwnd)
{
BROWSEINFO bi;
LPSTR lpBuffer;
LPITEMIDLIST pidlPrograms; // PIDL for Programs folder
LPITEMIDLIST pidlBrowse; // PIDL selected by user
2014-11-18 05:13:13 +00:00
if (g_pMalloc == NULL)
::SHGetMalloc(&g_pMalloc);
2007-03-27 17:47:10 +00:00
// Allocate a buffer to receive browse information.
if ((lpBuffer = (LPSTR) g_pMalloc->Alloc(
MAX_PATH)) == NULL)
return;
// Get the PIDL for the Programs folder.
if (!SUCCEEDED(SHGetSpecialFolderLocation(
hwnd, CSIDL_PROGRAMS, &pidlPrograms))) {
g_pMalloc->Free(lpBuffer);
return;
}
// Fill in the BROWSEINFO structure.
bi.hwndOwner = hwnd;
bi.pidlRoot = pidlPrograms;
bi.pszDisplayName = lpBuffer;
bi.lpszTitle = "Choose a Program Group";
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = 0;
// Browse for a folder and return its PIDL.
pidlBrowse = SHBrowseForFolder(&bi);
if (pidlBrowse != NULL) {
// Show the display name, title, and file system path.
MessageBox(hwnd, lpBuffer, "Display name", MB_OK);
if (SHGetPathFromIDList(pidlBrowse, lpBuffer))
SetWindowText(hwnd, lpBuffer);
// Free the PIDL returned by SHBrowseForFolder.
g_pMalloc->Free(pidlBrowse);
}
// Clean up.
g_pMalloc->Free(pidlPrograms);
g_pMalloc->Free(lpBuffer);
}
#endif