[ros-diffs] [mf] 20406: lean explorer: get and use the parent folder to display correct context menu in all cases

mf at svn.reactos.com mf at svn.reactos.com
Wed Dec 28 23:45:18 CET 2005


lean explorer: get and use the parent folder to display correct context
menu in all cases
Modified:
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.cpp
Modified:
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.h
Modified:
branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass
es.h
  _____  

Modified:
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.cpp
---
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.cpp	2005-12-28 21:46:31 UTC (rev 20405)
+++
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.cpp	2005-12-28 22:45:04 UTC (rev 20406)
@@ -197,6 +197,66 @@

 	}
 }
 
+ // local replacement implementation for SHBindToParent()
+ // (derived from
http://www.geocities.com/SiliconValley/2060/articles/shell-helpers.html)
+static HRESULT my_SHBindToParent(LPCITEMIDLIST pidl, REFIID riid,
VOID** ppv, LPCITEMIDLIST* ppidlLast)
+{
+	HRESULT hr;
+
+	if (!ppv)
+		return E_POINTER;
+
+	// There must be at least one item ID.
+	if (!pidl || !pidl->mkid.cb)
+		return E_INVALIDARG;
+
+	 // Get the desktop folder as root.
+	ShellFolder desktop;
+/*	IShellFolderPtr desktop;
+	hr = SHGetDesktopFolder(&desktop);
+	if (FAILED(hr))
+		return hr; */
+
+	// Walk to the penultimate item ID.
+	LPCITEMIDLIST marker = pidl;
+	for (;;)
+	{
+		LPCITEMIDLIST next = reinterpret_cast<LPCITEMIDLIST>(
+			marker->mkid.abID - sizeof(marker->mkid.cb) +
marker->mkid.cb);
+		if (!next->mkid.cb)
+			break;
+		marker = next;
+	}
+
+	if (marker == pidl)
+	{
+		// There was only a single item ID, so bind to the root
folder.
+		hr = desktop->QueryInterface(riid, ppv);
+	}
+	else
+	{
+		// Copy the ID list, truncating the last item.
+		int length = marker->mkid.abID - pidl->mkid.abID;
+		if (LPITEMIDLIST parent_id =
reinterpret_cast<LPITEMIDLIST>(
+			malloc(length + sizeof(pidl->mkid.cb))))
+		{
+			LPBYTE raw_data =
reinterpret_cast<LPBYTE>(parent_id);
+			memcpy(raw_data, pidl, length);
+			memset(raw_data + length, 0,
sizeof(pidl->mkid.cb));
+			hr = desktop->BindToObject(parent_id, 0, riid,
ppv);
+			free(parent_id);
+		}
+		else
+			return E_OUTOFMEMORY;
+	}
+
+	// Return a pointer to the last item ID.
+	if (ppidlLast)
+		*ppidlLast = marker;
+
+	return hr;
+}
+
 void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM
hItem, LPPOINT pptScreen)
 {
 	CONTEXT("ShellBrowserChild::Tree_DoItemMenu()");
@@ -214,10 +274,21 @@
 			CHECKERROR(ShellFolderContextMenu(folder,
::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y,
_cm_ifs));
 		} else {
 			ShellPath shell_path =
entry->create_absolute_pidl();
-			LPCITEMIDLIST pidl = shell_path;
+			LPCITEMIDLIST pidl_abs = shell_path;
 
-			///@todo use parent folder instead of desktop
-
CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl,
pptScreen->x, pptScreen->y, _cm_ifs));
+			IShellFolder* parentFolder;
+			LPCITEMIDLIST pidlLast;
+
+			 // get and use the parent folder to display
correct context menu in all cases -> correct "Properties" dialog for
directories, ...
+			HRESULT hr = my_SHBindToParent(pidl_abs,
IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);
+
+			if (SUCCEEDED(hr)) {
+				hr =
ShellFolderContextMenu(parentFolder, _hwnd, 1, &pidlLast, pptScreen->x,
pptScreen->y, _cm_ifs);
+
+				parentFolder->Release();
+			}
+
+			CHECKERROR(hr);
 		}
 	}
 }
@@ -289,7 +360,7 @@
 		ShellDirectory* entry =
(ShellDirectory*)TreeView_GetItemData(_left_hwnd, pnmtv->itemNew.hItem);
 
 		if (entry)
-			if (!InsertSubitems(pnmtv->itemNew.hItem, entry,
entry->_folder)) {
+			if (!InsertSubitems(pnmtv->itemNew.hItem,
entry)) {
 				entry->_shell_attribs &=
~SFGAO_HASSUBFOLDER;
 
 				 // remove subitem "+"
@@ -304,7 +375,7 @@
 	}
 }
 
-int ShellBrowserChild::InsertSubitems(HTREEITEM hParentItem, Entry*
entry, IShellFolder* pParentFolder)
+int ShellBrowserChild::InsertSubitems(HTREEITEM hParentItem, Entry*
entry)
 {
 	CONTEXT("ShellBrowserChild::InsertSubitems()");
 
@@ -347,9 +418,9 @@
 			tvInsert.hParent = hParentItem;
 
 			TreeView_InsertItem(_left_hwnd, &tvInsert);
+
+			++cnt;
 		}
-
-		++cnt;
 	}
 
 	SendMessage(_left_hwnd, WM_SETREDRAW, TRUE, 0);
  _____  

Modified:
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.h
---
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.h	2005-12-28 21:46:31 UTC (rev 20405)
+++
branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser
.h	2005-12-28 22:45:04 UTC (rev 20406)
@@ -128,7 +128,7 @@

 
 	LRESULT	Init(HWND hWndFrame);
 	void	InitializeTree();
-	int		InsertSubitems(HTREEITEM hParentItem, Entry*
entry, IShellFolder* pParentFolder);
+	int		InsertSubitems(HTREEITEM hParentItem, Entry*
entry);
 	bool	InitDragDrop();
 
 	HRESULT OnDefaultCommand(LPIDA pida);
@@ -148,9 +148,9 @@
 	int		_last_split;
 	RECT	_clnt_rect;
 
-	/*virtual*/ void resize_children();
-	/*virtual*/ void jump_to(LPCTSTR path);
-	/*virtual*/ void jump_to(LPCITEMIDLIST pidl);
+	void	resize_children();
+	void	jump_to(LPCTSTR path);
+	void	jump_to(LPCITEMIDLIST pidl);
 
 	void	jump_to(Entry* entry);
 
  _____  

Modified:
branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass
es.h
---
branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass
es.h	2005-12-28 21:46:31 UTC (rev 20405)
+++
branches/lean-explorer/reactos/subsys/system/explorer/utility/shellclass
es.h	2005-12-28 22:45:04 UTC (rev 20406)
@@ -1079,5 +1079,6 @@

 	CtxMenuInterfaces _cm_ifs;
 };
 
+
 extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND
hwndParent, int cidl,
 
LPCITEMIDLIST* ppidl, int x, int y, CtxMenuInterfaces& cm_ifs);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20051228/17b303d4/attachment.html


More information about the Ros-diffs mailing list