From b0665e94ab38e070baa7f2db6106d6e63422520a Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Thu, 18 Sep 2003 22:18:38 +0000 Subject: [PATCH] compatibility changes for correct start menu subentries on Windows 9x svn path=/trunk/; revision=6094 --- .../subsys/system/explorer/doc/changes.txt | 2 + reactos/subsys/system/explorer/explorer.cpp | 21 +++- .../system/explorer/taskbar/startmenu.cpp | 27 ++--- .../system/explorer/utility/shellclasses.cpp | 110 +++++++++++++++--- .../system/explorer/utility/shellclasses.h | 52 +-------- .../subsys/system/explorer/utility/utility.h | 41 +++++++ 6 files changed, 170 insertions(+), 83 deletions(-) diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index d6a8eb3d8af..649fad2e1a9 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -32,3 +32,5 @@ 28.08.2003 m. fuchs control panel window in cabinet view mode 29.09.2003 m. fuchs Now we handle start menu popups via StartMenuRoot::TrackStartmenu(). 30.09.2003 m. fuchs compatibility to building as Winelib application +10.09.2003 m. fuchs compatibility changes for correct desktop windows size on Windows NT +19.09.2003 m. fuchs compatibility changes for correct start menu subentries on Windows 9x diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index 43a10f38160..9b411f617e4 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -159,6 +159,12 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL // the first explorer instance BOOL startup_desktop = !IsAnyDesktopRunning(); + bool autostart = true; + +#ifdef _DEBUG //MF: disabled for debugging + autostart = false; +#endif + // If there is given the command line option "-desktop", create desktop window anyways if (!lstrcmp(lpCmdLine,TEXT("-desktop"))) startup_desktop = TRUE; @@ -171,6 +177,14 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL startup_desktop = TRUE; } + if (!lstrcmp(lpCmdLine,TEXT("-noautostart"))) + autostart = false; + +//REMOTE DBG +startup_desktop = TRUE; +nShowCmd = SW_HIDE; + + g_Globals._hInstance = hInstance; HWND hwndDesktop = 0; @@ -179,12 +193,11 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL { hwndDesktop = DesktopWindow::Create(); -#ifndef _DEBUG //MF: disabled for debugging + if (autostart) { - char* argv[] = {""}; - startup(1, argv); + char* argv[] = {""}; + startup(1, argv); } -#endif } int ret = explorer_main(hInstance, hwndDesktop, nShowCmd); diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index a7d1ca47389..e51cef2cc5d 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -777,8 +777,7 @@ void StartMenuRoot::ShowLaunchDialog(HWND hwndDesktopBar) static LPCSTR szTitle = "Create New Task"; static LPCSTR szText = "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you."; - HMODULE hShell32 = GetModuleHandle(_T("SHELL32")); - RUNFILEDLG RunFileDlg = (RUNFILEDLG)GetProcAddress(hShell32, (LPCSTR)61); + static DynamicFct RunFileDlg(_T("SHELL32"), 61); // Show "Run..." dialog if (RunFileDlg) { @@ -789,47 +788,43 @@ void StartMenuRoot::ShowLaunchDialog(HWND hwndDesktopBar) MultiByteToWideChar(CP_ACP, 0, szTitle, -1, wTitle, 40); MultiByteToWideChar(CP_ACP, 0, szText, -1, wText, 256); - RunFileDlg(hwndDesktopBar, 0, NULL, (LPCSTR)wTitle, (LPCSTR)wText, RFF_CALCDIRECTORY); + (*RunFileDlg)(hwndDesktopBar, 0, NULL, (LPCSTR)wTitle, (LPCSTR)wText, RFF_CALCDIRECTORY); } else - RunFileDlg(hwndDesktopBar, 0, NULL, szTitle, szText, RFF_CALCDIRECTORY); + (*RunFileDlg)(hwndDesktopBar, 0, NULL, szTitle, szText, RFF_CALCDIRECTORY); } } void StartMenuRoot::ShowExitWindowsDialog(HWND hwndOwner) { - HMODULE hShell32 = GetModuleHandle(_T("SHELL32")); - EXITWINDOWSDLG ExitWindowsDlg = (EXITWINDOWSDLG)GetProcAddress(hShell32, (LPCSTR)60); + static DynamicFct ExitWindowsDlg(_T("SHELL32"), 60); if (ExitWindowsDlg) - ExitWindowsDlg(hwndOwner); + (*ExitWindowsDlg)(hwndOwner); } void StartMenuRoot::ShowRestartDialog(HWND hwndOwner, UINT flags) { - HMODULE hShell32 = GetModuleHandle(_T("SHELL32")); - RESTARTWINDOWSDLG RestartDlg = (RESTARTWINDOWSDLG)GetProcAddress(hShell32, (LPCSTR)59); + static DynamicFct RestartDlg(_T("SHELL32"), 59); if (RestartDlg) - RestartDlg(hwndOwner, (LPWSTR)L"You selected .\n\n", flags); //TODO: ANSI string conversion if needed + (*RestartDlg)(hwndOwner, (LPWSTR)L"You selected .\n\n", flags); //TODO: ANSI string conversion if needed } void StartMenuRoot::ShowSearchDialog() { - HMODULE hShell32 = GetModuleHandle(_T("SHELL32")); - SHFINDFILES SHFindFiles = (SHFINDFILES)GetProcAddress(hShell32, (LPCSTR)90); + static DynamicFct SHFindFiles(_T("SHELL32"), 90); if (SHFindFiles) - SHFindFiles(NULL, NULL); + (*SHFindFiles)(NULL, NULL); } void StartMenuRoot::ShowSearchComputer() { - HMODULE hShell32 = GetModuleHandle(_T("SHELL32")); - SHFINDCOMPUTER SHFindComputer = (SHFINDCOMPUTER)GetProcAddress(hShell32, (LPCSTR)91); + static DynamicFct SHFindComputer(_T("SHELL32"), 91); if (SHFindComputer) - SHFindComputer(NULL, NULL); + (*SHFindComputer)(NULL, NULL); } diff --git a/reactos/subsys/system/explorer/utility/shellclasses.cpp b/reactos/subsys/system/explorer/utility/shellclasses.cpp index aa6d929eda2..6438b34c650 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.cpp +++ b/reactos/subsys/system/explorer/utility/shellclasses.cpp @@ -35,6 +35,31 @@ #pragma comment(lib, "shell32") // link to shell32.dll + // helper functions for string copying + +LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count) +{ + LPCSTR s; + LPSTR d = dest; + + for(s=source; count&&(*d++=*s++); ) + count--; + + return dest; +} + +LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count) +{ + LPCWSTR s; + LPWSTR d = dest; + + for(s=source; count&&(*d++=*s++); ) + count--; + + return dest; +} + + // Exception Handler for COM exceptions void HandleException(COMException& e, HWND hwnd) @@ -240,26 +265,83 @@ String ShellFolder::get_name(LPCITEMIDLIST pidl, SHGDNF flags) const } - // helper function for string copying - -LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count) +void ShellPath::split(ShellPath& parent, ShellPath& obj) const { - LPCSTR s; - LPSTR d = dest; + SHITEMID *piid, *piidLast; + int size = 0; - for(s=source; count&&(*d++=*s++); ) - count--; + // find last item-id and calculate total size of pidl + for(piid=piidLast=&_p->mkid; piid->cb; ) { + piidLast = piid; + size += (piid->cb); + piid = (SHITEMID*)((LPBYTE)piid + (piid->cb)); + } - return dest; + // copy parent folder portion + size -= piidLast->cb; // don't count "object" item-id + + if (size > 0) + parent.assign(_p, size); + + // copy "object" portion + obj.assign((ITEMIDLIST*)piidLast, piidLast->cb); } -LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count) +void ShellPath::GetUIObjectOf(REFIID riid, LPVOID* ppvOut, HWND hWnd, ShellFolder& sf) { - LPCWSTR s; - LPWSTR d = dest; + ShellPath parent, obj; - for(s=source; count&&(*d++=*s++); ) - count--; + split(parent, obj); - return dest; + LPCITEMIDLIST idl = obj; + + if (parent && parent->mkid.cb) + // use the IShellFolder of the parent + CheckError(ShellFolder((IShellFolder*)sf,parent)->GetUIObjectOf(hWnd, 1, &idl, riid, 0, ppvOut)); + else // else use desktop folder + CheckError(sf->GetUIObjectOf(hWnd, 1, &idl, riid, 0, ppvOut)); } + +#ifndef __MINGW32__ // ILCombine() is currently missing in MinGW. + + // convert an item id list from relative to absolute (=relative to the desktop) format +LPITEMIDLIST ShellPath::create_absolute_pidl(LPCITEMIDLIST parent_pidl, HWND hwnd) const +{ + return ILCombine(parent_pidl, _p); + +/* seems to work only for NT upwards + // create a new item id list with _p append behind parent_pidl + int l1 = _malloc->GetSize((void*)parent_pidl) - sizeof(USHORT/ SHITEMID::cb /); + int l2 = _malloc->GetSize(_p); + + LPITEMIDLIST p = (LPITEMIDLIST) _malloc->Alloc(l1+l2); + + memcpy(p, parent_pidl, l1); + memcpy((LPBYTE)p+l1, _p, l2); + + return p; +*/ +} + +#else + +LPITEMIDLIST ShellPath::create_absolute_pidl(LPCITEMIDLIST parent_pidl, HWND hwnd) const +{ + static DynamicFct ILCombine(_T("SHELL32"), 25); + + if (ILCombine.found()) + return ILCombine(parent_pidl, _p); + + // create a new item id list with _p append behind parent_pidl + int l1 = _malloc->GetSize((void*)parent_pidl) - sizeof(USHORT/*SHITEMID::cb*/); + int l2 = _malloc->GetSize(_p); + + LPITEMIDLIST p = (LPITEMIDLIST) _malloc->Alloc(l1+l2); + + memcpy(p, parent_pidl, l1); + memcpy((LPBYTE)p+l1, _p, l2); + + return p; +} + +#endif diff --git a/reactos/subsys/system/explorer/utility/shellclasses.h b/reactos/subsys/system/explorer/utility/shellclasses.h index 2340afae5f5..253c806cdcb 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.h +++ b/reactos/subsys/system/explorer/utility/shellclasses.h @@ -555,42 +555,9 @@ struct ShellPath : public SShellPtr _malloc->Free(h); } - void split(ShellPath& parent, ShellPath& obj) const - { - SHITEMID *piid, *piidLast; - int size = 0; - - // find last item-id and calculate total size of pidl - for(piid=piidLast=&_p->mkid; piid->cb; ) { - piidLast = piid; - size += (piid->cb); - piid = (SHITEMID*)((LPBYTE)piid + (piid->cb)); - } - - // copy parent folder portion - size -= piidLast->cb; // don't count "object" item-id + void split(ShellPath& parent, ShellPath& obj) const; - if (size > 0) - parent.assign(_p, size); - - // copy "object" portion - obj.assign((ITEMIDLIST*)piidLast, piidLast->cb); - } - - void GetUIObjectOf(REFIID riid, LPVOID* ppvOut, HWND hWnd=0, ShellFolder& sf=Desktop()) - { - ShellPath parent, obj; - - split(parent, obj); - - LPCITEMIDLIST idl = obj; - - if (parent && parent->mkid.cb) - // use the IShellFolder of the parent - CheckError(ShellFolder((IShellFolder*)sf,parent)->GetUIObjectOf(hWnd, 1, &idl, riid, 0, ppvOut)); - else // else use desktop folder - CheckError(sf->GetUIObjectOf(hWnd, 1, &idl, riid, 0, ppvOut)); - } + void GetUIObjectOf(REFIID riid, LPVOID* ppvOut, HWND hWnd=0, ShellFolder& sf=Desktop()); ShellFolder get_folder() { @@ -602,21 +569,8 @@ struct ShellPath : public SShellPtr return ShellFolder(parent, _p); } - // convert an item id list from relative to absolute (=relative to the desktop) format - LPITEMIDLIST create_absolute_pidl(LPCITEMIDLIST parent_pidl, HWND hwnd) const - { - // create a new item id list with _p append behind parent_pidl - int l1 = _malloc->GetSize((void*)parent_pidl) - sizeof(USHORT/*SHITEMID::cb*/); - int l2 = _malloc->GetSize(_p); - - LPITEMIDLIST p = (LPITEMIDLIST) _malloc->Alloc(l1+l2); - - memcpy(p, parent_pidl, l1); - memcpy((LPBYTE)p+l1, _p, l2); - - return p; - } + LPITEMIDLIST create_absolute_pidl(LPCITEMIDLIST parent_pidl, HWND hwnd) const; }; diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index f951c8f8ac2..6d6b5528a02 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -397,6 +397,47 @@ struct String }; + /// link dynamicly to functions by using GetModuleHandle() and GetProcAddress() +template struct DynamicFct +{ + DynamicFct(LPCTSTR moduleName, UINT ordinal) + { + HMODULE hModule = GetModuleHandle(moduleName); + + _fct = (FCT) GetProcAddress(hModule, (LPCSTR)ordinal); + } + + FCT operator*() const {return _fct;} + operator bool() const {return _fct? true: false;} + +protected: + FCT _fct; +}; + + + /// link dynamicly to functions by using LoadLibrary() and GetProcAddress() +template struct DynamicLoadLibFct +{ + DynamicLoadLibFct(LPCTSTR moduleName, UINT ordinal) + { + _hModule = LoadLibrary(moduleName); + + _fct = (FCT) GetProcAddress(_hModule, (LPCSTR)ordinal); + } + + ~DynamicLoadLibFct() + { + FreeLibrary(_hModule); + } + + FCT operator*() const {return _fct;} + operator bool() const {return _fct? true: false;} + +protected: + HMODULE _hModule; + FCT _fct; +}; + #endif // __cplusplus