Modified: trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp
Modified: trunk/reactos/subsys/system/explorer/doc/changes.txt
Modified: trunk/reactos/subsys/system/explorer/explorer.cpp
Modified: trunk/reactos/subsys/system/explorer/globals.h
Modified: trunk/reactos/subsys/system/explorer/shell/entries.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/entries.h
Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.h
Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.cpp
Modified: trunk/reactos/subsys/system/explorer/shell/shellfs.h
Modified: trunk/reactos/subsys/system/explorer/taskbar/desktopbar.cpp
Modified: trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp
Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp
Modified: trunk/reactos/subsys/system/explorer/taskbar/startmenu.h
Modified: trunk/reactos/subsys/system/explorer/utility/utility.h
--- trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/dialogs/searchprogram.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -344,7 +344,7 @@
Entry* entry = cache_entry._entry;
if (entry->_icon_id == ICID_UNKNOWN)
- entry->extract_icon(false);
+ entry->_icon_id = entry->extract_icon(ICF_SYSCACHE);
pDispInfo->item.iImage = g_Globals._icon_cache.get_icon(entry->_icon_id).get_sysiml_idx();
pDispInfo->item.mask |= LVIF_DI_SETITEM;
--- trunk/reactos/subsys/system/explorer/doc/changes.txt 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/doc/changes.txt 2005-12-28 16:14:10 UTC (rev 20396)
@@ -166,3 +166,4 @@
m. fuchs replace "search computer" start menu entry by a "not yet implemented" message
01.11.2005 m. fuchs String::str(), String::toLower() to allow conventient and WINE compatible string conversions
29.11.2005 m. fuchs Adjustments for Visual Studio 2005: use new secure CT functions, COUNTOF for buffer sizes
+28.12.2005 m. fuchs display icon overlays in Explorer tree view
--- trunk/reactos/subsys/system/explorer/explorer.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/explorer.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -322,7 +322,7 @@
return ret;
}
-HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd/*, bool big_icons*/)
+HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd/*, bool large_icons*/)
{
int cx = GetSystemMetrics(SM_CXSMICON); //ICON_SIZE_X;
int cy = GetSystemMetrics(SM_CYSMICON); //ICON_SIZE_Y;
@@ -396,27 +396,65 @@
}
-const Icon& IconCache::extract(LPCTSTR path, bool big_icons)
+const Icon& IconCache::extract(LPCTSTR path, ICONCACHE_FLAGS flags)
{
- PathMap::iterator found = _pathMap.find(path);
+ // search for matching icon with unchanged flags in the cache
+ CacheKey mapkey(path, flags);
+ PathCacheMap::iterator found = _pathCache.find(mapkey);
- if (found != _pathMap.end())
+ if (found != _pathCache.end())
return _icons[found->second];
+ // search for matching icon with handle
+ CacheKey mapkey_hicon(path, flags|ICF_HICON);
+ if (flags != mapkey_hicon.second) {
+ found = _pathCache.find(mapkey_hicon);
+
+ if (found != _pathCache.end())
+ return _icons[found->second];
+ }
+
+ // search for matching icon in the system image list cache
+ CacheKey mapkey_syscache(path, flags|ICF_SYSCACHE);
+ if (flags != mapkey_syscache.second) {
+ found = _pathCache.find(mapkey_syscache);
+
+ if (found != _pathCache.end())
+ return _icons[found->second];
+ }
+
SHFILEINFO sfi;
- if (big_icons) {
- if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON)) {
+ int shgfi_flags = 0;
+
+ if (flags & ICF_OPEN)
+ shgfi_flags |= SHGFI_OPENICON;
+
+ if ((flags&(ICF_LARGE|ICF_OVERLAYS|ICF_HICON)) && !(flags&ICF_SYSCACHE)) {
+ shgfi_flags |= SHGFI_ICON;
+
+ if (!(flags & ICF_LARGE))
+ shgfi_flags |= SHGFI_SMALLICON;
+
+ if (flags & ICF_OVERLAYS)
+ shgfi_flags |= SHGFI_ADDOVERLAYS;
+
+ // get small/big icons with/without overlays
+ if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), shgfi_flags)) {
const Icon& icon = add(sfi.hIcon, IT_CACHED);
///@todo limit cache size
- _pathMap[path] = icon;
+ _pathCache[mapkey_hicon] = icon;
return icon;
}
} else {
+ assert(!(flags&ICF_OVERLAYS));
+
+ shgfi_flags |= SHGFI_SYSICONINDEX|SHGFI_SMALLICON;
+
// use system image list - the "search program dialog" needs it
- HIMAGELIST himlSys_small = (HIMAGELIST) SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
+ HIMAGELIST himlSys_small = (HIMAGELIST) SHGetFileInfo(path, 0, &sfi, sizeof(sfi), shgfi_flags);
if (himlSys_small) {
_himlSys_small = himlSys_small;
@@ -424,7 +462,7 @@
const Icon& icon = add(sfi.iIcon/*, IT_SYSCACHE*/);
///@todo limit cache size
- _pathMap[path] = icon;
+ _pathCache[mapkey_syscache] = icon;
return icon;
}
@@ -433,15 +471,15 @@
return _icons[ICID_NONE];
}
-const Icon& IconCache::extract(LPCTSTR path, int idx)
+const Icon& IconCache::extract(LPCTSTR path, int idx, ICONCACHE_FLAGS flags)
{
- CachePair key(path, idx);
+ IdxCacheKey key(path, make_pair(idx, (flags|ICF_HICON)&~ICF_SYSCACHE));
key.first.toLower();
- PathIdxMap::iterator found = _pathIdxMap.find(key);
+ IdxCacheMap::iterator found = _idxCache.find(key);
- if (found != _pathIdxMap.end())
+ if (found != _idxCache.end())
return _icons[found->second];
HICON hIcon;
@@ -449,7 +487,7 @@
if ((int)ExtractIconEx(path, idx, NULL, &hIcon, 1) > 0) {
const Icon& icon = add(hIcon, IT_CACHED);
- _pathIdxMap[key] = icon;
+ _idxCache[key] = icon;
return icon;
} else {
@@ -460,15 +498,16 @@
}
}
-const Icon& IconCache::extract(IExtractIcon* pExtract, LPCTSTR path, int idx, bool big_icons)
+const Icon& IconCache::extract(IExtractIcon* pExtract, LPCTSTR path, int idx, ICONCACHE_FLAGS flags)
{
HICON hIconLarge = 0;
HICON hIcon;
+ bool large_icons = flags & ICF_LARGE;
HRESULT hr = pExtract->Extract(path, idx, &hIconLarge, &hIcon, MAKELONG(GetSystemMetrics(SM_CXICON), ICON_SIZE_X));
if (hr == NOERROR) { //@@ oder SUCCEEDED(hr) ?
- if (big_icons) { //@@ OK?
+ if (large_icons) { //@@ OK?
if (hIcon)
DestroyIcon(hIcon);
@@ -479,7 +518,7 @@
}
if (hIcon)
- return add(hIcon);
+ return add(hIcon); //@@ When do we want not to free this icons?
}
return _icons[ICID_NONE];
--- trunk/reactos/subsys/system/explorer/globals.h 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/globals.h 2005-12-28 16:14:10 UTC (rev 20396)
@@ -98,6 +98,7 @@
int add_to_imagelist(HIMAGELIST himl, HDC hdc_wnd, COLORREF bk_color=GetSysColor(COLOR_WINDOW), HBRUSH bk_brush=GetSysColorBrush(COLOR_WINDOW)) const;
int get_sysiml_idx() const {return _itype==IT_SYSCACHE? _sys_idx: -1;}
+ HICON get_hicon() const {return _itype!=IT_SYSCACHE? _hicon: 0;}
bool destroy() {if (_itype == IT_DYNAMIC) {DestroyIcon(_hicon); return true;} else return false;}
@@ -118,9 +119,9 @@
void init();
- const Icon& extract(LPCTSTR path, bool big_icons);
- const Icon& extract(LPCTSTR path, int idx);
- const Icon& extract(IExtractIcon* pExtract, LPCTSTR path, int idx, bool big_icons);
+ const Icon& extract(LPCTSTR path, ICONCACHE_FLAGS flags=ICF_NORMAL);
+ const Icon& extract(LPCTSTR path, int idx, ICONCACHE_FLAGS flags=ICF_HICON);
+ const Icon& extract(IExtractIcon* pExtract, LPCTSTR path, int idx, ICONCACHE_FLAGS flags=ICF_HICON);
const Icon& add(HICON hIcon, ICON_TYPE type=IT_DYNAMIC);
const Icon& add(int sys_idx/*, ICON_TYPE type=IT_SYSCACHE*/);
@@ -137,23 +138,24 @@
typedef map<int, Icon> IconMap;
IconMap _icons;
- typedef map<String, ICON_ID> PathMap;
- PathMap _pathMap;
+ typedef pair<String,int/*ICONCACHE_FLAGS*/> CacheKey;
+ typedef map<CacheKey, ICON_ID> PathCacheMap;
+ PathCacheMap _pathCache;
- typedef pair<String, int> CachePair;
- typedef map<CachePair, ICON_ID> PathIdxMap;
- PathIdxMap _pathIdxMap;
+ typedef pair<String,pair<int,int/*ICONCACHE_FLAGS*/> > IdxCacheKey;
+ typedef map<IdxCacheKey, ICON_ID> IdxCacheMap;
+ IdxCacheMap _idxCache;
HIMAGELIST _himlSys_small;
};
-#define ICON_SIZE_X GetSystemMetrics(big_icons? SM_CXICON: SM_CXSMICON)
-#define ICON_SIZE_Y GetSystemMetrics(big_icons? SM_CYICON: SM_CYSMICON)
+#define ICON_SIZE_X GetSystemMetrics(large_icons? SM_CXICON: SM_CXSMICON)
+#define ICON_SIZE_Y GetSystemMetrics(large_icons? SM_CYICON: SM_CYSMICON)
/// create a bitmap from an icon
-extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd/*, bool big_icons*/);
+extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd/*, bool large_icons*/);
/// add icon with alpha channel to imagelist using the specified background color
extern int ImageList_AddAlphaIcon(HIMAGELIST himl, HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd);
--- trunk/reactos/subsys/system/explorer/shell/entries.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/entries.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -319,52 +319,55 @@
}
-void Entry::extract_icon(bool big_icons)
+
+int Entry::extract_icon(ICONCACHE_FLAGS flags)
{
TCHAR path[MAX_PATH];
ICON_ID icon_id = ICID_NONE;
if (get_path(path, COUNTOF(path)) && _tcsncmp(path,TEXT("::{"),3))
- icon_id = g_Globals._icon_cache.extract(path, big_icons);
+ icon_id = g_Globals._icon_cache.extract(path, flags);
if (icon_id == ICID_NONE) {
- IExtractIcon* pExtract;
- if (SUCCEEDED(GetUIObjectOf(0, IID_IExtractIcon, (LPVOID*)&pExtract))) {
- unsigned flags;
- int idx;
+ if (!(flags & (ICF_OPEN|ICF_OVERLAYS))) {
+ IExtractIcon* pExtract;
+ if (SUCCEEDED(GetUIObjectOf(0, IID_IExtractIcon, (LPVOID*)&pExtract))) {
+ unsigned gil_flags;
+ int idx;
- if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, COUNTOF(path), &idx, &flags))) {
- if (flags & GIL_NOTFILENAME)
- icon_id = g_Globals._icon_cache.extract(pExtract, path, idx, big_icons);
- else {
- if (idx == -1)
- idx = 0; // special case for some control panel applications ("System")
+ if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, COUNTOF(path), &idx, &gil_flags))) {
+ if (gil_flags & GIL_NOTFILENAME)
+ icon_id = g_Globals._icon_cache.extract(pExtract, path, idx, flags);
+ else {
+ if (idx == -1)
+ idx = 0; // special case for some control panel applications ("System")
- icon_id = g_Globals._icon_cache.extract(path, idx);
- }
+ icon_id = g_Globals._icon_cache.extract(path, idx, flags);
+ }
- /* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets ("NVidia").
- if (icon_id == ICID_NONE) {
- SHFILEINFO sfi;
+ /* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets (NVidia display driver).
+ if (icon_id == ICID_NONE) {
+ SHFILEINFO sfi;
- if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON))
- icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id;
- } */
- /*
- if (icon_id == ICID_NONE) {
- LPBYTE b = (LPBYTE) alloca(0x10000);
- SHFILEINFO sfi;
+ if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON))
+ icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id;
+ } */
+ /*
+ if (icon_id == ICID_NONE) {
+ LPBYTE b = (LPBYTE) alloca(0x10000);
+ SHFILEINFO sfi;
- FILE* file = fopen(path, "rb");
- if (file) {
- int l = fread(b, 1, 0x10000, file);
- fclose(file);
+ FILE* file = fopen(path, "rb");
+ if (file) {
+ int l = fread(b, 1, 0x10000, file);
+ fclose(file);
- if (l)
- icon_id = g_Globals._icon_cache.add(CreateIconFromResourceEx(b, l, TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR));
- }
- } */
+ if (l)
+ icon_id = g_Globals._icon_cache.add(CreateIconFromResourceEx(b, l, TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR));
+ }
+ } */
+ }
}
}
@@ -374,20 +377,41 @@
const ShellPath& pidl_abs = create_absolute_pidl();
LPCITEMIDLIST pidl = pidl_abs;
- HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_PIDL|(big_icons? SHGFI_SMALLICON: 0));
+ int shgfi_flags = SHGFI_SYSICONINDEX|SHGFI_PIDL;
+
+ if (!(flags & ICF_LARGE))
+ shgfi_flags |= SHGFI_SMALLICON;
+
+ if (flags & ICF_OPEN)
+ shgfi_flags |= SHGFI_OPENICON;
+
+ // ICF_OVERLAYS is not supported in this case.
+
+ HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), shgfi_flags);
if (himlSys)
icon_id = g_Globals._icon_cache.add(sfi.iIcon);
/*
- if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|(g_Globals._big_icons? SHGFI_SMALLICON: 0)))
+ if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|(g_Globals._large_icons? SHGFI_SMALLICON: 0)))
icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id;
*/
}
}
- _icon_id = icon_id;
+ return icon_id;
}
+int Entry::safe_extract_icon(ICONCACHE_FLAGS flags)
+{
+ try {
+ return extract_icon(flags);
+ } catch(COMException&) {
+ // ignore unexpected exceptions while extracting icons
+ }
+ return ICID_NONE;
+}
+
+
BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow)
{
TCHAR cmd[MAX_PATH];
--- trunk/reactos/subsys/system/explorer/shell/entries.h 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/entries.h 2005-12-28 16:14:10 UTC (rev 20396)
@@ -64,7 +64,20 @@
#define ATTRIBUTE_EXECUTABLE 0x80000000
#endif
+enum ICONCACHE_FLAGS {
+ ICF_NORMAL = 0,
+ ICF_LARGE = 1,
+ ICF_OPEN = 2,
+ ICF_OVERLAYS = 4,
+ ICF_HICON = 8,
+ ICF_SYSCACHE = 16
+};
+#ifndef SHGFI_ADDOVERLAYS // missing in MinGW (as of 28.12.2005)
+#define SHGFI_ADDOVERLAYS 0x000000020
+#endif
+
+
/// base of all file and directory entries
struct Entry
{
@@ -103,7 +116,8 @@
Entry* read_tree(const void* path, SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL);
void sort_directory(SORT_ORDER sortOrder);
void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL);
- void extract_icon(bool big_icons);
+ int extract_icon(ICONCACHE_FLAGS flags=ICF_NORMAL);
+ int safe_extract_icon(ICONCACHE_FLAGS flags=ICF_NORMAL);
virtual void read_directory(int scan_flags=SCAN_ALL) {}
virtual const void* get_next_path_component(const void*) const {return NULL;}
--- trunk/reactos/subsys/system/explorer/shell/mainframe.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/mainframe.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -1335,9 +1335,6 @@
_split_pos = DEFAULT_SPLIT_POS;
_last_split = DEFAULT_SPLIT_POS;
- // create image list for explorer tree view
- init_himl();
-
/* wait for PM_OPEN_WINDOW message before creating a shell view
update_shell_browser();*/
}
@@ -1647,12 +1644,12 @@
}
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
- _shellpath_info, _himlSmall, this, _cm_ifs));
+ _shellpath_info, this, _cm_ifs));
_shellBrowser->Init(_hwnd);
if (_left_hwnd)
- _shellBrowser->Init(_himlSmall);
+ _shellBrowser->Init();
// update _clnt_rect and set size of new created shell view windows
update_clnt_rect();
--- trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -38,7 +38,7 @@
ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
- HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
+ BrowserCallback* cb, CtxMenuInterfaces& cm_ifs)
#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
: super(IID_IShellFolderViewCB),
#else
@@ -48,7 +48,6 @@
_left_hwnd(left_hwnd),
_right_hwnd(right_hwnd),
_create_info(create_info),
- _himl(himl),
_callback(cb),
_cm_ifs(cm_ifs)
{
@@ -57,11 +56,15 @@
_last_sel = 0;
_cur_dir = NULL;
+
+ _himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0);
+ ImageList_SetBkColor(_himl, GetSysColor(COLOR_WINDOW));
}
ShellBrowser::~ShellBrowser()
{
(void)TreeView_SetImageList(_left_hwnd, _himl_old, TVSIL_NORMAL);
+ ImageList_Destroy(_himl);
if (_pShellView)
_pShellView->Release();
@@ -148,22 +151,22 @@
}
-void ShellBrowser::InitializeTree(HIMAGELIST himl)
+void ShellBrowser::InitializeTree()
{
CONTEXT("ShellBrowserChild::InitializeTree()");
- _himl_old = TreeView_SetImageList(_left_hwnd, himl, TVSIL_NORMAL);
+ _himl_old = TreeView_SetImageList(_left_hwnd, _himl, TVSIL_NORMAL);
TreeView_SetScrollTime(_left_hwnd, 100);
TV_INSERTSTRUCT tvInsert;
+ TV_ITEM& tvItem = tvInsert.item;
tvInsert.hParent = 0;
tvInsert.hInsertAfter = TVI_LAST;
- TV_ITEM& tvItem = tvInsert.item;
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;
@@ -239,33 +242,43 @@
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;
-
- 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|TVIF_SELECTEDIMAGE)) {
if (lpdi->item.mask & TVIF_IMAGE)
- if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_LINKOVERLAY|SHGFI_SMALLICON) == _himl)
- lpdi->item.iImage = sfi.iIcon;
- else
- lpdi->item.iImage = -1;
+ lpdi->item.iImage = get_image_idx(
+ entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS)));
if (lpdi->item.mask & TVIF_SELECTEDIMAGE)
- if ((HIMAGELIST)SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_OPENICON|SHGFI_SMALLICON) == _himl)
- lpdi->item.iSelectedImage = sfi.iIcon;
- else
- lpdi->item.iSelectedImage = -1;
+ lpdi->item.iSelectedImage = get_image_idx(
+ entry->safe_extract_icon((ICONCACHE_FLAGS)(ICF_HICON|ICF_OVERLAYS|ICF_OPEN)));
}
}
}
+int ShellBrowser::get_image_idx(int icon_id)
+{
+ if (icon_id != ICID_NONE) {
+ map<int,int>::const_iterator found = _image_map.find(icon_id);
+
+ if (found != _image_map.end())
+ return found->second;
+
+ int idx = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(icon_id).get_hicon());
+
+ _image_map[icon_id] = idx;
+
+ return idx;
+ } else
+ return -1;
+}
+
+void ShellBrowser::invalidate_cache()
+{
+ for(map<int,int>::const_iterator it=_image_map.begin(); it!=_image_map.end(); ++it)
+ g_Globals._icon_cache.free_icon(it->first);
+
+ _image_map.clear();
+}
+
void ShellBrowser::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv)
{
CONTEXT("ShellBrowser::OnTreeItemExpanding()");
@@ -554,13 +567,11 @@
if (super::Init(pcs))
return 1;
- init_himl();
-
update_shell_browser();
if (_shellBrowser.get())
if (_left_hwnd)
- _shellBrowser->Init(_himlSmall);
+ _shellBrowser->Init();
else
_shellBrowser->UpdateFolderView(_create_info._shell_path.get_folder());
@@ -579,6 +590,7 @@
case ID_REFRESH:
//@todo refresh shell child
+ _shellBrowser->invalidate_cache();
break;
case ID_VIEW_SDI:
@@ -626,7 +638,7 @@
}
_shellBrowser = auto_ptr<ShellBrowser>(new ShellBrowser(_hwnd, _left_hwnd, _right_hwnd,
- _shellpath_info, _himlSmall, this, _cm_ifs));
+ _shellpath_info, this, _cm_ifs));
_shellBrowser->Init(_hwndFrame);
}
--- trunk/reactos/subsys/system/explorer/shell/shellbrowser.h 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/shellbrowser.h 2005-12-28 16:14:10 UTC (rev 20396)
@@ -62,7 +62,7 @@
#endif
{
ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info,
- HIMAGELIST himl, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs);
+ BrowserCallback* cb, CtxMenuInterfaces& cm_ifs);
virtual ~ShellBrowser();
//IOleWindow
@@ -124,9 +124,9 @@
LRESULT Init(HWND hWndFrame);
- void Init(HIMAGELIST himl)
+ void Init()
{
- InitializeTree(himl);
+ InitializeTree();
InitDragDrop();
}
@@ -142,6 +142,8 @@
// for SDIMainFrame
void jump_to(LPCITEMIDLIST pidl);
+ void invalidate_cache();
+
protected:
HWND _hwnd;
HWND _left_hwnd;
@@ -164,7 +166,7 @@
CtxMenuInterfaces& _cm_ifs;
- void InitializeTree(HIMAGELIST himl);
+ void InitializeTree();
bool InitDragDrop();
#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005)
@@ -173,6 +175,10 @@
// IShellFolderViewCB
virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
+
+ map<int, int> _image_map;
+
+ int get_image_idx(int icon_id);
};
@@ -194,29 +200,15 @@
ShellBrowserChildT(HWND hwnd)
: super(hwnd)
{
- _himlSmall = 0;
}
// constructor for MDIShellBrowserChild
ShellBrowserChildT(HWND hwnd, const ShellChildWndInfo& info)
: super(hwnd, info)
{
- _himlSmall = 0;
}
- void init_himl()
- {
- SHFILEINFO sfi;
-
- _himlSmall = (HIMAGELIST)SHGetFileInfo(C_DRIVE, 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
-// _himlLarge = (HIMAGELIST)SHGetFileInfo(C_DRIVE, 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_LARGEICON);
- }
-
protected:
- HIMAGELIST _himlSmall; // list
-// HIMAGELIST _himlLarge; // shell image
-
-protected:
auto_ptr<ShellBrowser> _shellBrowser;
LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
--- trunk/reactos/subsys/system/explorer/shell/shellfs.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/shellfs.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -325,11 +325,7 @@
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry->_icon_id = ICID_FOLDER;
/* else if (scan_flags & SCAN_EXTRACT_ICONS)
- try {
- entry->extract_icon(big_icons);
- } catch(COMException&) {
- // ignore unexpected exceptions while extracting icons
- }
+ entry->safe_extract_icon(large_icons);
*/
last = entry;
} while(FindNextFile(hFind, &w32fd));
@@ -431,11 +427,7 @@
if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
!(attribs & SFGAO_FILESYSTEM)) {
/* if (scan_flags & SCAN_EXTRACT_ICONS)
- try {
- entry->extract_icon(big_icons);
- } catch(COMException&) {
- // ignore unexpected exceptions while extracting icons
- }
+ entry->extract_icon(large_icons);
*/ } else if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry->_icon_id = ICID_FOLDER;
else
@@ -488,13 +480,13 @@
return NULL;
}
-int ShellDirectory::extract_icons(bool big_icons)
+int ShellDirectory::extract_icons(ICONCACHE_FLAGS flags)
{
int cnt = 0;
for(Entry*entry=_down; entry; entry=entry->_next)
if (entry->_icon_id == ICID_UNKNOWN) {
- entry->extract_icon(big_icons);
+ entry->_icon_id = entry->extract_icon(flags);
if (entry->_icon_id != ICID_NONE)
++cnt;
--- trunk/reactos/subsys/system/explorer/shell/shellfs.h 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/shell/shellfs.h 2005-12-28 16:14:10 UTC (rev 20396)
@@ -105,7 +105,7 @@
virtual bool get_path(PTSTR path, size_t path_count) const;
- int extract_icons(bool big_icons);
+ int extract_icons(ICONCACHE_FLAGS flags);
ShellFolder _folder;
HWND _hwnd;
--- trunk/reactos/subsys/system/explorer/taskbar/desktopbar.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/taskbar/desktopbar.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -161,7 +161,7 @@
RegisterHotkeys();
// prepare Startmenu, but hide it for now
- _startMenuRoot = GET_WINDOW(StartMenuRoot, StartMenuRoot::Create(_hwnd, true)); //@@ _big_icons
+ _startMenuRoot = GET_WINDOW(StartMenuRoot, StartMenuRoot::Create(_hwnd, true)); //@@ _large_icons
return 0;
}
--- trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -109,11 +109,7 @@
// immediatelly extract the shortcut icons
for(Entry*entry=_dir->_down; entry; entry=entry->_next)
- try {
- entry->extract_icon(false);
- } catch(COMException&) {
- // ignore unexpected exceptions while extracting icons
- }
+ entry->_icon_id = entry->safe_extract_icon(ICF_NORMAL);
} catch(COMException&) {
return;
}
--- trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp 2005-12-28 14:55:22 UTC (rev 20395)
+++ trunk/reactos/subsys/system/explorer/taskbar/startmenu.cpp 2005-12-28 16:14:10 UTC (rev 20396)
@@ -46,9 +46,9 @@
#define SHELLPATH_NET_CONNECTIONS TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}")
-StartMenu::StartMenu(HWND hwnd, bool big_icons)
+StartMenu::StartMenu(HWND hwnd, bool large_icons)
: super(hwnd),
- _big_icons(big_icons)
+ _large_icons(large_icons)
{
_next_id = IDC_FIRST_MENU;
_submenu_id = 0;
@@ -70,10 +70,10 @@
#endif
}
-StartMenu::StartMenu(HWND hwnd, const StartMenuCreateInfo& create_info, bool big_icons)
+StartMenu::StartMenu(HWND hwnd, const StartMenuCreateInfo& create_info, bool large_icons)
: super(hwnd),
_create_info(create_info),
- _big_icons(big_icons)
+ _large_icons(large_icons)
{
for(StartMenuFolders::const_iterator it=create_info._folders.begin(); it!=create_info._folders.end(); ++it)
if (*it)
@@ -117,7 +117,7 @@
Window::CREATORFUNC_INFO StartMenu::s_def_creator = STARTMENU_CREATOR(StartMenu);
-HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent, LPCTSTR title, bool parent_big_icons,
+HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent, LPCTSTR title,
CREATORFUNC_INFO creator, void* info, const String& filter)
{
UINT style, ex_style;
@@ -133,7 +133,7 @@
top_height = 0;
}
- bool big_icons = false;
+ bool large_icons = false;
RECT rect = {x, y-STARTMENU_LINE_HEIGHT-top_height, x+STARTMENU_WIDTH_MIN, y};
#ifndef _LIGHT_STARTMENU
@@ -348,7 +348,7 @@
WindowRect pos(_hwnd);
///@todo do something similar to StartMenuRoot::TrackStartmenu() in order to automatically close submenus when clicking on the desktop background
- StartMenu::Create(pos.left+3, pos.bottom-3, _create_info._folders, 0, _create_info._title, _big_icons, _create_info._creator, _create_info._info);
+ StartMenu::Create(pos.left+3, pos.bottom-3, _create_info._folders, 0, _create_info._title, _create_info._creator, _create_info._info);
CloseStartMenu();
}
@@ -391,7 +391,7 @@
if (_arrow_btns) {
RECT rect_up, rect_down;
- GetArrowButtonRects(&rect_up, &rect_down, _big_icons);
+ GetArrowButtonRects(&rect_up, &rect_down, _large_icons);
SCROLL_MODE scroll_mode = SCROLL_NOT;
@@ -515,7 +515,7 @@
int StartMenu::ButtonHitTest(POINT pt)
{
ClientRect clnt(_hwnd);
- const bool big_icons = _big_icons;
+ const bool large_icons = _large_icons;
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
if (pt.x<rect.left || pt.x>rect.right)
@@ -547,7 +547,7 @@
return;
ClientRect clnt(_hwnd);
- const bool big_icons = _big_icons;
+ const bool large_icons = _large_icons;
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
for(SMBtnVector::const_iterator it=_buttons.begin()+_scroll_pos; it!=_buttons.end(); ++it) {
@@ -773,7 +773,7 @@
{
#ifdef _LIGHT_STARTMENU
ClientRect clnt(_hwnd);
- const bool big_icons = _big_icons;
+ const bool large_icons = _large_icons;
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
for(SMBtnVector::const_iterator it=_buttons.begin()+_scroll_pos; it!=_buttons.end(); ++it) {
@@ -823,10 +823,10 @@
}
-void StartMenu::DrawArrows(HDC hdc, bool big_icons)
+void StartMenu::DrawArrows(HDC hdc, bool large_icons)
{
- int cx = big_icons? 16: 8;
- int cy = big_icons? 8: 4;
+ int cx = large_icons? 16: 8;
+ int cy = large_icons? 8: 4;
ResIconEx arrowUpIcon(IDI_ARROW_UP, cx, cy);
ResIconEx arrowDownIcon(IDI_ARROW_DOWN, cx, cy);
@@ -837,10 +837,10 @@
DrawIconEx(hdc, clnt.right/2-cx/2, clnt.bottom-cy-1, arrowDownIcon, cx, cy, 0, 0, DI_NORMAL);
}
-void StartMenu::GetArrowButtonRects(LPRECT prect_up, LPRECT prect_down, bool big_icons)
+void StartMenu::GetArrowButtonRects(LPRECT prect_up, LPRECT prect_down, bool large_icons)
{
- int cx = big_icons? 16: 8;
- int cy = big_icons? 8: 4;
+ int cx = large_icons? 16: 8;
+ int cy = large_icons? 8: 4;
GetClientRect(_hwnd, prect_up);
*prect_down = *prect_up;
@@ -865,10 +865,10 @@
#ifdef _LIGHT_STARTMENU
if (_arrow_btns)
- DrawArrows(canvas, _big_icons);
+ DrawArrows(canvas, _large_icons);
ClientRect clnt(_hwnd);
- const bool big_icons = _big_icons;
+ const bool large_icons = _large_icons;
RECT rect = {_border_left, _border_top, clnt.right, STARTMENU_LINE_HEIGHT};
int sep_width = rect.right-rect.left - 4;
@@ -900,7 +900,7 @@
break;
if (rect.top >= canvas.rcPaint.top)
- DrawStartMenuButton(canvas, rect, btn._title, btn, btn._id==_selected_id, false, _big_icons);
+ DrawStartMenuButton(canvas, rect, btn._title, btn, btn._id==_selected_id, false, _large_icons);
}
rect.top = rect.bottom;
@@ -930,11 +930,7 @@
Entry* entry = *it;
if (entry->_icon_id == ICID_UNKNOWN)
- try {
- entry->extract_icon(_big_icons);
- } catch(COMException&) {
- // ignore unexpected exceptions while extracting icons
- }
+ entry->_icon_id = entry->safe_extract_icon(_large_icons? ICF_LARGE: ICF_NORMAL);
if (entry->_icon_id > ICID_NONE) {
btn._icon_id = (ICON_ID)/*@@*/ entry->_icon_id;
@@ -947,7 +943,7 @@
break;
WindowCanvas canvas(_hwnd);
- DrawStartMenuButton(canvas, rect, NULL, btn, btn._id==_selected_id, false, _big_icons);
+ DrawStartMenuButton(canvas, rect, NULL, btn, btn._id==_selected_id, false, _large_icons);
//InvalidateRect(_hwnd, &rect, FALSE);
//UpdateWindow(_hwnd);
@@ -1266,7 +1262,7 @@
ClientToScreen(_hwnd, &rect);
x = rect.right; // Submenus should overlap their parent a bit.
- const bool big_icons = _big_icons;
+ const bool large_icons = _large_icons;
y = rect.top+STARTMENU_LINE_HEIGHT +_border_top/*own border*/ -STARTMENU_TOP_BTN_SPACE/*border of new submenu*/;
} else {
WindowRect pos(_hwnd);
@@ -1276,7 +1272,7 @@
}
_submenu_id = id;
- _submenu = StartMenu::Create(x, y, new_folders, _hwnd, title, _big_icons, creator, info, _create_info._filter);
+ _submenu = StartMenu::Create(x, y, new_folders, _hwnd, title, creator, info, _create_info._filter);
}
@@ -1368,10 +1364,10 @@
}
#ifdef _LIGHT_STARTMENU
-void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, const SMBtnInfo& btn, bool has_focus, bool pushed, bool big_icons)
+void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, const SMBtnInfo& btn, bool has_focus, bool pushed, bool large_icons)
#else
void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, HICON hIcon,
- bool hasSubmenu, bool enabled, bool has_focus, bool pushed, bool big_icons);
+ bool hasSubmenu, bool enabled, bool has_focus, bool pushed, bool large_icons);
#endif
{
UINT style = DFCS_BUTTONPUSH;
@@ -1404,7 +1400,7 @@
FillRect(hdc, &rect, bk_brush);
if (btn._icon_id > ICID_NONE)
- g_Globals._icon_cache.get_icon(btn._icon_id).draw(hdc, iconPos.x, iconPos.y, ICON_SIZE_X, ICON_SIZE_Y, bk_color, bk_brush/*, big_icons*/);
+ g_Globals._icon_cache.get_icon(btn._icon_id).draw(hdc, iconPos.x, iconPos.y, ICON_SIZE_X, ICON_SIZE_Y, bk_color, bk_brush/*, large_icons*/);
// draw submenu arrow at the right
if (btn._hasSubmenu) {
@@ -1438,7 +1434,7 @@
WindowCanvas canvas(_hwnd);
FontSelection font(canvas, GetStockFont(DEFAULT_GUI_FONT));
- const bool big_icons = _big_icons;
+ const bool large_icons = _large_icons;
int max_width = STARTMENU_WIDTH_MIN;
int height = 0;
@@ -1583,7 +1579,7 @@
}
-static void CalculateStartPos(HWND hwndOwner, RECT& rect, bool big_icons)
+static void CalculateStartPos(HWND hwndOwner, RECT& rect, bool large_icons)
{
WindowRect pos(hwndOwner);
@@ -1599,11 +1595,11 @@
AdjustWindowRectEx(&rect, WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, FALSE, 0);
}
-HWND StartMenuRoot::Create(HWND hwndOwner, bool big_icons)
+HWND StartMenuRoot::Create(HWND hwndOwner, bool large_icons)
{
RECT rect;
- CalculateStartPos(hwndOwner, rect, big_icons);
+ CalculateStartPos(hwndOwner, rect, large_icons);
[truncated at 1000 lines; 106 more skipped]