/*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <fcntl.h> // for _O_RDONLY
#endif
+#include "dialogs/settings.h" // for MdiSdiDlg
+
+#include "services/shellservices.h"
+
extern "C" int initialize_gdb_stub(); // start up GDB stub
+DynamicLoadLibFct<void(__stdcall*)(BOOL)> g_SHDOCVW_ShellDDEInit(TEXT("SHDOCVW"), 118);
+
+
ExplorerGlobals g_Globals;
ExplorerGlobals::ExplorerGlobals()
{
_hInstance = 0;
- _hframeClass = 0;
_cfStrFName = 0;
+
+#ifndef ROSSHELL
+ _hframeClass = 0;
_hMainWnd = 0;
- _prescan_nodes = false;
_desktop_mode = false;
+ _prescan_nodes = false;
+#endif
+
_log = NULL;
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
_SHRestricted = 0;
XMLPos ExplorerGlobals::get_cfg()
{
- XMLPos pos(&_cfg);
+ XMLPos cfg_pos(&_cfg);
- pos.smart_create("explorer-cfg");
+ cfg_pos.smart_create("explorer-cfg");
- return pos;
+ return cfg_pos;
}
-XMLPos ExplorerGlobals::get_cfg(const String& name)
+XMLPos ExplorerGlobals::get_cfg(const char* path)
{
- XMLPos pos(&_cfg);
+ XMLPos cfg_pos(&_cfg);
- pos.smart_create("explorer-cfg");
- pos.smart_create(name);
+ cfg_pos.smart_create("explorer-cfg");
+ cfg_pos.create_relative(path);
- return pos;
+ return cfg_pos;
}
SHFILEINFO sfi;
-#if 1 // use system image list
+#if 1 // use system image list - the "search program dialog" needs it
HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
if (himlSys) {
HRESULT hr = pExtract->Extract(path, idx, &hIconLarge, &hIcon, MAKELONG(0/*GetSystemMetrics(SM_CXICON)*/,GetSystemMetrics(SM_CXSMICON)));
- if (hr == NOERROR) {
+ if (hr == NOERROR) { //@@ oder SUCCEEDED(hr) ?
if (hIconLarge)
DestroyIcon(hIconLarge);
}
+#ifndef ROSSHELL
+
void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine)
{
if (g_Globals._hMainWnd) {
g_Globals._prescan_nodes = false;
- // create main window
- HWND hMainFrame = MainFrame::Create();
+ XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
+ XS_String mdiStr = XMLString(explorer_options, "mdi");
- if (hMainFrame) {
- g_Globals._hMainWnd = hMainFrame;
+ if (mdiStr.empty())
+ Dialog::DoModal(IDD_MDI_SDI, WINDOW_CREATOR(MdiSdiDlg), g_Globals._hwndDesktop);
- ShowWindow(hMainFrame, cmdshow);
- UpdateWindow(hMainFrame);
+ bool mdi = XMLBool(explorer_options, "mdi", true);
- bool valid_dir = false;
+ // create main window
+ MainFrameBase::Create(lpCmdLine, mdi, cmdshow);
+}
- if (lpCmdLine) {
- DWORD attribs = GetFileAttributes(lpCmdLine);
+#else
- if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY))
- valid_dir = true;
- else if (*lpCmdLine==':' || *lpCmdLine=='"')
- valid_dir = true;
- }
+void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine)
+{
+ if (!lpCmdLine)
+ lpCmdLine = TEXT("explorer.exe");
- // Open the first child window after initializing the application
- if (valid_dir)
- PostMessage(hMainFrame, PM_OPEN_WINDOW, 0, (LPARAM)lpCmdLine);
- else
- PostMessage(hMainFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0);
- }
+ launch_file(GetDesktopWindow(), lpCmdLine, cmdshow);
}
+#endif
+
PopupMenu::PopupMenu(UINT nid)
{
new HyperlinkCtrl(hwnd, IDC_WWW);
+ FmtString ver_txt(ResString(IDS_EXPLORER_VERSION_STR), (LPCTSTR)ResString(IDS_VERSION_STR));
+ SetWindowText(GetDlgItem(hwnd, IDC_VERSION_TXT), ver_txt);
+
+ HWND hwnd_winver = GetDlgItem(hwnd, IDC_WIN_VERSION);
+ SetWindowText(hwnd_winver, get_windows_version_str());
+ SetWindowFont(hwnd_winver, GetStockFont(DEFAULT_GUI_FONT), FALSE);
+
CenterWindow(hwnd);
}
setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName
+#ifndef ROSSHELL
// register frame window class
g_Globals._hframeClass = IconWindowClass(CLASSNAME_FRAME,IDI_EXPLORER);
- // register child windows class
+ // register child window class
WindowClass(CLASSNAME_CHILDWND, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register();
- // register tree windows class
+ // register tree window class
WindowClass(CLASSNAME_WINEFILETREE, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register();
+#endif
g_Globals._cfStrFName = RegisterClipboardFormat(CFSTR_FILENAME);
}
return -1;
}
+#ifndef ROSSHELL
if (cmdshow != SW_HIDE) {
/* // don't maximize if being called from the ROS desktop
if (cmdshow == SW_SHOWNORMAL)
explorer_show_frame(cmdshow, lpCmdLine);
}
+#endif
return Window::MessageLoop();
}
while(*cmdline && !_istspace(*cmdline))
++cmdline;
+ while(_istspace(*cmdline))
+ ++cmdline;
+
return wWinMain(GetModuleHandle(NULL), 0, cmdline, nShowCmd);
}
#endif // __MINGW && UNICODE
+static bool SetShellReadyEvent(LPCTSTR evtName)
+{
+ HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, evtName);
+ if (!hEvent)
+ return false;
+
+ SetEvent(hEvent);
+ CloseHandle(hEvent);
+
+ return true;
+}
+
+
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
CONTEXT("WinMain()");
RegSetValueEx(hkey, TEXT("Shell"), 0, REG_SZ, (LPBYTE)path, l*sizeof(TCHAR));
RegCloseKey(hkey);
}
+
+ if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hkey)) {
+
+ ///@todo save previous shell application in config file
+
+ RegSetValueEx(hkey, TEXT("Shell"), 0, REG_SZ, (LPBYTE)TEXT(""), l*sizeof(TCHAR));
+ RegCloseKey(hkey);
+ }
}
HWND shellWindow = GetShellWindow();
}
startup_desktop = TRUE;
- } else
+ } else {
// create desktop window and task bar only, if there is no other shell and we are
// the first explorer instance
+ // MS Explorer looks additionally into the registry entry HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\shell,
+ // to decide wether it is currently configured as shell application.
startup_desktop = !any_desktop_running;
+ }
+
bool autostart = !any_desktop_running;
// If there is given the command line option "-desktop", create desktop window anyways
if (_tcsstr(lpCmdLine,TEXT("-desktop")))
startup_desktop = TRUE;
+#ifndef ROSSHELL
else if (_tcsstr(lpCmdLine,TEXT("-nodesktop")))
startup_desktop = FALSE;
// Don't display cabinet window in desktop mode
if (startup_desktop && !_tcsstr(lpCmdLine,TEXT("-explorer")))
nShowCmd = SW_HIDE;
+#endif
if (_tcsstr(lpCmdLine,TEXT("-noautostart")))
autostart = false;
}
#endif
+
+ if (startup_desktop) {
+ // hide the XP login screen (Credit to Nicolas Escuder)
+ // another undocumented event: "Global\\msgina: ReturnToWelcome"
+ if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
+ SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
+ }
+#ifdef ROSSHELL
+ else
+ return 0; // no shell to launch, so exit immediatelly
+#endif
+
+
+ if (!any_desktop_running) {
+ // launch the shell DDE server
+ if (g_SHDOCVW_ShellDDEInit)
+ (*g_SHDOCVW_ShellDDEInit)(TRUE);
+ }
+
+
bool use_gdb_stub = false; // !IsDebuggerPresent();
if (_tcsstr(lpCmdLine,TEXT("-debug")))
g_Globals.read_persistent();
if (startup_desktop) {
+ WaitCursor wait;
+
g_Globals._desktops.init();
g_Globals._hwndDesktop = DesktopWindow::Create();
#ifdef _USE_HDESK
g_Globals._desktops.get_current_Desktop()->_hwndDesktop = g_Globals._hwndDesktop;
#endif
+ }
- if (autostart) {
- char* argv[] = {"", "s"}; // call startup routine in SESSION_START mode
- startup(2, argv);
- }
+ Thread* pSSOThread = NULL;
+
+ if (startup_desktop) {
+ // launch SSO thread to allow message processing independent from the explorer main thread
+ pSSOThread = new SSOThread;
+ pSSOThread->Start();
+ }
+
+ /**TODO launching autostart programs can be moved into a background thread. */
+ if (autostart) {
+ char* argv[] = {"", "s"}; // call startup routine in SESSION_START mode
+ startup(2, argv);
}
+#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
- if (g_Globals._hwndDesktop)
- g_Globals._desktop_mode = true;
int ret = explorer_main(hInstance, lpCmdLine, nShowCmd);
// write configuration file
g_Globals.write_persistent();
+ if (pSSOThread) {
+ pSSOThread->Stop();
+ delete pSSOThread;
+ }
+
+ if (!any_desktop_running) {
+ // shutdown the shell DDE server
+ if (g_SHDOCVW_ShellDDEInit)
+ (*g_SHDOCVW_ShellDDEInit)(FALSE);
+ }
+
return ret;
}