diff --git a/reactos/subsys/system/explorer/Makefile.MinGW b/reactos/subsys/system/explorer/Makefile.MinGW index ccb9196201b..a95dd3fac0a 100644 --- a/reactos/subsys/system/explorer/Makefile.MinGW +++ b/reactos/subsys/system/explorer/Makefile.MinGW @@ -4,13 +4,11 @@ # Makefile.MinGW # - CC = gcc CXX = g++ LINK = g++ CFLAGS = -DWIN32 -D_ROS_ -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -fexceptions -Wall -CXXFLAGS= $(CFLAGS) RCFLAGS = -DWIN32 -D_ROS_ LFLAGS = -Wl,--subsystem,windows @@ -29,6 +27,8 @@ CFLAGS += -DUNICODE # LFLAGS+= -Wl,--entry,_wWinMain@16 endif +CXXFLAGS = $(CFLAGS) + EXEC_SUFFIX = .exe RES_SUFFIX = .coff @@ -71,5 +71,5 @@ explorer$(RES_SUFFIX): $(PROGRAM)_intres.rc windres $(RCFLAGS) -o $@ $^ clean: - rm -f $(TARGET) *.o *$(RES_SUFFIX) + rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) diff --git a/reactos/subsys/system/explorer/doc/TODO.txt b/reactos/subsys/system/explorer/doc/TODO.txt index 751b13e66ae..7fc7c44f4ed 100644 --- a/reactos/subsys/system/explorer/doc/TODO.txt +++ b/reactos/subsys/system/explorer/doc/TODO.txt @@ -10,7 +10,6 @@ - activate accelerator keys like in shell view folders - program manager "progman" DDE server - command line parameters like "/e,/root,c:\" and "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D}" (launch of control panel) -- search functionality in start menu - Windows-key combos - Application Desktop Toolbars - desktop switching diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index ae540476a77..aba5767015e 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -38,3 +38,4 @@ created a Makefile for compiling as standalone project using MinGW eliminated all warnings displayed when using -Wall activated option for compiling as UNICODE version + merged start menus of the same name (e.g. "All Users\Startup" with "\Startup") diff --git a/reactos/subsys/system/explorer/make_explorer.dsp b/reactos/subsys/system/explorer/make_explorer.dsp index 7a726a3d74c..c52688a782d 100644 --- a/reactos/subsys/system/explorer/make_explorer.dsp +++ b/reactos/subsys/system/explorer/make_explorer.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) External Target" 0x0106 -CFG=make_explorer - Win32 Debug +CFG=make_explorer - Win32 Unicode Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,12 +13,14 @@ CFG=make_explorer - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "make_explorer.mak" CFG="make_explorer - Win32 Debug" +!MESSAGE NMAKE /f "make_explorer.mak" CFG="make_explorer - Win32 Unicode Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "make_explorer - Win32 Release" (based on "Win32 (x86) External Target") !MESSAGE "make_explorer - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE "make_explorer - Win32 Unicode Debug" (based on "Win32 (x86) External Target") +!MESSAGE "make_explorer - Win32 Unicode Release" (based on "Win32 (x86) External Target") !MESSAGE # Begin Project @@ -41,7 +43,7 @@ CFG=make_explorer - Win32 Debug # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" -# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1" +# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW" # PROP Rebuild_Opt "clean all" # PROP Target_File "explorer.exe" # PROP Bsc_Name "" @@ -62,23 +64,71 @@ CFG=make_explorer - Win32 Debug # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW DEBUG=1" +# PROP Rebuild_Opt "clean all" +# PROP Target_File "explorer.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "make_explorer - Win32 Unicode Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "UDebug" +# PROP BASE Intermediate_Dir "UDebug" +# PROP BASE Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1 DEBUG=1" +# PROP BASE Rebuild_Opt "clean all" +# PROP BASE Target_File "explorer.exe" +# PROP BASE Bsc_Name "" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "UDebug" +# PROP Intermediate_Dir "UDebug" # PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1 DEBUG=1" # PROP Rebuild_Opt "clean all" # PROP Target_File "explorer.exe" # PROP Bsc_Name "" # PROP Target_Dir "" +!ELSEIF "$(CFG)" == "make_explorer - Win32 Unicode Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "URelease" +# PROP BASE Intermediate_Dir "URelease" +# PROP BASE Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1" +# PROP BASE Rebuild_Opt "clean all" +# PROP BASE Target_File "explorer.exe" +# PROP BASE Bsc_Name "" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "URelease" +# PROP Intermediate_Dir "URelease" +# PROP Cmd_Line "msdevfilt -gcc -pipe "perl d:\tools\gSTLFilt.pl" make -f Makefile.MinGW UNICODE=1" +# PROP Rebuild_Opt "clean all" +# PROP Target_File "explorer.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + !ENDIF # Begin Target # Name "make_explorer - Win32 Release" # Name "make_explorer - Win32 Debug" +# Name "make_explorer - Win32 Unicode Debug" +# Name "make_explorer - Win32 Unicode Release" !IF "$(CFG)" == "make_explorer - Win32 Release" !ELSEIF "$(CFG)" == "make_explorer - Win32 Debug" +!ELSEIF "$(CFG)" == "make_explorer - Win32 Unicode Debug" + +!ELSEIF "$(CFG)" == "make_explorer - Win32 Unicode Release" + !ENDIF # Begin Source File diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index 2c4e1d863c3..722afc489b7 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -94,8 +94,6 @@ HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndP LRESULT StartMenu::Init(LPCREATESTRUCT pcs) { - WaitCursor wait; - try { AddEntries(); @@ -107,8 +105,9 @@ LRESULT StartMenu::Init(LPCREATESTRUCT pcs) const StartMenuEntry& sme = it->second; bool hasSubmenu = false; - if (sme._entry && (sme._entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) - hasSubmenu = true; + for(ShellEntrySet::const_iterator it=sme._entries.begin(); it!=sme._entries.end(); ++it) + if ((*it)->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + hasSubmenu = true; AddButton(sme._title, sme._hIcon, hasSubmenu, it->first); } @@ -128,7 +127,11 @@ void StartMenu::AddEntries() StartMenuDirectory& smd = *it; ShellDirectory& dir = smd._dir; - dir.smart_scan(); + if (!dir._scanned) { + WaitCursor wait; + + dir.smart_scan(); + } AddShellEntries(dir, -1, smd._subfolders); } @@ -255,13 +258,10 @@ int StartMenu::Command(int id, int code) break; default: { - ShellEntryMap::const_iterator found = _entries.find(id); + ShellEntryMap::iterator found = _entries.find(id); if (found != _entries.end()) { - ShellEntry* entry = const_cast(found->second._entry); - - if (entry) - ActivateEntry(id, entry); + ActivateEntry(id, found->second._entries); break; } @@ -294,9 +294,23 @@ StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, const ShellEntry* const String& entry_name = folder.get_name(entry->_pidl); + // search for an already existing subdirectory entry with the same name + for(ShellEntryMap::iterator it=_entries.begin(); it!=_entries.end(); ++it) { + StartMenuEntry& sme = it->second; + + if (sme._title == entry_name) + for(ShellEntrySet::iterator it2=sme._entries.begin(); it2!=sme._entries.end(); ++it2) { + if ((*it2)->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + // merge the new shell entry with the existing of the same name + sme._entries.insert(entry); + return sme; + } + } + } + StartMenuEntry& sme = AddEntry(entry_name, hIcon); - sme._entry = entry; + sme._entries.insert(entry); return sme; } @@ -432,25 +446,35 @@ void StartMenu::CreateSubmenu(int id, const StartMenuFolders& new_folders, CREAT } -void StartMenu::ActivateEntry(int id, ShellEntry* entry) +void StartMenu::ActivateEntry(int id, const ShellEntrySet& entries) { - if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + StartMenuFolders new_folders; + + for(ShellEntrySet::const_iterator it=entries.begin(); it!=entries.end(); ++it) { + ShellEntry* entry = const_cast(*it); + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + new_folders.push_back(entry->create_absolute_pidl(_hwnd)); + else { + // If the entry is no subdirectory, there can only be one shell entry. + assert(entries.size()==1); + + entry->launch_entry(_hwnd); //TODO: launch in the background; specify correct HWND for error message box titles + + // close start menus after launching the selected entry + CloseStartMenu(id); + + // we deleted 'this' - ensure we leave loop and function + return; + } + } + + if (!new_folders.empty()) { // Only open one submenu at a time. if (!CloseOtherSubmenus(id)) return; - StartMenuFolders new_folders; - - new_folders.push_back(entry->create_absolute_pidl(_hwnd)); - - //TODO: merge all entries of subdirectories with the same name, like "All Users\...\Accessories" and "\...\Accessories" - CreateSubmenu(id, new_folders); - } else { - entry->launch_entry(_hwnd); //TODO: launch in the background; specify correct HWND for error message box titles - - // close start menus after launching the selected entry - CloseStartMenu(id); } } @@ -896,7 +920,11 @@ void RecentStartMenu::AddEntries() StartMenuDirectory& smd = *it; ShellDirectory& dir = smd._dir; - dir.smart_scan(); + if (!dir._scanned) { + WaitCursor wait; + + 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 b62b49a3eda..2a7c74e6e5c 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.h +++ b/reactos/subsys/system/explorer/taskbar/startmenu.h @@ -58,14 +58,15 @@ struct StartMenuDirectory }; typedef list StartMenuShellDirs; +typedef set ShellEntrySet; struct StartMenuEntry { - StartMenuEntry() : _hIcon(0), _entry(NULL) {} + StartMenuEntry() : _hIcon(0) {} String _title; HICON _hIcon; - const ShellEntry* _entry; + ShellEntrySet _entries; }; @@ -173,7 +174,7 @@ protected: void CreateSubmenu(int id, int folder, CREATORFUNC creator=s_def_creator); void CreateSubmenu(int id, int folder1, int folder2, CREATORFUNC creator=s_def_creator); void CreateSubmenu(int id, const StartMenuFolders& new_folders, CREATORFUNC creator=s_def_creator); - void ActivateEntry(int id, ShellEntry* entry); + void ActivateEntry(int id, const ShellEntrySet& entries); void CloseStartMenu(int id=0); };