merged start menus of the same name (e.g. "All Users\Startup" with "<User>\Startup")
authorMartin Fuchs <fuchs.martin@gmail.com>
Sat, 27 Sep 2003 21:20:32 +0000 (21:20 +0000)
committerMartin Fuchs <fuchs.martin@gmail.com>
Sat, 27 Sep 2003 21:20:32 +0000 (21:20 +0000)
svn path=/trunk/; revision=6170

reactos/subsys/system/explorer/Makefile.MinGW
reactos/subsys/system/explorer/doc/TODO.txt
reactos/subsys/system/explorer/doc/changes.txt
reactos/subsys/system/explorer/make_explorer.dsp
reactos/subsys/system/explorer/taskbar/startmenu.cpp
reactos/subsys/system/explorer/taskbar/startmenu.h

index ccb9196..a95dd3f 100644 (file)
@@ -4,13 +4,11 @@
 #  Makefile.MinGW
 #
 
 #  Makefile.MinGW
 #
 
-
 CC = gcc
 CXX = g++
 LINK = g++
 
 CFLAGS = -DWIN32 -D_ROS_ -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -fexceptions -Wall
 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
 
 RCFLAGS        = -DWIN32 -D_ROS_
 LFLAGS = -Wl,--subsystem,windows
 
@@ -29,6 +27,8 @@ CFLAGS        += -DUNICODE
 # LFLAGS+= -Wl,--entry,_wWinMain@16
 endif
 
 # LFLAGS+= -Wl,--entry,_wWinMain@16
 endif
 
+CXXFLAGS = $(CFLAGS)
+
 EXEC_SUFFIX = .exe
 RES_SUFFIX = .coff
 
 EXEC_SUFFIX = .exe
 RES_SUFFIX = .coff
 
@@ -71,5 +71,5 @@ explorer$(RES_SUFFIX): $(PROGRAM)_intres.rc
        windres $(RCFLAGS) -o $@ $^
 
 clean:
        windres $(RCFLAGS) -o $@ $^
 
 clean:
-       rm -f $(TARGET) *.o *$(RES_SUFFIX)
+       rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX)
 
 
index 751b13e..7fc7c44 100644 (file)
@@ -10,7 +10,6 @@
 - activate accelerator keys like <DEL> 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)
 - activate accelerator keys like <DEL> 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
 - Windows-key combos
 - Application Desktop Toolbars
 - desktop switching
index ae54047..aba5767 100644 (file)
@@ -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
                                                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 "<User>\Startup")
index 7a726a3..c52688a 100644 (file)
@@ -4,7 +4,7 @@
 
 # TARGTYPE "Win32 (x86) External Target" 0x0106
 
 
 # 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 
 !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 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 
 !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
 !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 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 ""
 # 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 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 ""
 
 # 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"
 !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"
 
 
 !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
 !ENDIF 
 
 # Begin Source File
index 2c4e1d8..722afc4 100644 (file)
@@ -94,8 +94,6 @@ HWND StartMenu::Create(int x, int y, const StartMenuFolders& folders, HWND hwndP
 
 LRESULT        StartMenu::Init(LPCREATESTRUCT pcs)
 {
 
 LRESULT        StartMenu::Init(LPCREATESTRUCT pcs)
 {
-       WaitCursor wait;
-
        try {
                AddEntries();
 
        try {
                AddEntries();
 
@@ -107,8 +105,9 @@ LRESULT     StartMenu::Init(LPCREATESTRUCT pcs)
                        const StartMenuEntry& sme = it->second;
                        bool hasSubmenu = false;
 
                        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);
                }
 
                        AddButton(sme._title, sme._hIcon, hasSubmenu, it->first);
                }
@@ -128,7 +127,11 @@ void StartMenu::AddEntries()
                StartMenuDirectory& smd = *it;
                ShellDirectory& dir = smd._dir;
 
                StartMenuDirectory& smd = *it;
                ShellDirectory& dir = smd._dir;
 
-               dir.smart_scan();
+               if (!dir._scanned) {
+                       WaitCursor wait;
+
+                       dir.smart_scan();
+               }
 
                AddShellEntries(dir, -1, smd._subfolders);
        }
 
                AddShellEntries(dir, -1, smd._subfolders);
        }
@@ -255,13 +258,10 @@ int StartMenu::Command(int id, int code)
                break;
 
          default: {
                break;
 
          default: {
-               ShellEntryMap::const_iterator found = _entries.find(id);
+               ShellEntryMap::iterator found = _entries.find(id);
 
                if (found != _entries.end()) {
 
                if (found != _entries.end()) {
-                       ShellEntry* entry = const_cast<ShellEntry*>(found->second._entry);
-
-                       if (entry)
-                               ActivateEntry(id, entry);
+                       ActivateEntry(id, found->second._entries);
                        break;
                }
 
                        break;
                }
 
@@ -294,9 +294,23 @@ StartMenuEntry& StartMenu::AddEntry(const ShellFolder folder, const ShellEntry*
 
        const String& entry_name = folder.get_name(entry->_pidl);
 
 
        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);
 
        StartMenuEntry& sme = AddEntry(entry_name, hIcon);
 
-       sme._entry = entry;
+       sme._entries.insert(entry);
 
        return sme;
 }
 
        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) {
-                // Only open one submenu at a time.
-               if (!CloseOtherSubmenus(id))
-                       return;
+       StartMenuFolders new_folders;
 
 
-               StartMenuFolders new_folders;
+       for(ShellEntrySet::const_iterator it=entries.begin(); it!=entries.end(); ++it) {
+               ShellEntry* entry = const_cast<ShellEntry*>(*it);
 
 
-               new_folders.push_back(entry->create_absolute_pidl(_hwnd));
+               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);
 
 
-               //TODO: merge all entries of subdirectories with the same name, like "All Users\...\Accessories" and "<user>\...\Accessories"
+                       entry->launch_entry(_hwnd);     //TODO: launch in the background; specify correct HWND for error message box titles
 
 
-               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);
 
 
-                // 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;
+
+               CreateSubmenu(id, new_folders);
        }
 }
 
        }
 }
 
@@ -896,7 +920,11 @@ void RecentStartMenu::AddEntries()
                StartMenuDirectory& smd = *it;
                ShellDirectory& dir = smd._dir;
 
                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
 
                dir.sort_directory(SORT_DATE);
                AddShellEntries(dir, 16, smd._subfolders);      //TODO: read max. count of entries from registry
index b62b49a..2a7c74e 100644 (file)
@@ -58,14 +58,15 @@ struct StartMenuDirectory
 };
 
 typedef list<StartMenuDirectory> StartMenuShellDirs;
 };
 
 typedef list<StartMenuDirectory> StartMenuShellDirs;
+typedef set<const ShellEntry*> ShellEntrySet;
 
 struct StartMenuEntry
 {
 
 struct StartMenuEntry
 {
-       StartMenuEntry() : _hIcon(0), _entry(NULL) {}
+       StartMenuEntry() : _hIcon(0) {}
 
        String  _title;
        HICON   _hIcon;
 
        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    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);
 };
 
        void    CloseStartMenu(int id=0);
 };