implemented command line parser for Explorer Modified: trunk/reactos/subsys/system/explorer/doc/TODO.txt Modified: trunk/reactos/subsys/system/explorer/explorer.cpp Modified: trunk/reactos/subsys/system/explorer/explorer.h Modified: trunk/reactos/subsys/system/explorer/shell/filechild.cpp Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.h Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp _____
Modified: trunk/reactos/subsys/system/explorer/doc/TODO.txt --- trunk/reactos/subsys/system/explorer/doc/TODO.txt 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/doc/TODO.txt 2005-10-05 23:05:13 UTC (rev 18284) @@ -7,7 +7,6 @@
- implement Drag Drop from the tree view. - 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-080 02B30309D}" (launch of control panel) - Windows-key combos - Application Desktop Toolbars - hide CVS subdirectories, may be even implement a CVS managment plugin _____
Modified: trunk/reactos/subsys/system/explorer/explorer.cpp --- trunk/reactos/subsys/system/explorer/explorer.cpp 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/explorer.cpp 2005-10-05 23:05:13 UTC (rev 18284) @@ -533,8 +533,10 @@
#ifndef ROSSHELL
-void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine) +void explorer_show_frame(int cmdShow, LPTSTR lpCmdLine) { + ExplorerCmd cmd; + if (g_Globals._hMainWnd) { if (IsIconic(g_Globals._hMainWnd)) ShowWindow(g_Globals._hMainWnd, SW_RESTORE); @@ -553,21 +555,121 @@ if (mdiStr.empty()) Dialog::DoModal(IDD_MDI_SDI, WINDOW_CREATOR(MdiSdiDlg), g_Globals._hwndDesktop);
- // Now read the setting again and interpret it as boolean value. - bool mdi = XMLBool(explorer_options, "mdi", true); + // Now read the MDI attribute again and interpret it as boolean value. + cmd._mdi = XMLBool(explorer_options, "mdi", true);
+ cmd._cmdShow = cmdShow; + + // parse command line options, which may overwrite the MDI flag + cmd.ParseCmdLine(lpCmdLine); + // create main window - MainFrameBase::Create(lpCmdLine, mdi, cmdshow); + MainFrameBase::Create(cmd); }
+bool ExplorerCmd::ParseCmdLine(LPCTSTR lpCmdLine) +{ + bool ok = true; + + LPCTSTR b = lpCmdLine; + LPCTSTR p = b; + + while(*b) { + // remove leading space + while(_istspace((unsigned)*b)) + ++b; + + p = b; + + bool quote = false; + + // options are separated by ',' + for(; *p; ++p) { + if (*p == '"') // Quote characters may appear at any position in the command line. + quote = !quote; + else if (*p==',' && !quote) + break; + } + + if (p > b) { + int l = p - b; + + // remove trailing space + while(l>0 && _istspace((unsigned)b[l-1])) + --l; + + if (!EvaluateOption(String(b, l))) + ok = false; + + if (*p) + ++p; + + b = p; + } + } + + return ok; +} + +bool ExplorerCmd::EvaluateOption(LPCTSTR option) +{ + String opt_str; + + // Remove quote characters, as they are evaluated at this point. + for(; *option; ++option) + if (*option != '"') + opt_str += *option; + + option = opt_str; + + if (option[0] == '/') { + ++option; + + // option /e for windows in explorer mode + if (!_tcsicmp(option, TEXT("e"))) + _flags |= OWM_EXPLORE; + // option /root for rooted explorer windows + else if (!_tcsicmp(option, TEXT("root"))) + _flags |= OWM_ROOTED; + // non-standard options: /mdi, /sdi + else if (!_tcsicmp(option, TEXT("mdi"))) + _mdi = true; + else if (!_tcsicmp(option, TEXT("sdi"))) + _mdi = false; + else + return false; + } else { + if (!_path.empty()) + return false; + + _path = opt_str; + } + + return true; +} + +bool ExplorerCmd::IsValidPath() const +{ + if (!_path.empty()) { + DWORD attribs = GetFileAttributes(_path); + + if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY)) + return true; // file system path + else if (*_path==':' && _path.at(1)==':') + return true; // text encoded IDL + } + + return false; +} + #else
-void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine) +void explorer_show_frame(int cmdShow, LPTSTR lpCmdLine) { if (!lpCmdLine) lpCmdLine = TEXT("explorer.exe");
- launch_file(GetDesktopWindow(), lpCmdLine, cmdshow); + launch_file(GetDesktopWindow(), lpCmdLine, cmdShow); }
#endif @@ -671,7 +773,7 @@ }
-int explorer_main(HINSTANCE hInstance, LPTSTR lpCmdLine, int cmdshow) +int explorer_main(HINSTANCE hInstance, LPTSTR lpCmdLine, int cmdShow) { CONTEXT("explorer_main");
@@ -686,14 +788,14 @@ }
#ifndef ROSSHELL - if (cmdshow != SW_HIDE) { + if (cmdShow != SW_HIDE) { /* // don't maximize if being called from the ROS desktop - if (cmdshow == SW_SHOWNORMAL) + if (cmdShow == SW_SHOWNORMAL) ///@todo read window placement from registry - cmdshow = SW_MAXIMIZE; + cmdShow = SW_MAXIMIZE; */
- explorer_show_frame(cmdshow, lpCmdLine); + explorer_show_frame(cmdShow, lpCmdLine); } #endif
@@ -721,10 +823,10 @@
LPWSTR cmdline = GetCommandLineW();
- while(*cmdline && !_istspace(*cmdline)) + while(*cmdline && !_istspace((unsigned)*cmdline)) ++cmdline;
- while(_istspace(*cmdline)) + while(_istspace((unsigned)*cmdline)) ++cmdline;
return wWinMain(GetModuleHandle(NULL), 0, cmdline, nShowCmd); @@ -929,17 +1031,12 @@ #ifndef ROSSHELL if (g_Globals._hwndDesktop) g_Globals._desktop_mode = true; - - /**TODO fix command line handling */ - if (*lpCmdLine=='"' && lpCmdLine[_tcslen(lpCmdLine)-1]=='"') { - ++lpCmdLine; - lpCmdLine[_tcslen(lpCmdLine)-1] = '\0'; - } #endif
int ret = explorer_main(hInstance, lpCmdLine, nShowCmd);
+ // write configuration file g_Globals.write_persistent();
_____
Modified: trunk/reactos/subsys/system/explorer/explorer.h --- trunk/reactos/subsys/system/explorer/explorer.h 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/explorer.h 2005-10-05 23:05:13 UTC (rev 18284) @@ -72,6 +72,42 @@
#include "shell/filechild.h" #include "shell/shellbrowser.h"
+ #ifndef ROSSHELL + + /// Explorer command line parser + // for commands like "/e,/root,c:" + // or "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}::{21EC2020-3AEA-1069-A2DD-080 02B30309D}" (launch of control panel) +struct ExplorerCmd +{ + ExplorerCmd() + : _flags(0), + _cmdShow(SW_SHOWNORMAL), + _mdi(false), + _valid_path(false) + { + } + + ExplorerCmd(LPCTSTR url, bool mdi) + : _path(url), + _flags(0), + _cmdShow(SW_SHOWNORMAL), + _mdi(mdi), + _valid_path(true) //@@ + { + } + + bool ParseCmdLine(LPCTSTR lpCmdLine); + bool EvaluateOption(LPCTSTR option); + bool IsValidPath() const; + + String _path; + int _flags; // OPEN_WINDOW_MODE + int _cmdShow; + bool _mdi; + bool _valid_path; +}; + #include "shell/mainframe.h" + #endif _____
Modified: trunk/reactos/subsys/system/explorer/shell/filechild.cpp --- trunk/reactos/subsys/system/explorer/shell/filechild.cpp 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/shell/filechild.cpp 2005-10-05 23:05:13 UTC (rev 18284) @@ -228,6 +228,8 @@
_root._entry->_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+ ///@todo use OWM_ROOTED flag + if (info._open_mode & OWM_EXPLORE) ///@todo Is not-explore-mode for FileChildWindow completely implemented? _left_hwnd = *(_left=new Pane(_hwnd, IDW_TREE_LEFT, IDW_HEADER_LEFT, _root._entry, true, COL_CONTENT));
_____
Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.cpp --- trunk/reactos/subsys/system/explorer/shell/mainframe.cpp 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/shell/mainframe.cpp 2005-10-05 23:05:13 UTC (rev 18284) @@ -38,12 +38,12 @@
#include "../dialogs/settings.h" // for MdiSdiDlg
-HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow) +HWND MainFrameBase::Create(const ExplorerCmd& cmd) { HWND hFrame;
-#ifndef _NO_MDI ///@todo implement command line option to switch between MDI and SDI - if (mdi) +#ifndef _NO_MDI + if (cmd._mdi) hFrame = MDIMainFrame::Create(); else #endif @@ -54,32 +54,20 @@
g_Globals._hMainWnd = hFrame;
- if (path) { - static String sPath = path; // copy path to avoid accessing freed memory - path = sPath; - } - if (hwndOld) DestroyWindow(hwndOld);
- ShowWindow(hFrame, cmdshow); + ShowWindow(hFrame, cmd._cmdShow); UpdateWindow(hFrame);
- bool valid_dir = false; - - if (path) { - DWORD attribs = GetFileAttributes(path); - - if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY)) - valid_dir = true; - else if (*path==':' || *path=='"') - valid_dir = true; - } - // Open the first child window after initializing the application - if (valid_dir) - PostMessage(hFrame, PM_OPEN_WINDOW, 0, (LPARAM)path); - else + if (cmd.IsValidPath()) { + // We use the static s_path variable to store the path string in order + // to avoid accessing prematurely freed memory in the PostMessage handlers. + static String s_path = cmd._path; + + PostMessage(hFrame, PM_OPEN_WINDOW, cmd._flags, (LPARAM)(LPCTSTR)s_path); + } else PostMessage(hFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0); }
@@ -989,7 +977,7 @@ create_info._pos.rcNormalPosition.right = CW_USEDEFAULT; create_info._pos.rcNormalPosition.bottom = CW_USEDEFAULT;
- create_info._open_mode = (OPEN_WINDOW_MODE)wparam; + create_info._open_mode = wparam;
// FileChildWindow::create(_hmdiclient, create_info); return (LRESULT)MDIShellBrowserChild::create(create_info); @@ -1149,7 +1137,7 @@ break;
case ID_VIEW_SDI: - MainFrameBase::Create(NULL, false); + MainFrameBase::Create(ExplorerCmd()); break;
case IDW_COMMANDBAR: @@ -1516,7 +1504,7 @@ root_path = path; }
- jump_to(root_path, (OPEN_WINDOW_MODE)wparam); //@todo content of 'path' not used any more + jump_to(root_path, wparam); //@todo content of 'path' not used any more return TRUE;} // success
default: def: @@ -1530,7 +1518,7 @@ { switch(id) { case ID_VIEW_MDI: - MainFrameBase::Create(_url, true); + MainFrameBase::Create(ExplorerCmd(_url, true)); break;
case IDW_COMMANDBAR: @@ -1632,6 +1620,8 @@ delete _shellBrowser.release(); }
+ ///@todo use OWM_ROOTED flag + // create explorer treeview if (_shellpath_info._open_mode & OWM_EXPLORE) { if (!_left_hwnd) { _____
Modified: trunk/reactos/subsys/system/explorer/shell/mainframe.h --- trunk/reactos/subsys/system/explorer/shell/mainframe.h 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/shell/mainframe.h 2005-10-05 23:05:13 UTC (rev 18284) @@ -27,9 +27,16 @@
#define PM_OPEN_WINDOW (WM_APP+0x07) -enum OPEN_WINDOW_MODE {OWM_EXPLORE=1, OWM_DETAILS=2, OWM_PIDL=4, OWM_SEPARATE=8};
+enum OPEN_WINDOW_MODE { + OWM_EXPLORE=1, /// window in explore mode + OWM_ROOTED=2, /// "rooted" window with special shell namespace root + OWM_DETAILS=4, /// view files in detail mode + OWM_PIDL=8, /// path is given as PIDL, otherwise as LPCTSTR + OWM_SEPARATE=16 /// open separate subfolder windows +};
+ /// Explorer frame window base class struct MainFrameBase : public PreTranslateWindow { @@ -38,7 +45,7 @@ MainFrameBase(HWND hwnd); ~MainFrameBase();
- static HWND Create(LPCTSTR path, bool mdi=true, UINT cmdshow=SW_SHOWNORMAL); + static HWND Create(const ExplorerCmd& cmd); static int OpenShellFolders(LPIDA pida, HWND hFrameWnd);
WindowHandle _hwndrebar; _____
Modified: trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp --- trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp 2005-10-05 20:36:23 UTC (rev 18283) +++ trunk/reactos/subsys/system/explorer/shell/shellbrowser.cpp 2005-10-05 23:05:13 UTC (rev 18284) @@ -112,17 +112,17 @@
if (!_cur_dir) _cur_dir = static_cast<ShellDirectory*>(_root._entry);
-/*@todo - we should call read_tree() here to iterate through the hierarchy and open all folders from shell_info._root_shell_path to shell_info._shell_path - _root._entry->read_tree(shell_info._root_shell_path.get_folder(), info._shell_path, SORT_NAME); - -> see FileChildWindow::FileChildWindow() -*/ + //LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl)));
- LOG(FmtString(TEXT("ShellBrowser::jump_to(): pidl=%s"), (LPCTSTR)FileSysShellPath(pidl))); - if (_cur_dir) { static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST, LPCITEMIDLIST)> ILFindChild(TEXT("SHELL32"), 24);
+/*@todo + we should call read_tree() here to iterate through the hierarchy and open all folders from _create_info._root_shell_path (_cur_dir) to _create_info._shell_path (pidl) + _root._entry->read_tree(_create_info._root_shell_path.get_folder(), info._shell_path, SORT_NAME); + -> see FileChildWindow::FileChildWindow()_create_info._shell_path +*/ + LPCITEMIDLIST child_pidl;
if (ILFindChild) @@ -582,7 +582,7 @@ break;
case ID_VIEW_SDI: - MainFrameBase::Create(_url, false); + MainFrameBase::Create(ExplorerCmd(_url, false)); break;
default: @@ -606,6 +606,8 @@ delete _shellBrowser.release(); }
+ ///@todo use OWM_ROOTED flag + // create explorer treeview if (_create_info._open_mode & OWM_EXPLORE) { if (!_left_hwnd) {