diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index 4d68a29b2a3..fd14610c199 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -14,6 +14,9 @@ #define IDS_PROGRAMS 10 #define IDS_SETTINGS 11 #define IDS_EXPLORE 12 +#define IDS_EMPTY 13 +#define IDS_RECENT 14 +#define IDS_ADMIN 15 #define IDI_REACTOS 100 #define IDI_EXPLORER 101 #define IDI_STARTMENU 102 @@ -59,7 +62,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 125 +#define _APS_NEXT_RESOURCE_VALUE 126 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/reactos/subsys/system/explorer/explorer_intres.rc b/reactos/subsys/system/explorer/explorer_intres.rc index 7728ae0c9be..1b88b21fdb2 100644 --- a/reactos/subsys/system/explorer/explorer_intres.rc +++ b/reactos/subsys/system/explorer/explorer_intres.rc @@ -251,6 +251,9 @@ BEGIN IDS_PROGRAMS "Programs" IDS_SETTINGS "Settings" IDS_EXPLORE "Explore" + IDS_EMPTY "(Empty)" + IDS_RECENT "Recent Documents" + IDS_ADMIN "Administration" END #endif // German (Germany) resources diff --git a/reactos/subsys/system/explorer/shell/shellfs.cpp b/reactos/subsys/system/explorer/shell/shellfs.cpp index 06c3d9f0b51..dd5f5eaa22e 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.cpp +++ b/reactos/subsys/system/explorer/shell/shellfs.cpp @@ -30,6 +30,7 @@ #include "../utility/shellclasses.h" #include "../globals.h" + #include "entries.h" #include "shellfs.h" @@ -243,22 +244,18 @@ void ShellDirectory::read_directory() HRESULT hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs); if (SUCCEEDED(hr)) { - if (attribs != ~SFGAO_FILESYSTEM) { + if (attribs != ~SFGAO_FILESYSTEM) bhfi_valid = fill_w32fdata_shell(pidls[n], attribs, &w32fd, &bhfi); - } else + else attribs = 0; } else attribs = 0; Entry* entry; - if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - IShellFolder* child = NULL; - - /*hr = */_folder->BindToObject(pidls[n], 0, IID_IShellFolder, (void**)&child); - - entry = new ShellDirectory(this, child, pidls[n], _hwnd); - } else + if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + entry = new ShellDirectory(this, pidls[n], _hwnd); + else entry = new ShellEntry(this, pidls[n]); if (!first_entry) diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h index b5bcdd6464d..c146eb8a532 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.h +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -62,9 +62,9 @@ struct ShellDirectory : public ShellEntry, public Directory _path = pFolder; } - explicit ShellDirectory(ShellDirectory* parent, IShellFolder* shell_root, LPITEMIDLIST shell_path, HWND hwnd) + explicit ShellDirectory(ShellDirectory* parent, LPITEMIDLIST shell_path, HWND hwnd) : ShellEntry(parent, shell_path), - _folder(shell_root), + _folder(parent->_folder, shell_path), _hwnd(hwnd) { /* not neccessary - the caller will fill the info @@ -72,8 +72,18 @@ struct ShellDirectory : public ShellEntry, public Directory _data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; _shell_attribs = SFGAO_FOLDER; */ - shell_root->AddRef(); - _path = shell_root; + _folder->AddRef(); + _path = _folder; + } + + ShellDirectory(const ShellDirectory& other) + : ShellEntry(other), + Directory(other), + _folder(other._folder), + _hwnd(other._hwnd) + { + IShellFolder* pFolder = (IShellFolder*)_path; + pFolder->AddRef(); } ~ShellDirectory() diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index b7927845fa4..ca2643cbd41 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -51,7 +51,8 @@ StartMenu::StartMenu(HWND hwnd, const StartMenuFolders& info) : super(hwnd) { for(StartMenuFolders::const_iterator it=info.begin(); it!=info.end(); ++it) - _dirs.push_back(ShellDirectory(Desktop(), *it, _hwnd)); + if (*it) + _dirs.push_back(ShellDirectory(Desktop(), *it, _hwnd)); _next_id = IDC_FIRST_MENU; } @@ -65,33 +66,50 @@ HWND StartMenu::Create(int x, int y, HWND hwndParent) } */ -HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent) +Window::CREATORFUNC StartMenu::s_def_creator = STARTMENU_CREATOR(StartMenu); + +HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndParent, CREATORFUNC creator) { - return Window::Create(WINDOW_CREATOR_INFO(StartMenu,StartMenuFolders), &folders, 0, s_wcStartMenu, NULL, + return Window::Create(creator, &folders, 0, s_wcStartMenu, NULL, WS_POPUP|WS_THICKFRAME|WS_CLIPCHILDREN|WS_VISIBLE, x, y, STARTMENU_WIDTH, 4, hwndParent); } LRESULT StartMenu::Init(LPCREATESTRUCT pcs) { + WaitCursor wait; + + AddEntries(); + if (super::Init(pcs)) return 1; - WaitCursor wait; - - for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) { - ShellDirectory& dir = *it; + for(ShellEntryMap::const_iterator it=_entries.begin(); it!=_entries.end(); ++it) { + const StartMenuEntry& sme = it->second; - dir.smart_scan(); - - AddShellEntries(dir); + AddButton(sme._title, sme._hIcon, it->first); } return 0; } -void StartMenu::AddShellEntries(const ShellDirectory& dir, bool subfolders) +void StartMenu::AddEntries() { + for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) { + StartMenuDirectory& smd = *it; + ShellDirectory& dir = smd._dir; + + dir.smart_scan(); + + AddShellEntries(dir, -1, smd._subfolders); + } +} + + +void StartMenu::AddShellEntries(const ShellDirectory& dir, int max, bool subfolders) +{ + int cnt = 0; + for(const Entry*entry=dir._down; entry; entry=entry->_next) { // hide files like "desktop.ini" if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) @@ -102,14 +120,17 @@ void StartMenu::AddShellEntries(const ShellDirectory& dir, bool subfolders) if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; + // only 'max' entries shall be added. + if (++cnt == max) + break; + const ShellEntry* shell_entry = static_cast(entry); - AddButton(dir._folder, shell_entry); + AddEntry(dir._folder, shell_entry); } } - LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { @@ -141,10 +162,13 @@ int StartMenu::Command(int id, int code) break; default: { - ShellEntryMap::const_iterator found = _entry_map.find(id); + ShellEntryMap::const_iterator found = _entries.find(id); - if (found != _entry_map.end()) { - ActivateEntry(const_cast(found->second)); + if (found != _entries.end()) { + ShellEntry* entry = const_cast(found->second._entry); + + if (entry) + ActivateEntry(id, entry); break; } @@ -154,11 +178,39 @@ int StartMenu::Command(int id, int code) return 0; } -UINT StartMenu::AddButton(LPCTSTR text, HICON hIcon, UINT id) + +StartMenuEntry& StartMenu::AddEntry(LPCTSTR title, HICON hIcon, UINT id) { if (id == (UINT)-1) id = ++_next_id; + StartMenuEntry& sme = _entries[id]; + + sme._title = title; + sme._hIcon = hIcon; + + return sme; +} + +StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, const ShellEntry* entry) +{ + HICON hIcon = entry->_hicon; + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + hIcon = SmallIcon(IDI_EXPLORER); + + const String& entry_name = folder.get_name(entry->_pidl); + + StartMenuEntry& sme = AddEntry(entry_name, hIcon); + + sme._entry = entry; + + return sme; +} + + +void StartMenu::AddButton(LPCTSTR title, HICON hIcon, UINT id) +{ WindowRect rect(_hwnd); rect.top -= STARTMENU_LINE_HEIGHT; @@ -170,36 +222,86 @@ UINT StartMenu::AddButton(LPCTSTR text, HICON hIcon, UINT id) MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); - StartMenuButton(_hwnd, rect.bottom-rect.top-STARTMENU_LINE_HEIGHT-4, text, id, hIcon); - - return id; + StartMenuButton(_hwnd, rect.bottom-rect.top-STARTMENU_LINE_HEIGHT-4, title, id, hIcon); } -UINT StartMenu::AddButton(const ShellFolder folder, const ShellEntry* entry) +void StartMenu::AddSeparator() { - HICON hIcon = entry->_hicon; + WindowRect rect(_hwnd); - if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - hIcon = SmallIcon(IDI_EXPLORER); + rect.top -= STARTMENU_SEP_HEIGHT; - const String& entry_name = folder.get_name(entry->_pidl); + if (rect.top < 0) { + rect.top += STARTMENU_LINE_HEIGHT; + rect.bottom += STARTMENU_LINE_HEIGHT; + } - UINT id = AddButton(entry_name, hIcon); + MoveWindow(_hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); - _entry_map[id] = entry; - - return id; + StartMenuSeparator(_hwnd, rect.bottom-rect.top-STARTMENU_SEP_HEIGHT-4); } -void StartMenu::ActivateEntry(ShellEntry* entry) + +void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator) +{ + HWND btn = GetDlgItem(_hwnd, id); + int x, y; + + if (btn) { + WindowRect pos(btn); + + x = pos.right; + y = pos.top+STARTMENU_HEIGHT-4; + } else { + WindowRect pos(_hwnd); + + x = pos.right; + y = pos.top+STARTMENU_HEIGHT-4; + } + + StartMenu::Create(x, y, new_folders, _hwnd, creator); +} + +void StartMenu::CreateSubmenu(int id, int folder_id, CREATORFUNC creator) +{ + StartMenuFolders new_folders; + + SpecialFolder folder(folder_id, _hwnd); + + if (folder) + new_folders.push_back(folder); + + CreateSubmenu(id, new_folders, creator); +} + +void StartMenu::CreateSubmenu(int id, int folder_id1, int folder_id2, CREATORFUNC creator) +{ + StartMenuFolders new_folders; + + SpecialFolder folder1(folder_id1, _hwnd); + + if (folder1) + new_folders.push_back(folder1); + + if (folder_id2 != -1) { + SpecialFolder folder2(folder_id2, _hwnd); + + if (folder2) + new_folders.push_back(folder2); + } + + CreateSubmenu(id, new_folders, creator); +} + + +void StartMenu::ActivateEntry(int id, ShellEntry* entry) { if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { StartMenuFolders new_folders; new_folders.push_back(entry->create_absolute_pidl(_hwnd)); - WindowRect my_pos(_hwnd); - StartMenu::Create(my_pos.right, my_pos.top+STARTMENU_HEIGHT-4, new_folders, _hwnd); + CreateSubmenu(id, new_folders); } else { entry->launch_entry(_hwnd); } @@ -209,6 +311,13 @@ void StartMenu::ActivateEntry(ShellEntry* entry) StartMenuRoot::StartMenuRoot(HWND hwnd) : super(hwnd) { + // insert directory "All Users\Start Menu" + ShellDirectory cmn_startmenu(Desktop(), SpecialFolder(CSIDL_COMMON_STARTMENU, _hwnd), _hwnd); + _dirs.push_back(StartMenuDirectory(cmn_startmenu, false)); // dont't add subfolders + + // insert directory "\Start Menu" + ShellDirectory usr_startmenu(Desktop(), SpecialFolder(CSIDL_STARTMENU, _hwnd), _hwnd); + _dirs.push_back(StartMenuDirectory(usr_startmenu, false)); // dont't add subfolders } HWND StartMenuRoot::Create(int x, int y, HWND hwndParent) @@ -219,29 +328,26 @@ HWND StartMenuRoot::Create(int x, int y, HWND hwndParent) LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) { + // add buttons for entries in _entries if (super::Init(pcs)) return 1; - WaitCursor wait; - - // insert start menu entries links from "All Users\Start Menu" and "\Start Menu" - ShellDirectory cmn_startmenu(Desktop(), SpecialFolder(CSIDL_COMMON_STARTMENU, _hwnd), _hwnd); - cmn_startmenu.read_directory(); - AddShellEntries(cmn_startmenu, false); - - ShellDirectory usr_startmenu(Desktop(), SpecialFolder(CSIDL_STARTMENU, _hwnd), _hwnd); - usr_startmenu.read_directory(); - AddShellEntries(usr_startmenu, false); + AddSeparator(); // insert hard coded start entries AddButton(ResString(IDS_PROGRAMS), 0, IDC_PROGRAMS); AddButton(ResString(IDS_EXPLORE), SmallIcon(IDI_EXPLORER), IDC_EXPLORE); AddButton(ResString(IDS_FAVORITES), 0, IDC_FAVORITES); AddButton(ResString(IDS_DOCUMENTS), 0, IDC_DOCUMENTS); + AddButton(ResString(IDS_RECENT), 0, IDC_RECENT); AddButton(ResString(IDS_SETTINGS), 0, IDC_SETTINGS); + AddButton(ResString(IDS_ADMIN), 0, IDC_ADMIN); AddButton(ResString(IDS_SEARCH), 0, IDC_SEARCH); AddButton(ResString(IDS_START_HELP),0, IDC_START_HELP); AddButton(ResString(IDS_LAUNCH), 0, IDC_LAUNCH); + + AddSeparator(); + AddButton(ResString(IDS_SHUTDOWN), SmallIcon(IDI_LOGOFF), IDC_SHUTDOWN); AddButton(ResString(IDS_LOGOFF), SmallIcon(IDI_LOGOFF), IDC_LOGOFF); @@ -251,20 +357,34 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) int StartMenuRoot::Command(int id, int code) { switch(id) { - case IDC_PROGRAMS: { - StartMenuFolders prg_folders; - - prg_folders.push_back(SpecialFolder(CSIDL_COMMON_PROGRAMS, _hwnd)); - prg_folders.push_back(SpecialFolder(CSIDL_PROGRAMS, _hwnd)); - - WindowRect my_pos(_hwnd); - StartMenu::Create(my_pos.right, my_pos.top+STARTMENU_HEIGHT-4, prg_folders, _hwnd); - break;} + case IDC_PROGRAMS: + CreateSubmenu(id, CSIDL_COMMON_PROGRAMS, CSIDL_PROGRAMS); + break; case IDC_EXPLORE: explorer_show_frame(_hwnd, SW_SHOWNORMAL); break; + case IDC_DOCUMENTS: + CreateSubmenu(id, CSIDL_PERSONAL); + break; + + case IDC_RECENT: + CreateSubmenu(id, CSIDL_RECENT, STARTMENU_CREATOR(RecentStartMenu)); + break; + + case IDC_SETTINGS: + CreateSubmenu(id, CSIDL_CONTROLS); + break; + + case IDC_FAVORITES: + CreateSubmenu(id, CSIDL_FAVORITES); + break; + + case IDC_ADMIN: + CreateSubmenu(id, CSIDL_COMMON_ADMINTOOLS, CSIDL_ADMINTOOLS); + break; + case IDC_LOGOFF: DestroyWindow(GetParent(_hwnd)); //TODO: show dialog and ask for acknowledge break; @@ -279,3 +399,22 @@ int StartMenuRoot::Command(int id, int code) return 0; } + + +RecentStartMenu::RecentStartMenu(HWND hwnd, const StartMenuFolders& info) + : super(hwnd, info) +{ +} + +void RecentStartMenu::AddEntries() +{ + for(StartMenuShellDirs::iterator it=_dirs.begin(); it!=_dirs.end(); ++it) { + StartMenuDirectory& smd = *it; + ShellDirectory& dir = smd._dir; + + dir.smart_scan(); + + dir.sort_directory(SORT_DATE); + AddShellEntries(dir, 16, smd._subfolders); //TODO: read max. count of entries from registry + } +} diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.h b/reactos/subsys/system/explorer/taskbar/startmenu.h index 092abb0ec78..65ddd2b8dad 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.h +++ b/reactos/subsys/system/explorer/taskbar/startmenu.h @@ -36,9 +36,9 @@ // Startmenu button struct StartMenuButton : public Button { - StartMenuButton(HWND parent, int y, LPCTSTR text, - UINT id, HICON hIcon, DWORD style=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW, DWORD exStyle=0) - : Button(parent, text, 2, y, STARTMENU_WIDTH-4, STARTMENU_LINE_HEIGHT, id, style, exStyle) + StartMenuButton(HWND parent, int y, LPCTSTR title, + UINT id, HICON hIcon=0, DWORD style=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW, DWORD exStyle=0) + : Button(parent, title, 2, y, STARTMENU_WIDTH-4, STARTMENU_LINE_HEIGHT, id, style, exStyle) { *new StartmenuEntry(_hwnd, hIcon); @@ -47,9 +47,41 @@ struct StartMenuButton : public Button }; +struct StartMenuSeparator : public Static +{ + StartMenuSeparator(HWND parent, int y, DWORD style=WS_VISIBLE|WS_CHILD|SS_ETCHEDHORZ, DWORD exStyle=0) + : Static(parent, NULL, 2, y+STARTMENU_SEP_HEIGHT/2-1, STARTMENU_WIDTH-4, 2, -1, style, exStyle) + { + } +}; + + +struct StartMenuDirectory +{ + StartMenuDirectory(const ShellDirectory& dir, bool subfolders=true) + : _dir(dir), _subfolders(subfolders) {} + + ShellDirectory _dir; + bool _subfolders; +}; + +typedef list StartMenuShellDirs; + +struct StartMenuEntry +{ + StartMenuEntry() : _entry(NULL), _hIcon(0) {} + + String _title; + HICON _hIcon; + const ShellEntry* _entry; +}; + +typedef map ShellEntryMap; + + typedef list StartMenuFolders; -typedef list StartMenuShellDirs; -typedef map ShellEntryMap; + +#define STARTMENU_CREATOR(WND_CLASS) WINDOW_CREATOR_INFO(WND_CLASS, StartMenuFolders) // Startmenu window @@ -61,12 +93,13 @@ struct StartMenu : public OwnerDrawParent StartMenu(HWND hwnd, const StartMenuFolders& info); static HWND Create(int x, int y, HWND hwndParent=0); - static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent=0); + static HWND Create(int x, int y, const StartMenuFolders&, HWND hwndParent=0, CREATORFUNC creator=s_def_creator); + static CREATORFUNC s_def_creator; protected: int _next_id; + ShellEntryMap _entries; StartMenuShellDirs _dirs; - ShellEntryMap _entry_map; static BtnWindowClass s_wcStartMenu; @@ -74,12 +107,20 @@ protected: LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); int Command(int id, int code); - UINT AddButton(LPCTSTR text, HICON hIcon=0, UINT id=(UINT)-1); - UINT AddButton(const ShellFolder folder, const ShellEntry* entry); + virtual void AddEntries(); - void AddShellEntries(const ShellDirectory& dir, bool subfolders=true); + StartMenuEntry& AddEntry(LPCTSTR title, HICON hIcon=0, UINT id=(UINT)-1); + StartMenuEntry& AddEntry(const ShellFolder folder, const ShellEntry* entry); - void ActivateEntry(ShellEntry* entry); + void AddShellEntries(const ShellDirectory& dir, int max=-1, bool subfolders=true); + + void AddButton(LPCTSTR title, HICON hIcon=0, UINT id=(UINT)-1); + void AddSeparator(); + + void CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator=s_def_creator); + void CreateSubmenu(int id, int folder1, int folder2, CREATORFUNC creator=s_def_creator); + void CreateSubmenu(int id, int folder, CREATORFUNC creator=s_def_creator); + void ActivateEntry(int id, ShellEntry* entry); }; @@ -96,3 +137,14 @@ protected: LRESULT Init(LPCREATESTRUCT pcs); int Command(int id, int code); }; + + +struct RecentStartMenu : public StartMenu +{ + typedef StartMenu super; + + RecentStartMenu(HWND hwnd, const StartMenuFolders& info); + +protected: + virtual void AddEntries(); +}; diff --git a/reactos/subsys/system/explorer/taskbar/taskbar.h b/reactos/subsys/system/explorer/taskbar/taskbar.h index 2accae85865..20756b13a05 100644 --- a/reactos/subsys/system/explorer/taskbar/taskbar.h +++ b/reactos/subsys/system/explorer/taskbar/taskbar.h @@ -37,6 +37,7 @@ #define STARTMENU_WIDTH 150 #define STARTMENU_HEIGHT 4 #define STARTMENU_LINE_HEIGHT 22 +#define STARTMENU_SEP_HEIGHT (STARTMENU_LINE_HEIGHT/2) #define WM_SHELLHOOK_NOTIFY (WM_APP+0x10) @@ -55,10 +56,12 @@ #define IDC_START_HELP 0x1004 #define IDC_SEARCH 0x1005 #define IDC_SETTINGS 0x1006 -#define IDC_DOCUMENTS 0x1007 -#define IDC_FAVORITES 0x1008 -#define IDC_PROGRAMS 0x1009 -#define IDC_EXPLORE 0x100A +#define IDC_ADMIN 0x1007 +#define IDC_DOCUMENTS 0x1008 +#define IDC_RECENT 0x1009 +#define IDC_FAVORITES 0x100A +#define IDC_PROGRAMS 0x100B +#define IDC_EXPLORE 0x100C #define IDC_FIRST_APP 0x2000 #define IDC_FIRST_MENU 0x3000 diff --git a/reactos/subsys/system/explorer/utility/shellclasses.cpp b/reactos/subsys/system/explorer/utility/shellclasses.cpp index bb41b57825d..b3405df25d5 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.cpp +++ b/reactos/subsys/system/explorer/utility/shellclasses.cpp @@ -139,7 +139,7 @@ ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl) { IShellFolder* ptr; - if (pidl->mkid.cb) + if (pidl && pidl->mkid.cb) CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr)); else ptr = parent; @@ -153,7 +153,7 @@ ShellFolder::ShellFolder(LPCITEMIDLIST pidl) IShellFolder* ptr; IShellFolder* parent = Desktop(); - if (pidl->mkid.cb) + if (pidl && pidl->mkid.cb) CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr)); else ptr = parent; @@ -166,7 +166,7 @@ void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl) { IShellFolder* ptr; - if (pidl->mkid.cb) + if (pidl && pidl->mkid.cb) CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr)); else ptr = parent; @@ -192,7 +192,7 @@ ShellFolder::ShellFolder(IShellFolder* p) ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl) { - if (pidl->mkid.cb) + if (pidl && pidl->mkid.cb) CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p)); else _p = Desktop(); @@ -202,7 +202,7 @@ ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl) ShellFolder::ShellFolder(LPCITEMIDLIST pidl) { - if (pidl->mkid.cb) + if (pidl && pidl->mkid.cb) CheckError(Desktop()->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p)); else _p = Desktop(); diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index d74daf6b3ab..02365e0f614 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -58,11 +58,11 @@ IconWindowClass::IconWindowClass(LPCTSTR classname, UINT nid, UINT style, WNDPRO HHOOK Window::s_hcbtHook = 0; -Window::WINDOWCREATORFUNC Window::s_window_creator = NULL; +Window::CREATORFUNC Window::s_window_creator = NULL; const void* Window::s_new_info = NULL; -HWND Window::Create(WINDOWCREATORFUNC creator, DWORD dwExStyle, +HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int w, int h, HWND hwndParent, HMENU hMenu, LPVOID lpParam) @@ -75,7 +75,7 @@ HWND Window::Create(WINDOWCREATORFUNC creator, DWORD dwExStyle, hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); } -HWND Window::Create(WINDOWCREATORFUNC creator, const void* info, DWORD dwExStyle, +HWND Window::Create(CREATORFUNC creator, const void* info, DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int w, int h, HWND hwndParent, HMENU hMenu, LPVOID lpParam) @@ -91,7 +91,7 @@ HWND Window::Create(WINDOWCREATORFUNC creator, const void* info, DWORD dwExStyle static Window* s_new_child_wnd = NULL; -Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, WINDOWCREATORFUNC creator, const void* info) +Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, CREATORFUNC creator, const void* info) { s_window_creator = creator; s_new_info = info; @@ -141,7 +141,7 @@ Window* Window::get_window(HWND hwnd) const void* info = s_new_info; s_new_info = NULL; - WINDOWCREATORFUNC window_creator = s_window_creator; + CREATORFUNC window_creator = s_window_creator; s_window_creator = NULL; wnd = window_creator(hwnd, info); @@ -227,7 +227,7 @@ ChildWindow::ChildWindow(HWND hwnd) } -ChildWindow* ChildWindow::create(HWND hmdiclient, const RECT& rect, WINDOWCREATORFUNC creator, LPCTSTR classname, LPCTSTR title) +ChildWindow* ChildWindow::create(HWND hmdiclient, const RECT& rect, CREATORFUNC creator, LPCTSTR classname, LPCTSTR title) { MDICREATESTRUCT mcs; @@ -464,7 +464,7 @@ int Window::MessageLoop() Button::Button(HWND parent, LPCTSTR text, int left, int top, int width, int height, - UINT id, DWORD flags, DWORD exStyle) + int id, DWORD flags, DWORD exStyle) { _hwnd = CreateWindowEx(exStyle, TEXT("BUTTON"), text, flags, left, top, width, height, parent, (HMENU)id, g_Globals._hInstance, 0); @@ -481,6 +481,14 @@ LRESULT OwnerdrawnButton::WndProc(UINT message, WPARAM wparam, LPARAM lparam) } +Static::Static(HWND parent, LPCTSTR text, int left, int top, int width, int height, + int id, DWORD flags, DWORD exStyle) +{ + _hwnd = CreateWindowEx(exStyle, TEXT("STATIC"), text, flags, left, top, width, height, + parent, (HMENU)id, g_Globals._hInstance, 0); +} + + static RECT s_MyDrawText_Rect = {0, 0, 0, 0}; static BOOL CALLBACK MyDrawText(HDC hdc, LPARAM data, int cnt) diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index 084568f3c53..b1ffdf4487b 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -68,19 +68,19 @@ struct Window operator HWND() const {return _hwnd;} - typedef Window* (*WINDOWCREATORFUNC)(HWND, const void*); + typedef Window* (*CREATORFUNC)(HWND, const void*); - static HWND Create(WINDOWCREATORFUNC creator, DWORD dwExStyle, + static HWND Create(CREATORFUNC creator, DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int w, int h, HWND hwndParent=0, HMENU hMenu=0, LPVOID lpParam=0); - static HWND Create(WINDOWCREATORFUNC creator, const void* info, + static HWND Create(CREATORFUNC creator, const void* info, DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int w, int h, HWND hwndParent=0, HMENU hMenu=0, LPVOID lpParam=0); - static Window* create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, WINDOWCREATORFUNC creator, const void* info=NULL); + static Window* create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, CREATORFUNC creator, const void* info=NULL); static LRESULT CALLBACK WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); static Window* get_window(HWND hwnd); @@ -108,7 +108,7 @@ protected: static const void* s_new_info; //TODO: protect for multithreaded access - static WINDOWCREATORFUNC s_window_creator; //TODO: protect for multithreaded access + static CREATORFUNC s_window_creator; //TODO: protect for multithreaded access // MDI child creation static HHOOK s_hcbtHook; @@ -147,7 +147,7 @@ template struct WindowCreator }; #define WINDOW_CREATOR(WND_CLASS) \ - (Window::WINDOWCREATORFUNC) WindowCreator::window_creator + (Window::CREATORFUNC) WindowCreator::window_creator template struct WindowCreatorInfo @@ -159,7 +159,7 @@ template struct WindowCreatorInfo }; #define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \ - (Window::WINDOWCREATORFUNC) WindowCreatorInfo::window_creator + (Window::CREATORFUNC) WindowCreatorInfo::window_creator /** @@ -239,7 +239,7 @@ struct ChildWindow : public Window ChildWindow(HWND hwnd); static ChildWindow* create(HWND hmdiclient, const RECT& rect, - WINDOWCREATORFUNC creator, LPCTSTR classname, LPCTSTR title=NULL); + CREATORFUNC creator, LPCTSTR classname, LPCTSTR title=NULL); protected: LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); @@ -295,7 +295,24 @@ struct Dialog : public Window struct Button { Button(HWND parent, LPCTSTR text, int left, int top, int width, int height, - UINT id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD ex_flags=0); + int id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD exStyle=0); + + operator HWND() const {return _hwnd;} + +protected: + HWND _hwnd; +}; + + + /** + This class constructs static controls. + The control will remain existent when the C++ object is destroyed. + There is no conjunction between C++ object and windows control life time. + */ +struct Static +{ + Static(HWND parent, LPCTSTR text, int left, int top, int width, int height, + int id, DWORD flags=WS_VISIBLE|WS_CHILD|SS_SIMPLE, DWORD ex_flags=0); operator HWND() const {return _hwnd;}