implemented command line parser for Explorer

svn path=/trunk/; revision=18284
This commit is contained in:
Martin Fuchs 2005-10-05 23:05:13 +00:00
parent 361239a411
commit 499bb6d2d7
7 changed files with 190 additions and 57 deletions

View file

@ -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-08002B30309D}" (launch of control panel)
- Windows-key combos
- Application Desktop Toolbars
- hide CVS subdirectories, may be even implement a CVS managment plugin

View file

@ -533,8 +533,10 @@ ResBitmap::ResBitmap(UINT nid)
#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 @@ void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine)
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 @@ static void InitInstance(HINSTANCE hInstance)
}
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 @@ int explorer_main(HINSTANCE hInstance, LPTSTR lpCmdLine, int cmdshow)
}
#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 @@ int main(int argc, char* argv[])
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 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
#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();

View file

@ -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-08002B30309D}" (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

View file

@ -228,6 +228,8 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
_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));

View file

@ -38,12 +38,12 @@ extern HWND create_webchildwindow(const WebChildWndInfo& info);
#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 @@ HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow)
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 @@ LRESULT MDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
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 @@ int MDIMainFrame::Command(int id, int code)
break;
case ID_VIEW_SDI:
MainFrameBase::Create(NULL, false);
MainFrameBase::Create(ExplorerCmd());
break;
case IDW_COMMANDBAR:
@ -1516,7 +1504,7 @@ LRESULT SDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
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 @@ int SDIMainFrame::Command(int id, int code)
{
switch(id) {
case ID_VIEW_MDI:
MainFrameBase::Create(_url, true);
MainFrameBase::Create(ExplorerCmd(_url, true));
break;
case IDW_COMMANDBAR:
@ -1632,6 +1620,8 @@ void SDIMainFrame::update_shell_browser()
delete _shellBrowser.release();
}
///@todo use OWM_ROOTED flag
// create explorer treeview
if (_shellpath_info._open_mode & OWM_EXPLORE) {
if (!_left_hwnd) {

View file

@ -27,7 +27,14 @@
#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
@ -38,7 +45,7 @@ struct MainFrameBase : public PreTranslateWindow
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;

View file

@ -112,17 +112,17 @@ void ShellBrowser::jump_to(LPCITEMIDLIST pidl)
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 @@ LRESULT MDIShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
break;
case ID_VIEW_SDI:
MainFrameBase::Create(_url, false);
MainFrameBase::Create(ExplorerCmd(_url, false));
break;
default:
@ -606,6 +606,8 @@ void MDIShellBrowserChild::update_shell_browser()
delete _shellBrowser.release();
}
///@todo use OWM_ROOTED flag
// create explorer treeview
if (_create_info._open_mode & OWM_EXPLORE) {
if (!_left_hwnd) {