From 3073e11cf8b8c8184acb5ad043e40916d9a9b4e5 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sun, 4 Jan 2004 17:11:53 +0000 Subject: [PATCH] icon caching svn path=/trunk/; revision=7450 --- .../system/explorer/dialogs/searchprogram.cpp | 26 ++- .../subsys/system/explorer/doc/changes.txt | 1 + .../subsys/system/explorer/doxy-footer.html | 2 +- reactos/subsys/system/explorer/explorer.cpp | 166 +++++++++++++++++- .../subsys/system/explorer/explorer_intres.h | 4 +- reactos/subsys/system/explorer/globals.h | 78 +++++++- .../subsys/system/explorer/shell/entries.cpp | 82 ++++++++- .../subsys/system/explorer/shell/entries.h | 4 +- reactos/subsys/system/explorer/shell/pane.cpp | 4 +- .../subsys/system/explorer/shell/shellfs.cpp | 141 ++------------- .../subsys/system/explorer/shell/shellfs.h | 21 +-- .../system/explorer/taskbar/quicklaunch.cpp | 3 +- .../system/explorer/taskbar/startmenu.cpp | 96 +++++----- .../system/explorer/taskbar/startmenu.h | 22 +-- .../system/explorer/taskbar/taskbar.cpp | 16 +- .../subsys/system/explorer/utility/utility.h | 3 - .../subsys/system/explorer/utility/window.cpp | 12 -- .../subsys/system/explorer/utility/window.h | 14 +- 18 files changed, 425 insertions(+), 270 deletions(-) diff --git a/reactos/subsys/system/explorer/dialogs/searchprogram.cpp b/reactos/subsys/system/explorer/dialogs/searchprogram.cpp index 98400cf742d..a0d87c0edc5 100644 --- a/reactos/subsys/system/explorer/dialogs/searchprogram.cpp +++ b/reactos/subsys/system/explorer/dialogs/searchprogram.cpp @@ -60,7 +60,7 @@ void CollectProgramsThread::collect_programs(const ShellPath& path) ShellDirectory* dir = new ShellDirectory(Desktop(), path, 0); _dirs.push(dir); - dir->smart_scan(SCAN_EXTRACT_ICONS|SCAN_FILESYSTEM); + dir->smart_scan(/*SCAN_EXTRACT_ICONS|*/SCAN_FILESYSTEM); for(Entry*entry=dir->_down; entry; entry=entry->_next) { if (!_alive) @@ -70,10 +70,7 @@ void CollectProgramsThread::collect_programs(const ShellPath& path) continue; if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - ShellPath shell_path; - - if (get_entry_pidl(entry, shell_path)) - collect_programs(shell_path); + collect_programs(entry->create_absolute_pidl()); } else if (entry->_shell_attribs & SFGAO_LINK) if (_alive) _callback(entry, _para); @@ -212,11 +209,7 @@ void FindProgramDlg::collect_programs_callback(Entry* entry, void* param) new_entry._entry = entry; new_entry._menu_path = menu_path; new_entry._path = path; - - if (entry->_hIcon != (HICON)-1) - new_entry._idxIcon = ImageList_AddIcon(pThis->_himl, entry->_hIcon); - else - new_entry._idxIcon = pThis->_idxNoIcon; + new_entry._idxIcon = I_IMAGECALLBACK; pThis->_cache.push_front(new_entry); FPDEntry& cache_entry = pThis->_cache.front(); @@ -311,22 +304,23 @@ void FindProgramDlg::LaunchSelected() int FindProgramDlg::Notify(int id, NMHDR* pnmh) { switch(pnmh->code) { - case LVN_GETDISPINFO: {/* + case LVN_GETDISPINFO: { LV_DISPINFO* pDispInfo = (LV_DISPINFO*) pnmh; if (pnmh->hwndFrom == _list_ctrl) { if (pDispInfo->item.mask & LVIF_IMAGE) { - int icon; - HRESULT hr = pShellLink->GetIconLocation(path, MAX_PATH-1, &icon); + FPDEntry& cache_entry = *(FPDEntry*)pDispInfo->item.lParam; + Entry* entry = cache_entry._entry; - HICON hIcon = ExtractIcon(); - pDispInfo->item.iImage = ImageList_AddIcon(_himl, hIcon); + 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.mask |= LVIF_DI_SETITEM; return 1; } - }*/} + }} break; case NM_DBLCLK: diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index a47bc88eccc..4ab47ca2f4e 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -53,3 +53,4 @@ If you search for more information, look into the CVS repository. 02.01.2004 m. fuchs reimplemented start menu as light weight version 03.01.2004 m. fuchs lazy icon extraction for start menu direct file system access for start menu +04.01.2004 m. fuchs implemented icon cache diff --git a/reactos/subsys/system/explorer/doxy-footer.html b/reactos/subsys/system/explorer/doxy-footer.html index 89fcacec46c..91095f191a8 100644 --- a/reactos/subsys/system/explorer/doxy-footer.html +++ b/reactos/subsys/system/explorer/doxy-footer.html @@ -3,7 +3,7 @@
ROS Explorer Source Code Documentation -
generated on 03.01.2004 by +
generated on 04.01.2004 by
doxygen
diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index de2b16e9161..6a51376129d 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -67,6 +67,18 @@ ExplorerGlobals::ExplorerGlobals() } +void ExplorerGlobals::init(HINSTANCE hInstance) +{ + _hInstance = hInstance; + +#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) + _SHRestricted = (DWORD(STDAPICALLTYPE*)(RESTRICTIONS)) GetProcAddress(GetModuleHandle(TEXT("SHELL32")), "SHRestricted"); +#endif + + _icon_cache.init(); +} + + void _log_(LPCTSTR txt) { FmtString msg(TEXT("%s\n"), txt); @@ -81,7 +93,7 @@ void _log_(LPCTSTR txt) const FileTypeInfo& FileTypeManager::operator[](String ext) { #ifndef __WINE__ ///@todo - _tcslwr((LPTSTR)ext.data()); + _tcslwr((LPTSTR)ext.c_str()); #endif iterator found = find(ext); @@ -111,6 +123,153 @@ const FileTypeInfo& FileTypeManager::operator[](String ext) } +Icon::Icon() + : _id(ICID_UNKNOWN), + _itype(IT_STATIC), + _hIcon(0) +{ +} + +Icon::Icon(ICON_ID id, UINT nid) + : _id(id), + _itype(IT_STATIC), + _hIcon(SmallIcon(nid)) +{ +} + +Icon::Icon(ICON_TYPE itype, int id, HICON hIcon) + : _id((ICON_ID)id), + _itype(itype), + _hIcon(hIcon) +{ +} + + +int IconCache::s_next_id = ICID_DYNAMIC; + + +void IconCache::init() +{ + _icons[ICID_NONE] = Icon(IT_STATIC, ICID_NONE, 0); + + _icons[ICID_FOLDER] = Icon(ICID_FOLDER, IDI_FOLDER); + //_icons[ICID_DOCUMENT] = Icon(ICID_DOCUMENT, IDI_DOCUMENT); + _icons[ICID_EXPLORER] = Icon(ICID_EXPLORER, IDI_EXPLORER); + _icons[ICID_APP] = Icon(ICID_APP, IDI_APPICON); + + _icons[ICID_CONFIG] = Icon(ICID_CONFIG, IDI_CONFIG); + _icons[ICID_DOCUMENTS] = Icon(ICID_DOCUMENTS, IDI_DOCUMENTS); + _icons[ICID_FAVORITES] = Icon(ICID_FAVORITES, IDI_FAVORITES); + _icons[ICID_INFO] = Icon(ICID_INFO, IDI_INFO); + _icons[ICID_APPS] = Icon(ICID_APPS, IDI_APPS); + _icons[ICID_SEARCH] = Icon(ICID_SEARCH, IDI_SEARCH); + _icons[ICID_ACTION] = Icon(ICID_ACTION, IDI_ACTION); + _icons[ICID_SEARCH_DOC] = Icon(ICID_SEARCH_DOC, IDI_SEARCH_DOC); + _icons[ICID_PRINTER] = Icon(ICID_PRINTER, IDI_PRINTER); + _icons[ICID_NETWORK] = Icon(ICID_NETWORK, IDI_NETWORK); + _icons[ICID_COMPUTER] = Icon(ICID_COMPUTER, IDI_COMPUTER); + _icons[ICID_LOGOFF] = Icon(ICID_LOGOFF, IDI_LOGOFF); +} + + +const Icon& IconCache::extract(IExtractIcon* pExtract, LPCTSTR path, int idx) +{ + HICON hIconLarge = 0; + HICON hIcon; + + HRESULT hr = pExtract->Extract(path, idx, &hIconLarge, &hIcon, MAKELONG(0/*GetSystemMetrics(SM_CXICON)*/,GetSystemMetrics(SM_CXSMICON))); + + if (hr == NOERROR) { + if (hIconLarge) + DestroyIcon(hIconLarge); + + if (hIcon) + return add(hIcon); + } + + return _icons[ICID_NONE]; +} + +const Icon& IconCache::extract_from_file(LPCTSTR path, int idx) +{ + CachePair key(path, idx); + +#ifndef __WINE__ ///@todo + _tcslwr((LPTSTR)key.first.c_str()); +#endif + + CacheMap::iterator found = _cache_map.find(key); + + if (found != _cache_map.end()) + return _icons[found->second]; + + HICON hIcon; + + if ((int)ExtractIconEx(path, idx, NULL, &hIcon, 1) > 0) { + const Icon& icon = add_cached(hIcon, path, idx); + + _cache_map[key] = icon._id; + + return icon; + } else + return _icons[ICID_NONE]; +} + +const Icon& IconCache::add(HICON hIcon) +{ + int id = ++s_next_id; + + return _icons[id] = Icon(IT_DYNAMIC, id, hIcon); +} + +const Icon& IconCache::add_cached(HICON hIcon, LPCTSTR path, int idx) +{ + int id = ++s_next_id; + + return _icons[id] = Icon(IT_CACHED, id, hIcon); +} + +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); + + if (found != _icons.end()) { + Icon& icon = found->second; + + if (icon._itype == IT_DYNAMIC) { + DestroyIcon(icon._hIcon); + _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]; @@ -394,10 +553,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL initialize_gdb_stub(); } - g_Globals._hInstance = hInstance; -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) - g_Globals._SHRestricted = (DWORD(STDAPICALLTYPE*)(RESTRICTIONS)) GetProcAddress(GetModuleHandle(TEXT("SHELL32")), "SHRestricted"); -#endif + g_Globals.init(hInstance); // initialize COM and OLE before creating the desktop window OleInit usingCOM; diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index fd2e8c78d87..50c3789938d 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -54,8 +54,8 @@ #define IDI_FLOATING 135 #define IDD_ABOUT_EXPLORER 135 #define IDI_REACTOS_BIG 137 -#define IDI_CONFIG 138 -#define IDI_DOCUMENTS 139 +#define IDI_DOCUMENTS 138 +#define IDI_CONFIG 139 #define IDI_FAVORITES 140 #define IDI_INFO 141 #define IDI_APPS 142 diff --git a/reactos/subsys/system/explorer/globals.h b/reactos/subsys/system/explorer/globals.h index 587cd8cfa81..601466c53d9 100644 --- a/reactos/subsys/system/explorer/globals.h +++ b/reactos/subsys/system/explorer/globals.h @@ -40,11 +40,86 @@ struct FileTypeManager : public map }; - /// structure containing global variable of Explorer +enum ICON_TYPE { + IT_STATIC, + IT_CACHED, + IT_DYNAMIC, + IT_SYSCACHE +}; + +enum ICON_ID { + ICID_UNKNOWN, + ICID_NONE, + + ICID_FOLDER, + //ICID_DOCUMENT, + ICID_APP, + ICID_EXPLORER, + + ICID_CONFIG, + ICID_DOCUMENTS, + ICID_FAVORITES, + ICID_INFO, + ICID_APPS, + ICID_SEARCH, + ICID_ACTION, + ICID_SEARCH_DOC, + ICID_PRINTER, + ICID_NETWORK, + ICID_COMPUTER, + ICID_LOGOFF, + + ICID_DYNAMIC +}; + +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); +}; + +struct IconCache { + void init(); + + const Icon& extract(IExtractIcon* pExtract, LPCTSTR path, int idx); + const Icon& extract_from_file(LPCTSTR path, int idx); + + const Icon& add(HICON hIcon); + const Icon& add_cached(HICON hIcon, LPCTSTR path, int idx); + + const Icon& get_icon(int icon_id); + HBITMAP get_icon_bitmap(int icon_id, HBRUSH hbrBkgnd, HDC hdc); + + void free_icon(int icon_id); + +protected: + typedef map IconMap; + + typedef pair CachePair; + typedef map CacheMap; + + static int s_next_id; + + IconMap _icons; + CacheMap _cache_map; +}; + + + /// create a bitmap from an icon +extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd); + + + /// structure containing global variables of Explorer extern struct ExplorerGlobals { ExplorerGlobals(); + void init(HINSTANCE hInstance); + HINSTANCE _hInstance; ATOM _hframeClass; UINT _cfStrFName; @@ -59,6 +134,7 @@ extern struct ExplorerGlobals #endif FileTypeManager _ftype_mgr; + IconCache _icon_cache; } g_Globals; diff --git a/reactos/subsys/system/explorer/shell/entries.cpp b/reactos/subsys/system/explorer/shell/entries.cpp index 55e6af338a2..bc50fecd668 100644 --- a/reactos/subsys/system/explorer/shell/entries.cpp +++ b/reactos/subsys/system/explorer/shell/entries.cpp @@ -44,7 +44,7 @@ Entry::Entry(ENTRY_TYPE etype) _scanned = false; _bhfi_valid = false; _level = 0; - _hIcon = 0; + _icon_id = ICID_UNKNOWN; _display_name = _data.cFileName; } @@ -58,7 +58,7 @@ Entry::Entry(Entry* parent, ENTRY_TYPE etype) _scanned = false; _bhfi_valid = false; _level = 0; - _hIcon = 0; + _icon_id = ICID_UNKNOWN; _display_name = _data.cFileName; } @@ -82,7 +82,7 @@ Entry::Entry(const Entry& other) _display_name = other._display_name==other._data.cFileName? _data.cFileName: _tcsdup(other._display_name); _etype = other._etype; - _hIcon = other._hIcon; + _icon_id = other._icon_id; _bhfi = other._bhfi; _bhfi_valid = other._bhfi_valid; @@ -91,8 +91,8 @@ Entry::Entry(const Entry& other) // free a directory entry Entry::~Entry() { - if (_hIcon && _hIcon!=(HICON)-1) - DestroyIcon(_hIcon); + if (_icon_id > ICID_NONE) + g_Globals._icon_cache.free_icon(_icon_id); if (_display_name != _data.cFileName) free(_display_name); @@ -295,6 +295,78 @@ void Entry::smart_scan(int scan_flags) } +ShellPath Entry::create_absolute_pidl() const +{ + CONTEXT("Entry::create_absolute_pidl()"); + + TCHAR path[MAX_PATH]; + + if (get_path(path)) + return ShellPath(path); + + return ShellPath(); +} + + +void Entry::extract_icon() +{ + ICON_ID icon_id = ICID_NONE; + + IExtractIcon* pExtract; + if (SUCCEEDED(GetUIObjectOf(0, IID_IExtractIcon, (LPVOID*)&pExtract))) { + TCHAR path[MAX_PATH]; + unsigned flags; + int idx; + + 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; + else { + if (idx == -1) + idx = 0; // special case for some control panel applications ("System") + + icon_id = g_Globals._icon_cache.extract_from_file(path, idx)._id; + } + +/* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets ("NVidia"). + 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; + + 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 (icon_id == ICID_NONE) { + SHFILEINFO sfi; + + 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 ? + icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id; + } + + _icon_id = icon_id; +} + + BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow) { TCHAR cmd[MAX_PATH]; diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h index 75a08acfeba..fab8fb51668 100644 --- a/reactos/subsys/system/explorer/shell/entries.h +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -75,7 +75,7 @@ public: LPTSTR _display_name; ENTRY_TYPE _etype; - HICON _hIcon; + int /*ICON_ID*/ _icon_id; BY_HANDLE_FILE_INFORMATION _bhfi; bool _bhfi_valid; @@ -86,11 +86,13 @@ public: 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(); virtual void read_directory(int scan_flags=SCAN_ALL) {} virtual const void* get_next_path_component(const void*) {return NULL;} virtual Entry* find_entry(const void*) {return NULL;} virtual bool get_path(PTSTR path) const = 0; + virtual ShellPath create_absolute_pidl() const; virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); }; diff --git a/reactos/subsys/system/explorer/shell/pane.cpp b/reactos/subsys/system/explorer/shell/pane.cpp index 4a700b1f7e9..2c72d806053 100644 --- a/reactos/subsys/system/explorer/shell/pane.cpp +++ b/reactos/subsys/system/explorer/shell/pane.cpp @@ -501,8 +501,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol) if (cx > IMAGE_WIDTH) cx = IMAGE_WIDTH; - if (entry->_hIcon && entry->_hIcon!=(HICON)-1) - DrawIconEx(dis->hDC, img_pos, dis->rcItem.top, entry->_hIcon, cx, GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL); + 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); else ImageList_DrawEx(_himl, img, dis->hDC, img_pos, dis->rcItem.top, cx, diff --git a/reactos/subsys/system/explorer/shell/shellfs.cpp b/reactos/subsys/system/explorer/shell/shellfs.cpp index 76034466f6d..55963d13577 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.cpp +++ b/reactos/subsys/system/explorer/shell/shellfs.cpp @@ -121,10 +121,7 @@ ShellPath ShellEntry::create_absolute_pidl() const if (dir->_pidl->mkid.cb) // Caching of absolute PIDLs could enhance performance. return _pidl.create_absolute_pidl(dir->create_absolute_pidl()); } else { - ShellPath shell_path; - - if (get_entry_pidl(_up, shell_path)) - return _pidl.create_absolute_pidl(shell_path); + return _pidl.create_absolute_pidl(_up->create_absolute_pidl()); } return _pidl; @@ -151,14 +148,6 @@ bool ShellEntry::get_path(PTSTR path) const } -HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut) -{ - LPCITEMIDLIST pidl = _pidl; - - return get_parent_folder()->GetUIObjectOf(hWnd, 1, &pidl, riid, NULL, ppvOut); -} - - // get full path of a shell folder bool ShellDirectory::get_path(PTSTR path) const { @@ -211,100 +200,11 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow) } -static HICON extract_icon(IShellFolder* folder, LPCITEMIDLIST pidl) +HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut) { - CONTEXT("extract_icon()"); + LPCITEMIDLIST pidl = _pidl; - IExtractIcon* pExtract; - - if (SUCCEEDED(folder->GetUIObjectOf(0, 1, (LPCITEMIDLIST*)&pidl, IID_IExtractIcon, 0, (LPVOID*)&pExtract))) { - TCHAR path[MAX_PATH]; - unsigned flags; - HICON hIcon; - int idx; - - if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, MAX_PATH, &idx, &flags))) { - if (!(flags & GIL_NOTFILENAME)) { - if (idx == -1) - idx = 0; // special case for some control panel applications - - if ((int)ExtractIconEx(path, idx, 0, &hIcon, 1) > 0) - flags &= ~GIL_DONTCACHE; - } else { - HICON hIconLarge = 0; - - HRESULT hr = pExtract->Extract(path, idx, &hIconLarge, &hIcon, MAKELONG(0/*GetSystemMetrics(SM_CXICON)*/,GetSystemMetrics(SM_CXSMICON))); - - if (SUCCEEDED(hr)) - DestroyIcon(hIconLarge); - } - - if (!hIcon) { - SHFILEINFO sfi; - - if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON)) - hIcon = sfi.hIcon; - } -/* - if (!hIcon) { - LPBYTE b = (LPBYTE) alloca(0x10000); - SHFILEINFO sfi; - - FILE* file = fopen(path, "rb"); - if (file) { - int l = fread(b, 1, 0x10000, file); - fclose(file); - - if (l) - hIcon = CreateIconFromResourceEx(b, l, TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR); - } - } -*/ - return hIcon; - } - } - - return 0; -} - -static HICON extract_icon(IShellFolder* folder, const ShellEntry* entry) -{ - HICON hIcon = extract_icon(folder, entry->_pidl); - - if (!hIcon) { - SHFILEINFO sfi; - - ShellPath pidl_abs = entry->create_absolute_pidl(); - LPCITEMIDLIST pidl = pidl_abs; - - if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|SHGFI_SMALLICON)) - hIcon = sfi.hIcon; - } - - return hIcon; -} - -HICON extract_icon(const Entry* entry) -{ - if (entry->_etype == ET_SHELL) { - const ShellEntry* shell_entry = static_cast(entry); - - return extract_icon(shell_entry->get_parent_folder(), shell_entry); - } else { - TCHAR path[MAX_PATH]; - - if (entry->get_path(path)) { - SHFILEINFO sfi; - - ShellPath shell_path(path); - LPCITEMIDLIST pidl = shell_path; - - if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|SHGFI_SMALLICON)) - return sfi.hIcon; - } - } - - return 0; + return get_parent_folder()->GetUIObjectOf(hWnd, 1, &pidl, riid, NULL, ppvOut); } @@ -361,15 +261,10 @@ void ShellDirectory::read_directory(int scan_flags) memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - if (scan_flags & SCAN_EXTRACT_ICONS) { - entry->_hIcon = extract_icon(entry); - - if (!entry->_hIcon) - entry->_hIcon = (HICON)-1; // don't try again later - } else - entry->_hIcon = 0; + if (scan_flags & SCAN_EXTRACT_ICONS) + entry->extract_icon(); } else - entry->_hIcon = (HICON)-1; // don't try again later + entry->_icon_id = ICID_NONE; // don't try again later entry->_down = NULL; entry->_expanded = false; @@ -510,15 +405,10 @@ void ShellDirectory::read_directory(int scan_flags) // get icons for files and virtual objects if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || !(attribs & SFGAO_FILESYSTEM)) { - if (scan_flags & SCAN_EXTRACT_ICONS) { - entry->_hIcon = extract_icon(_folder, static_cast(entry)); - - if (!entry->_hIcon) - entry->_hIcon = (HICON)-1; // don't try again later - } else - entry->_hIcon = 0; + if (scan_flags & SCAN_EXTRACT_ICONS) + entry->extract_icon(); } else - entry->_hIcon = (HICON)-1; // don't try again later + entry->_icon_id = ICID_NONE; // don't try again later entry->_down = NULL; entry->_expanded = false; @@ -575,16 +465,13 @@ int ShellDirectory::extract_icons() int cnt = 0; for(Entry*entry=_down; entry; entry=entry->_next) - if (!entry->_hIcon) { - if (entry->_etype == ET_SHELL) - entry->_hIcon = extract_icon(_folder, static_cast(entry)); - else // !ET_SHELL - entry->_hIcon = extract_icon(entry); + if (entry->_icon_id == ICID_UNKNOWN) { + entry->extract_icon(); - if (entry->_hIcon) + if (entry->_icon_id != ICID_NONE) ++cnt; else - entry->_hIcon = (HICON)-1; // don't try again later + entry->_icon_id = ICID_NONE; // don't try again later } return cnt; diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h index 5a009fc1baa..0a189910596 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.h +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -33,11 +33,11 @@ struct ShellEntry : public Entry ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {} virtual bool get_path(PTSTR path) const; + virtual ShellPath create_absolute_pidl() const; virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); IShellFolder* get_parent_folder() const; - ShellPath create_absolute_pidl() const; ShellPath _pidl; // parent relative PIDL @@ -46,23 +46,6 @@ protected: ShellEntry(const ShellPath& shell_path) : Entry(ET_SHELL), _pidl(shell_path) {} }; -bool inline get_entry_pidl(Entry* entry, ShellPath& shell_path) -{ - if (entry->_etype == ET_SHELL) { - shell_path = static_cast(entry)->create_absolute_pidl(); - return true; - } else { - TCHAR path[MAX_PATH]; - - if (!entry->get_path(path)) - return false; - - shell_path = path; - - return true; - } -} - /// shell folder entry struct ShellDirectory : public ShellEntry, public Directory @@ -138,5 +121,3 @@ inline IShellFolder* ShellEntry::get_parent_folder() const else return Desktop(); } - -extern HICON extract_icon(const Entry* entry); diff --git a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp index 2b857e093c4..b2dbb351432 100644 --- a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp +++ b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp @@ -29,6 +29,7 @@ #include "../utility/utility.h" #include "../explorer.h" +#include "../globals.h" #include "quicklaunch.h" @@ -120,7 +121,7 @@ void QuickLaunchBar::AddShortcuts() // hide subfolders if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - HBITMAP hbmp = create_bitmap_from_icon(entry->_hIcon, GetSysColorBrush(COLOR_BTNFACE), canvas); + HBITMAP hbmp = g_Globals._icon_cache.get_icon_bitmap(entry->_icon_id, GetSysColorBrush(COLOR_BTNFACE), 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 4d2e160d279..706ffc82af5 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -162,7 +162,7 @@ LRESULT StartMenu::Init(LPCREATESTRUCT pcs) #else if (!GetWindow(_hwnd, GW_CHILD)) #endif - AddButton(ResString(IDS_EMPTY), 0, false, 0, false); + AddButton(ResString(IDS_EMPTY), ICID_NONE, false, 0, false); #ifdef _LIGHT_STARTMENU ResizeToButtons(); @@ -431,6 +431,7 @@ void StartMenu::SelectButton(int id) // automatically open submenus if (btn->_hasSubmenu) { + //@@ allows destroying of startmenu when processing PM_UPDATE_ICONS -> GPF UpdateWindow(_hwnd); // draw focused button before waiting on submenu creation Command(_selected_id, BN_CLICKED); } else @@ -548,19 +549,19 @@ void StartMenu::UpdateIcons(/*int idx*/) for(; idx<(int)_buttons.size(); ++idx) { SMBtnInfo& btn = _buttons[idx]; - if (!btn._hIcon && btn._id>0) { + if (btn._icon_id==ICID_UNKNOWN && btn._id>0) { StartMenuEntry& sme = _entries[btn._id]; - btn._hIcon = (HICON)-1; + btn._icon_id = ICID_NONE; for(ShellEntrySet::iterator it=sme._entries.begin(); it!=sme._entries.end(); ++it) { Entry* entry = *it; - HICON hIcon = extract_icon(entry); + if (entry->_icon_id == ICID_UNKNOWN) + entry->extract_icon(); - if (hIcon) { - btn._hIcon = hIcon; - entry->_hIcon = hIcon; + if (entry->_icon_id > ICID_NONE) { + btn._icon_id = (ICON_ID)/*@@*/ entry->_icon_id; RECT rect; @@ -674,7 +675,7 @@ int StartMenu::Command(int id, int code) } -StartMenuEntry& StartMenu::AddEntry(const String& title, HICON hIcon, Entry* entry) +StartMenuEntry& StartMenu::AddEntry(const String& title, ICON_ID icon_id, Entry* entry) { // search for an already existing subdirectory entry with the same name if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) @@ -691,14 +692,14 @@ StartMenuEntry& StartMenu::AddEntry(const String& title, HICON hIcon, Entry* ent } } - StartMenuEntry& sme = AddEntry(title, hIcon); + StartMenuEntry& sme = AddEntry(title, icon_id); sme._entries.insert(entry); return sme; } -StartMenuEntry& StartMenu::AddEntry(const String& title, HICON hIcon, int id) +StartMenuEntry& StartMenu::AddEntry(const String& title, ICON_ID icon_id, int id) { if (id == -1) id = ++_next_id; @@ -706,36 +707,40 @@ StartMenuEntry& StartMenu::AddEntry(const String& title, HICON hIcon, int id) StartMenuEntry& sme = _entries[id]; sme._title = title; - sme._hIcon = hIcon; + sme._icon_id = icon_id; return sme; } StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, ShellEntry* entry) { - HICON hIcon = entry->_hIcon; + ICON_ID icon_id; if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - hIcon = SmallIcon(IDI_FOLDER); + icon_id = ICID_FOLDER; + else + icon_id = (ICON_ID)/*@@*/ entry->_icon_id; - return AddEntry(folder.get_name(entry->_pidl), hIcon, entry); + return AddEntry(folder.get_name(entry->_pidl), icon_id, entry); } StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, Entry* entry) { - HICON hIcon = entry->_hIcon; + ICON_ID icon_id; if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - hIcon = SmallIcon(IDI_FOLDER); + icon_id = ICID_FOLDER; + else + icon_id = (ICON_ID)/*@@*/ entry->_icon_id; - return AddEntry(entry->_display_name, hIcon, entry); + return AddEntry(entry->_display_name, icon_id, entry); } -void StartMenu::AddButton(LPCTSTR title, HICON hIcon, bool hasSubmenu, int id, bool enabled) +void StartMenu::AddButton(LPCTSTR title, ICON_ID icon_id, bool hasSubmenu, int id, bool enabled) { #ifdef _LIGHT_STARTMENU - _buttons.push_back(SMBtnInfo(title, hIcon, id, hasSubmenu, enabled)); + _buttons.push_back(SMBtnInfo(title, icon_id, id, hasSubmenu, enabled)); #else DWORD style = enabled? WS_VISIBLE|WS_CHILD|BS_OWNERDRAW: WS_VISIBLE|WS_CHILD|BS_OWNERDRAW|WS_DISABLED; @@ -764,14 +769,14 @@ void StartMenu::AddButton(LPCTSTR title, HICON hIcon, bool hasSubmenu, int id, b MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); StartMenuCtrl(_hwnd, _border_left, clnt.bottom, rect.right-rect.left-_border_left, - title, id, hIcon, hasSubmenu, style); + title, id, g_Globals._icon_cache.get_icon(icon_id)._hIcon, hasSubmenu, style); #endif } void StartMenu::AddSeparator() { #ifdef _LIGHT_STARTMENU - _buttons.push_back(SMBtnInfo(NULL, 0, -1, false)); + _buttons.push_back(SMBtnInfo(NULL, ICID_NONE, -1, false)); #else WindowRect rect(_hwnd); ClientRect clnt(_hwnd); @@ -888,7 +893,7 @@ void StartMenu::ActivateEntry(int id, const ShellEntrySet& entries) ///@todo If the user explicitely clicked on a submenu, display this folder as floating start menu. if (entry->_etype == ET_SHELL) - new_folders.push_back(static_cast(entry)->create_absolute_pidl()); + new_folders.push_back(entry->create_absolute_pidl()); else { TCHAR path[MAX_PATH]; @@ -976,7 +981,8 @@ void DrawStartMenuButton(HDC hdc, const RECT& rect, LPCTSTR title, HICON hIcon, if (title) FillRect(hdc, &rect, bk_brush); - DrawIconEx(hdc, iconPos.x, iconPos.y, btn._hIcon, 16, 16, 0, bk_brush, DI_NORMAL); + 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); // draw submenu arrow at the right if (btn._hasSubmenu) { @@ -1213,38 +1219,38 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) // insert hard coded start entries - AddButton(ResString(IDS_PROGRAMS), SmallIcon(IDI_APPS), true, IDC_PROGRAMS); + AddButton(ResString(IDS_PROGRAMS), ICID_APPS, true, IDC_PROGRAMS); - AddButton(ResString(IDS_DOCUMENTS), SmallIcon(IDI_DOCUMENTS), true, IDC_DOCUMENTS); + AddButton(ResString(IDS_DOCUMENTS), ICID_DOCUMENTS, true, IDC_DOCUMENTS); #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NORECENTDOCSMENU)) #else if (IS_VALUE_ZERO(hkey, _T("NoRecentDocsMenu"))) #endif - AddButton(ResString(IDS_RECENT), SmallIcon(IDI_DOCUMENTS), true, IDC_RECENT); + AddButton(ResString(IDS_RECENT), ICID_DOCUMENTS, true, IDC_RECENT); - AddButton(ResString(IDS_FAVORITES), SmallIcon(IDI_FAVORITES), true, IDC_FAVORITES); + AddButton(ResString(IDS_FAVORITES), ICID_FAVORITES, true, IDC_FAVORITES); - AddButton(ResString(IDS_SETTINGS), SmallIcon(IDI_CONFIG), true, IDC_SETTINGS); + AddButton(ResString(IDS_SETTINGS), ICID_CONFIG, true, IDC_SETTINGS); - AddButton(ResString(IDS_BROWSE), SmallIcon(IDI_FOLDER), true, IDC_BROWSE); + AddButton(ResString(IDS_BROWSE), ICID_FOLDER, true, IDC_BROWSE); #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOFIND)) #else if (IS_VALUE_ZERO(hkey, _T("NoFind"))) #endif - AddButton(ResString(IDS_SEARCH), SmallIcon(IDI_SEARCH), true, IDC_SEARCH); + AddButton(ResString(IDS_SEARCH), ICID_SEARCH, true, IDC_SEARCH); - AddButton(ResString(IDS_START_HELP), SmallIcon(IDI_INFO), false, IDC_START_HELP); + AddButton(ResString(IDS_START_HELP), ICID_INFO, false, IDC_START_HELP); #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NORUN)) #else if (IS_VALUE_ZERO(hkey, _T("NoRun"))) #endif - AddButton(ResString(IDS_LAUNCH), SmallIcon(IDI_ACTION), false, IDC_LAUNCH); + AddButton(ResString(IDS_LAUNCH), ICID_ACTION, false, IDC_LAUNCH); AddSeparator(); @@ -1255,7 +1261,7 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) #else if (IS_VALUE_NOT_ZERO(hkeyAdv, _T("StartMenuLogoff"))) #endif - AddButton(ResString(IDS_LOGOFF), SmallIcon(IDI_LOGOFF), false, IDC_LOGOFF); + AddButton(ResString(IDS_LOGOFF), ICID_LOGOFF, false, IDC_LOGOFF); #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) @@ -1263,7 +1269,7 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) #else if (IS_VALUE_ZERO(hkey, _T("NoClose"))) #endif - AddButton(ResString(IDS_SHUTDOWN), SmallIcon(IDI_LOGOFF), false, IDC_SHUTDOWN); + AddButton(ResString(IDS_SHUTDOWN), ICID_LOGOFF, false, IDC_SHUTDOWN); #ifdef __MINGW32__ @@ -1285,7 +1291,7 @@ void StartMenuRoot::AddEntries() { super::AddEntries(); - AddButton(ResString(IDS_EXPLORE), SmallIcon(IDI_EXPLORER), false, IDC_EXPLORE); + AddButton(ResString(IDS_EXPLORE), ICID_EXPLORER, false, IDC_EXPLORE); } @@ -1538,16 +1544,16 @@ void SettingsMenu::AddEntries() #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL)) #endif - AddButton(ResString(IDS_CONTROL_PANEL), SmallIcon(IDI_CONFIG), false, IDC_CONTROL_PANEL); + AddButton(ResString(IDS_CONTROL_PANEL), ICID_CONFIG, false, IDC_CONTROL_PANEL); - AddButton(ResString(IDS_PRINTERS), SmallIcon(IDI_PRINTER), true, IDC_PRINTERS); - AddButton(ResString(IDS_CONNECTIONS), SmallIcon(IDI_NETWORK), true, IDC_CONNECTIONS); - AddButton(ResString(IDS_ADMIN), SmallIcon(IDI_CONFIG), true, IDC_ADMIN); + AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, true, IDC_PRINTERS); + AddButton(ResString(IDS_CONNECTIONS), ICID_NETWORK, true, IDC_CONNECTIONS); + AddButton(ResString(IDS_ADMIN), ICID_CONFIG, true, IDC_ADMIN); #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL)) #endif - AddButton(ResString(IDS_SETTINGS_MENU), SmallIcon(IDI_CONFIG), true, IDC_SETTINGS_MENU); + AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU); } void BrowseMenu::AddEntries() @@ -1557,23 +1563,23 @@ void BrowseMenu::AddEntries() #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NONETHOOD)) // or REST_NOENTIRENETWORK ? #endif - AddButton(ResString(IDS_NETWORK), SmallIcon(IDI_NETWORK), true, IDC_NETWORK); + AddButton(ResString(IDS_NETWORK), ICID_NETWORK, true, IDC_NETWORK); - AddButton(ResString(IDS_DRIVES), SmallIcon(IDI_FOLDER), true, IDC_DRIVES); + AddButton(ResString(IDS_DRIVES), ICID_FOLDER, true, IDC_DRIVES); } void SearchMenu::AddEntries() { super::AddEntries(); - AddButton(ResString(IDS_SEARCH_PRG), SmallIcon(IDI_APPS), false, IDC_SEARCH_PROGRAM); + AddButton(ResString(IDS_SEARCH_PRG), ICID_APPS, false, IDC_SEARCH_PROGRAM); - AddButton(ResString(IDS_SEARCH_FILES), SmallIcon(IDI_SEARCH_DOC), false, IDC_SEARCH_FILES); + AddButton(ResString(IDS_SEARCH_FILES), ICID_SEARCH_DOC, false, IDC_SEARCH_FILES); #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_HASFINDCOMPUTERS)) #endif - AddButton(ResString(IDS_SEARCH_COMPUTER), SmallIcon(IDI_COMPUTER), false, IDC_SEARCH_COMPUTER); + AddButton(ResString(IDS_SEARCH_COMPUTER), ICID_COMPUTER, false, IDC_SEARCH_COMPUTER); } diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.h b/reactos/subsys/system/explorer/taskbar/startmenu.h index 56c80bb8db0..0bc1882a804 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.h +++ b/reactos/subsys/system/explorer/taskbar/startmenu.h @@ -75,10 +75,10 @@ typedef set ShellEntrySet; /// structure holding information about one start menu entry struct StartMenuEntry { - StartMenuEntry() : _hIcon(0) {} + StartMenuEntry() : _icon_id(ICID_UNKNOWN) {} String _title; - HICON _hIcon; + ICON_ID _icon_id; ShellEntrySet _entries; }; @@ -95,14 +95,14 @@ struct StartMenuButton : public OwnerdrawnButton { typedef OwnerdrawnButton super; - StartMenuButton(HWND hwnd, HICON hIcon, bool hasSubmenu) + StartMenuButton(HWND hwnd, ICON_ID icon_id, bool hasSubmenu) : super(hwnd), _hIcon(hIcon), _hasSubmenu(hasSubmenu) {} protected: LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); virtual void DrawItem(LPDRAWITEMSTRUCT dis); - HICON _hIcon; + ICON_ID _icon_id; bool _hasSubmenu; }; @@ -159,16 +159,16 @@ struct SMBtnInfo { SMBtnInfo(const StartMenuEntry& entry, int id, bool hasSubmenu=false, bool enabled=true) : _title(entry._title), - _hIcon(entry._hIcon), + _icon_id(entry._icon_id), _id(id), _hasSubmenu(hasSubmenu), _enabled(enabled) { } - SMBtnInfo(LPCTSTR title, HICON hIcon, int id, bool hasSubmenu=false, bool enabled=true) + SMBtnInfo(LPCTSTR title, ICON_ID icon_id, int id, bool hasSubmenu=false, bool enabled=true) : _title(title), - _hIcon(hIcon), + _icon_id(icon_id), _id(id), _hasSubmenu(hasSubmenu), _enabled(enabled) @@ -176,7 +176,7 @@ struct SMBtnInfo } String _title; - HICON _hIcon; + ICON_ID _icon_id; int _id; bool _hasSubmenu; bool _enabled; @@ -258,14 +258,14 @@ protected: virtual void AddEntries(); - StartMenuEntry& AddEntry(const String& title, HICON hIcon, Entry* entry); - StartMenuEntry& AddEntry(const String& title, HICON hIcon=0, int id=-1); + StartMenuEntry& AddEntry(const String& title, ICON_ID icon_id, Entry* entry); + StartMenuEntry& AddEntry(const String& title, ICON_ID icon_id=ICID_NONE, int id=-1); StartMenuEntry& AddEntry(const ShellFolder folder, ShellEntry* entry); StartMenuEntry& AddEntry(const ShellFolder folder, Entry* entry); void AddShellEntries(const ShellDirectory& dir, int max=-1, bool subfolders=true); - void AddButton(LPCTSTR title, HICON hIcon=0, bool hasSubmenu=false, int id=-1, bool enabled=true); + void AddButton(LPCTSTR title, ICON_ID icon_id=ICID_NONE, bool hasSubmenu=false, int id=-1, bool enabled=true); void AddSeparator(); bool CloseSubmenus() {return CloseOtherSubmenus(0);} diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.cpp b/reactos/subsys/system/explorer/taskbar/taskbar.cpp index 5ffb4213ae9..88599820066 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/taskbar.cpp @@ -29,6 +29,7 @@ #include "../utility/utility.h" #include "../explorer.h" +#include "../globals.h" #include "taskbar.h" #include "traynotify.h" // for NOTIFYAREA_WIDTH @@ -249,21 +250,6 @@ static HICON get_window_icon(HWND hwnd) return hIcon; } -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; -} - // fill task bar with buttons for enumerated top level windows BOOL CALLBACK TaskBar::EnumWndProc(HWND hwnd, LPARAM lparam) { diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index c27b4b6c6f4..9fa61d19ea9 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -134,9 +134,6 @@ extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime); // search for windows of a specific classname extern int find_window_class(LPCTSTR classname); - // create a bitmap from an icon -extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd); - // launch a program or document file extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow); #ifdef UNICODE diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index 3a870f88a9a..10b8441b2e6 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -591,18 +591,6 @@ PreTranslateWindow::~PreTranslateWindow() } -DialogWindow::DialogWindow(HWND hwnd) - : super(hwnd) -{ - register_dialog(hwnd); -} - -DialogWindow::~DialogWindow() -{ - unregister_dialog(_hwnd); -} - - Dialog::Dialog(HWND hwnd) : super(hwnd) { diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index 82cca02ac63..ec8654ba79c 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -319,14 +319,22 @@ struct DialogWindow : public Window { typedef Window super; - DialogWindow(HWND); - ~DialogWindow(); + DialogWindow(HWND hwnd) + : super(hwnd) + { + register_dialog(hwnd); + } + + ~DialogWindow() + { + unregister_dialog(_hwnd); + } }; /** The class Dialog implements modal dialogs. - A DialogWindow object should be constructed by calling Dialog::DoModal() + A Dialog object should be constructed by calling Dialog::DoModal() and specifying the class using the WINDOW_CREATOR() macro. */ struct Dialog : public Window