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) {