open child folders by double click in ShellBrowserChild

svn path=/trunk/; revision=5537
This commit is contained in:
Martin Fuchs 2003-08-11 22:04:26 +00:00
parent 4504834722
commit 6010f3ea82
9 changed files with 153 additions and 35 deletions

View file

@ -2,6 +2,7 @@
* subsys/system/explorer Subclassing of shell window for drawing
desktop background.
* open child folders by double click in ShellBrowserChild
2003-08-11 Casper S. Hornstrup <chorns@users.sourceforge.net>

View file

@ -65,13 +65,19 @@ static void draw_desktop_background(HWND hwnd, HDC hdc)
// This next part could be improved by working out how much
// space the text actually needs...
rect.left = rect.right - 260;
rect.top = rect.bottom - 80;
rect.left = rect.right - 280;
rect.top = rect.bottom - 60;
rect.right = rect.left + 250;
rect.bottom = rect.top + 40;
SetTextColor(hdc, RGB(255,255,255));
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(128,128,192));
DrawText(hdc, BkgndText, -1, &rect, DT_RIGHT);
SetTextColor(hdc, RGB(255,255,255));
--rect.right;
++rect.top;
DrawText(hdc, BkgndText, -1, &rect, DT_RIGHT);
}
@ -83,7 +89,7 @@ LRESULT BackgroundWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
draw_desktop_background(_hwnd, (HDC)wparam);
return TRUE;
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
explorer_show_frame(_hwnd, SW_SHOWNORMAL);
break;
@ -119,6 +125,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
explorer_show_frame(_hwnd, SW_SHOWNORMAL);
break;
@ -134,7 +141,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
FOLDERSETTINGS fs;
fs.ViewMode = FVM_ICON;
fs.fFlags = FWF_DESKTOP|FWF_TRANSPARENT|FWF_NOCLIENTEDGE|FWF_NOSCROLL|FWF_BESTFITWINDOW|FWF_SNAPTOGRID;
fs.fFlags = FWF_DESKTOP|FWF_NOCLIENTEDGE|FWF_NOSCROLL|FWF_BESTFITWINDOW|FWF_SNAPTOGRID;
RECT rect;
GetClientRect(_hwnd, &rect);

View file

@ -70,7 +70,7 @@ struct DesktopWindow : public Window, public IShellBrowserImpl
return E_NOTIMPL;
}
STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pret)
{
return E_NOTIMPL;
}

View file

@ -13,3 +13,4 @@
usage of IShellView C++, implementation of IShellBrowser, ...
09.08.2003 m. fuchs class DesktopWindow for shell view on the desktop
11.08.2003 m. fuchs class BackgroundWindow for painting of desktop background
open child folders by double click in ShellBrowserChild

View file

@ -247,6 +247,15 @@ void Entry::sort_directory(SORT_ORDER sortOrder)
}
void Entry::smart_scan()
{
if (!_scanned) {
free_subentries();
read_directory(SORT_NAME); // we could use IShellFolder2::GetDefaultColumn to determine sort order
}
}
BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow)
{
TCHAR cmd[MAX_PATH];

View file

@ -73,6 +73,7 @@ public:
void read_directory(SORT_ORDER sortOrder);
Entry* read_tree(const void* path, SORT_ORDER sortOrder);
void sort_directory(SORT_ORDER sortOrder);
void smart_scan();
virtual void read_directory() {}
virtual const void* get_next_path_component(const void*) {return NULL;}

View file

@ -35,6 +35,20 @@
#include "../explorer_intres.h"
static LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
{
TVITEM tvItem;
tvItem.mask = TVIF_PARAM;
tvItem.hItem = hItem;
if (!TreeView_GetItem(hwndTreeView, &tvItem))
return 0;
return tvItem.lParam;
}
ShellBrowserChild::ShellBrowserChild(HWND hwnd)
: super(hwnd)
{
@ -42,6 +56,7 @@ ShellBrowserChild::ShellBrowserChild(HWND hwnd)
_pShellView = NULL;
_pDropTarget = NULL;
_himlSmall = 0;
_last_sel = 0;
}
ShellBrowserChild::~ShellBrowserChild()
@ -71,7 +86,7 @@ void ShellBrowserChild::OnCreate(LPCREATESTRUCT pcs)
// create explorer treeview
_left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL,
WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_NOTOOLTIPS,
WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_NOTOOLTIPS|TVS_SHOWSELALWAYS,
0, rect.top, _split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top,
_hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0);
@ -172,14 +187,11 @@ void ShellBrowserChild::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen)
{
TVITEM tvItem;
LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem);
tvItem.mask = TVIF_PARAM;
tvItem.hItem = hItem;
if (TreeView_GetItem(hwndTreeView, &tvItem)) {
if (itemData) {
HWND hwndParent = ::GetParent(hwndTreeView);
Entry* entry = (Entry*)tvItem.lParam;
Entry* entry = (Entry*)itemData;
IShellFolder* folder;
@ -279,30 +291,20 @@ void ShellBrowserChild::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
if (pnmtv->action == TVE_COLLAPSE)
TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET);
else if (pnmtv->action == TVE_EXPAND) {
TVITEM tvItem;
ShellDirectory* entry = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, pnmtv->itemNew.hItem);
tvItem.mask = TVIF_PARAM;
tvItem.hItem = pnmtv->itemNew.hItem;
if (!TreeView_GetItem(_left_hwnd, &tvItem))
return;
WaitCursor wait;
ShellDirectory* entry = (ShellDirectory*)tvItem.lParam;
InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder);
if (entry)
InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder);
}
}
void ShellBrowserChild::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder)
{
WaitCursor wait;
SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0);
if (!entry->_scanned) {
entry->free_subentries();
entry->read_directory(SORT_NAME); // we could use IShellFolder2::GetDefaultColumn to determine sort order
}
entry->smart_scan();
TV_ITEM tvItem;
TV_INSERTSTRUCT tvInsert;
@ -341,6 +343,8 @@ void ShellBrowserChild::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv)
{
ShellEntry* entry = (ShellEntry*)pnmtv->itemNew.lParam;
_last_sel = pnmtv->itemNew.hItem;
IShellFolder* folder;
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
@ -360,7 +364,7 @@ void ShellBrowserChild::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv)
pLastShellView->GetCurrentInfo(&fs);
else {
fs.ViewMode = FVM_DETAILS;
fs.fFlags = 0;
fs.fFlags = FWF_NOCLIENTEDGE;
}
HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView);
@ -417,3 +421,93 @@ int ShellBrowserChild::Notify(int id, NMHDR* pnmh)
return 0;
}
// process default command: look for folders and traverse into them
HRESULT ShellBrowserChild::OnDefaultCommand(IShellView* ppshv)
{
static UINT CF_IDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
HRESULT ret = E_NOTIMPL;
IDataObject* selection;
HRESULT hr = ppshv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&selection);
if (FAILED(hr))
return hr;
FORMATETC fetc;
fetc.cfFormat = CF_IDLIST;
fetc.ptd = NULL;
fetc.dwAspect = DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.tymed = TYMED_HGLOBAL;
hr = selection->QueryGetData(&fetc);
if (FAILED(hr))
return hr;
STGMEDIUM stgm = {sizeof(STGMEDIUM)};
hr = selection->GetData(&fetc, &stgm);
if (FAILED(hr))
return hr;
DWORD pData = (DWORD)GlobalLock(stgm.hGlobal);
CIDA* pIDList = (CIDA*)pData;
if (pIDList->cidl >= 1) {
//UINT folderOffset = pIDList->aoffset[0];
//LPITEMIDLIST folder = (LPITEMIDLIST)(pData+folderOffset);
UINT firstOffset = pIDList->aoffset[1];
LPITEMIDLIST pidl = (LPITEMIDLIST)(pData+firstOffset);
//HTREEITEM hitem_sel = TreeView_GetSelection(_left_hwnd);
if (_last_sel) {
ShellDirectory* parent = (ShellDirectory*)TreeView_GetItemData(_left_hwnd, _last_sel);
if (parent) {
parent->smart_scan();
Entry* entry = parent->find_entry(pidl);
if (entry && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
if (expand_folder(static_cast<ShellDirectory*>(entry)))
ret = S_OK;
}
}
}
GlobalUnlock(stgm.hGlobal);
ReleaseStgMedium(&stgm);
selection->Release();
return ret;
}
bool ShellBrowserChild::expand_folder(ShellDirectory* entry)
{
//HTREEITEM hitem_sel = TreeView_GetSelection(_left_hwnd);
if (!_last_sel)
return false;
if (!TreeView_Expand(_left_hwnd, _last_sel, TVE_EXPAND))
return false;
for(HTREEITEM hitem=TreeView_GetChild(_left_hwnd,_last_sel); hitem; hitem=TreeView_GetNextSibling(_left_hwnd,hitem)) {
if ((ShellDirectory*)TreeView_GetItemData(_left_hwnd,hitem) == entry) {
if (TreeView_SelectItem(_left_hwnd, hitem) &&
TreeView_Expand(_left_hwnd, hitem, TVE_EXPAND))
return true;
break;
}
}
return false;
}

View file

@ -84,7 +84,7 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl
return E_NOTIMPL;
}
STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pret)
{
if (!pret)
return E_POINTER;
@ -99,6 +99,8 @@ struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl
return E_NOTIMPL;
}
STDMETHOD(OnDefaultCommand)(IShellView* ppshv);
protected:
Root _root;
@ -109,6 +111,8 @@ protected:
// HIMAGELIST _himlLarge; // shell image
TreeDropTarget* _pDropTarget;
HTREEITEM _last_sel;
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
int Notify(int id, NMHDR* pnmh);
@ -123,4 +127,5 @@ protected:
void OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv);
void Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen);
bool expand_folder(ShellDirectory* entry);
};

View file

@ -63,17 +63,17 @@ struct IShellBrowserImpl : public IShellBrowser, public ICommDlgBrowser
STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) {return E_NOTIMPL;}
// *** ICommDlgBrowser methods ***
STDMETHOD(OnDefaultCommand)(THIS_ struct IShellView* ppshv)
{ //handle double click and ENTER key if needed
STDMETHOD(OnDefaultCommand)(struct IShellView* ppshv)
{
return E_NOTIMPL;
}
STDMETHOD(OnStateChange)(THIS_ struct IShellView* ppshv, ULONG uChange)
STDMETHOD(OnStateChange)(struct IShellView* ppshv, ULONG uChange)
{ //handle selection, rename, focus if needed
return E_NOTIMPL;
}
STDMETHOD(IncludeObject)(THIS_ struct IShellView* ppshv, LPCITEMIDLIST pidl)
STDMETHOD(IncludeObject)(struct IShellView* ppshv, LPCITEMIDLIST pidl)
{ //filter files if needed
return S_OK;
}