lean explorer:
- merge a few bug fixes from trunk
- display icon overlays in Explorer tree view
Modified: branches/lean-explorer/reactos/subsys/system/explorer/explorer.cpp
Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.cpp
Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.h
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/shell/shellfs.cpp

Modified: branches/lean-explorer/reactos/subsys/system/explorer/explorer.cpp
--- branches/lean-explorer/reactos/subsys/system/explorer/explorer.cpp	2005-12-28 17:10:36 UTC (rev 20398)
+++ branches/lean-explorer/reactos/subsys/system/explorer/explorer.cpp	2005-12-28 17:37:37 UTC (rev 20399)
@@ -443,8 +443,6 @@
 		ShowWindow(hMainFrame, cmdShow);
 		UpdateWindow(hMainFrame);
 
-		bool valid_dir = false;
-
 		cmd._cmdShow = cmdShow;
 
 		 // parse command line options

Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.cpp
--- branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.cpp	2005-12-28 17:10:36 UTC (rev 20398)
+++ branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.cpp	2005-12-28 17:37:37 UTC (rev 20399)
@@ -319,7 +319,7 @@
 }
 
 
-void Entry::extract_icon()
+int Entry::extract_icon()
 {
 	TCHAR path[MAX_PATH];
 
@@ -384,10 +384,21 @@
 		}
 	}
 
-	_icon_id = icon_id;
+	return icon_id;
 }
 
+int Entry::safe_extract_icon()
+{
+	try {
+		return extract_icon();
+	} catch(COMException&) {
+		// ignore unexpected exceptions while extracting icons
+	}
 
+	return ICID_NONE;
+}
+
+
 BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow)
 {
 	TCHAR cmd[MAX_PATH];

Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.h
--- branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.h	2005-12-28 17:10:36 UTC (rev 20398)
+++ branches/lean-explorer/reactos/subsys/system/explorer/shell/entries.h	2005-12-28 17:37:37 UTC (rev 20399)
@@ -96,7 +96,8 @@
 	Entry*	read_tree(const void* path, SORT_ORDER sortOrder);
 	void	sort_directory(SORT_ORDER sortOrder);
 	void	smart_scan(int scan_flags=SCAN_ALL);
-	void	extract_icon();
+	int		extract_icon();
+	int		safe_extract_icon();
 
 	virtual void read_directory(int scan_flags=SCAN_ALL) {}
 	virtual const void* get_next_path_component(const void*) const {return NULL;}

Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser.cpp
--- branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser.cpp	2005-12-28 17:10:36 UTC (rev 20398)
+++ branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser.cpp	2005-12-28 17:37:37 UTC (rev 20399)
@@ -51,11 +51,10 @@
 	_left_hwnd(left_hwnd),
 	_right_hwnd(right_hwnd),
 	_create_info(create_info),
-	_cm_ifs(_cm_ifs)
+	_cm_ifs(cm_ifs)
 {
 	_pShellView = NULL;
 	_pDropTarget = NULL;
-	_himlSmall = 0;
 	_last_sel = 0;
 
 	 // SDI integration
@@ -64,12 +63,16 @@
 
 	_cur_dir = NULL;
 
+	_himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
+	ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
+
 	Init(hwnd);
 }
 
 ShellBrowserChild::~ShellBrowserChild()
 {
 	TreeView_SetImageList(_left_hwnd, 0, TVSIL_NORMAL);
+	ImageList_Destroy(_himl);
 
 	if (_pShellView)
 		_pShellView->Release();
@@ -94,16 +97,6 @@
 
 	ClientRect rect(_hwnd);
 
-	SHFILEINFO sfi;
-
-	_himlSmall = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
-//	_himlLarge = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_LARGEICON);
-
-	if (_left_hwnd) {
-		InitializeTree();
-		InitDragDrop();
-	}
-
 	const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR);
 
 	_root._drive_type = DRIVE_UNKNOWN;
@@ -118,6 +111,11 @@
 	 // -> set_curdir()
 	_root._entry->read_directory();
 
+	if (_left_hwnd) {
+		InitializeTree();
+		InitDragDrop();
+	}
+
 	/* already filled by ShellDirectory constructor
 	lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); */
 
@@ -129,23 +127,21 @@
 {
 	CONTEXT("ShellBrowserChild::InitializeTree()");
 
-	TreeView_SetImageList(_left_hwnd, _himlSmall, TVSIL_NORMAL);
+	TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
 	TreeView_SetScrollTime(_left_hwnd, 100);
 
-	TV_ITEM tvItem;
+	TV_INSERTSTRUCT tvInsert;
+	TV_ITEM& tvItem = tvInsert.item;
 
+	tvInsert.hParent = 0;
+	tvInsert.hInsertAfter = TVI_LAST;
+
 	tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
 	tvItem.lParam = (LPARAM)_root._entry;
-	tvItem.pszText = LPSTR_TEXTCALLBACK;
+	tvItem.pszText = _root._volname; //LPSTR_TEXTCALLBACK;
 	tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;
 	tvItem.cChildren = 1;
 
-	TV_INSERTSTRUCT tvInsert;
-
-	tvInsert.hParent = 0;
-	tvInsert.hInsertAfter = TVI_LAST;
-	tvInsert.item = tvItem;
-
 	HTREEITEM hItem = TreeView_InsertItem(_left_hwnd, &tvInsert);
 	TreeView_SelectItem(_left_hwnd, hItem);
 	TreeView_Expand(_left_hwnd, hItem, TVE_EXPAND);
@@ -167,8 +163,7 @@
 		_pDropTarget->Release(); // free TreeDropTarget
 		_pDropTarget = NULL;
 		return false;
-	}
-	else
+	} else
 		_pDropTarget->Release();
 
 	FORMATETC ftetc;
@@ -233,38 +228,57 @@
 
 	LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh;
 	ShellEntry* entry = (ShellEntry*)lpdi->item.lParam;
-	if (!entry)
-		return;
 
-	if (lpdi->item.mask & TVIF_TEXT)
-		lpdi->item.pszText = entry->_display_name;
+	if (entry) {
+		if (lpdi->item.mask & TVIF_TEXT)
+			lpdi->item.pszText = entry->_display_name;
 
-	if (lpdi->item.mask & (/*TVIF_TEXT|*/TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
-		ShellPath pidl_abs = entry->create_absolute_pidl();	// Caching of absolute PIDLs could enhance performance.
-		LPCITEMIDLIST pidl = pidl_abs;
+		if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
+			ShellPath pidl_abs = entry->create_absolute_pidl();	// Caching of absolute PIDLs could enhance performance.
+			LPCITEMIDLIST pidl = pidl_abs;
 
-		SHFILEINFO sfi;
-/*
-		if (lpdi->item.mask & TVIF_TEXT)
-			if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_DISPLAYNAME))
-				lstrcpy(lpdi->item.pszText, sfi.szDisplayName);	///@todo look at cchTextMax if there is enough space available
-			else
-				lpdi->item.pszText = entry->_data.cFileName;
-*/
-		if (lpdi->item.mask & TVIF_IMAGE)
-			if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_LINKOVERLAY) == _himlSmall)
-				lpdi->item.iImage = sfi.iIcon;
-			else
-				lpdi->item.iImage = -1;
+			if (lpdi->item.mask & TVIF_IMAGE)
+				lpdi->item.iImage = get_entry_image(entry, pidl, SHGFI_SMALLICON, _image_map);
 
-		if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
-			if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON) == _himlSmall)
-				lpdi->item.iSelectedImage = sfi.iIcon;
-			else
-				lpdi->item.iSelectedImage = -1;
+			if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
+				lpdi->item.iSelectedImage = get_entry_image(entry, pidl, SHGFI_SMALLICON|SHGFI_OPENICON, _image_map_open);
+		}
 	}
 }
 
+int ShellBrowserChild::get_entry_image(Entry* entry, LPCITEMIDLIST pidl, int shgfi_flags, ImageMap& cache)
+{
+	SHFILEINFO sfi;
+	int idx = -1;
+
+	ImageMap::const_iterator found = cache.find(entry);
+
+	if (found != cache.end())
+		return found->second;
+
+	if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), shgfi_flags|SHGFI_PIDL|SHGFI_ICON|SHGFI_ADDOVERLAYS)) {
+		idx = ImageList_AddIcon(_himl, sfi.hIcon);
+
+		DestroyIcon(sfi.hIcon);
+	}
+
+	cache[entry] = idx;
+
+	return idx;
+}
+
+void ShellBrowserChild::invalidate_cache()
+{
+	TreeView_SetImageList(_left_hwnd, 0, TVSIL_NORMAL);
+	ImageList_Destroy(_himl);
+
+	TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
+	_himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
+
+	_image_map.clear();
+	_image_map_open.clear();
+}
+
 void ShellBrowserChild::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
 {
 	CONTEXT("ShellBrowserChild::OnTreeItemExpanding()");

Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser.h
--- branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser.h	2005-12-28 17:10:36 UTC (rev 20398)
+++ branches/lean-explorer/reactos/subsys/system/explorer/shell/shellbrowser.h	2005-12-28 17:37:37 UTC (rev 20399)
@@ -41,6 +41,10 @@
 };
 
 
+#ifndef SHGFI_ADDOVERLAYS // missing in MinGW (as of 28.12.2005)
+#define SHGFI_ADDOVERLAYS 0x000000020
+#endif
+
  /// Implementation of IShellBrowserImpl interface in explorer child windows
 struct ShellBrowserChild : public IShellBrowserImpl
 {
@@ -112,11 +116,10 @@
 	ShellFolder	_folder;
 
 	IShellView*	_pShellView;	// current hosted shellview
-	HIMAGELIST	_himlSmall;		// list
-//	HIMAGELIST	_himlLarge;		// shell image
 	TreeDropTarget* _pDropTarget;
 
-	HTREEITEM _last_sel;
+	HIMAGELIST	_himl;
+	HTREEITEM	_last_sel;
 
 public:
 	LRESULT	WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
@@ -154,4 +157,11 @@
 protected:
 	ShellDirectory*	_cur_dir;
 	CtxMenuInterfaces& _cm_ifs;
+
+	typedef map<Entry*, int> ImageMap;
+	ImageMap _image_map;
+	ImageMap _image_map_open;
+
+	int		get_entry_image(Entry* entry, LPCITEMIDLIST pidl, int shgfi_flags, ImageMap& cache);
+	void	invalidate_cache();
 };

Modified: branches/lean-explorer/reactos/subsys/system/explorer/shell/shellfs.cpp
--- branches/lean-explorer/reactos/subsys/system/explorer/shell/shellfs.cpp	2005-12-28 17:10:36 UTC (rev 20398)
+++ branches/lean-explorer/reactos/subsys/system/explorer/shell/shellfs.cpp	2005-12-28 17:37:37 UTC (rev 20399)
@@ -298,11 +298,7 @@
 				if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 					entry->_icon_id = ICID_FOLDER;
 				else if (scan_flags & SCAN_EXTRACT_ICONS)
-					try {
-						entry->extract_icon();
-					} catch(COMException&) {
-						// ignore unexpected exceptions while extracting icons
-					}
+					entry->_icon_id = entry->safe_extract_icon();
 
 				last = entry;
 			} while(FindNextFile(hFind, &w32fd));
@@ -404,11 +400,7 @@
 					if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
 						!(attribs & SFGAO_FILESYSTEM)) {
 						if (scan_flags & SCAN_EXTRACT_ICONS)
-							try {
-								entry->extract_icon();
-							} catch(COMException&) {
-								// ignore unexpected exceptions while extracting icons
-							}
+							entry->_icon_id = entry->safe_extract_icon();
 					} else if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 						entry->_icon_id = ICID_FOLDER;
 					else
@@ -463,7 +455,7 @@
 
 	for(Entry*entry=_down; entry; entry=entry->_next)
 		if (entry->_icon_id == ICID_UNKNOWN) {
-			entry->extract_icon();
+			entry->_icon_id = entry->extract_icon();
 
 			if (entry->_icon_id != ICID_NONE)
 				++cnt;