diff --git a/reactos/subsys/system/explorer/dialogs/searchprogram.cpp b/reactos/subsys/system/explorer/dialogs/searchprogram.cpp index a0d87c0edc5..c9c671be913 100644 --- a/reactos/subsys/system/explorer/dialogs/searchprogram.cpp +++ b/reactos/subsys/system/explorer/dialogs/searchprogram.cpp @@ -94,7 +94,7 @@ void CollectProgramsThread::free_dirs() FindProgramDlg::FindProgramDlg(HWND hwnd) : super(hwnd), _list_ctrl(GetDlgItem(hwnd, IDC_MAILS_FOUND)), - _himl(ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32, 0, 0)), + //_himl(ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32, 0, 0)), _thread(collect_programs_callback, hwnd, this), _sort(_list_ctrl, CompareFunc/*, (LPARAM)this*/) { @@ -107,8 +107,9 @@ FindProgramDlg::FindProgramDlg(HWND hwnd) _haccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_SEARCH_PROGRAM)); - ListView_SetImageList(_list_ctrl, _himl, LVSIL_SMALL); - _idxNoIcon = ImageList_AddIcon(_himl, SmallIcon(IDI_APPICON)); + ListView_SetImageList(_list_ctrl, g_Globals._icon_cache.get_sys_imagelist(), LVSIL_SMALL); + //ListView_SetImageList(_list_ctrl, _himl, LVSIL_SMALL); + //_idxNoIcon = ImageList_AddIcon(_himl, SmallIcon(IDI_APPICON)); LV_COLUMN column = {LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 250}; @@ -140,7 +141,7 @@ FindProgramDlg::FindProgramDlg(HWND hwnd) FindProgramDlg::~FindProgramDlg() { - ImageList_Destroy(_himl); + //ImageList_Destroy(_himl); } @@ -315,7 +316,7 @@ int FindProgramDlg::Notify(int id, NMHDR* pnmh) if (entry->_icon_id == ICID_UNKNOWN) entry->extract_icon(); - pDispInfo->item.iImage = ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(entry->_icon_id)._hIcon); //@@ directly use image list in icon cache + pDispInfo->item.iImage = g_Globals._icon_cache.get_icon(entry->_icon_id).get_sysiml_idx();//ImageList_AddIcon(_himl, g_Globals._icon_cache.get_icon(entry->_icon_id).get_hicon()); pDispInfo->item.mask |= LVIF_DI_SETITEM; return 1; diff --git a/reactos/subsys/system/explorer/dialogs/searchprogram.h b/reactos/subsys/system/explorer/dialogs/searchprogram.h index 4ce15c8d68b..b62f908a1bb 100644 --- a/reactos/subsys/system/explorer/dialogs/searchprogram.h +++ b/reactos/subsys/system/explorer/dialogs/searchprogram.h @@ -88,8 +88,8 @@ protected: CommonControlInit _usingCmnCtrl; HWND _list_ctrl; HACCEL _haccel; - HIMAGELIST _himl; - int _idxNoIcon; // replacement icon + //HIMAGELIST _himl; + //int _idxNoIcon; // replacement icon String _lwr_filter; CollectProgramsThread _thread; diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index d4a862da662..b3e32ca7955 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -126,31 +126,80 @@ const FileTypeInfo& FileTypeManager::operator[](String ext) Icon::Icon() : _id(ICID_UNKNOWN), _itype(IT_STATIC), - _hIcon(0) + _hicon(0) { } Icon::Icon(ICON_ID id, UINT nid) : _id(id), _itype(IT_STATIC), - _hIcon(SmallIcon(nid)) + _hicon(SmallIcon(nid)) { } Icon::Icon(ICON_TYPE itype, int id, HICON hIcon) : _id((ICON_ID)id), _itype(itype), - _hIcon(hIcon) + _hicon(hIcon) { } +Icon::Icon(ICON_TYPE itype, int id, int sys_idx) + : _id((ICON_ID)id), + _itype(itype), + _sys_idx(sys_idx) +{ +} + +void Icon::draw(HDC hdc, int x, int y, int cx, int cy, COLORREF bk_color, HBRUSH bk_brush) const +{ + if (_itype == IT_SYSCACHE) + ImageList_DrawEx(g_Globals._icon_cache.get_sys_imagelist(), _sys_idx, hdc, x, y, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL); + else + DrawIconEx(hdc, x, y, _hicon, cx, cy, 0, bk_brush, DI_NORMAL); +} + +HBITMAP Icon::create_bitmap(COLORREF bk_color, HBRUSH hbrBkgnd, HDC hdc_wnd) const +{ + if (_itype == IT_SYSCACHE) { + HIMAGELIST himl = g_Globals._icon_cache.get_sys_imagelist(); + + int cx, cy; + ImageList_GetIconSize(himl, &cx, &cy); + + HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, cx, cy); + HDC hdc = CreateCompatibleDC(hdc_wnd); + HBITMAP hbmp_old = SelectBitmap(hdc, hbmp); + ImageList_DrawEx(himl, _sys_idx, hdc, 0, 0, cx, cy, bk_color, CLR_DEFAULT, ILD_NORMAL); + SelectBitmap(hdc, hbmp_old); + DeleteDC(hdc); + return hbmp; + } else + return create_bitmap_from_icon(_hicon, hbrBkgnd, hdc_wnd); +} + +HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd) +{ + HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, 16, 16); + + MemCanvas canvas; + BitmapSelection sel(canvas, hbmp); + + RECT rect = {0, 0, 16, 16}; + FillRect(canvas, &rect, hbrush_bkgnd); + + DrawIconEx(canvas, 0, 0, hIcon, 16, 16, 0, hbrush_bkgnd, DI_NORMAL); + + return hbmp; +} + int IconCache::s_next_id = ICID_DYNAMIC; void IconCache::init() { - _icons[ICID_NONE] = Icon(IT_STATIC, ICID_NONE, 0); + _icons[ICID_NONE] = Icon(IT_STATIC, ICID_NONE, (HICON)0); _icons[ICID_FOLDER] = Icon(ICID_FOLDER, IDI_FOLDER); //_icons[ICID_DOCUMENT] = Icon(ICID_DOCUMENT, IDI_DOCUMENT); @@ -181,11 +230,20 @@ const Icon& IconCache::extract(const String& path) SHFILEINFO sfi; - if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON)) { //@@ besser SHGFI_SYSICONINDEX ? +#if 1 // use system image list + HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON); + + if (himlSys) { + _himlSys = himlSys; + + const Icon& icon = add(sfi.iIcon/*, IT_SYSCACHE*/); +#else + if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON)) { const Icon& icon = add(sfi.hIcon, IT_CACHED); +#endif ///@todo limit cache size - _pathMap[path] = icon._id; + _pathMap[path] = icon; return icon; } else @@ -210,7 +268,7 @@ const Icon& IconCache::extract(LPCTSTR path, int idx) if ((int)ExtractIconEx(path, idx, NULL, &hIcon, 1) > 0) { const Icon& icon = add(hIcon, IT_CACHED); - _pathIdxMap[key] = icon._id; + _pathIdxMap[key] = icon; return icon; } else @@ -242,16 +300,18 @@ const Icon& IconCache::add(HICON hIcon, ICON_TYPE type) return _icons[id] = Icon(type, id, hIcon); } +const Icon& IconCache::add(int sys_idx/*, ICON_TYPE type=IT_SYSCACHE*/) +{ + int id = ++s_next_id; + + return _icons[id] = SysCacheIcon(id, sys_idx); +} + const Icon& IconCache::get_icon(int id) { return _icons[id]; } -HBITMAP IconCache::get_icon_bitmap(int id, HBRUSH hbrBkgnd, HDC hdc) -{ - return create_bitmap_from_icon(_icons[id]._hIcon, hbrBkgnd, hdc); -} - void IconCache::free_icon(int icon_id) { IconMap::iterator found = _icons.find(icon_id); @@ -259,30 +319,12 @@ void IconCache::free_icon(int icon_id) if (found != _icons.end()) { Icon& icon = found->second; - if (icon._itype == IT_DYNAMIC) { - DestroyIcon(icon._hIcon); + if (icon.destroy()) _icons.erase(found); - } } } -HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd) -{ - HBITMAP hbmp = CreateCompatibleBitmap(hdc_wnd, 16, 16); - - MemCanvas canvas; - BitmapSelection sel(canvas, hbmp); - - RECT rect = {0, 0, 16, 16}; - FillRect(canvas, &rect, hbrush_bkgnd); - - DrawIconEx(canvas, 0, 0, hIcon, 16, 16, 0, hbrush_bkgnd, DI_NORMAL); - - return hbmp; -} - - ResString::ResString(UINT nid) { TCHAR buffer[BUFFER_LEN]; @@ -295,17 +337,17 @@ ResString::ResString(UINT nid) ResIcon::ResIcon(UINT nid) { - _hIcon = LoadIcon(g_Globals._hInstance, MAKEINTRESOURCE(nid)); + _hicon = LoadIcon(g_Globals._hInstance, MAKEINTRESOURCE(nid)); } SmallIcon::SmallIcon(UINT nid) { - _hIcon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); + _hicon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); } ResIconEx::ResIconEx(UINT nid, int w, int h) { - _hIcon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, w, h, LR_SHARED); + _hicon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, w, h, LR_SHARED); } diff --git a/reactos/subsys/system/explorer/globals.h b/reactos/subsys/system/explorer/globals.h index a5d559f3364..83340014eb7 100644 --- a/reactos/subsys/system/explorer/globals.h +++ b/reactos/subsys/system/explorer/globals.h @@ -44,7 +44,7 @@ enum ICON_TYPE { IT_STATIC, IT_CACHED, IT_DYNAMIC, - IT_SYSCACHE ///@todo + IT_SYSCACHE }; enum ICON_ID { @@ -73,16 +73,35 @@ enum ICON_ID { }; struct Icon { - ICON_ID _id; - ICON_TYPE _itype; - HICON _hIcon; - Icon(); Icon(ICON_ID id, UINT nid); Icon(ICON_TYPE itype, int id, HICON hIcon); + Icon(ICON_TYPE itype, int id, int sys_idx); + + operator ICON_ID() const {return _id;} + + void draw(HDC hdc, int x, int y, int cx, int cy, COLORREF bk_color, HBRUSH bk_brush) const; + HBITMAP create_bitmap(COLORREF bk_color, HBRUSH hbrBkgnd, HDC hdc_wnd) const; + + int get_sysiml_idx() const {return _itype==IT_SYSCACHE? _sys_idx: -1;} + + bool destroy() {if (_itype == IT_DYNAMIC) {DestroyIcon(_hicon); return true;} else return false;} + +protected: + ICON_ID _id; + ICON_TYPE _itype; + HICON _hicon; + int _sys_idx; +}; + +struct SysCacheIcon : public Icon { + SysCacheIcon(int id, int sys_idx) + : Icon(IT_SYSCACHE, id, sys_idx) {} }; struct IconCache { + IconCache() : _himlSys(0) {} + void init(); const Icon& extract(const String& path); @@ -90,9 +109,10 @@ struct IconCache { const Icon& extract(IExtractIcon* pExtract, LPCTSTR path, int idx); const Icon& add(HICON hIcon, ICON_TYPE type=IT_DYNAMIC); + const Icon& add(int sys_idx/*, ICON_TYPE type=IT_SYSCACHE*/); const Icon& get_icon(int icon_id); - HBITMAP get_icon_bitmap(int icon_id, HBRUSH hbrBkgnd, HDC hdc); + HIMAGELIST get_sys_imagelist() const {return _himlSys;} void free_icon(int icon_id); @@ -108,6 +128,8 @@ protected: typedef pair CachePair; typedef map PathIdxMap; PathIdxMap _pathIdxMap; + + HIMAGELIST _himlSys; }; @@ -151,10 +173,10 @@ struct ResIcon { ResIcon(UINT nid); - operator HICON() const {return _hIcon;} + operator HICON() const {return _hicon;} protected: - HICON _hIcon; + HICON _hicon; }; /// convenient loading of small (16x16) icon resources @@ -162,10 +184,10 @@ struct SmallIcon { SmallIcon(UINT nid); - operator HICON() const {return _hIcon;} + operator HICON() const {return _hicon;} protected: - HICON _hIcon; + HICON _hicon; }; /// convenient loading of icon resources with specified sizes @@ -173,10 +195,10 @@ struct ResIconEx { ResIconEx(UINT nid, int w, int h); - operator HICON() const {return _hIcon;} + operator HICON() const {return _hicon;} protected: - HICON _hIcon; + HICON _hicon; }; /// set big and small icons out of the resources for a window diff --git a/reactos/subsys/system/explorer/shell/entries.cpp b/reactos/subsys/system/explorer/shell/entries.cpp index 2731fedc57f..1e2a208e132 100644 --- a/reactos/subsys/system/explorer/shell/entries.cpp +++ b/reactos/subsys/system/explorer/shell/entries.cpp @@ -315,7 +315,7 @@ void Entry::extract_icon() ICON_ID icon_id = ICID_NONE; if (get_path(path)) - icon_id = g_Globals._icon_cache.extract(path)._id; + icon_id = g_Globals._icon_cache.extract(path); if (icon_id == ICID_NONE) { IExtractIcon* pExtract; @@ -325,12 +325,12 @@ void Entry::extract_icon() if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, MAX_PATH, &idx, &flags))) { if (flags & GIL_NOTFILENAME) - icon_id = g_Globals._icon_cache.extract(pExtract, path, idx)._id; + icon_id = g_Globals._icon_cache.extract(pExtract, path, idx); else { if (idx == -1) idx = 0; // special case for some control panel applications ("System") - icon_id = g_Globals._icon_cache.extract(path, idx)._id; + icon_id = g_Globals._icon_cache.extract(path, idx); } /* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets ("NVidia"). @@ -363,8 +363,13 @@ void Entry::extract_icon() const ShellPath& pidl_abs = create_absolute_pidl(); LPCITEMIDLIST pidl = pidl_abs; - if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|SHGFI_SMALLICON)) //@@ besser SHGFI_SYSICONINDEX ? + HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON); + if (himlSys) + icon_id = g_Globals._icon_cache.add(sfi.iIcon); + /* + if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|SHGFI_SMALLICON)) icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id; + */ } } diff --git a/reactos/subsys/system/explorer/shell/pane.cpp b/reactos/subsys/system/explorer/shell/pane.cpp index 2c72d806053..3ba2a16d952 100644 --- a/reactos/subsys/system/explorer/shell/pane.cpp +++ b/reactos/subsys/system/explorer/shell/pane.cpp @@ -502,7 +502,7 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol) cx = IMAGE_WIDTH; if (entry->_icon_id > ICID_NONE) - DrawIconEx(dis->hDC, img_pos, dis->rcItem.top, g_Globals._icon_cache.get_icon(entry->_icon_id)._hIcon, cx, GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL); + g_Globals._icon_cache.get_icon(entry->_icon_id).draw(dis->hDC, img_pos, dis->rcItem.top, cx, GetSystemMetrics(SM_CYSMICON), bkcolor, 0); else ImageList_DrawEx(_himl, img, dis->hDC, img_pos, dis->rcItem.top, cx, diff --git a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp index c5db7a52c09..25211354550 100644 --- a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp +++ b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp @@ -113,6 +113,9 @@ void QuickLaunchBar::AddShortcuts() ShellFolder desktop_folder; WindowCanvas canvas(_hwnd); + COLORREF bk_color = GetSysColor(COLOR_BTNFACE); + HBRUSH bk_brush = GetSysColorBrush(COLOR_BTNFACE); + TBBUTTON btn = {0, 0, TBSTATE_ENABLED, BTNS_BUTTON|BTNS_NOPREFIX, {0, 0}, 0, 0}; for(Entry*entry=_dir->_down; entry; entry=entry->_next) { @@ -122,7 +125,7 @@ void QuickLaunchBar::AddShortcuts() // hide subfolders if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - HBITMAP hbmp = g_Globals._icon_cache.get_icon_bitmap(entry->_icon_id, GetSysColorBrush(COLOR_BTNFACE), canvas); + HBITMAP hbmp = g_Globals._icon_cache.get_icon(entry->_icon_id).create_bitmap(bk_color, bk_brush, canvas); TBADDBITMAP ab = {0, (UINT_PTR)hbmp}; int bmp_idx = SendMessage(_hwnd, TB_ADDBITMAP, 1, (LPARAM)&ab); diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index b3428c466d1..a89f7e9c34e 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -1117,21 +1117,22 @@ void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, HICON hIcon, ++textRect.right; ++textRect.bottom; } - int bk_color = COLOR_BTNFACE; - int text_color = COLOR_BTNTEXT; + int bk_color_idx = COLOR_BTNFACE; + int text_color_idx = COLOR_BTNTEXT; if (has_focus) { - bk_color = COLOR_HIGHLIGHT; - text_color = COLOR_HIGHLIGHTTEXT; + bk_color_idx = COLOR_HIGHLIGHT; + text_color_idx = COLOR_HIGHLIGHTTEXT; } - HBRUSH bk_brush = GetSysColorBrush(bk_color); + COLORREF bk_color = GetSysColor(bk_color_idx); + HBRUSH bk_brush = GetSysColorBrush(bk_color_idx); if (title) FillRect(hdc, &rect, bk_brush); if (btn._icon_id > ICID_NONE) - DrawIconEx(hdc, iconPos.x, iconPos.y, g_Globals._icon_cache.get_icon(btn._icon_id)._hIcon, 16, 16, 0, bk_brush, DI_NORMAL); + g_Globals._icon_cache.get_icon(btn._icon_id).draw(hdc, iconPos.x, iconPos.y, 16, 16, bk_color, bk_brush); // draw submenu arrow at the right if (btn._hasSubmenu) { @@ -1149,7 +1150,7 @@ void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, HICON hIcon, if (!btn._enabled) // dis->itemState & (ODS_DISABLED|ODS_GRAYED) DrawGrayText(hdc, &textRect, title, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER); else { - TextColor lcColor(hdc, GetSysColor(text_color)); + TextColor lcColor(hdc, GetSysColor(text_color_idx)); DrawText(hdc, title, -1, &textRect, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER); } }