From 8e4b0ed4e71e3030a3c53db49038d9f95e920220 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Sat, 9 Aug 2003 17:11:40 +0000 Subject: [PATCH] Implemented explorer and desktop window using shell views svn path=/trunk/; revision=5492 --- reactos/lib/user32/misc/desktop.c | 4 +- .../system/explorer/desktop/desktop.cpp | 166 +++ .../subsys/system/explorer/desktop/desktop.h | 72 + reactos/subsys/system/explorer/doc/TODO.txt | 210 +-- .../subsys/system/explorer/doc/changes.txt | 4 +- reactos/subsys/system/explorer/ex_bar.c | 299 ---- reactos/subsys/system/explorer/explorer.coff | Bin 0 -> 12566 bytes reactos/subsys/system/explorer/explorer.cpp | 218 +++ reactos/subsys/system/explorer/explorer.dsp | 197 ++- reactos/subsys/system/explorer/explorer.dsw | 14 +- reactos/subsys/system/explorer/explorer.h | 83 ++ reactos/subsys/system/explorer/explorer.lst | 12 +- reactos/subsys/system/explorer/explorer.rc | 5 + .../subsys/system/explorer/explorer_intres.h | 53 + .../subsys/system/explorer/explorer_intres.rc | 432 ++++++ reactos/subsys/system/explorer/externals.h | 62 + reactos/subsys/system/explorer/globals.h | 40 + .../subsys/system/explorer/include/explorer.h | 27 - .../subsys/system/explorer/make_explorer.dsp | 89 ++ reactos/subsys/system/explorer/makefile_rex | 50 +- .../subsys/system/explorer/res/explorer.ico | Bin 0 -> 1078 bytes .../subsys/system/explorer/shell/entries.cpp | 277 ++++ .../subsys/system/explorer/shell/entries.h | 104 ++ .../system/explorer/shell/filechild.cpp | 511 +++++++ .../subsys/system/explorer/shell/filechild.h | 96 ++ .../system/explorer/shell/mainframe.cpp | 614 ++++++++ .../subsys/system/explorer/shell/mainframe.h | 70 + reactos/subsys/system/explorer/shell/pane.cpp | 985 +++++++++++++ reactos/subsys/system/explorer/shell/pane.h | 105 ++ .../system/explorer/shell/shellbrowser.cpp | 418 ++++++ .../system/explorer/shell/shellbrowser.h | 126 ++ .../subsys/system/explorer/shell/shellfs.cpp | 335 +++++ .../subsys/system/explorer/shell/shellfs.h | 73 + .../system/explorer/{ => shell}/startup.c | 2 +- .../subsys/system/explorer/shell/unixfs.cpp | 196 +++ reactos/subsys/system/explorer/shell/unixfs.h | 58 + .../subsys/system/explorer/shell/winfs.cpp | 177 +++ reactos/subsys/system/explorer/shell/winfs.h | 55 + .../subsys/system/explorer/taskbar/ex_bar.c | 383 +++++ .../subsys/system/explorer/taskbar/ex_bar.h | 41 + .../subsys/system/explorer/taskbar/ex_clock.c | 143 ++ .../subsys/system/explorer/taskbar/ex_menu.c | 196 +++ .../system/explorer/taskbar/ex_shutdwn.c | 132 ++ .../subsys/system/explorer/utility/.cvsignore | 15 + .../system/explorer/utility/dragdropimpl.cpp | 592 ++++++++ .../system/explorer/utility/dragdropimpl.h | 263 ++++ .../explorer/utility/shellbrowserimpl.h | 99 ++ .../system/explorer/utility/shellclasses.cpp | 243 ++++ .../system/explorer/utility/shellclasses.h | 777 ++++++++++ .../system/explorer/utility/shelltests.cpp | 139 ++ .../system/explorer/{ => utility}/splitpath.c | 2 +- .../system/explorer/utility/treedroptarget.h | 79 + .../system/explorer/utility/utility.cpp | 123 ++ .../subsys/system/explorer/utility/utility.h | 157 ++ .../subsys/system/explorer/utility/window.cpp | 333 +++++ .../subsys/system/explorer/utility/window.h | 155 ++ .../system/explorer/{De.rc => winefile/de.rc} | 0 .../system/explorer/{ => winefile}/desktop.c | 136 +- .../system/explorer/{En.rc => winefile/en.rc} | 0 .../system/explorer/winefile/explorer.rc | 39 + .../system/explorer/{ => winefile}/license.c | 0 .../explorer/{include => winefile}/license.h | 0 .../explorer/winefile/make_winefile.dsp | 89 ++ .../subsys/system/explorer/winefile/makefile | 58 + .../explorer/{include => winefile}/resource.h | 10 +- .../explorer/{ => winefile}/resource.rc | 8 +- .../system/explorer/winefile/wine_explore.dsp | 343 +++++ .../system/explorer/winefile/wine_explore.dsw | 41 + .../system/explorer/{ => winefile}/winefile.c | 1295 +++++++++++++---- .../{WineFile.dsp => winefile/winefile.dsp} | 94 +- .../explorer/{ => winefile}/winefile.dsw | 2 +- .../explorer/{include => winefile}/winefile.h | 29 +- .../explorer/{ => winefile}/winefile.rc | 6 +- reactos/tools/helper.mk | 30 +- 74 files changed, 11278 insertions(+), 1013 deletions(-) create mode 100644 reactos/subsys/system/explorer/desktop/desktop.cpp create mode 100644 reactos/subsys/system/explorer/desktop/desktop.h delete mode 100644 reactos/subsys/system/explorer/ex_bar.c create mode 100644 reactos/subsys/system/explorer/explorer.coff create mode 100644 reactos/subsys/system/explorer/explorer.cpp create mode 100644 reactos/subsys/system/explorer/explorer.h create mode 100644 reactos/subsys/system/explorer/explorer_intres.h create mode 100644 reactos/subsys/system/explorer/explorer_intres.rc create mode 100644 reactos/subsys/system/explorer/externals.h create mode 100644 reactos/subsys/system/explorer/globals.h delete mode 100644 reactos/subsys/system/explorer/include/explorer.h create mode 100644 reactos/subsys/system/explorer/make_explorer.dsp create mode 100644 reactos/subsys/system/explorer/res/explorer.ico create mode 100644 reactos/subsys/system/explorer/shell/entries.cpp create mode 100644 reactos/subsys/system/explorer/shell/entries.h create mode 100644 reactos/subsys/system/explorer/shell/filechild.cpp create mode 100644 reactos/subsys/system/explorer/shell/filechild.h create mode 100644 reactos/subsys/system/explorer/shell/mainframe.cpp create mode 100644 reactos/subsys/system/explorer/shell/mainframe.h create mode 100644 reactos/subsys/system/explorer/shell/pane.cpp create mode 100644 reactos/subsys/system/explorer/shell/pane.h create mode 100644 reactos/subsys/system/explorer/shell/shellbrowser.cpp create mode 100644 reactos/subsys/system/explorer/shell/shellbrowser.h create mode 100644 reactos/subsys/system/explorer/shell/shellfs.cpp create mode 100644 reactos/subsys/system/explorer/shell/shellfs.h rename reactos/subsys/system/explorer/{ => shell}/startup.c (99%) create mode 100644 reactos/subsys/system/explorer/shell/unixfs.cpp create mode 100644 reactos/subsys/system/explorer/shell/unixfs.h create mode 100644 reactos/subsys/system/explorer/shell/winfs.cpp create mode 100644 reactos/subsys/system/explorer/shell/winfs.h create mode 100644 reactos/subsys/system/explorer/taskbar/ex_bar.c create mode 100644 reactos/subsys/system/explorer/taskbar/ex_bar.h create mode 100644 reactos/subsys/system/explorer/taskbar/ex_clock.c create mode 100644 reactos/subsys/system/explorer/taskbar/ex_menu.c create mode 100644 reactos/subsys/system/explorer/taskbar/ex_shutdwn.c create mode 100644 reactos/subsys/system/explorer/utility/.cvsignore create mode 100644 reactos/subsys/system/explorer/utility/dragdropimpl.cpp create mode 100644 reactos/subsys/system/explorer/utility/dragdropimpl.h create mode 100644 reactos/subsys/system/explorer/utility/shellbrowserimpl.h create mode 100644 reactos/subsys/system/explorer/utility/shellclasses.cpp create mode 100644 reactos/subsys/system/explorer/utility/shellclasses.h create mode 100644 reactos/subsys/system/explorer/utility/shelltests.cpp rename reactos/subsys/system/explorer/{ => utility}/splitpath.c (99%) create mode 100644 reactos/subsys/system/explorer/utility/treedroptarget.h create mode 100644 reactos/subsys/system/explorer/utility/utility.cpp create mode 100644 reactos/subsys/system/explorer/utility/utility.h create mode 100644 reactos/subsys/system/explorer/utility/window.cpp create mode 100644 reactos/subsys/system/explorer/utility/window.h rename reactos/subsys/system/explorer/{De.rc => winefile/de.rc} (100%) rename reactos/subsys/system/explorer/{ => winefile}/desktop.c (61%) rename reactos/subsys/system/explorer/{En.rc => winefile/en.rc} (100%) create mode 100644 reactos/subsys/system/explorer/winefile/explorer.rc rename reactos/subsys/system/explorer/{ => winefile}/license.c (100%) rename reactos/subsys/system/explorer/{include => winefile}/license.h (100%) create mode 100644 reactos/subsys/system/explorer/winefile/make_winefile.dsp create mode 100644 reactos/subsys/system/explorer/winefile/makefile rename reactos/subsys/system/explorer/{include => winefile}/resource.h (95%) rename reactos/subsys/system/explorer/{ => winefile}/resource.rc (99%) create mode 100644 reactos/subsys/system/explorer/winefile/wine_explore.dsp create mode 100644 reactos/subsys/system/explorer/winefile/wine_explore.dsw rename reactos/subsys/system/explorer/{ => winefile}/winefile.c (70%) rename reactos/subsys/system/explorer/{WineFile.dsp => winefile/winefile.dsp} (75%) rename reactos/subsys/system/explorer/{ => winefile}/winefile.dsw (89%) rename reactos/subsys/system/explorer/{include => winefile}/winefile.h (87%) rename reactos/subsys/system/explorer/{ => winefile}/winefile.rc (93%) diff --git a/reactos/lib/user32/misc/desktop.c b/reactos/lib/user32/misc/desktop.c index 82aa512a1ae..0b89b937395 100644 --- a/reactos/lib/user32/misc/desktop.c +++ b/reactos/lib/user32/misc/desktop.c @@ -1,4 +1,4 @@ -/* $Id: desktop.c,v 1.20 2003/08/09 13:13:43 mf Exp $ +/* $Id: desktop.c,v 1.21 2003/08/09 17:08:14 mf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -351,7 +351,7 @@ SetShellWindowEx(HWND hwndShell, HWND hwndShellListView) BOOL STDCALL SetShellWindow(HWND hwndShell) { - return SetShellWindowEx(hwndShell, 0); + return SetShellWindowEx(hwndShell, hwndShell); } /* EOF */ diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp new file mode 100644 index 00000000000..4dbd5671c77 --- /dev/null +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -0,0 +1,166 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // desktop.cpp + // + // Martin Fuchs, 09.08.2003 + // + + +#include "desktop.h" + +#include "../externals.h" + + +static BOOL (WINAPI*SetShellWindow)(HWND); + + +BOOL IsAnyDesktopRunning() +{ + HINSTANCE shell32 = GetModuleHandle(TEXT("user32")); + + SetShellWindow = (BOOL(WINAPI*)(HWND)) GetProcAddress(shell32, "SetShellWindow"); + + return GetShellWindow() != 0; +} + + +DesktopWindow::DesktopWindow(HWND hwnd) + : super(hwnd) +{ + _pShellView = NULL; + + if (SetShellWindow) + SetShellWindow(hwnd); +} + +DesktopWindow::~DesktopWindow() +{ + if (SetShellWindow) + SetShellWindow(0); + + if (_pShellView) + _pShellView->Release(); +} + + +LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_PAINT: { + // We'd want to draw the desktop wallpaper here. Need to + // maintain a copy of the wallpaper in an off-screen DC and then + // bitblt (or stretchblt?) it to the screen appropriately. For + // now, though, we'll just draw some text. + + PAINTSTRUCT ps; + HDC DesktopDC = BeginPaint(_hwnd, &ps); + + static const TCHAR Text [] = TEXT("ReactOS 0.1.2 Desktop Example\nby Silver Blade, Martin Fuchs"); + + RECT rect; + GetClientRect(_hwnd, &rect); + + // This next part could be improved by working out how much + // space the text actually needs... + + rect.left = rect.right - 260; + rect.top = rect.bottom - 80; + rect.right = rect.left + 250; + rect.bottom = rect.top + 40; + + SetTextColor(DesktopDC, 0x00ffffff); + SetBkMode(DesktopDC, TRANSPARENT); + DrawText(DesktopDC, Text, -1, &rect, DT_RIGHT); + + EndPaint(_hwnd, &ps); + break;} + + case WM_LBUTTONDBLCLK: + explorer_show_frame(_hwnd, SW_SHOWNORMAL); + break; + + case WM_GETISHELLBROWSER: + return (LRESULT)static_cast(this); + + case WM_CLOSE: + break; // Over-ride close. We need to close desktop some other way. + + default: + return super::WndProc(nmsg, wparam, lparam); + } + + return 0; +} + + +HWND create_desktop_window(HINSTANCE hInstance) +{ + WindowClass wcDesktop(_T("Program Manager")); + + wcDesktop.style = CS_DBLCLKS; + wcDesktop.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcDesktop.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wcDesktop.hCursor = LoadCursor(NULL, IDC_ARROW); + + + ATOM desktopClass = wcDesktop.Register(); + + int width = GetSystemMetrics(SM_CXSCREEN); + int height = GetSystemMetrics(SM_CYSCREEN); + + HWND hwndDesktop = Window::Create(WINDOW_CREATOR(DesktopWindow), + 0, (LPCTSTR)desktopClass, _T("Progman"), WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN, + 0, 0, width, height, 0); + + if (!hwndDesktop) + return 0; + + + ShellFolder folder; + + IShellView* pShellView; + HRESULT hr = folder->CreateViewObject(hwndDesktop, IID_IShellView, (void**)&pShellView); + + HWND hWndListView = 0; + + if (SUCCEEDED(hr)) { + FOLDERSETTINGS fs; + + fs.ViewMode = 0; + fs.fFlags = FVM_ICON; + + RECT rect = {0, 0, width, height}; + + DesktopWindow* shell_browser = static_cast(Window::get_window(hwndDesktop)); + + hr = pShellView->CreateViewWindow(NULL, &fs, shell_browser, &rect, &hWndListView); + + if (SUCCEEDED(hr)) { + HWND hwndFolderView = GetNextWindow(hWndListView, GW_CHILD); + + ShowWindow(hwndFolderView, SW_SHOW); + } + } + + return hwndDesktop; +} diff --git a/reactos/subsys/system/explorer/desktop/desktop.h b/reactos/subsys/system/explorer/desktop/desktop.h new file mode 100644 index 00000000000..0ec1fb39af5 --- /dev/null +++ b/reactos/subsys/system/explorer/desktop/desktop.h @@ -0,0 +1,72 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // desktop.h + // + // Martin Fuchs, 09.08.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" +#include "../utility/shellbrowserimpl.h" +#include "../utility/window.h" + +#include "../externals.h" + + +struct DesktopWindow : public Window, public IShellBrowserImpl +{ + typedef Window super; + + DesktopWindow::DesktopWindow(HWND hwnd); + + DesktopWindow::~DesktopWindow(); + + STDMETHOD(GetWindow)(HWND* lphwnd) + { + *lphwnd = _hwnd; + return S_OK; + } + + STDMETHOD(QueryActiveShellView)(struct IShellView ** ppshv) + { + _pShellView->AddRef(); + *ppshv = _pShellView; + return S_OK; + } + + STDMETHOD(GetControlWindow)(UINT id, HWND * lphwnd) + { + return E_NOTIMPL; + } + + STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) + { + return E_NOTIMPL; + } + +protected: + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + + IShellView* _pShellView; +}; diff --git a/reactos/subsys/system/explorer/doc/TODO.txt b/reactos/subsys/system/explorer/doc/TODO.txt index a70f63cbcba..3d6b106b123 100644 --- a/reactos/subsys/system/explorer/doc/TODO.txt +++ b/reactos/subsys/system/explorer/doc/TODO.txt @@ -1,211 +1,3 @@ + 1. Fix the Explorer Bar/Start Menu. Currently it is almost nothing like Windows. -2. Implement support for ICONs on the desktop. - -3. Fix Mingw build. Currently Explorer requires the WINE headers to build. -When build with Mingw headers you will get a error like this: - -G:\src\rosapps\explorer>make1 -windres -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ --include-dir ../../reactos/include - --include-dir ../../reactos/include explorer.rc -o explorer.coff -gcc -fexceptions -O2 -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ -W -I./ -I../../reactos/ -include -pipe -march=i386 -D_M_IX86 -c desktop.c -o desktop.o -gcc -fexceptions -O2 -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ -W -I./ -I../../reactos/ -include -pipe -march=i386 -D_M_IX86 -c ex_bar.c -o ex_bar.o -gcc -fexceptions -O2 -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ -W -I./ -I../../reactos/ -include -pipe -march=i386 -D_M_IX86 -c license.c -o license.o -gcc -fexceptions -O2 -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ -W -I./ -I../../reactos/ -include -pipe -march=i386 -D_M_IX86 -c splitpath.c -o splitpath.o -In file included from C:/mingw/include/commctrl.h:7, - from winefile.h:38, - from splitpath.c:19: -C:/mingw/include/prsht.h:123: parse error before "LPCDLGTEMPLATE" -C:/mingw/include/prsht.h:138: parse error before '}' token -C:/mingw/include/prsht.h:139: parse error before '*' token -C:/mingw/include/prsht.h:146: parse error before "LPCDLGTEMPLATE" -C:/mingw/include/prsht.h:152: conflicting types for `pszTitle' -C:/mingw/include/prsht.h:129: previous declaration of `pszTitle' -C:/mingw/include/prsht.h:155: conflicting types for `pfnCallback' -C:/mingw/include/prsht.h:132: previous declaration of `pfnCallback' -C:/mingw/include/prsht.h:161: parse error before '}' token -C:/mingw/include/prsht.h:162: parse error before '*' token -C:/mingw/include/prsht.h:163: parse error before "LPPROPSHEETPAGEA" -C:/mingw/include/prsht.h:164: parse error before "LPPROPSHEETPAGEW" -C:/mingw/include/prsht.h:183: parse error before "LPCPROPSHEETPAGEA" -C:/mingw/include/prsht.h:185: parse error before '}' token -C:/mingw/include/prsht.h:186: conflicting types for `pfnCallback' -C:/mingw/include/prsht.h:155: previous declaration of `pfnCallback' -C:/mingw/include/prsht.h:198: parse error before '}' token -C:/mingw/include/prsht.h:199: parse error before '*' token -C:/mingw/include/prsht.h:216: parse error before "LPCPROPSHEETPAGEW" -C:/mingw/include/prsht.h:218: parse error before '}' token -C:/mingw/include/prsht.h:231: parse error before '}' token -C:/mingw/include/prsht.h:232: parse error before '*' token -C:/mingw/include/prsht.h:236: parse error before "NMHDR" -C:/mingw/include/prsht.h:238: parse error before '}' token -In file included from winefile.h:38, - from splitpath.c:19: -C:/mingw/include/commctrl.h:1473: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1478: parse error before '}' token -C:/mingw/include/commctrl.h:1480: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1483: conflicting types for `szText' -C:/mingw/include/commctrl.h:1476: previous declaration of `szText' -C:/mingw/include/commctrl.h:1485: parse error before '}' token -C:/mingw/include/commctrl.h:1493: parse error before "POINT" -C:/mingw/include/commctrl.h:1548: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1553: parse error before '}' token -C:/mingw/include/commctrl.h:1564: parse error before "RECT" -C:/mingw/include/commctrl.h:1606: parse error before "RECT" -C:/mingw/include/commctrl.h:1608: parse error before '}' token -C:/mingw/include/commctrl.h:1611: parse error before "POINT" -C:/mingw/include/commctrl.h:1614: parse error before '}' token -C:/mingw/include/commctrl.h:1616: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1620: parse error before '}' token -C:/mingw/include/commctrl.h:1622: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1625: conflicting types for `pitem' -C:/mingw/include/commctrl.h:1619: previous declaration of `pitem' -C:/mingw/include/commctrl.h:1626: parse error before '}' token -C:/mingw/include/commctrl.h:1631: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1634: conflicting types for `pitem' -C:/mingw/include/commctrl.h:1625: previous declaration of `pitem' -C:/mingw/include/commctrl.h:1635: parse error before '}' token -C:/mingw/include/commctrl.h:1638: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1641: conflicting types for `pitem' -C:/mingw/include/commctrl.h:1634: previous declaration of `pitem' -C:/mingw/include/commctrl.h:1642: parse error before '}' token -C:/mingw/include/commctrl.h:1652: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1655: conflicting types for `pszText' -C:/mingw/include/commctrl.h:1552: previous declaration of `pszText' -C:/mingw/include/commctrl.h:1659: parse error before '}' token -C:/mingw/include/commctrl.h:1661: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1664: conflicting types for `pszText' -C:/mingw/include/commctrl.h:1655: previous declaration of `pszText' -C:/mingw/include/commctrl.h:1668: parse error before '}' token -C:/mingw/include/commctrl.h:1670: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1673: parse error before "rc" -C:/mingw/include/commctrl.h:1677: parse error before '}' token -C:/mingw/include/commctrl.h:1679: parse error before "NMCUSTOMDRAW" -C:/mingw/include/commctrl.h:1685: parse error before '}' token -C:/mingw/include/commctrl.h:1687: parse error before "NMCUSTOMDRAW" -C:/mingw/include/commctrl.h:1693: parse error before '}' token -C:/mingw/include/commctrl.h:1729: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1733: conflicting types for `pszText' -C:/mingw/include/commctrl.h:1664: previous declaration of `pszText' -C:/mingw/include/commctrl.h:1737: parse error before '}' token -C:/mingw/include/commctrl.h:1741: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1745: conflicting types for `pszText' -C:/mingw/include/commctrl.h:1733: previous declaration of `pszText' -C:/mingw/include/commctrl.h:1749: parse error before '}' token -C:/mingw/include/commctrl.h:1757: parse error before "RECT" -C:/mingw/include/commctrl.h:1763: parse error before '}' token -C:/mingw/include/commctrl.h:1769: parse error before "RECT" -C:/mingw/include/commctrl.h:1771: conflicting types for `lpszText' -C:/mingw/include/commctrl.h:1759: previous declaration of `lpszText' -C:/mingw/include/commctrl.h:1775: parse error before '}' token -C:/mingw/include/commctrl.h:1778: parse error before "POINT" -C:/mingw/include/commctrl.h:1783: parse error before "POINT" -C:/mingw/include/commctrl.h:1787: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1788: conflicting types for `lpszText' -C:/mingw/include/commctrl.h:1771: previous declaration of `lpszText' -C:/mingw/include/commctrl.h:1789: conflicting types for `szText' -C:/mingw/include/commctrl.h:1483: previous declaration of `szText' -C:/mingw/include/commctrl.h:1795: parse error before '}' token -C:/mingw/include/commctrl.h:1799: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1800: conflicting types for `lpszText' -C:/mingw/include/commctrl.h:1788: previous declaration of `lpszText' -C:/mingw/include/commctrl.h:1801: conflicting types for `szText' -C:/mingw/include/commctrl.h:1789: previous declaration of `szText' -C:/mingw/include/commctrl.h:1807: parse error before '}' token -C:/mingw/include/commctrl.h:1815: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1818: parse error before '}' token -C:/mingw/include/commctrl.h:1835: parse error before '*' token -C:/mingw/include/commctrl.h:1851: conflicting types for `FAR' -C:/mingw/include/commctrl.h:1835: previous declaration of `FAR' -C:/mingw/include/commctrl.h:1851: parse error before '*' token -C:/mingw/include/commctrl.h:1858: parse error before "POINT" -C:/mingw/include/commctrl.h:1860: parse error before '}' token -C:/mingw/include/commctrl.h:1860: parse error before "FAR" -C:/mingw/include/commctrl.h:1867: parse error before "POINT" -C:/mingw/include/commctrl.h:1869: parse error before '}' token -C:/mingw/include/commctrl.h:1869: parse error before "FAR" -C:/mingw/include/commctrl.h:1873: parse error before "POINT" -C:/mingw/include/commctrl.h:1879: parse error before '}' token -C:/mingw/include/commctrl.h:1893: conflicting types for `FAR' -C:/mingw/include/commctrl.h:1851: previous declaration of `FAR' -C:/mingw/include/commctrl.h:1893: parse error before '*' token -C:/mingw/include/commctrl.h:1907: conflicting types for `FAR' -C:/mingw/include/commctrl.h:1893: previous declaration of `FAR' -C:/mingw/include/commctrl.h:1907: parse error before '*' token -C:/mingw/include/commctrl.h:1912: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1918: parse error before "ptAction" -C:/mingw/include/commctrl.h:1920: parse error before '}' token -C:/mingw/include/commctrl.h:1926: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1928: parse error before '}' token -C:/mingw/include/commctrl.h:1928: parse error before "FAR" -C:/mingw/include/commctrl.h:1932: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1933: conflicting types for `item' -C:/mingw/include/commctrl.h:1927: previous declaration of `item' -C:/mingw/include/commctrl.h:1934: parse error before '}' token -C:/mingw/include/commctrl.h:1934: parse error before "FAR" -C:/mingw/include/commctrl.h:1938: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1941: parse error before '}' token -C:/mingw/include/commctrl.h:1943: parse error before "NMHDR" -C:/mingw/include/commctrl.h:1946: parse error before '}' token -C:/mingw/include/commctrl.h:2038: parse error before "POINT" -C:/mingw/include/commctrl.h:2041: parse error before '}' token -C:/mingw/include/commctrl.h:2055: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2059: parse error before "ptDrag" -C:/mingw/include/commctrl.h:2065: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2067: conflicting types for `itemOld' -C:/mingw/include/commctrl.h:2057: previous declaration of `itemOld' -C:/mingw/include/commctrl.h:2068: conflicting types for `itemNew' -C:/mingw/include/commctrl.h:2058: previous declaration of `itemNew' -C:/mingw/include/commctrl.h:2069: parse error before "ptDrag" -C:/mingw/include/commctrl.h:2075: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2076: conflicting types for `item' -C:/mingw/include/commctrl.h:1933: previous declaration of `item' -C:/mingw/include/commctrl.h:2077: parse error before '}' token -C:/mingw/include/commctrl.h:2079: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2080: conflicting types for `item' -C:/mingw/include/commctrl.h:2076: previous declaration of `item' -C:/mingw/include/commctrl.h:2081: parse error before '}' token -C:/mingw/include/commctrl.h:2083: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2086: parse error before '}' token -C:/mingw/include/commctrl.h:2122: parse error before "POINT" -C:/mingw/include/commctrl.h:2124: parse error before '}' token -C:/mingw/include/commctrl.h:2126: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2129: parse error before '}' token -C:/mingw/include/commctrl.h:2165: parse error before "POINT" -C:/mingw/include/commctrl.h:2168: parse error before '}' token -C:/mingw/include/commctrl.h:2172: parse error before "NMHDR" -C:/mingw/include/commctrl.h:2176: parse error before '}' token -C:/mingw/include/commctrl.h:2329: parse error before "LPRECT" -C:/mingw/include/commctrl.h:2330: parse error before "LPRECT" -C:/mingw/include/commctrl.h:2331: parse error before "LPRECT" -C:/mingw/include/commctrl.h:2361: parse error before "IMAGEINFO" -C:/mingw/include/commctrl.h:2382: parse error before "POINT" -C:/mingw/include/commctrl.h:2585: parse error before "TOOLINFO" -C:/mingw/include/commctrl.h:2586: parse error before "TTHITTESTINFO" -C:/mingw/include/commctrl.h:2587: parse error before "TOOLTIPTEXT" -C:/mingw/include/commctrl.h:2588: parse error before "NMTTDISPINFO" -C:/mingw/include/commctrl.h:2596: parse error before "NM_TREEVIEW" -C:/mingw/include/commctrl.h:2597: parse error before "NMTREEVIEW" -C:/mingw/include/commctrl.h:2598: parse error before "NMHDDISPINFO" -In file included from winefile.h:39, - from splitpath.c:19: -C:/mingw/include/shellapi.h:101: parse error before "RECT" -C:/mingw/include/shellapi.h:103: parse error before '}' token -In file included from winefile.h:39, - from splitpath.c:19: -C:/mingw/include/shellapi.h:199: parse error before "LPPOINT" -C:/mingw/include/shellapi.h:208: parse error before "PAPPBARDATA" -In file included from splitpath.c:19: -winefile.h:131: parse error before "SIZE" -winefile.h:131: warning: no semicolon at end of struct or union -winefile.h:138: parse error before '}' token -winefile.h:138: warning: data definition has no type or storage class -winefile.h:140: parse error before "Globals" -winefile.h:140: warning: data definition has no type or storage class -make1: *** [splitpath.o] Error 1 - -G:\src\rosapps\explorer> diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index 809469285de..6b04d9cd72b 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -8,4 +8,6 @@ 15.10.2002 m. fuchs Programmaufruf über Doppelklick in der Dateiliste 07.06.2003 m. fuchs integration with ROS desktop window - +21.07.2003 m. fuchs extension of winefile for shell namespace +04.08.2003 m. fuchs C++ explorer with architecture like MS Explorer: + usage of IShellView C++, implementation of IShellBrowser, ... diff --git a/reactos/subsys/system/explorer/ex_bar.c b/reactos/subsys/system/explorer/ex_bar.c deleted file mode 100644 index e671d35b696..00000000000 --- a/reactos/subsys/system/explorer/ex_bar.c +++ /dev/null @@ -1,299 +0,0 @@ -// Explorer Panel (PlugIn based) -// -// Alexander Ciobanu -// alex@prodidactica.md -// -// - -#include -#include - -#include "include/explorer.h" - -HFONT tf; -HINSTANCE PlugInsHI[2]; // PlugIns table -int PlugNumber; // Number of loaded plugins - -LRESULT WINAPI ExplorerBarProc(HWND, UINT, WPARAM, LPARAM); - -// Loads a configuration style given by PInt -// FIXME : Load all these values from registry ! -// -DWORD LoadProperty(int PInt) -{ - switch(PInt) - { - case 1: // WS_EX_Style for creating the bar - return WS_EX_DLGMODALFRAME | WS_EX_TOPMOST; - break; - case 2: // WS_Style for creating the bar - return 0; - break; - case 3: // Start X for the panel - return 0; - break; - case 4: - return 0; // Start Y for the panel - break; - case 5: - return GetSystemMetrics(SM_CXSCREEN); // XLen for the panel - break; - case 6: - return 50; // YLen for the panel - break; - } - return 0; -} - -// Initializez and creates the Explorer Panel -// HINSTANCE as a parameter -// -HWND InitializeExplorerBar(HINSTANCE hInstance, int nCmdShow) -{ - HWND ExplorerBar; - WNDCLASS ExplorerBarClass; - - ExplorerBarClass.lpszClassName = TEXT("ExplorerBar"); // ExplorerBar classname - ExplorerBarClass.lpfnWndProc = ExplorerBarProc; // Default Explorer Callback Procedure - ExplorerBarClass.style = CS_VREDRAW | CS_HREDRAW; // Styles - ExplorerBarClass.hInstance = hInstance; // Instance - ExplorerBarClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Configurable ???? - ExplorerBarClass.hCursor = LoadCursor(NULL, IDC_ARROW); - ExplorerBarClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); // BackGround - ExplorerBarClass.lpszMenuName = NULL; // No Menu needed for the bar - ExplorerBarClass.cbClsExtra = 0; // Nothing YET! !! - ExplorerBarClass.cbWndExtra = 0; // - - if (RegisterClass(&ExplorerBarClass) == 0) // Cold not register anything :( - { - fprintf(stderr, "Could not register Explorer Bar. Last error was 0x%X\n",GetLastError()); - return NULL; - } - - ExplorerBar = CreateWindowEx(LoadProperty(1),TEXT("ExplorerBar"), - TEXT("ReactOS Explorer Bar"),LoadProperty(2),LoadProperty(3),LoadProperty(4), - LoadProperty(5),LoadProperty(6),NULL,NULL,hInstance,NULL); - if (ExplorerBar == NULL) - { - fprintf(stderr, "Cold not create Explorer Bar.Last error 0x%X\n",GetLastError()); - return(NULL); - } - - tf = CreateFontA(14, 0, 0, TA_BASELINE, FW_NORMAL, FALSE, FALSE, FALSE, - ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "Timmons"); - - ShowWindow(ExplorerBar, nCmdShow); // Show the bar - return ExplorerBar; -} - - -// ************************************************************************************** -// * Default Buit-in Plugin * -// ************************************************************************************** -HWND epl_AppButtons[10]; -char epl_line[10][80]; -int epl_Buttons; - - - -// Initialize the plugin -// -HINSTANCE InitializeExplorerPlugIn(HWND ExplorerHandle) -{ - FILE* Conf; // Configuration File; - char line[80]; // Blah Blah Blah - char ttl[80]; // Title of the button - int i; - int x; - - if (!(Conf=fopen("explorer.lst","r"))) // Error ! - { - fprintf(stderr,"DefaultPlugin : No configuration file found !\n"); - return NULL; - } - - fgets(line,80,Conf); // Read how many entries are in the file - epl_Buttons=atoi(line); // atoi it ! - - - for (i=0;iK@C+UV&WvGge1ZyMU@Kq@o(ceqqWUA zBvJ+m5eq*+|3DQ#iuz)-PkE@6NT{;amjLAfRaMo8N{uCi^3>)b!mb=L{l0VN&Yhjz z1e2Dk553OpoqO;3Kj)r%W_Gi?R1$5QMC`6rHdZI9hiz6rw|0sA0C$t<*>1zNO=JO` z-1F@RA7(GoCN22fClaqgzkt3KeP>DHFQFene+&9E=+~nE5IyMtDegqqg`PuCZ;cFM zJPkTS=wCrUjQ(x(=yGr-^#L+(G9O-NK5m$AQT;E1K9`o8@Cl&MD-C!h;ry9~`4$-k zoi6Bk1br`hbaisC1>V^vc%-+0d9HuhuwD|{A#R}8qH23n!ppTvkCkF=D*h9N26bE0#A8*o4`}=F2HZYbvDH#&&vp)zodF`{4N4%8nCWy zLqJ{1t*^gbWW9xlg6z9PGR1gm<{`$0>Y7Q8dGb-kOePPTOqO&rG}dC<@r3XtD>b7f8CIqn@7Ag}#?SXs1)^ zA@IO90iNOOD7kVP{T2L6`=obolHlK!)5eR~8J^*!0sxhSt+w4?3v;LRGTb;Sr|qq&cE|p=yy65vk{N-Le7&P zL?1*KPDZjcO&x>D8Q}GRu8DbFybCAMq6-(o4p~yhl+)z$-p|KN#?SDgHg!WVeGX{E zQ){MClgHyc>>Q>1qPRoZorq@XLBrdX;aSx6^tgW4NeT-6;vl4Dz;w2!AM2}WCjrzJ zg#x!n+^+|4eHoYAuVF6VU^>@gZc<#>r|kHLn^o@D)rfY}Fc9Z+wKmHO@oM`Zgo#5* zy##MD14XIVj=zTakTdAj8*vbYfe6RQh5>q$PRF2xUiWLb`Xx;96{gtc1QYln%n zk85VP_Tt#h*U{o&j*cTe>*r2s3+Gm}#kEuOXy@9CV>b^9P@tWZsANV5^pM!Y+T4=1 za4sR8`Pk@OehK5V>G<->3dYLr@=LYanU6BGwXeyt&cX}nWpBuZrc1A9mU`Ec_&Gkk3%zpE!{b@gKu%GpC$IyY4ly;DBDSD26 z>0$5vOGOj)FM7zQ&5vPM&ev+U4Ye2PEn$Lm(P!}t_@yXPIkYd1As*+O*>4HrDLsn$ zcWoi#mD9CTNn(9*oX*#3?F7pj1>zv>Q~98{O@C&e5waWRoieU%xZHUfe*xzy$p5Ds z4B;9Nr2rmrO~)27`pNMrw}_tO6Mp?%8_*NKzQnO#o)7UPdcrTSgy%udub*4DT*p1? zIA4#xQn$Vo&STw)j(#21!QT_ax&-g!7~af!4t-^s`WyXoWQ?Jcn5M9%0O#BY0EG0* ze&J^BZ2S4oYa(l|;(}&+T}IFAVtOs0=M@(&w_fal+p#QnCs*a+_uI|VEplBG$)lx_d7#?PT2 zS2@P8c3dI1)IshCMimgF%E6%O>2Fc2HE}oKs*qwFZ-2<88=6gm{!z@;;}c=iViBGe zIS%MUz!`%^wA0(SROAUz8v^A)%#A=d)94k|Vi1s_Laqxc;7D9@EdzQQD`OZFvnm_) zkDS?PsiFehiO~sy9azlDx;jnHDt-Nckbf8UxmD`6LHT znd!|TT|bKTC)J+h$;&>yCAKbBR7+AHPw5;4HnsFpc0+CywMKC-yKbI;Al%0H~t= zM*mpq$qIG@qk;Y$S1&M%s^Cj|F!H@sh&cj^eah8*1 zF^^P`1qPMNfPSup-e&u!0MV&bE2($5zdzErU`7#nFXPDw@N3-dv~^?r5$pXMU@_{O z#|<$>{%`}_A+@>N`HeAP6t2o1@R)?%BlK0s$ylF)pWT?!KdWnp;1TA;dLMkcDhjj* z@tXVp8g^7gAx71nrZ;`YEabhK0FHDBWjUd&d!Cdl4U$pASXQt@iyGZ17MPbTuM}f( z0-V`4;N;i?&ofFbGRxSR&R2|B+KE|%a=AFdYhkpFz-5Lp9j*ua9fiHW#MpD^h3CL% zZqB1m<8Bz4!YFi=^1Lc)hlvKs@WMH5vHTPAIqjX4Q_#ZlQ#sw;<8}L#T3SBu#@z(8 zr)78&i@aGfnWlirbG8cEE9hyLa>j|;_&ra&*Gqd+XyP+AJO!@5k*#}q8>tXd zVwwAkr@GZ0%uzg>`<$`S(@yzHstkRcxA(yw$FQGRr!j7*yV;1@DnVTBQ2os&lpw$V zm}MAmtXA{qR2g(aUE@BY&Tdck0p87V#cE`cpR|}SnNMxMGOK!C-eXU<{1sLpP1@7+ zU_>~GSe|LIy}&wwX9;25Dr0FUW|$f1Wjiaao}R*(m3K3U&5NEZ&m_EES1R;FqxF4_ z&5DcXFF8?LTHdm-ao)1X?ComBB1CiAuD<5EK@ELHZ85-;Y8f5#Qor-KVNO*Q3!1(==K6)3_FZxH@(X2!HRjO;4AtRrm-^e>phE}fw-tI#;Sr^_$uE$EAa`zo^G7yiC2796L7HHV)E_)O&=Ak=^qCN)*D8J z68kECJJv$%eZN+$-nXm$LY0rZY9I&eYj#$@-0|eR7CD0%O-n!jsx6^t?Vw6nkbn;9X5lEQiN+tHlrB0K%wnZ#|*=(@Vv=n{qMA^Eq}H zRV%q1!_FRsF4WUw8NFkWiaUBRUFX>~iWz1DMtC)|GvP-N$%L$8wStkSMq6-=_9SK* z9Uw&`TJ&+X5N*F5*0OV$?dAeoD{C%VuL$LQX?z3~B>m3Fq}L8%x3ZGV*O7j;lCJjyiW!XU zRcKI;%}T+Zz`6cf!@7T8!*w>+l|?F*Y?snU`6|*hWo^V5;90_mbWf<9@j4QU`?fx> zCCPSVK-Lk=rhIos5B6ikn4*@i2)SDrC0i^BCjT-a4`(?8fY2ShfC)dKxRcVdG)^@vIrnY|Pq^ zUXCzZtor`{4s~_!Q1ewC^KO{NG~X8;h9`X0wsWx;RyGLB`gS6_^Vmc7phkQWxaO@g z>P5rz5ZoI#Q`IfVyD@PC>A-IR{wOAWx9-dQ+d=NU$C07z>>_u|X=8{UwpsldD84+A zTjV#=4*7UixcAfwBDYG*KHja7JMi1mc054-}p^(x6#N*EZm3`c}Mqegry9YHs1P6SKBGo8)VFLoTJbZ$b9^@k`ed=*HLu zkEOKn4UW=&OTMb>ExO)~{B%e&hCPqjn*mcBVV^V^tl&0<#7(|*n$MH}0$Fbj8T&BfY|HjlqJElFpmjre<0euaJ48a`R>2gWn_+yVZ5_!eR> z&hcl^@4*SUmxSbZt^dH+k+25tE5Kw=3byxfF5$2EmH0`Wu=>lgfUCDupf!)z)fTKx%}#qEu~jNoGqPg0XHixq{R(IAp?)a0 zgQk;#6%e1DdH(qKOw_7KyO|F*BPV)V`$3D}5!kyb(&)nZv|Y@jnVA2Y_u;cG}^;5 zFVA*n?BlQ}?PR{|LY^z>ljbozQ5(&o)xFIH^)1_e(5zpix$t!G;gqyZg>`}JgCKf1?ykp03w$bM5FWWSOR^mp;36J)=P59DG-&;9B>;K8CT Z$bP9FNI9G1uglqjy8r7?!ps_#|6kmo5w8FM literal 0 HcmV?d00001 diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp new file mode 100644 index 00000000000..6bc1007e603 --- /dev/null +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -0,0 +1,218 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // explorer.cpp + // + // Martin Fuchs, 23.07.2003 + // + // Credits: Thanks to Leon Finker for his explorer window example + // + + +#include "utility/utility.h" +#include "utility/shellclasses.h" + +#include "explorer.h" +#include "globals.h" + +#include "explorer_intres.h" +#include "externals.h" + + +ExplorerGlobals g_Globals; + + +ExplorerGlobals::ExplorerGlobals() +{ + _hInstance = 0; + _hframeClass = 0; + _cfStrFName = 0; + _hMainWnd = 0; + _prescan_nodes = false; + _desktop_mode = false; +} + + +ResString::ResString(UINT nid) +{ + TCHAR buffer[BUFFER_LEN]; + + int len = LoadString(g_Globals._hInstance, nid, buffer, sizeof(buffer)/sizeof(TCHAR)); + + assign(buffer, len); +} + + +void explorer_show_frame(HWND hwndParent, int cmdshow) +{ + if (g_Globals._hMainWnd) + return; + + g_Globals._prescan_nodes = false; + + HMENU hMenuFrame = LoadMenu(g_Globals._hInstance, MAKEINTRESOURCE(IDM_MAINFRAME)); + + // create main window + g_Globals._hMainWnd = Window::Create(WINDOW_CREATOR(MainFrame), 0, + (LPCTSTR)g_Globals._hframeClass, ResString(IDS_TITLE), WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + hwndParent, hMenuFrame); + + ShowWindow(g_Globals._hMainWnd, cmdshow); + + UpdateWindow(g_Globals._hMainWnd); + + // Open the first child window after initialiszing the whole application + PostMessage(g_Globals._hMainWnd, WM_OPEN_WINDOW, 0, 0); +} + + +static void InitInstance(HINSTANCE hinstance) +{ + g_Globals._hInstance = hinstance; + + setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName + + + // register frame window class + + WindowClass wcFrame(CLASSNAME_FRAME); + + wcFrame.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_EXPLORER)); + wcFrame.hCursor = LoadCursor(0, IDC_ARROW); + wcFrame.hIconSm = (HICON)LoadImage(hinstance, + MAKEINTRESOURCE(IDI_EXPLORER), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_SHARED); + + g_Globals._hframeClass = wcFrame.Register(); + + + // register child windows class + + WindowClass wcChild(CLASSNAME_CHILDWND); + + wcChild.style = CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW; + wcChild.hCursor = LoadCursor(0, IDC_ARROW); + + wcChild.Register(); + + + // register tree windows class + + WindowClass wcTreeChild(CLASSNAME_WINEFILETREE); + + wcTreeChild.style = CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW; + wcTreeChild.hCursor = LoadCursor(0, IDC_ARROW); + + wcTreeChild.Register(); + + + g_Globals._cfStrFName = RegisterClipboardFormat(CFSTR_FILENAME); +} + + +int explorer_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow) +{ + // initialize COM and OLE + OleInit usingCOM; + + // initialize Common Controls library + CommonControlInit usingCmnCtrl(ICC_LISTVIEW_CLASSES|ICC_TREEVIEW_CLASSES|ICC_BAR_CLASSES); + + try { + MSG msg; + + InitInstance(hinstance); + +#ifndef _ROS_ // don't maximize if being called from the ROS desktop + if (cmdshow == SW_SHOWNORMAL) + /*TODO: read window placement from registry */ + cmdshow = SW_MAXIMIZE; +#endif + + if (hwndParent) + g_Globals._desktop_mode = true; + + explorer_show_frame(hwndParent, cmdshow); + + while(GetMessage(&msg, 0, 0, 0)) { + if (g_Globals._hMainWnd && SendMessage(g_Globals._hMainWnd, WM_TRANSLATE_MSG, 0, (LPARAM)&msg)) + continue; + + TranslateMessage(&msg); + + try { + DispatchMessage(&msg); + } catch(COMException& e) { + HandleException(e, g_Globals._hMainWnd); + } + } + + return msg.wParam; + + } catch(COMException& e) { + HandleException(e, g_Globals._hMainWnd); + } + + return -1; +} + + +int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) +{ + // create desktop window and task bar only, if there is no other shell and we are + // the first explorer instance + BOOL startup_desktop = !IsAnyDesktopRunning(); + + // If there is given the command line option "-desktop", create desktop window anyways + if (!lstrcmp(lpCmdLine,TEXT("-desktop"))) + startup_desktop = TRUE; + + HWND hwndDesktop = 0; + + if (startup_desktop) + { + hwndDesktop = create_desktop_window(hInstance); + + // Initialize the explorer bar + HWND hwndExplorerBar = InitializeExplorerBar(hInstance, nShowCmd); + + // Load plugins + LoadAvailablePlugIns(hwndExplorerBar); + +#ifndef _DEBUG //MF: disabled for debugging + { + char* argv[] = {""}; + startup(1, argv); + } +#endif + } + + int ret = explorer_main(hInstance, hwndDesktop, nShowCmd); + + ReleaseAvailablePlugIns(); + + return ret; +} diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index dfcc8517678..876f2ca4bff 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -45,7 +45,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /YX /FD /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -53,7 +53,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.cmd # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 +# SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Debug" @@ -69,7 +70,7 @@ LINK32=link.cmd # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe @@ -77,7 +78,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.cmd # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Debug Release" @@ -94,7 +96,7 @@ LINK32=link.cmd # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /YX /FD /c -# ADD CPP /nologo /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /FR /YX /FD /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -102,7 +104,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.cmd # ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Unicode Release" @@ -119,7 +122,7 @@ LINK32=link.cmd # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -127,7 +130,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.cmd # ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 +# SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "explorer - Win32 Unicode Debug" @@ -144,7 +148,7 @@ LINK32=link.cmd # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe @@ -152,7 +156,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.cmd # ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none !ENDIF @@ -163,12 +168,56 @@ LINK32=link.cmd # Name "explorer - Win32 Debug Release" # Name "explorer - Win32 Unicode Release" # Name "explorer - Win32 Unicode Debug" -# Begin Group "res" +# Begin Group "utility" # PROP Default_Filter "" # Begin Source File -SOURCE=.\De.rc +SOURCE=.\utility\dragdropimpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\utility\dragdropimpl.h +# End Source File +# Begin Source File + +SOURCE=.\utility\shellbrowserimpl.h +# End Source File +# Begin Source File + +SOURCE=.\utility\shellclasses.cpp +# End Source File +# Begin Source File + +SOURCE=.\utility\shellclasses.h +# End Source File +# Begin Source File + +SOURCE=.\utility\treedroptarget.h +# End Source File +# Begin Source File + +SOURCE=.\utility\utility.cpp +# End Source File +# Begin Source File + +SOURCE=.\utility\utility.h +# End Source File +# Begin Source File + +SOURCE=.\utility\window.cpp +# End Source File +# Begin Source File + +SOURCE=.\utility\window.h +# End Source File +# End Group +# Begin Group "resources" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\de.rc !IF "$(CFG)" == "explorer - Win32 Release" @@ -201,7 +250,7 @@ SOURCE=.\res\drivebar.bmp # End Source File # Begin Source File -SOURCE=.\En.rc +SOURCE=.\en.rc !IF "$(CFG)" == "explorer - Win32 Release" @@ -230,11 +279,19 @@ SOURCE=.\En.rc # End Source File # Begin Source File -SOURCE=.\res\images.bmp +SOURCE=.\res\explorer.ico # End Source File # Begin Source File -SOURCE=.\include\resource.h +SOURCE=.\explorer_intres.h +# End Source File +# Begin Source File + +SOURCE=.\explorer_intres.rc +# End Source File +# Begin Source File + +SOURCE=.\res\images.bmp # End Source File # Begin Source File @@ -269,50 +326,126 @@ SOURCE=.\resource.rc SOURCE=.\res\toolbar.bmp # End Source File -# Begin Source File - -SOURCE=.\res\winefile.ico -# End Source File -# Begin Source File - -SOURCE=.\winefile.rc -# End Source File # End Group -# Begin Group "include" +# Begin Group "taskbar" # PROP Default_Filter "" # Begin Source File -SOURCE=.\include\explorer.h +SOURCE=.\taskbar\ex_bar.c # End Source File # Begin Source File -SOURCE=.\include\license.h +SOURCE=.\taskbar\ex_bar.h # End Source File # Begin Source File -SOURCE=.\include\winefile.h +SOURCE=.\taskbar\ex_clock.c +# End Source File +# Begin Source File + +SOURCE=.\taskbar\ex_menu.c +# End Source File +# Begin Source File + +SOURCE=.\taskbar\ex_shutdwn.c +# End Source File +# End Group +# Begin Group "desktop" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\desktop\desktop.cpp +# End Source File +# Begin Source File + +SOURCE=.\desktop\desktop.h # End Source File # End Group # Begin Source File -SOURCE=.\desktop.c +SOURCE=.\shell\entries.cpp # End Source File # Begin Source File -SOURCE=.\ex_bar.c +SOURCE=.\shell\entries.h # End Source File # Begin Source File -SOURCE=.\splitpath.c +SOURCE=.\explorer.cpp # End Source File # Begin Source File -SOURCE=.\startup.c +SOURCE=.\explorer.h # End Source File # Begin Source File -SOURCE=.\winefile.c +SOURCE=.\externals.h +# End Source File +# Begin Source File + +SOURCE=.\shell\filechild.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\filechild.h +# End Source File +# Begin Source File + +SOURCE=.\globals.h +# End Source File +# Begin Source File + +SOURCE=.\shell\mainframe.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\mainframe.h +# End Source File +# Begin Source File + +SOURCE=.\shell\pane.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\pane.h +# End Source File +# Begin Source File + +SOURCE=.\shell\shellbrowser.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\shellbrowser.h +# End Source File +# Begin Source File + +SOURCE=.\shell\shellfs.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\shellfs.h +# End Source File +# Begin Source File + +SOURCE=.\shell\startup.c +# End Source File +# Begin Source File + +SOURCE=.\shell\unixfs.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\unixfs.h +# End Source File +# Begin Source File + +SOURCE=.\shell\winfs.cpp +# End Source File +# Begin Source File + +SOURCE=.\shell\winfs.h # End Source File # End Target # End Project diff --git a/reactos/subsys/system/explorer/explorer.dsw b/reactos/subsys/system/explorer/explorer.dsw index 4d457e67756..34bf5a90a43 100644 --- a/reactos/subsys/system/explorer/explorer.dsw +++ b/reactos/subsys/system/explorer/explorer.dsw @@ -3,7 +3,19 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "explorer"=.\explorer.dsp - Package Owner=<4> +Project: "explorer"=".\explorer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "make_explorer"=".\make_explorer.dsp" - Package Owner=<4> Package=<5> {{{ diff --git a/reactos/subsys/system/explorer/explorer.h b/reactos/subsys/system/explorer/explorer.h new file mode 100644 index 00000000000..5ac7704d9c7 --- /dev/null +++ b/reactos/subsys/system/explorer/explorer.h @@ -0,0 +1,83 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // explorer.h + // + // Martin Fuchs, 23.07.2003 + // + + +#include "shell/entries.h" + +#include "shell/winfs.h" +#include "shell/unixfs.h" +#include "shell/shellfs.h" + +#include "utility/window.h" + + +#define BUFFER_LEN 1024 + + +#define IDW_STATUSBAR 0x100 +#define IDW_TOOLBAR 0x101 +#define IDW_DRIVEBAR 0x102 +#define IDW_FIRST_CHILD 0xC000 /*0x200*/ + + +#define WM_TRANSLATE_MSG (WM_APP+2) +#define WM_GET_FILEWND_PTR (WM_APP+3) + +#define FRM_CALC_CLIENT (WM_APP+4) +#define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt)) + +#define WM_OPEN_WINDOW (WM_APP+5) + +#define WM_GET_CONTROLWINDOW (WM_APP+6) + + +#define CLASSNAME_FRAME TEXT("CabinetWClass") // same class name for frame window as in MS Explorer + +#define CLASSNAME_CHILDWND TEXT("WFS_Child") +#define CLASSNAME_WINEFILETREE TEXT("WFS_Tree") + + +struct String +#ifdef UNICODE + : public wstring +#else + : public string +#endif +{ + operator LPCTSTR() const {return c_str();} +}; + +struct ResString : public String +{ + ResString(UINT nid); +}; + + +#include "shell/mainframe.h" +#include "shell/pane.h" +#include "shell/filechild.h" +#include "shell/shellbrowser.h" diff --git a/reactos/subsys/system/explorer/explorer.lst b/reactos/subsys/system/explorer/explorer.lst index f87d871ac08..56356fc9378 100644 --- a/reactos/subsys/system/explorer/explorer.lst +++ b/reactos/subsys/system/explorer/explorer.lst @@ -1,5 +1,13 @@ -2 +6 Calculator calc.exe Excel -c:\windows\calc.exe \ No newline at end of file +excel.exe +Word +winword.exe +Explorer +explorer.exe +cmd Prompt +cmd.exe +File Manager +winefile.exe diff --git a/reactos/subsys/system/explorer/explorer.rc b/reactos/subsys/system/explorer/explorer.rc index 197bd89c8f7..64d3f2a5bc7 100644 --- a/reactos/subsys/system/explorer/explorer.rc +++ b/reactos/subsys/system/explorer/explorer.rc @@ -1,6 +1,11 @@ #include #include + +#ifdef _WINEFILE_ #include "winefile.rc" +#else +#include "explorer_intres.rc" +#endif LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h new file mode 100644 index 00000000000..ca4adb5544b --- /dev/null +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -0,0 +1,53 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by explorer_intres.rc +// +#define IDS_TITLE 1 +#define IDI_EXPLORER 100 +#define IDB_TOOLBAR 101 +#define IDA_EXPLORER 101 +#define ID_ACTIVATE 101 +#define IDB_DRIVEBAR 102 +#define IDB_IMAGES 103 +#define IDD_EXECUTE 103 +#define IDR_MAINFRAME 104 +#define IDM_MAINFRAME 105 +#define ID_EXECUTE 105 +#define IDM_WINEFILE 107 +#define ID_VIEW_NAME 401 +#define ID_VIEW_ALL_ATTRIBUTES 402 +#define ID_VIEW_SELECTED_ATTRIBUTES 403 +#define ID_VIEW_STATUSBAR 503 +#define ID_VIEW_DRIVE_BAR 507 +#define ID_VIEW_TOOL_BAR 508 +#define ID_REFRESH 1704 +#define ID_ABOUT 1803 +#define IDC_FILETREE 10001 +#define ID_WINDOW_AUTOSORT 0x8003 +#define ID_VIEW_FULLSCREEN 0x8004 +#define ID_PREFERED_SIZES 0x8005 +#define ID_DRIVE_DESKTOP 0x9000 +#define ID_DRIVE_SHELL_NS 0x9001 +#define ID_DRIVE_UNIX_FS 0x9002 +#define ID_DRIVE_FIRST 0x9003 +#define ID_WINDOW_NEW 0xE130 +#define ID_WINDOW_ARRANGE 0xE131 +#define ID_WINDOW_CASCADE 0xE132 +#define ID_WINDOW_TILE_HORZ 0xE133 +#define ID_WINDOW_TILE_VERT 0xE134 +#define ID_WINDOW_SPLIT 0xE135 +#define ID_EDIT_PROPERTIES 57656 +#define ID_FILE_EXIT 0xE141 +#define ID_HELP_USING 0xE144 +#define ID_HELP 0xE146 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 119 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/reactos/subsys/system/explorer/explorer_intres.rc b/reactos/subsys/system/explorer/explorer_intres.rc new file mode 100644 index 00000000000..ff23b29f9c2 --- /dev/null +++ b/reactos/subsys/system/explorer/explorer_intres.rc @@ -0,0 +1,432 @@ +//Microsoft Developer Studio generated resource script. +// +#include "explorer_intres.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#ifndef _ROS_ +#include "afxres.h" +#endif +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_IMAGES BITMAP DISCARDABLE "res/images.bmp" +IDB_TOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp" +IDB_DRIVEBAR BITMAP DISCARDABLE "res/drivebar.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDA_EXPLORER ACCELERATORS DISCARDABLE +BEGIN + "X", ID_FILE_EXIT, VIRTKEY, ALT, NOINVERT + "S", ID_VIEW_FULLSCREEN, VIRTKEY, SHIFT, CONTROL, + NOINVERT +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// German (Germany) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "explorer_intres.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#ifndef _ROS_\r\n" + "#include ""afxres.h""\r\n" + "#endif\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_EXPLORER ICON DISCARDABLE "res\\explorer.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDM_WINEFILE MENU FIXED IMPURE +BEGIN + POPUP "&Datei" + BEGIN + MENUITEM "Ö&ffnen\tEingabetaste", 101 + MENUITEM "&Verschieben...\tF7", 106 + MENUITEM "&Kopieren...\tF8", 107 + MENUITEM "&In Zwischenablage...\tF9", 118 + MENUITEM "&Löschen\tEntf", 108 + MENUITEM "&Umbenennen...", 109 + MENUITEM "&Eigenschaften...\tAlt+Eingabetaste", ID_EDIT_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "K&omprimieren...", 119 + MENUITEM "Deko&mprimieren...", 120 + MENUITEM SEPARATOR + MENUITEM "&Ausführen...", ID_EXECUTE + MENUITEM "&Drucken...", 102 + MENUITEM "Zuord&nen...", 103 + MENUITEM SEPARATOR + MENUITEM "Ver&zeichnis erstellen...", 111 + MENUITEM "&Suchen...", 104 + MENUITEM "Dateien aus&wählen...", 116 + MENUITEM SEPARATOR + MENUITEM "&Beenden\tAlt+X", ID_FILE_EXIT + END + POPUP "Da&tenträger" + BEGIN + MENUITEM "Datenträger &kopieren...", 201 + MENUITEM "Datenträger &benennen...", 202 + MENUITEM SEPARATOR + MENUITEM "Datenträger &formatieren...", 203 + MENUITEM SEPARATOR + MENUITEM "Netzwerklaufwerk &verbinden...", 252 + MENUITEM "Netzwerklaufwerk &trennen...", 253 + MENUITEM SEPARATOR + MENUITEM "F&reigeben als...", 254 + MENUITEM "Freigabe been&den...", 255 + MENUITEM SEPARATOR + MENUITEM "Laufwerk aus&wählen...", 251 + END + POPUP "&Verzeichnisse" + BEGIN + MENUITEM "&Nächste Ebene einblenden\t+", 301 + MENUITEM "&Zweig einblenden\t*", 302 + MENUITEM "Alle &Ebenen einblenden\tStrg+*", 303 + MENUITEM "Zweig &ausblenden\t-", 304 + MENUITEM SEPARATOR + MENUITEM "&Verzweigungen kennzeichnen", 505 + END + POPUP "&Ansicht" + BEGIN + MENUITEM "Struktur &und Verzeichnis", 413 + MENUITEM "Nur St&ruktur", 411 + MENUITEM "Nur &Verzeichnis", 412 + MENUITEM SEPARATOR + MENUITEM "&Teilen", 414 + MENUITEM SEPARATOR + MENUITEM "&Name", ID_VIEW_NAME + MENUITEM "A&lle Dateiangaben", ID_VIEW_ALL_ATTRIBUTES + , CHECKED + MENUITEM "&Bestimmte Dateiangaben...", ID_VIEW_SELECTED_ATTRIBUTES + MENUITEM SEPARATOR + MENUITEM "Nach N&ame", 404 + MENUITEM "Nach T&yp", 405 + MENUITEM "Nach &Größe", 406 + MENUITEM "Nach &Datum", 407 + MENUITEM SEPARATOR + MENUITEM "Angaben ausw&ählen...", 409 + END + POPUP "&Optionen" + BEGIN + MENUITEM "&Bestätigen...", 65535 + MENUITEM "Schrift&art...", 65535 + MENUITEM "Symbolleiste &definieren...", 65535 + MENUITEM SEPARATOR + MENUITEM "Sy&mbolleiste", ID_VIEW_TOOL_BAR, CHECKED + MENUITEM "Lauf&werkleiste", ID_VIEW_DRIVE_BAR, CHECKED + MENUITEM "&Statusleiste", ID_VIEW_STATUSBAR, CHECKED + MENUITEM "Vollb&ild\tStrg+Umschalt+S", ID_VIEW_FULLSCREEN + MENUITEM SEPARATOR + MENUITEM "&Symbol nach Programmstart", 65535 + MENUITEM "&Einstellungen beim Beenden speichern", 511 + END + POPUP "&Sicherheit" + BEGIN + MENUITEM "&Berechtigungen...", 605 + MENUITEM "Über&wachen...", 606 + MENUITEM "Besi&tzer...", 607 + END + POPUP "&Fenster" + BEGIN + MENUITEM "Neues &Fenster", ID_WINDOW_NEW + MENUITEM "Über&lappend\tUmschalt+F5", ID_WINDOW_CASCADE + MENUITEM "&Untereinander", ID_WINDOW_TILE_HORZ + MENUITEM "&Nebeneinander\tUmschalt+F4", ID_WINDOW_TILE_VERT + MENUITEM "au&tomatisch anordnen", ID_WINDOW_AUTOSORT + MENUITEM "&Symbole anordnen", ID_WINDOW_ARRANGE + MENUITEM "&Aktualisieren\tF5", ID_REFRESH + END + POPUP "&?" + BEGIN + MENUITEM "&Hilfethemen\tF1", ID_HELP + MENUITEM "&Suchen...\tF1", ID_HELP + MENUITEM "Hilfe &verwenden\tF1", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "Info about &Winefile...", ID_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Ausführen" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",101,"Static",SS_SIMPLE | SS_NOPREFIX,3,6,162,10 + CONTROL "Befehls&zeile:",-1,"Static",SS_LEFTNOWORDWRAP | + WS_GROUP,3,18,60,10 + EDITTEXT 201,3,29,134,12,ES_AUTOHSCROLL + CONTROL "Als &Symbol",214,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 3,45,71,12 + DEFPUSHBUTTON "OK",1,158,6,47,14 + PUSHBUTTON "Abbrechen",2,158,23,47,14 + PUSHBUTTON "&Hilfe",254,158,43,47,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TITLE "Reactos Explorer" +END + +#endif // German (Germany) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDM_MAINFRAME MENU PRELOAD DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&View" + BEGIN + MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR + MENUITEM "&Status Bar", ID_VIEW_STATUSBAR + END + POPUP "&Window" + BEGIN + MENUITEM "New &Window", ID_WINDOW_NEW + MENUITEM "Cascading\tCtrl+F5", ID_WINDOW_CASCADE + MENUITEM "Tile &Horizontally", ID_WINDOW_TILE_HORZ + MENUITEM "Tile &Vertically\tCtrl+F4", ID_WINDOW_TILE_VERT + MENUITEM "Arrange Automatically", ID_WINDOW_AUTOSORT + MENUITEM "Arrange &Symbols", ID_WINDOW_ARRANGE + MENUITEM "&Refresh\tF5", ID_REFRESH + END + POPUP "&Help" + BEGIN + MENUITEM "&About explorer...", ID_ABOUT + END +END + +IDM_WINEFILE MENU FIXED IMPURE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open\tEnter", 101 + MENUITEM "&Move...\tF7", 106 + MENUITEM "&Copy...\tF8", 107 + MENUITEM "&In Clipboard...\tF9", 118 + MENUITEM "&Delete\tDel", 108 + MENUITEM "Re&name...", 109 + MENUITEM "Propert&ies...\tAlt+Enter", ID_EDIT_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "C&ompress...", 119 + MENUITEM "Dec&ompress...", 120 + MENUITEM SEPARATOR + MENUITEM "&Run...", ID_EXECUTE + MENUITEM "&Print...", 102 + MENUITEM "Associate...", 103 + MENUITEM SEPARATOR + MENUITEM "Cr&eate Directory...", 111 + MENUITEM "Searc&h...", 104 + MENUITEM "&Select Files...", 116 + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+X", ID_FILE_EXIT + END + POPUP "&Disk" + BEGIN + MENUITEM "&Copy Disk...", 201 + MENUITEM "&Label Disk...", 202 + MENUITEM SEPARATOR + MENUITEM "&Format Disk...", 203 + MENUITEM SEPARATOR + MENUITEM "Connect &Network Drive", 252 + MENUITEM "&Disconnect Network Drive", 253 + MENUITEM SEPARATOR + MENUITEM "Share as...", 254 + MENUITEM "&Remove Share...", 255 + MENUITEM SEPARATOR + MENUITEM "&Select Drive...", 251 + END + POPUP "&Directories" + BEGIN + MENUITEM "&Next Level\t+", 301 + MENUITEM "Expand &Tree\t*", 302 + MENUITEM "Expand &all\tStrg+*", 303 + MENUITEM "Collapse &Tree\t-", 304 + MENUITEM SEPARATOR + MENUITEM "&Mark Childs", 505 + END + POPUP "&View" + BEGIN + MENUITEM "T&ree and Directory", 413 + MENUITEM "Tr&ee Only", 411 + MENUITEM "Directory &Only", 412 + MENUITEM SEPARATOR + MENUITEM "Sp&lit", 414 + MENUITEM SEPARATOR + MENUITEM "&Name", ID_VIEW_NAME + MENUITEM "&All File Details", ID_VIEW_ALL_ATTRIBUTES + , CHECKED + MENUITEM "&Partial Details...", ID_VIEW_SELECTED_ATTRIBUTES + MENUITEM SEPARATOR + MENUITEM "&Sort by Name", 404 + MENUITEM "Sort &by Type", 405 + MENUITEM "Sort by Si&ze", 406 + MENUITEM "Sort by &Date", 407 + MENUITEM SEPARATOR + MENUITEM "Sort by &...", 409 + END + POPUP "&Options" + BEGIN + MENUITEM "&Confirmation...", 65535 + MENUITEM "&Font...", 65535 + MENUITEM "Customize Tool&bar...", 65535 + MENUITEM SEPARATOR + MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR, CHECKED + MENUITEM "&Drivebar", ID_VIEW_DRIVE_BAR, CHECKED + MENUITEM "&Status Bar", ID_VIEW_STATUSBAR, CHECKED + MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN + MENUITEM SEPARATOR + MENUITEM "&Symbol nach Programmstart", 65535 + MENUITEM "&Einstellungen beim Beenden speichern", 511 + END + POPUP "&Security" + BEGIN + MENUITEM "&Access...", 605 + MENUITEM "&Logging...", 606 + MENUITEM "&Owner...", 607 + END + POPUP "&Window" + BEGIN + MENUITEM "New &Window", ID_WINDOW_NEW + MENUITEM "Cascading\tCtrl+F5", ID_WINDOW_CASCADE + MENUITEM "Tile &Horizontally", ID_WINDOW_TILE_HORZ + MENUITEM "Tile &Vertically\tCtrl+F4", ID_WINDOW_TILE_VERT + MENUITEM "Arrange Automatically", ID_WINDOW_AUTOSORT + MENUITEM "Arrange &Symbols", ID_WINDOW_ARRANGE + MENUITEM "&Refresh\tF5", ID_REFRESH + END + POPUP "&?" + BEGIN + MENUITEM "&Help Topics\tF1", ID_HELP + MENUITEM "Help &Search...\tF1", ID_HELP + MENUITEM "&Using Help\tF1", ID_HELP_USING + MENUITEM SEPARATOR + MENUITEM "Info about &Winefile...", ID_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_EXECUTE DIALOG FIXED IMPURE 15, 13, 210, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Execute" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",101,"Static",SS_SIMPLE | SS_NOPREFIX,3,6,162,10 + CONTROL "&Command:",-1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,3, + 18,60,10 + EDITTEXT 201,3,29,134,12,ES_AUTOHSCROLL + CONTROL "As &Symbol",214,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3, + 45,71,12 + DEFPUSHBUTTON "OK",1,158,6,47,14 + PUSHBUTTON "Cancel",2,158,23,47,14 + PUSHBUTTON "&Help",254,158,43,47,14 +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/reactos/subsys/system/explorer/externals.h b/reactos/subsys/system/explorer/externals.h new file mode 100644 index 00000000000..e12171f896b --- /dev/null +++ b/reactos/subsys/system/explorer/externals.h @@ -0,0 +1,62 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // externals.h + // + // Martin Fuchs, 07.06.2003 + // + + +#ifdef __cplusplus +extern "C" { +#endif + + + // launch start programs +extern int startup(int argc, char *argv[]); + + // explorer main routine +extern int explorer_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow); + + // display explorer/file manager window +extern void explorer_show_frame(HWND hWndParent, int cmdshow); + + // create desktop window +extern HWND create_desktop_window(HINSTANCE hInstance); + + // test for already running desktop instance +extern BOOL IsAnyDesktopRunning(); + + // start desktop bar +extern HWND InitializeExplorerBar(HINSTANCE hInstance, int nCmdShow); + + // load plugins +extern int LoadAvailablePlugIns(HWND ExplWnd); + + // shut down plugins +extern int ReleaseAvailablePlugIns(); + + +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/reactos/subsys/system/explorer/globals.h b/reactos/subsys/system/explorer/globals.h new file mode 100644 index 00000000000..6023c84d6bb --- /dev/null +++ b/reactos/subsys/system/explorer/globals.h @@ -0,0 +1,40 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // globals.h + // + // Martin Fuchs, 23.07.2003 + // + + +extern struct ExplorerGlobals +{ + ExplorerGlobals(); + + HINSTANCE _hInstance; + ATOM _hframeClass; + UINT _cfStrFName; + HWND _hMainWnd; + bool _prescan_nodes; + bool _desktop_mode; +} g_Globals; + diff --git a/reactos/subsys/system/explorer/include/explorer.h b/reactos/subsys/system/explorer/include/explorer.h deleted file mode 100644 index b25788b9bf9..00000000000 --- a/reactos/subsys/system/explorer/include/explorer.h +++ /dev/null @@ -1,27 +0,0 @@ - - // launch start programs -extern int startup( int argc, char *argv[] ); - - // winefile main routine -extern int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow); - - // search for windows of a specific clasname -extern int find_window_class(LPCTSTR classname); - - // display file manager window -extern void ShowFileMgr(HWND hWndParent, int cmdshow); - - // start desktop bar -extern HWND InitializeExplorerBar(HINSTANCE hInstance, int nCmdShow); - - // load plugins -extern int ExplorerLoadPlugins(HWND ExplWnd); - - // launch a program or document file -extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow); -#ifdef UNICODE -extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow); -#else -#define launch_fileA launch_file -#endif - diff --git a/reactos/subsys/system/explorer/make_explorer.dsp b/reactos/subsys/system/explorer/make_explorer.dsp new file mode 100644 index 00000000000..0fa9ff0947d --- /dev/null +++ b/reactos/subsys/system/explorer/make_explorer.dsp @@ -0,0 +1,89 @@ +# Microsoft Developer Studio Project File - Name="make_explorer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=make_explorer - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "make_explorer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "make_explorer.mak" CFG="make_explorer - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "make_explorer - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "make_explorer - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "make_explorer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f make_explorer.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "make_explorer.exe" +# PROP BASE Bsc_Name "make_explorer.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make 2>&1 | perl d:\tools\gSTLFilt.pl | javac2vc " +# PROP Rebuild_Opt "clean all" +# PROP Target_File "explorer.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "make_explorer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f make_explorer.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "make_explorer.exe" +# PROP BASE Bsc_Name "make_explorer.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make 2>&1 | perl d:\tools\gSTLFilt.pl | javac2vc " +# PROP Rebuild_Opt "clean all" +# PROP Target_File "explorer.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "make_explorer - Win32 Release" +# Name "make_explorer - Win32 Debug" + +!IF "$(CFG)" == "make_explorer - Win32 Release" + +!ELSEIF "$(CFG)" == "make_explorer - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Target +# End Project diff --git a/reactos/subsys/system/explorer/makefile_rex b/reactos/subsys/system/explorer/makefile_rex index b6aafa86a96..2531b9fc1dc 100644 --- a/reactos/subsys/system/explorer/makefile_rex +++ b/reactos/subsys/system/explorer/makefile_rex @@ -1,5 +1,5 @@ # -# ReactOS winfile +# ReactOS explorer # # Makefile # @@ -12,35 +12,67 @@ TARGET_APPTYPE = windows TARGET_NAME = explorer -TARGET_CFLAGS = -fexceptions -O2 -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ -W +TARGET_CFLAGS = -fexceptions -O2 -DNDEBUG -DWIN32 -D_ROS_ -W -D_WIN32_IE=0x0500 + +TARGET_CPPFLAGS = -fexceptions -O2 -DNDEBUG -DWIN32 -D_ROS_ -W -D_WIN32_IE=0x0500 TARGET_RCFLAGS = -DNDEBUG -DWIN32 -DUNICODE -D_ROS_ +ifdef UNICODE +TARGET_CFLAGS += -DUNICODE +TARGET_CPPFLAGS += -DUNICODE +MK_DEFENTRY := _wWinMain@16 +endif + +VPATH += shell +VPATH += utility +VPATH += taskbar +VPATH += desktop + WINE_MODE = yes WINE_RC = $(TARGET_NAME) WINE_INCLUDE = ./ -TARGET_GCCLIBS = comctl32 +TARGET_GCCLIBS = comctl32 ole32 uuid + +all: explorer.exe + @strip explorer.exe TARGET_SDKLIBS = \ kernel32.a \ user32.a \ gdi32.a \ advapi32.a \ - version.a \ + version.a TARGET_OBJECTS = \ - desktop.o \ - ex_bar.o \ - license.o \ - splitpath.o \ startup.o \ - winefile.o + ex_bar.o \ + ex_menu.o \ + ex_clock.o \ + ex_shutdwn.o \ + shellclasses.o \ + utility.o \ + window.o \ + dragdropimpl.o \ + explorer.o \ + entries.o \ + winfs.o \ + unixfs.o \ + shellfs.o \ + mainframe.o \ + filechild.o \ + pane.o \ + shellbrowser.o \ + desktop.o include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk +# overide LD_CC to use g++ for linking of the executable +LD_CC = $(CXX) + # EOF diff --git a/reactos/subsys/system/explorer/res/explorer.ico b/reactos/subsys/system/explorer/res/explorer.ico new file mode 100644 index 0000000000000000000000000000000000000000..fd637a051137403c0962a15264ef637ee64d9212 GIT binary patch literal 1078 zcmb_bL2iRE5FC<9AVq5UK{-|VMfxP)h|~i<_SWZs)B`*v#~gdZ5>eb)8?+E{LfvG% zJIvZ^>;*`$Ls8@qyX}B?`aF;PlmM@L;KXMI@j)bb;RsmfuA8Mu#oFjNGDO#P^dk81 zhxZZ@{K+F3{@+S9!`0J4E$~)Nc%||n{8QyR<8-fjFI?r;IHs#Sn1;)#ULV||dU(^44blR~TMYNDmPmBqYsj>=NBKE+- z9>D%i@XZ2#=>^vj9lgLlVbY&H=N=v2{2gciK((kPMEX1@3S#Q>j`6x#u(b&r9Y==S z`aE8=8IRkH*O0}2>a*Bp%~u+BY+OwLZpMCdA>Vr^+?VBred2p=4OqV$`P6t8xQ^)P R1$GAE6Rv0GSMrTU`~h~>hO__x literal 0 HcmV?d00001 diff --git a/reactos/subsys/system/explorer/shell/entries.cpp b/reactos/subsys/system/explorer/shell/entries.cpp new file mode 100644 index 00000000000..9a2efa06815 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/entries.cpp @@ -0,0 +1,277 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // entries.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" +#include "../globals.h" + +#include "entries.h" + + + // allocate and initialise a directory entry +Entry::Entry(ENTRY_TYPE etype) + : _etype(etype) +{ + _up = NULL; + _next = NULL; + _down = NULL; + _expanded = false; + _scanned = false; + _level = 0; + _hicon = 0; +} + +Entry::Entry(Entry* parent) + : _etype(parent->_etype), + _up(parent) +{ + _next = NULL; + _down = NULL; + _expanded = false; + _scanned = false; + _level = 0; + _hicon = 0; +} + + // free a directory entry +Entry::~Entry() +{ + if (_hicon && _hicon!=(HICON)-1) + DestroyIcon(_hicon); +} + + + // read directory tree and expand to the given location +Entry* Entry::read_tree(const void* path, SORT_ORDER sortOrder) +{ + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + + Entry* entry = this; + Entry* next_entry = entry; + + for(const void*p=path; p&&next_entry; p=entry->get_next_path_component(p)) { + entry = next_entry; + + entry->read_directory(sortOrder); + + if (entry->_down) + entry->_expanded = true; + + next_entry = entry->find_entry(p); + } + + SetCursor(old_cursor); + + return entry; +} + + +void Entry::read_directory(SORT_ORDER sortOrder) +{ + // call into subclass + read_directory(); + + if (g_Globals._prescan_nodes) { + for(Entry*entry=_down; entry; entry=entry->_next) + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + entry->read_directory(); + entry->sort_directory(sortOrder); + } + } + + sort_directory(sortOrder); +} + + +Root::Root() +{ + memset(this, 0, sizeof(Root)); +} + +Root::~Root() +{ + if (_entry) + _entry->free_subentries(); +} + + + // directories first... +static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2) +{ + int dir1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + int dir2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + + return dir2==dir1? 0: dir2_data; + const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data; + + int cmp = compareType(fd1, fd2); + if (cmp) + return cmp; + + return lstrcmpi(fd1->cFileName, fd2->cFileName); +} + +static int compareExt(const void* arg1, const void* arg2) +{ + const WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data; + const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data; + const TCHAR *name1, *name2, *ext1, *ext2; + + int cmp = compareType(fd1, fd2); + if (cmp) + return cmp; + + name1 = fd1->cFileName; + name2 = fd2->cFileName; + + ext1 = _tcsrchr(name1, TEXT('.')); + ext2 = _tcsrchr(name2, TEXT('.')); + + if (ext1) + ++ext1; + else + ext1 = TEXT(""); + + if (ext2) + ++ext2; + else + ext2 = TEXT(""); + + cmp = lstrcmpi(ext1, ext2); + if (cmp) + return cmp; + + return lstrcmpi(name1, name2); +} + +static int compareSize(const void* arg1, const void* arg2) +{ + WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data; + WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data; + + int cmp = compareType(fd1, fd2); + if (cmp) + return cmp; + + cmp = fd2->nFileSizeHigh - fd1->nFileSizeHigh; + + if (cmp < 0) + return -1; + else if (cmp > 0) + return 1; + + cmp = fd2->nFileSizeLow - fd1->nFileSizeLow; + + return cmp<0? -1: cmp>0? 1: 0; +} + +static int compareDate(const void* arg1, const void* arg2) +{ + WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->_data; + WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->_data; + + int cmp = compareType(fd1, fd2); + if (cmp) + return cmp; + + return CompareFileTime(&fd2->ftLastWriteTime, &fd1->ftLastWriteTime); +} + + +static int (*sortFunctions[])(const void* arg1, const void* arg2) = { + compareName, // SORT_NAME + compareExt, // SORT_EXT + compareSize, // SORT_SIZE + compareDate // SORT_DATE +}; + + +void Entry::sort_directory(SORT_ORDER sortOrder) +{ + Entry* entry = _down; + Entry** array, **p; + int len; + + len = 0; + for(entry=_down; entry; entry=entry->_next) + ++len; + + if (len) { + array = (Entry**) alloca(len*sizeof(Entry*)); + + p = array; + for(entry=_down; entry; entry=entry->_next) + *p++ = entry; + + // call qsort with the appropriate compare function + qsort(array, len, sizeof(array[0]), sortFunctions[sortOrder]); + + _down = array[0]; + + for(p=array; --len; p++) + p[0]->_next = p[1]; + + (*p)->_next = 0; + } +} + + +BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow) +{ + TCHAR cmd[MAX_PATH]; + + get_path(cmd); + + // start program, open document... + return launch_file(hwnd, cmd, nCmdShow); +} + + + // recursively free all child entries +void Entry::free_subentries() +{ + Entry *entry, *next=_down; + + if (next) { + _down = 0; + + do { + entry = next; + next = entry->_next; + + entry->free_subentries(); + delete entry; + } while(next); + } +} diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h new file mode 100644 index 00000000000..8c9d328d668 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -0,0 +1,104 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // entries.h + // + // Martin Fuchs, 23.07.2003 + // + + +enum ENTRY_TYPE { + ET_WINDOWS, +#ifdef __linux__ + ET_UNIX, +#endif + ET_SHELL +}; + +enum SORT_ORDER { + SORT_NAME, + SORT_EXT, + SORT_SIZE, + SORT_DATE +}; + +struct Entry +{ +protected: + Entry(ENTRY_TYPE etype); + Entry(Entry* parent); + +public: + ~Entry(); + + Entry* _next; + Entry* _down; + Entry* _up; + + bool _expanded; + bool _scanned; + int _level; + + WIN32_FIND_DATA _data; + + BY_HANDLE_FILE_INFORMATION _bhfi; + bool _bhfi_valid; + + SFGAOF _shell_attribs; + + ENTRY_TYPE _etype; + HICON _hicon; + + void free_subentries(); + + void read_directory(SORT_ORDER sortOrder); + Entry* read_tree(const void* path, SORT_ORDER sortOrder); + void sort_directory(SORT_ORDER sortOrder); + + virtual void read_directory() {} + virtual const void* get_next_path_component(const void*) {return NULL;} + virtual Entry* find_entry(const void*) {return NULL;} + virtual void get_path(PTSTR path) = 0; + virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow); +}; + +struct Directory { +protected: + Directory(void* path) : _path(path) {} + ~Directory() {free(_path);} + + void* _path; +}; + + +struct Root { + Root(); + ~Root(); + + Entry* _entry; + TCHAR _path[MAX_PATH]; + TCHAR _volname[_MAX_FNAME]; + TCHAR _fs[_MAX_DIR]; + DWORD _drive_type; + DWORD _fs_flags; +}; + diff --git a/reactos/subsys/system/explorer/shell/filechild.cpp b/reactos/subsys/system/explorer/shell/filechild.cpp new file mode 100644 index 00000000000..0503b763027 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/filechild.cpp @@ -0,0 +1,511 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // filechild.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "../explorer.h" +#include "../globals.h" + +#include "../explorer_intres.h" + + +FileChildWndInfo::FileChildWndInfo(LPCTSTR path) +{ +#ifdef __linux__ + if (*path == '/') + _etype = ET_UNIX; + else +#endif + _etype = ET_WINDOWS; + + _path = path; + + _pos.length = sizeof(WINDOWPLACEMENT); + _pos.flags = 0; + _pos.showCmd = SW_SHOWNORMAL; + _pos.rcNormalPosition.left = CW_USEDEFAULT; + _pos.rcNormalPosition.top = CW_USEDEFAULT; + _pos.rcNormalPosition.right = CW_USEDEFAULT; + _pos.rcNormalPosition.bottom = CW_USEDEFAULT; +} + + +ShellChildWndInfo::ShellChildWndInfo(LPCTSTR path, const ShellPath& root_shell_path) + : FileChildWndInfo(path) +{ + _etype = ET_SHELL; + _path = path; + _shell_path = path; + _root_shell_path = root_shell_path; +} + + +FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info) + : ChildWindow(hwnd) +{ + TCHAR drv[_MAX_DRIVE+1]; + Entry* entry; + + if (info._etype == ET_SHELL) //@@ evtl. Aufteilung von FileChildWindow in ShellChildWindow, WinChildWindow, UnixChildWindow + { + _root._drive_type = DRIVE_UNKNOWN; + lstrcpy(drv, TEXT("\\")); + lstrcpy(_root._volname, TEXT("Desktop")); + _root._fs_flags = 0; + lstrcpy(_root._fs, TEXT("Shell")); + + const ShellChildWndInfo& shell_info = static_cast(info); + _root._entry = new ShellDirectory(ShellFolder(shell_info._root_shell_path), shell_info._shell_path, hwnd); + entry = _root._entry->read_tree((LPCTSTR)&*shell_info._shell_path, SORT_NAME/*_sortOrder*/); + } + else +#ifdef __linux__ + if (info._etype == ET_UNIX) + { + _root.drive_type = GetDriveType(path); + + _tsplitpath(info._path, drv, NULL, NULL, NULL); + lstrcat(drv, TEXT("/")); + lstrcpy(_root.volname, TEXT("root fs")); + _root.fs_flags = 0; + lstrcpy(_root.fs, TEXT("unixfs")); + lstrcpy(_root.path, TEXT("/")); + _root._entry = new UnixDirectory(_root._path, info._path); + entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/); + } + else +#endif + {// if (info._etype == ET_WINDOWS) + _root._drive_type = GetDriveType(info._path); + + _tsplitpath(info._path, drv, NULL, NULL, NULL); + lstrcat(drv, TEXT("\\")); + GetVolumeInformation(drv, _root._volname, _MAX_FNAME, 0, 0, &_root._fs_flags, _root._fs, _MAX_DIR); + lstrcpy(_root._path, drv); + _root._entry = new WinDirectory(_root._path); + entry = _root._entry->read_tree(info._path, SORT_NAME/*_sortOrder*/); + } + + if (info._etype == ET_SHELL) + lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); + else + wsprintf(_root._entry->_data.cFileName, TEXT("%s - %s"), drv, _root._fs); + + _root._entry->_data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; + + + _left._treePane = true; + _left._visible_cols = 0; + + _left._root = _root._entry; + _right._root = NULL; + + _right._treePane = false; + _right._visible_cols = COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_INDEX|COL_LINKS; + + _sortOrder = SORT_NAME; + _header_wdths_ok = false; + + _left_hwnd = _left.create(_hwnd, IDW_TREE_LEFT, IDW_HEADER_LEFT); + _right_hwnd = _right.create(_hwnd, IDW_TREE_RIGHT, IDW_HEADER_RIGHT); + + set_curdir(entry, hwnd); + + int idx = ListBox_FindItemData(_left._hwnd, ListBox_GetCurSel(_left._hwnd), _left._cur); + ListBox_SetCurSel(_left._hwnd, idx); + + //TODO: scroll to visibility + +} + +FileChildWindow::~FileChildWindow() +{ +} + + +void FileChildWindow::set_curdir(Entry* entry, HWND hwnd) +{ + _path[0] = TEXT('\0'); + + _left._cur = entry; + _right._root = entry&&entry->_down? entry->_down: entry; + _right._cur = entry; + + if (entry) { + if (!entry->_scanned) + scan_entry(entry, hwnd); + else { + ListBox_ResetContent(_right._hwnd); + _right.insert_entries(entry->_down, -1); + _right.calc_widths(false); + _right.set_header(); + } + + entry->get_path(_path); + } + + if (hwnd) // only change window title, if the window already exists + SetWindowText(hwnd, _path); + + if (_path[0]) + if (!SetCurrentDirectory(_path)) + _path[0] = TEXT('\0'); +} + + + // expand a directory entry + +bool FileChildWindow::expand_entry(Entry* dir) +{ + int idx; + Entry* p; + + if (!dir || dir->_expanded || !dir->_down) + return false; + + p = dir->_down; + + if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='\0' && p->_next) { + p = p->_next; + + if (p->_data.cFileName[0]=='.' && p->_data.cFileName[1]=='.' && + p->_data.cFileName[2]=='\0' && p->_next) + p = p->_next; + } + + // no subdirectories ? + if (!(p->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + return FALSE; + + idx = ListBox_FindItemData(_left._hwnd, 0, dir); + + dir->_expanded = true; + + // insert entries in left pane + _left.insert_entries(p, idx); + + if (!_header_wdths_ok) { + if (_left.calc_widths(false)) { + _left.set_header(); + + _header_wdths_ok = true; + } + } + + return true; +} + + +void FileChildWindow::collapse_entry(Pane* pane, Entry* dir) +{ + int idx = ListBox_FindItemData(pane->_hwnd, 0, dir); + + SendMessage(pane->_hwnd, WM_SETREDRAW, FALSE, 0); //ShowWindow(pane->_hwnd, SW_HIDE); + + // hide sub entries + for(;;) { + LRESULT res = ListBox_GetItemData(pane->_hwnd, idx+1); + Entry* sub = (Entry*) res; + + if (res==LB_ERR || !sub || sub->_level<=dir->_level) + break; + + ListBox_DeleteString(pane->_hwnd, idx+1); + } + + dir->_expanded = false; + + SendMessage(pane->_hwnd, WM_SETREDRAW, TRUE, 0); //ShowWindow(pane->_hwnd, SW_SHOW); +} + + +FileChildWindow* FileChildWindow::create(HWND hmdiclient, const FileChildWndInfo& info) +{ + MDICREATESTRUCT mcs; + + mcs.szClass = CLASSNAME_WINEFILETREE; + mcs.szTitle = (LPTSTR)info._path; + mcs.hOwner = g_Globals._hInstance; + mcs.x = info._pos.rcNormalPosition.left; + mcs.y = info._pos.rcNormalPosition.top; + mcs.cx = info._pos.rcNormalPosition.right - info._pos.rcNormalPosition.left; + mcs.cy = info._pos.rcNormalPosition.bottom - info._pos.rcNormalPosition.top; + mcs.style = 0; + mcs.lParam = 0; + + FileChildWindow* child = static_cast( + create_mdi_child(hmdiclient, mcs, WINDOW_CREATOR_INFO(FileChildWindow, FileChildWndInfo), &info)); + + return child; +} + + +void FileChildWindow::resize_children(int cx, int cy) +{ + HDWP hdwp = BeginDeferWindowPos(4); + RECT rt; + + rt.left = 0; + rt.top = 0; + rt.right = cx; + rt.bottom = cy; + + cx = _split_pos + SPLIT_WIDTH/2; + + { + WINDOWPOS wp; + HD_LAYOUT hdl; + + hdl.prc = &rt; + hdl.pwpos = ℘ + + Header_Layout(_left._hwndHeader, &hdl); + + DeferWindowPos(hdwp, _left._hwndHeader, wp.hwndInsertAfter, + wp.x-1, wp.y, _split_pos-SPLIT_WIDTH/2+1, wp.cy, wp.flags); + + DeferWindowPos(hdwp, _right._hwndHeader, wp.hwndInsertAfter, + rt.left+cx+1, wp.y, wp.cx-cx+2, wp.cy, wp.flags); + } + + DeferWindowPos(hdwp, _left._hwnd, 0, rt.left, rt.top, _split_pos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); + + DeferWindowPos(hdwp, _right._hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); + + EndDeferWindowPos(hdwp); +} + + +LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_DRAWITEM: { + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lparam; + Entry* entry = (Entry*) dis->itemData; + + if (dis->CtlID == IDW_TREE_LEFT) + _left.draw_item(dis, entry); + else + _right.draw_item(dis, entry); + + return TRUE;} + + case WM_SIZE: + if (wparam != SIZE_MINIMIZED) + resize_children(LOWORD(lparam), HIWORD(lparam)); + return DefMDIChildProc(_hwnd, nmsg, wparam, lparam); + + case WM_GET_FILEWND_PTR: + return (LRESULT)this; + + case WM_SETFOCUS: { + TCHAR path[MAX_PATH]; + + if (_left._cur) { + _left._cur->get_path(path); + SetCurrentDirectory(path); + } + + SetFocus(_focus_pane? _right._hwnd: _left._hwnd); + break;} + + case WM_DISPATCH_COMMAND: { + Pane* pane = GetFocus()==_left._hwnd? &_left: &_right; + + switch(LOWORD(wparam)) { + case ID_WINDOW_NEW: + if (_root._entry->_etype == ET_SHELL) + FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, ShellChildWndInfo(_path,DesktopFolder())); + else + FileChildWindow::create(GetParent(_hwnd)/*_hmdiclient*/, FileChildWndInfo(_path)); + break; + + case ID_REFRESH: { + bool expanded = _left._cur->_expanded; + + scan_entry(_left._cur, _hwnd); + + if (expanded) + expand_entry(_left._cur); + break;} + + case ID_ACTIVATE: + activate_entry(pane, _hwnd); + break; + + default: + return pane->command(LOWORD(wparam)); + } + + return TRUE;} + + default: + return super::WndProc(nmsg, wparam, lparam); + } + + return 0; +} + + +int FileChildWindow::Command(int id, int code) +{ + Pane* pane = GetFocus()==_left._hwnd? &_left: &_right; + + switch(code) { + case LBN_SELCHANGE: { + int idx = ListBox_GetCurSel(pane->_hwnd); + Entry* entry = (Entry*) ListBox_GetItemData(pane->_hwnd, idx); + + if (pane == &_left) + set_curdir(entry, _hwnd); + else + pane->_cur = entry; + break;} + + case LBN_DBLCLK: + activate_entry(pane, _hwnd); + break; + } + + return 0; +} + + +void FileChildWindow::activate_entry(Pane* pane, HWND hwnd) +{ + Entry* entry = pane->_cur; + + if (!entry) + return; + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + int scanned_old = entry->_scanned; + + if (!scanned_old) + scan_entry(entry, hwnd); + + if (entry->_data.cFileName[0]=='.' && entry->_data.cFileName[1]=='\0') + return; + + if (entry->_data.cFileName[0]=='.' && entry->_data.cFileName[1]=='.' && entry->_data.cFileName[2]=='\0') { + entry = _left._cur->_up; + collapse_entry(&_left, entry); + goto focus_entry; + } else if (entry->_expanded) + collapse_entry(pane, _left._cur); + else { + expand_entry(_left._cur); + + if (!pane->_treePane) focus_entry: { + int idx = ListBox_FindItemData(_left._hwnd, ListBox_GetCurSel(_left._hwnd), entry); + ListBox_SetCurSel(_left._hwnd, idx); + set_curdir(entry, _hwnd); + } + } + + if (!scanned_old) { + pane->calc_widths(FALSE); + + pane->set_header(); + } + } else { + entry->launch_entry(_hwnd, SW_SHOWNORMAL); + } +} + + +void FileChildWindow::scan_entry(Entry* entry, HWND hwnd) +{ + int idx = ListBox_GetCurSel(_left._hwnd); + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + + // delete sub entries in left pane + for(;;) { + LRESULT res = ListBox_GetItemData(_left._hwnd, idx+1); + Entry* sub = (Entry*) res; + + if (res==LB_ERR || !sub || sub->_level<=entry->_level) + break; + + ListBox_DeleteString(_left._hwnd, idx+1); + } + + // empty right pane + ListBox_ResetContent(_right._hwnd); + + // release memory + entry->free_subentries(); + entry->_expanded = false; + + // read contents from disk + entry->read_directory(_sortOrder); + + // insert found entries in right pane + _right.insert_entries(entry->_down, -1); + + _right.calc_widths(false); + _right.set_header(); + + _header_wdths_ok = FALSE; + + SetCursor(old_cursor); +} + + +int FileChildWindow::Notify(int id, NMHDR* pnmh) +{ + return (pnmh->idFrom==IDW_HEADER_LEFT? &_left: &_right)->Notify(pnmh); +} + + +BOOL CALLBACK ExecuteDialog::WndProg(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + static struct ExecuteDialog* dlg; + + switch(nmsg) { + case WM_INITDIALOG: + dlg = (struct ExecuteDialog*) lparam; + return 1; + + case WM_COMMAND: { + int id = (int)wparam; + + if (id == IDOK) { + GetWindowText(GetDlgItem(hwnd, 201), dlg->cmd, MAX_PATH); + dlg->cmdshow = Button_GetState(GetDlgItem(hwnd,214))&BST_CHECKED? + SW_SHOWMINIMIZED: SW_SHOWNORMAL; + EndDialog(hwnd, id); + } else if (id == IDCANCEL) + EndDialog(hwnd, id); + + return 1;} + } + + return 0; +} diff --git a/reactos/subsys/system/explorer/shell/filechild.h b/reactos/subsys/system/explorer/shell/filechild.h new file mode 100644 index 00000000000..f979cf38272 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/filechild.h @@ -0,0 +1,96 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // filechild.h + // + // Martin Fuchs, 23.07.2003 + // + + +struct FileChildWndInfo +{ + FileChildWndInfo(LPCTSTR path); + + ENTRY_TYPE _etype; + LPCTSTR _path; + + WINDOWPLACEMENT _pos; +}; + +struct ShellChildWndInfo : public FileChildWndInfo +{ + ShellChildWndInfo(LPCTSTR path, const ShellPath& root_shell_path); + + ShellPath _shell_path; + ShellPath _root_shell_path; +}; + + +struct FileChildWindow : public ChildWindow +{ + typedef ChildWindow super; + + FileChildWindow(HWND hwnd, const FileChildWndInfo& info); + ~FileChildWindow(); + + static FileChildWindow* create(HWND hmdiclient, const FileChildWndInfo& info); + +protected: + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + int Command(int id, int code); + int Notify(int id, NMHDR* pnmh); + + virtual void resize_children(int cx, int cy); + + void scan_entry(Entry* entry, HWND hwnd); + + bool expand_entry(Entry* dir); + static void collapse_entry(Pane* pane, Entry* dir); + + void set_curdir(Entry* entry, HWND hwnd); + void activate_entry(Pane* pane, HWND hwnd); + +protected: + Root _root; + Pane _left; + Pane _right; + SORT_ORDER _sortOrder; + TCHAR _path[MAX_PATH]; + bool _header_wdths_ok; + +public: + const Root& get_root() const {return _root;} + + void set_focus_pane(Pane* pane) + {_focus_pane = pane==&_right? 1: 0;} + + void switch_focus_pane() + {SetFocus(_focus_pane? _left._hwnd: _right._hwnd);} +}; + + +struct ExecuteDialog { // TODO: integrate with Window class + TCHAR cmd[MAX_PATH]; + int cmdshow; + + static BOOL CALLBACK WndProg(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); +}; diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp new file mode 100644 index 00000000000..7dfe3a3f63d --- /dev/null +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -0,0 +1,614 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // mainframe.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "../explorer.h" +#include "../globals.h" + +#include "../explorer_intres.h" + + +MainFrame::MainFrame(HWND hwnd) + : Window(hwnd) +{ + _hMenuFrame = GetMenu(hwnd); + _hMenuWindow = GetSubMenu(_hMenuFrame, GetMenuItemCount(_hMenuFrame)-2); + + _menu_info._hMenuView = GetSubMenu(_hMenuFrame, 3); + _menu_info._hMenuOptions = GetSubMenu(_hMenuFrame, 4); + + _hAccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_EXPLORER)); + + + CLIENTCREATESTRUCT ccs; + + ccs.hWindowMenu = _hMenuWindow; + ccs.idFirstChild = IDW_FIRST_CHILD; + +#ifndef _NO_MDI + _hmdiclient = CreateWindowEx(0, TEXT("MDICLIENT"), NULL, + WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER, + 0, 0, 0, 0, + hwnd, 0, g_Globals._hInstance, &ccs); +#endif + + TBBUTTON toolbarBtns[] = { + {0, 0, 0, TBSTYLE_SEP, {0, 0}, 0, 0}, + {0, ID_WINDOW_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {1, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {2, ID_WINDOW_TILE_HORZ, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {3, ID_WINDOW_TILE_VERT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, +/*TODO + {4, ID_... , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {5, ID_... , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, +*/ }; + + _htoolbar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE, + IDW_TOOLBAR, 2, g_Globals._hInstance, IDB_TOOLBAR, toolbarBtns, + sizeof(toolbarBtns)/sizeof(TBBUTTON), 16, 15, 16, 15, sizeof(TBBUTTON)); + CheckMenuItem(_menu_info._hMenuOptions, ID_VIEW_TOOL_BAR, MF_BYCOMMAND|MF_CHECKED); + + + TBBUTTON drivebarBtn = {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0}; + int btn = 1; + PTSTR p; + + _hdrivebar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE|CCS_NOMOVEY|TBSTYLE_LIST, + IDW_DRIVEBAR, 2, g_Globals._hInstance, IDB_DRIVEBAR, &drivebarBtn, + 1, 16, 13, 16, 13, sizeof(TBBUTTON)); + CheckMenuItem(_menu_info._hMenuOptions, ID_VIEW_DRIVE_BAR, MF_BYCOMMAND|MF_CHECKED); + + + GetLogicalDriveStrings(BUFFER_LEN, _drives); + + drivebarBtn.fsStyle = TBSTYLE_BUTTON; + +#ifdef _linux_ + // insert unix file system button + SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("/\0")); + + drivebarBtn.idCommand = ID_DRIVE_UNIX_FS; + SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); + ++drivebarBtn.iString; +#endif + + // insert explorer window button + SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("Explore\0")); + + drivebarBtn.idCommand = ID_DRIVE_DESKTOP; + SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); + ++drivebarBtn.iString; + + // insert shell namespace button + SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("Shell\0")); + + drivebarBtn.idCommand = ID_DRIVE_SHELL_NS; + SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); + ++drivebarBtn.iString; + + // register windows drive root strings + SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)_drives); + + drivebarBtn.idCommand = ID_DRIVE_FIRST; + + for(p=_drives; *p; ) { + // insert drive letter + TCHAR b[3] = {tolower(*p)}; + SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)b); + + switch(GetDriveType(p)) { + case DRIVE_REMOVABLE: drivebarBtn.iBitmap = 1; break; + case DRIVE_CDROM: drivebarBtn.iBitmap = 3; break; + case DRIVE_REMOTE: drivebarBtn.iBitmap = 4; break; + case DRIVE_RAMDISK: drivebarBtn.iBitmap = 5; break; + default:/*DRIVE_FIXED*/ drivebarBtn.iBitmap = 2; + } + + SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); + ++drivebarBtn.idCommand; + ++drivebarBtn.iString; + + while(*p++); + } + + + /* CreateStatusWindow does not accept WS_BORDER + _hstatusbar = CreateWindowEx(WS_EX_NOPARENTNOTIFY, STATUSCLASSNAME, 0, + WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_BORDER|CCS_NODIVIDER, 0,0,0,0, + hwnd, (HMENU)IDW_STATUSBAR, g_Globals._hInstance, 0);*/ + + _hstatusbar = CreateStatusWindow(WS_CHILD|WS_VISIBLE, 0, hwnd, IDW_STATUSBAR); + CheckMenuItem(_menu_info._hMenuOptions, ID_VIEW_STATUSBAR, MF_BYCOMMAND|MF_CHECKED); +} + + +MainFrame::~MainFrame() +{ + // don't exit desktop when closing file manager window + if (!g_Globals._desktop_mode) + PostQuitMessage(0); +} + + +LRESULT MainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_TRANSLATE_MSG: { + MSG* pmsg = (MSG*) lparam; + +#ifndef _NO_MDI + if (_hmdiclient && TranslateMDISysAccel(_hmdiclient, pmsg)) + return TRUE; +#endif + + if (TranslateAccelerator(_hwnd, _hAccel, pmsg)) + return TRUE; + + return FALSE;} + + case WM_CLOSE: + DestroyWindow(_hwnd); + g_Globals._hMainWnd = 0; + break; + + case WM_DESTROY: + break; + + case WM_SIZE: + resize_frame(LOWORD(lparam), HIWORD(lparam)); + break; // do not pass message to DefFrameProc + + case WM_GETMINMAXINFO: { + LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam; + + lpmmi->ptMaxTrackSize.x <<= 1;/*2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN */ + lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */ + break;} + + case FRM_CALC_CLIENT: + frame_get_clientspace((PRECT)lparam); + return TRUE; + + case FRM_GET_MENUINFO: + return (LPARAM)&_menu_info; + + case WM_OPEN_WINDOW: { + TCHAR path[MAX_PATH]; + + //TODO: read paths and window placements from registry + GetCurrentDirectory(MAX_PATH, path); + + // Shell Namespace as default view + ShellChildWndInfo create_info(path, DesktopFolder()); + + create_info._pos.showCmd = SW_SHOWMAXIMIZED; + create_info._pos.rcNormalPosition.left = 0; + create_info._pos.rcNormalPosition.top = 0; + create_info._pos.rcNormalPosition.right = 600; + create_info._pos.rcNormalPosition.bottom = 280; + + // FileChildWindow::create(_hmdiclient, create_info); + ShellBrowserChild::create(_hmdiclient, create_info); + break;} + + case WM_GET_CONTROLWINDOW: + if (wparam == FCW_STATUS) + return (LRESULT)_hstatusbar; + break; + + default: +#ifndef _NO_MDI + return DefFrameProc(_hwnd, _hmdiclient, nmsg, wparam, lparam); +#else + return super::WNdProc(nmsg, wparam, lparam); +#endif + } + + return 0; +} + + +int MainFrame::Command(int id, int code) +{ +#ifndef _NO_MDI + HWND hwndClient = (HWND) SendMessage(_hmdiclient, WM_MDIGETACTIVE, 0, 0); + + if (SendMessage(hwndClient, WM_DISPATCH_COMMAND, MAKELONG(id,code), 0)) + return 0; +#endif + + if (id>=ID_DRIVE_FIRST && id<=ID_DRIVE_FIRST+0xFF) { + TCHAR drv[_MAX_DRIVE], path[MAX_PATH]; + LPCTSTR root = _drives; + + for(int i=id-ID_DRIVE_FIRST; i--; root++) + while(*root) + ++root; + + if (activate_drive_window(root)) + return 0; + + _tsplitpath(root, drv, 0, 0, 0); + + if (!SetCurrentDirectory(drv)) { + display_error(_hwnd, GetLastError()); + return 0; + } + + GetCurrentDirectory(MAX_PATH, path); //TODO: store last directory per drive + +#ifndef _NO_MDI + FileChildWindow::create(_hmdiclient, FileChildWndInfo(path)); +#else + //TODO: SDI implementation +#endif + return 1; + } + + switch(id) { + case ID_FILE_EXIT: + SendMessage(_hwnd, WM_CLOSE, 0, 0); + break; + + case ID_WINDOW_NEW: { + TCHAR path[MAX_PATH]; + + GetCurrentDirectory(MAX_PATH, path); + +#ifndef _NO_MDI + FileChildWindow::create(_hmdiclient, FileChildWndInfo(path)); +#else + //TODO: SDI implementation +#endif + break;} + +#ifndef _NO_MDI + case ID_WINDOW_CASCADE: + SendMessage(_hmdiclient, WM_MDICASCADE, 0, 0); + break; + + case ID_WINDOW_TILE_HORZ: + SendMessage(_hmdiclient, WM_MDITILE, MDITILE_HORIZONTAL, 0); + break; + + case ID_WINDOW_TILE_VERT: + SendMessage(_hmdiclient, WM_MDITILE, MDITILE_VERTICAL, 0); + break; + + case ID_WINDOW_ARRANGE: + SendMessage(_hmdiclient, WM_MDIICONARRANGE, 0, 0); + break; +#endif + + case ID_VIEW_TOOL_BAR: + toggle_child(_hwnd, id, _htoolbar); + break; + + case ID_VIEW_DRIVE_BAR: + toggle_child(_hwnd, id, _hdrivebar); + break; + + case ID_VIEW_STATUSBAR: + toggle_child(_hwnd, id, _hstatusbar); + break; + + case ID_EXECUTE: { + ExecuteDialog dlg = {{0}}; + + if (DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(IDD_EXECUTE), _hwnd, ExecuteDialog::WndProg, (LPARAM)&dlg) == IDOK) { + HINSTANCE hinst = ShellExecute(_hwnd, NULL/*operation*/, dlg.cmd/*file*/, NULL/*parameters*/, NULL/*dir*/, dlg.cmdshow); + + if ((int)hinst <= 32) + display_error(_hwnd, GetLastError()); + } + break;} + + case ID_HELP: + WinHelp(_hwnd, TEXT("explorer")/*file explorer.hlp*/, HELP_INDEX, 0); + break; + + case ID_VIEW_FULLSCREEN: + CheckMenuItem(_menu_info._hMenuOptions, id, toggle_fullscreen()?MF_CHECKED:0); + break; + +#ifdef _linux_ + case ID_DRIVE_UNIX_FS: { + TCHAR path[MAX_PATH]; + FileChildWindow* child; + + if (activate_fs_window(TEXT("unixfs"))) + break; + + getcwd(path, MAX_PATH); + +#ifndef _NO_MDI + FileChildWindow::create(_hmdiclient, FileChildWndInfo(path)); +#else + //TODO: SDI implementation +#endif + break;} +#endif + case ID_DRIVE_SHELL_NS: { + TCHAR path[MAX_PATH]; + + if (activate_fs_window(TEXT("Shell"))) + break; + + GetCurrentDirectory(MAX_PATH, path); + +#ifndef _NO_MDI + FileChildWindow::create(_hmdiclient, ShellChildWndInfo(path,DesktopFolder())); +#else + //TODO: SDI implementation +#endif + break;} + + case ID_DRIVE_DESKTOP: { + TCHAR path[MAX_PATH]; + + /*TODO + if (activate_fs_window(TEXT("Desktop"))) + break; + */ + + GetCurrentDirectory(MAX_PATH, path); + + ShellBrowserChild::create(_hmdiclient, ShellChildWndInfo(path,DesktopFolder())); + break;} + + //TODO: There are even more menu items! + + case ID_ABOUT: + ShellAbout(_hwnd, ResString(IDS_TITLE), NULL, 0); + break; + + default: + /*TODO: if (wParam >= PM_FIRST_LANGUAGE && wParam <= PM_LAST_LANGUAGE) + STRING_SelectLanguageByNumber(wParam - PM_FIRST_LANGUAGE); + else */if ((id=IDW_FIRST_CHILD+0x100) && + (idSC_RESTORE)) + MessageBox(_hwnd, TEXT("Not yet implemented"), ResString(IDS_TITLE), MB_OK); + +#ifndef _NO_MDI + return DefFrameProc(_hwnd, _hmdiclient, WM_COMMAND, MAKELONG(id,code), 0); +#else + return 0; +#endif + } + + return 1; +} + + +void MainFrame::resize_frame_rect(PRECT prect) +{ + int new_top; + RECT rt; + + if (IsWindowVisible(_htoolbar)) { + SendMessage(_htoolbar, WM_SIZE, 0, 0); + GetClientRect(_htoolbar, &rt); + prect->top = rt.bottom+3; + prect->bottom -= rt.bottom+3; + } + + if (IsWindowVisible(_hdrivebar)) { + SendMessage(_hdrivebar, WM_SIZE, 0, 0); + GetClientRect(_hdrivebar, &rt); + new_top = --prect->top + rt.bottom+3; + MoveWindow(_hdrivebar, 0, prect->top, rt.right, new_top, TRUE); + prect->top = new_top; + prect->bottom -= rt.bottom+2; + } + + if (IsWindowVisible(_hstatusbar)) { + int parts[] = {300, 500}; + + SendMessage(_hstatusbar, WM_SIZE, 0, 0); + SendMessage(_hstatusbar, SB_SETPARTS, 2, (LPARAM)&parts); + GetClientRect(_hstatusbar, &rt); + prect->bottom -= rt.bottom; + } + +#ifndef _NO_MDI + MoveWindow(_hmdiclient, prect->left-1,prect->top-1,prect->right+2,prect->bottom+1, TRUE); +#endif +} + +void MainFrame::resize_frame(int cx, int cy) +{ + RECT rect; + + rect.left = 0; + rect.top = 0; + rect.right = cx; + rect.bottom = cy; + + resize_frame_rect(&rect); +} + +void MainFrame::resize_frame_client() +{ + RECT rect; + + GetClientRect(_hwnd, &rect); + + resize_frame_rect(&rect); +} + +void MainFrame::frame_get_clientspace(PRECT prect) +{ + RECT rt; + + if (!IsIconic(_hwnd)) + GetClientRect(_hwnd, prect); + else { + WINDOWPLACEMENT wp; + + GetWindowPlacement(_hwnd, &wp); + + prect->left = prect->top = 0; + prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left- + 2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE)); + prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top- + 2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))- + GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE); + } + + if (IsWindowVisible(_htoolbar)) { + GetClientRect(_htoolbar, &rt); + prect->top += rt.bottom+2; + } + + if (IsWindowVisible(_hdrivebar)) { + GetClientRect(_hdrivebar, &rt); + prect->top += rt.bottom+2; + } + + if (IsWindowVisible(_hstatusbar)) { + GetClientRect(_hstatusbar, &rt); + prect->bottom -= rt.bottom; + } +} + +BOOL MainFrame::toggle_fullscreen() +{ + RECT rt; + + if ((_fullscreen._mode=!_fullscreen._mode)) { + GetWindowRect(_hwnd, &_fullscreen._orgPos); + _fullscreen._wasZoomed = IsZoomed(_hwnd); + + Frame_CalcFrameClient(_hwnd, &rt); + ClientToScreen(_hwnd, (LPPOINT)&rt.left); + ClientToScreen(_hwnd, (LPPOINT)&rt.right); + + rt.left = _fullscreen._orgPos.left-rt.left; + rt.top = _fullscreen._orgPos.top-rt.top; + rt.right = GetSystemMetrics(SM_CXSCREEN)+_fullscreen._orgPos.right-rt.right; + rt.bottom = GetSystemMetrics(SM_CYSCREEN)+_fullscreen._orgPos.bottom-rt.bottom; + + MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE); + } else { + MoveWindow(_hwnd, _fullscreen._orgPos.left, _fullscreen._orgPos.top, + _fullscreen._orgPos.right-_fullscreen._orgPos.left, + _fullscreen._orgPos.bottom-_fullscreen._orgPos.top, TRUE); + + if (_fullscreen._wasZoomed) + ShowWindow(_hwnd, WS_MAXIMIZE); + } + + return _fullscreen._mode; +} + +void MainFrame::fullscreen_move() +{ + RECT rt, pos; + GetWindowRect(_hwnd, &pos); + + Frame_CalcFrameClient(_hwnd, &rt); + ClientToScreen(_hwnd, (LPPOINT)&rt.left); + ClientToScreen(_hwnd, (LPPOINT)&rt.right); + + rt.left = pos.left-rt.left; + rt.top = pos.top-rt.top; + rt.right = GetSystemMetrics(SM_CXSCREEN)+pos.right-rt.right; + rt.bottom = GetSystemMetrics(SM_CYSCREEN)+pos.bottom-rt.bottom; + + MoveWindow(_hwnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE); +} + + +void MainFrame::toggle_child(HWND hwnd, UINT cmd, HWND hchild) +{ + BOOL vis = IsWindowVisible(hchild); + + CheckMenuItem(_menu_info._hMenuOptions, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED); + + ShowWindow(hchild, vis?SW_HIDE:SW_SHOW); + + if (_fullscreen._mode) + fullscreen_move(); + + resize_frame_client(); +} + +#ifndef _NO_MDI +bool MainFrame::activate_drive_window(LPCTSTR path) +{ + TCHAR drv1[_MAX_DRIVE], drv2[_MAX_DRIVE]; + HWND child_wnd; + + _tsplitpath(path, drv1, 0, 0, 0); + + // search for a already open window for the same drive + for(child_wnd=::GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=::GetNextWindow(child_wnd, GW_HWNDNEXT)) { + FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, WM_GET_FILEWND_PTR, 0, 0); + + if (child) { + _tsplitpath(child->get_root()._path, drv2, 0, 0, 0); + + if (!lstrcmpi(drv2, drv1)) { + SendMessage(_hmdiclient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0); + + if (IsMinimized(child_wnd)) + ShowWindow(child_wnd, SW_SHOWNORMAL); + + return true; + } + } + } + + return false; +} + +bool MainFrame::activate_fs_window(LPCTSTR filesys) +{ + HWND child_wnd; + + // search for a already open window of the given file system name + for(child_wnd=::GetNextWindow(_hmdiclient,GW_CHILD); child_wnd; child_wnd=::GetNextWindow(child_wnd, GW_HWNDNEXT)) { + FileChildWindow* child = (FileChildWindow*) SendMessage(child_wnd, WM_GET_FILEWND_PTR, 0, 0); + + if (child) { + if (!lstrcmpi(child->get_root()._fs, filesys)) { + SendMessage(_hmdiclient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0); + + if (IsMinimized(child_wnd)) + ShowWindow(child_wnd, SW_SHOWNORMAL); + + return true; + } + } + } + + return false; +} +#endif diff --git a/reactos/subsys/system/explorer/shell/mainframe.h b/reactos/subsys/system/explorer/shell/mainframe.h new file mode 100644 index 00000000000..f8336c037df --- /dev/null +++ b/reactos/subsys/system/explorer/shell/mainframe.h @@ -0,0 +1,70 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // mainframe.h + // + // Martin Fuchs, 23.07.2003 + // + + +struct MainFrame : public Window +{ + typedef Window super; + + MainFrame(HWND hwnd); + ~MainFrame(); + +protected: + FullScreenParameters _fullscreen; + +#ifndef _NO_MDI + HWND _hmdiclient; +#endif + + HWND _hstatusbar; + HWND _htoolbar; + HWND _hdrivebar; + + HMENU _hMenuFrame; + HMENU _hMenuWindow; + + MenuInfo _menu_info; + +protected: + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + int Command(int id, int code); + + void toggle_child(HWND hwnd, UINT cmd, HWND hchild); + bool activate_drive_window(LPCTSTR path); + bool activate_fs_window(LPCTSTR filesys); + + void resize_frame_rect(PRECT prect); + void resize_frame(int cx, int cy); + void resize_frame_client(); + void frame_get_clientspace(PRECT prect); + BOOL toggle_fullscreen(); + void fullscreen_move(); + + HACCEL _hAccel; + TCHAR _drives[BUFFER_LEN]; +}; + diff --git a/reactos/subsys/system/explorer/shell/pane.cpp b/reactos/subsys/system/explorer/shell/pane.cpp new file mode 100644 index 00000000000..605771d12b2 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/pane.cpp @@ -0,0 +1,985 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // pane.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "../explorer.h" +#include "../globals.h" + +#include "../explorer_intres.h" + + +enum IMAGE { + IMG_NONE=-1, IMG_FILE=0, IMG_DOCUMENT, IMG_EXECUTABLE, + IMG_FOLDER, IMG_OPEN_FOLDER, IMG_FOLDER_PLUS,IMG_OPEN_PLUS, IMG_OPEN_MINUS, + IMG_FOLDER_UP, IMG_FOLDER_CUR +}; + + +#define IMAGE_WIDTH 16 +#define IMAGE_HEIGHT 13 + + +static int is_exe_file(LPCTSTR ext) +{ + static const LPCTSTR executable_extensions[] = { + TEXT("COM"), + TEXT("EXE"), + TEXT("BAT"), + TEXT("CMD"), + TEXT("CMM"), + TEXT("BTM"), + TEXT("AWK"), + 0 + }; + + TCHAR ext_buffer[_MAX_EXT]; + const LPCTSTR* p; + LPCTSTR s; + LPTSTR d; + + for(s=ext+1,d=ext_buffer; (*d=tolower(*s)); s++) + ++d; + + for(p=executable_extensions; *p; p++) + if (!lstrcmp(ext_buffer, *p)) + return 1; + + return 0; +} + +static int is_registered_type(LPCTSTR ext) +{ + // TODO + + return 1; +} + + +static const LPTSTR g_pos_names[COLUMNS] = { + TEXT(""), /* symbol */ + TEXT("Name"), + TEXT("Size"), + TEXT("CDate"), + TEXT("ADate"), + TEXT("MDate"), + TEXT("Index/Inode"), + TEXT("Links"), + TEXT("Attributes"), + TEXT("Security") +}; + +static const int g_pos_align[] = { + 0, + HDF_LEFT, /* Name */ + HDF_RIGHT, /* Size */ + HDF_LEFT, /* CDate */ + HDF_LEFT, /* ADate */ + HDF_LEFT, /* MDate */ + HDF_LEFT, /* Index */ + HDF_CENTER, /* Links */ + HDF_CENTER, /* Attributes */ + HDF_LEFT /* Security */ +}; + + +HWND Pane::create(HWND hparent, int id, int id_header) +{ + _hwnd = CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL| + LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY, + 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0); + + SetWindowLong(_hwnd, GWL_USERDATA, (LPARAM)this); + s_orgTreeWndProc = SubclassWindow(_hwnd, TreeWndProc); + + // insert entries into listbox + Entry* entry = _root; + + if (entry) + insert_entries(entry, -1); + + init(); + + create_header(hparent, id_header); + + return _hwnd; +} + + +WNDPROC Pane::s_orgTreeWndProc; + +LRESULT CALLBACK Pane::TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(hwnd), WM_GET_FILEWND_PTR, 0, 0); + Pane* pane = (Pane*) GetWindowLong(hwnd, GWL_USERDATA); + + switch(nmsg) { + case WM_HSCROLL: + pane->set_header(); + break; + + case WM_SETFOCUS: + child->set_focus_pane(pane); + ListBox_SetSel(hwnd, TRUE, 1); + /*TODO: check menu items */ + break; + + case WM_KEYDOWN: + if (wparam == VK_TAB) { + /*TODO: SetFocus(g_Globals.hdrivebar) */ + child->switch_focus_pane(); + } + } + + return CallWindowProc(s_orgTreeWndProc, hwnd, nmsg, wparam, lparam); +} + + +bool Pane::create_header(HWND hparent, int id) +{ + HWND hwnd = CreateWindow(WC_HEADER, 0, WS_CHILD|WS_VISIBLE|HDS_HORZ/*TODO: |HDS_BUTTONS + sort orders*/, + 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0); + if (!hwnd) + return false; + + SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), FALSE); + + HD_ITEM hdi; + + hdi.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT; + + for(int idx=0; idxdwLowDateTime && !ft->dwHighDateTime) + return; + + if (!FileTimeToLocalFileTime(ft, &lft)) + {err: lstrcpy(buffer,TEXT("???")); return;} + + if (!FileTimeToSystemTime(&lft, &systime)) + goto err; + + if (visible_cols & COL_DATE) { + len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer, BUFFER_LEN); + if (!len) + goto err; + } + + if (visible_cols & COL_TIME) { + if (len) + buffer[len-1] = ' '; + + buffer[len++] = ' '; + + if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer+len, BUFFER_LEN-len)) + buffer[len] = TEXT('\0'); + } +} + + +void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol) +{ + TCHAR buffer[BUFFER_LEN]; + DWORD attrs; + int visible_cols = _visible_cols; + COLORREF bkcolor, textcolor; + RECT focusRect = dis->rcItem; + HBRUSH hbrush; + enum IMAGE img; + int img_pos, cx; + int col = 0; + + if (entry) { + attrs = entry->_data.dwFileAttributes; + + if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('.') + && entry->_data.cFileName[2]==TEXT('\0')) + img = IMG_FOLDER_UP; + else if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('\0')) + img = IMG_FOLDER_CUR; + else if ((_treePane && (dis->itemState&ODS_FOCUS))) + img = IMG_OPEN_FOLDER; + else + img = IMG_FOLDER; + } else { + LPCTSTR ext = _tcsrchr(entry->_data.cFileName, '.'); + if (!ext) + ext = TEXT(""); + + if (is_exe_file(ext)) + img = IMG_EXECUTABLE; + else if (is_registered_type(ext)) + img = IMG_DOCUMENT; + else + img = IMG_FILE; + } + } else { + attrs = 0; + img = IMG_NONE; + } + + if (_treePane) { + if (entry) { + img_pos = dis->rcItem.left + entry->_level*(IMAGE_WIDTH+_out_wrkr._spaceSize.cx); + + if (calcWidthCol == -1) { + int x; + int y = dis->rcItem.top + IMAGE_HEIGHT/2; + Entry* up; + RECT rt_clip; + HRGN hrgn_org = CreateRectRgn(0, 0, 0, 0); + HRGN hrgn; + + rt_clip.left = dis->rcItem.left; + rt_clip.top = dis->rcItem.top; + rt_clip.right = dis->rcItem.left+_widths[col]; + rt_clip.bottom = dis->rcItem.bottom; + + hrgn = CreateRectRgnIndirect(&rt_clip); + + if (!GetClipRgn(dis->hDC, hrgn_org)) { + DeleteObject(hrgn_org); + hrgn_org = 0; + } + + //HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN)); + ExtSelectClipRgn(dis->hDC, hrgn, RGN_AND); + DeleteObject(hrgn); + + if ((up=entry->_up) != NULL) { + MoveToEx(dis->hDC, img_pos-IMAGE_WIDTH/2, y, 0); + LineTo(dis->hDC, img_pos-2, y); + + x = img_pos - IMAGE_WIDTH/2; + + do { + x -= IMAGE_WIDTH+_out_wrkr._spaceSize.cx; + + if (up->_next +#ifndef _LEFT_FILES + && (up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) +#endif + ) { + MoveToEx(dis->hDC, x, dis->rcItem.top, 0); + LineTo(dis->hDC, x, dis->rcItem.bottom); + } + } while((up=up->_up) != NULL); + } + + x = img_pos - IMAGE_WIDTH/2; + + MoveToEx(dis->hDC, x, dis->rcItem.top, 0); + LineTo(dis->hDC, x, y); + + if (entry->_next +#ifndef _LEFT_FILES + && (entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) +#endif + ) + LineTo(dis->hDC, x, dis->rcItem.bottom); + + if (entry->_down && entry->_expanded) { + x += IMAGE_WIDTH + _out_wrkr._spaceSize.cx; + MoveToEx(dis->hDC, x, dis->rcItem.top+IMAGE_HEIGHT, 0); + LineTo(dis->hDC, x, dis->rcItem.bottom); + } + + SelectClipRgn(dis->hDC, hrgn_org); + if (hrgn_org) DeleteObject(hrgn_org); + //SelectObject(dis->hDC, holdPen); + } else if (calcWidthCol==col || calcWidthCol==COLUMNS) { + int right = img_pos + IMAGE_WIDTH - _out_wrkr._spaceSize.cx; + + if (right > _widths[col]) + _widths[col] = right; + } + } else { + img_pos = dis->rcItem.left; + } + } else { + img_pos = dis->rcItem.left; + + if (calcWidthCol==col || calcWidthCol==COLUMNS) + _widths[col] = IMAGE_WIDTH; + } + + if (calcWidthCol == -1) { + focusRect.left = img_pos -2; + + if (attrs & FILE_ATTRIBUTE_COMPRESSED) + textcolor = COLOR_COMPRESSED; + else + textcolor = RGB(0,0,0); + + if (dis->itemState & ODS_FOCUS) { + textcolor = RGB(255,255,255); + bkcolor = COLOR_SELECTION; + } else { + bkcolor = RGB(255,255,255); + } + + hbrush = CreateSolidBrush(bkcolor); + FillRect(dis->hDC, &focusRect, hbrush); + DeleteObject(hbrush); + + SetBkMode(dis->hDC, TRANSPARENT); + SetTextColor(dis->hDC, textcolor); + + cx = _widths[col]; + + if (cx && img!=IMG_NONE) { + if (cx > IMAGE_WIDTH) + cx = IMAGE_WIDTH; + + if (entry->_hicon && entry->_hicon!=(HICON)-1) + DrawIconEx(dis->hDC, img_pos, dis->rcItem.top, entry->_hicon, cx, GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL); + else + ImageList_DrawEx(_himl, img, dis->hDC, + img_pos, dis->rcItem.top, cx, + IMAGE_HEIGHT, bkcolor, CLR_DEFAULT, ILD_NORMAL); + } + } + + if (!entry) + return; + + ++col; + + // ouput file name + if (calcWidthCol == -1) + _out_wrkr.output_text(dis, _positions, col, entry->_data.cFileName, 0); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, entry->_data.cFileName); + + ++col; + + // display file size + if (visible_cols & COL_SIZE) { + ULONGLONG size = ((ULONGLONG)entry->_data.nFileSizeHigh << 32) | entry->_data.nFileSizeLow; + + _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("d"), size); + + if (calcWidthCol == -1) + _out_wrkr.output_number(dis, _positions, col, buffer); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, buffer); // TODO: not ever time enough + + ++col; + } + + // display file date + if (visible_cols & (COL_DATE|COL_TIME)) { + format_date(&entry->_data.ftCreationTime, buffer, visible_cols); + if (calcWidthCol == -1) + _out_wrkr.output_text(dis, _positions, col, buffer, 0); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, buffer); + ++col; + + format_date(&entry->_data.ftLastAccessTime, buffer, visible_cols); + if (calcWidthCol == -1) + _out_wrkr.output_text(dis,_positions, col, buffer, 0); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, buffer); + ++col; + + format_date(&entry->_data.ftLastWriteTime, buffer, visible_cols); + if (calcWidthCol == -1) + _out_wrkr.output_text(dis, _positions, col, buffer, 0); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, buffer); + ++col; + } + + if (entry->_bhfi_valid) { + ULONGLONG index = ((ULONGLONG)entry->_bhfi.nFileIndexHigh << 32) | entry->_bhfi.nFileIndexLow; + + if (visible_cols & COL_INDEX) { + _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("X"), index); + if (calcWidthCol == -1) + _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, buffer); + ++col; + } + + if (visible_cols & COL_LINKS) { + wsprintf(buffer, TEXT("%d"), entry->_bhfi.nNumberOfLinks); + if (calcWidthCol == -1) + _out_wrkr.output_text(dis, _positions, col, buffer, DT_CENTER); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_width(dis, col, buffer); + ++col; + } + } else + col += 2; + + // show file attributes + if (visible_cols & COL_ATTRIBUTES) { + lstrcpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t ")); + + if (attrs & FILE_ATTRIBUTE_NORMAL) buffer[ 0] = 'N'; + else { + if (attrs & FILE_ATTRIBUTE_READONLY) buffer[ 2] = 'R'; + if (attrs & FILE_ATTRIBUTE_HIDDEN) buffer[ 4] = 'H'; + if (attrs & FILE_ATTRIBUTE_SYSTEM) buffer[ 6] = 'S'; + if (attrs & FILE_ATTRIBUTE_ARCHIVE) buffer[ 8] = 'A'; + if (attrs & FILE_ATTRIBUTE_COMPRESSED) buffer[10] = 'C'; + if (attrs & FILE_ATTRIBUTE_DIRECTORY) buffer[12] = 'D'; + if (attrs & FILE_ATTRIBUTE_ENCRYPTED) buffer[14] = 'E'; + if (attrs & FILE_ATTRIBUTE_TEMPORARY) buffer[16] = 'T'; + if (attrs & FILE_ATTRIBUTE_SPARSE_FILE) buffer[18] = 'P'; + if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) buffer[20] = 'Q'; + if (attrs & FILE_ATTRIBUTE_OFFLINE) buffer[22] = 'O'; + if (attrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) buffer[24] = 'X'; + } + + if (calcWidthCol == -1) + _out_wrkr.output_tabbed_text(dis, _positions, col, buffer); + else if (calcWidthCol==col || calcWidthCol==COLUMNS) + calc_tabbed_width(dis, col, buffer); + + ++col; + } + +/*TODO + if (flags.security) { + DWORD rights = get_access_mask(); + + tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t ")); + + if (rights & FILE_READ_DATA) buffer[ 0] = 'R'; + if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W'; + if (rights & FILE_APPEND_DATA) buffer[ 4] = 'A'; + if (rights & FILE_READ_EA) {buffer[6] = 'entry'; buffer[ 7] = 'R';} + if (rights & FILE_WRITE_EA) {buffer[9] = 'entry'; buffer[10] = 'W';} + if (rights & FILE_EXECUTE) buffer[12] = 'X'; + if (rights & FILE_DELETE_CHILD) buffer[14] = 'D'; + if (rights & FILE_READ_ATTRIBUTES) {buffer[16] = 'a'; buffer[17] = 'R';} + if (rights & FILE_WRITE_ATTRIBUTES) {buffer[19] = 'a'; buffer[20] = 'W';} + if (rights & WRITE_DAC) buffer[22] = 'C'; + if (rights & WRITE_OWNER) buffer[24] = 'O'; + if (rights & SYNCHRONIZE) buffer[26] = 'S'; + + output_text(dis, col++, buffer, DT_LEFT, 3, psize); + } + + if (flags.description) { + get_description(buffer); + output_text(dis, col++, buffer, 0, psize); + } +*/ +} + + +void Pane::calc_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) +{ + RECT rt = {0, 0, 0, 0}; + + DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX); + + if (rt.right > _widths[col]) + _widths[col] = rt.right; +} + +void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) +{ + RECT rt = {0, 0, 0, 0}; + +/* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; + DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ + + DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8)); + //FIXME rt (0,0) ??? + + if (rt.right > _widths[col]) + _widths[col] = rt.right; +} + + + // insert listbox entries after index idx + +void Pane::insert_entries(Entry* dir, int idx) +{ + Entry* entry = dir; + + if (!entry) + return; + + SendMessage(_hwnd, WM_SETREDRAW, FALSE, 0); //ShowWindow(_hwnd, SW_HIDE); + + for(; entry; entry=entry->_next) { +#ifndef _LEFT_FILES + if (_treePane && !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + continue; +#endif + + // don't display entries "." and ".." in the left pane + if (_treePane && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + && entry->_data.cFileName[0]==TEXT('.')) + if (entry->_data.cFileName[1]==TEXT('\0') || + (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0'))) + continue; + + if (idx != -1) + ++idx; + + ListBox_InsertItemData(_hwnd, idx, entry); + + if (_treePane && entry->_expanded) + insert_entries(entry->_down, idx); + } + + SendMessage(_hwnd, WM_SETREDRAW, TRUE, 0); //ShowWindow(_hwnd, SW_SHOW); +} + + +void Pane::set_header() +{ + HD_ITEM item; + int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); + int i=0, x=0; + + item.mask = HDI_WIDTH; + item.cxy = 0; + + for(; x+_widths[i]code) { + case HDN_TRACK: + case HDN_ENDTRACK: { + HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; + int idx = phdn->iItem; + int dx = phdn->pitem->cxy - _widths[idx]; + int i; + + RECT clnt; + GetClientRect(_hwnd, &clnt); + + // move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB) + Header_SetItem(_hwndHeader, idx, phdn->pitem); + + _widths[idx] += dx; + + for(i=idx; ++i<=COLUMNS; ) + _positions[i] += dx; + + { + int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); + RECT rt_scr; + RECT rt_clip; + + rt_scr.left = _positions[idx+1]-scroll_pos; + rt_scr.top = 0; + rt_scr.right = clnt.right; + rt_scr.bottom = clnt.bottom; + + rt_clip.left = _positions[idx]-scroll_pos; + rt_clip.top = 0; + rt_clip.right = clnt.right; + rt_clip.bottom = clnt.bottom; + + if (rt_scr.left < 0) rt_scr.left = 0; + if (rt_clip.left < 0) rt_clip.left = 0; + + ScrollWindowEx(_hwnd, dx, 0, &rt_scr, &rt_clip, 0, 0, SW_INVALIDATE); + + rt_clip.right = _positions[idx+1]; + RedrawWindow(_hwnd, &rt_clip, 0, RDW_INVALIDATE|RDW_UPDATENOW); + + if (pnmh->code == HDN_ENDTRACK) { + ListBox_SetHorizontalExtent(_hwnd, _positions[COLUMNS]); + + if (GetScrollPos(_hwnd, SB_HORZ) != scroll_pos) + set_header(); + } + } + + return 0; + } + + case HDN_DIVIDERDBLCLICK: { + HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; + HD_ITEM item; + + calc_single_width(phdn->iItem); + item.mask = HDI_WIDTH; + item.cxy = _widths[phdn->iItem]; + + Header_SetItem(_hwndHeader, phdn->iItem, &item); + InvalidateRect(_hwnd, 0, TRUE); + break;} + } + + return 0; +} + + +OutputWorker::OutputWorker() +{ + HDC hdc = GetDC(0); + + _hfont = CreateFont(-MulDiv(8,GetDeviceCaps(hdc,LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Sans Serif")); + + ReleaseDC(0, hdc); +} + +void OutputWorker::init_output(HWND hwnd) +{ + TCHAR b[16]; + HFONT old_font; + HDC hdc = GetDC(hwnd); + + if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4) + _num_sep = b[1]; + else + _num_sep = TEXT('.'); + + old_font = SelectFont(hdc, _hfont); + GetTextExtentPoint32(hdc, TEXT(" "), 1, &_spaceSize); + SelectFont(hdc, old_font); + ReleaseDC(hwnd, hdc); +} + + +void OutputWorker::output_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str, DWORD flags) +{ + int x = dis->rcItem.left; + RECT rt; + + rt.left = x+positions[col]+_spaceSize.cx; + rt.top = dis->rcItem.top; + rt.right = x+positions[col+1]-_spaceSize.cx; + rt.bottom = dis->rcItem.bottom; + + DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|flags); +} + +void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str) +{ + int x = dis->rcItem.left; + RECT rt; + + rt.left = x+positions[col]+_spaceSize.cx; + rt.top = dis->rcItem.top; + rt.right = x+positions[col+1]-_spaceSize.cx; + rt.bottom = dis->rcItem.bottom; + +/* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; + DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ + + DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8)); +} + +void OutputWorker::output_number(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str) +{ + int x = dis->rcItem.left; + RECT rt; + LPCTSTR s = str; + TCHAR b[128]; + LPTSTR d = b; + int pos; + + rt.left = x+positions[col]+_spaceSize.cx; + rt.top = dis->rcItem.top; + rt.right = x+positions[col+1]-_spaceSize.cx; + rt.bottom = dis->rcItem.bottom; + + if (*s) + *d++ = *s++; + + // insert number separator characters + pos = lstrlen(s) % 3; + + while(*s) + if (pos--) + *d++ = *s++; + else { + *d++ = _num_sep; + pos = 3; + } + + DrawText(dis->hDC, b, d-b, &rt, DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS); +} + + +BOOL Pane::command(UINT cmd) +{ + switch(cmd) { + case ID_VIEW_NAME: + if (_visible_cols) { + _visible_cols = 0; + calc_widths(true); + set_header(); + InvalidateRect(_hwnd, 0, TRUE); + MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); + if (menu_info) { + CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND|MF_CHECKED); + CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND); + CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); + } + } + break; + + case ID_VIEW_ALL_ATTRIBUTES: + if (_visible_cols != COL_ALL) { + _visible_cols = COL_ALL; + calc_widths(true); + set_header(); + InvalidateRect(_hwnd, 0, TRUE); + MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); + if (menu_info) { + CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND); + CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND|MF_CHECKED); + CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); + } + } + break; + + case ID_PREFERED_SIZES: { + calc_widths(true); + set_header(); + InvalidateRect(_hwnd, 0, TRUE); + break;} + + /* TODO: more command ids... */ + + default: + return FALSE; + } + + return TRUE; +} + +MainFrame* Pane::get_frame() +{ + HWND owner = GetParent(_hwnd); + + return (MainFrame*)owner; +} diff --git a/reactos/subsys/system/explorer/shell/pane.h b/reactos/subsys/system/explorer/shell/pane.h new file mode 100644 index 00000000000..c549207c9fb --- /dev/null +++ b/reactos/subsys/system/explorer/shell/pane.h @@ -0,0 +1,105 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // pane.h + // + // Martin Fuchs, 23.07.2003 + // + + +#define COLOR_COMPRESSED RGB(0,0,255) +#define COLOR_SELECTION RGB(0,0,128) + + +#define IDW_TREE_LEFT 3 +#define IDW_TREE_RIGHT 6 +#define IDW_HEADER_LEFT 2 +#define IDW_HEADER_RIGHT 5 + + +enum COLUMN_FLAGS { + COL_SIZE = 0x01, + COL_DATE = 0x02, + COL_TIME = 0x04, + COL_ATTRIBUTES = 0x08, + COL_DOSNAMES = 0x10, + COL_INDEX = 0x20, + COL_LINKS = 0x40, + COL_ALL = COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_DOSNAMES|COL_INDEX|COL_LINKS +}; + + +struct OutputWorker { + OutputWorker(); + + void init_output(HWND hwnd); + void output_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str, DWORD flags); + void output_tabbed_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str); + void output_number(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str); + + SIZE _spaceSize; + TCHAR _num_sep; + HFONT _hfont; +}; + + +struct Pane //@@: public Window +{ + HWND _hwnd; + HWND _hwndHeader; + +#define COLUMNS 10 + int _widths[COLUMNS]; + int _positions[COLUMNS+1]; + + bool _treePane; + int _visible_cols; + Entry* _root; + Entry* _cur; + + HWND create(HWND hparent, int id, int id_header); + static LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); + + static WNDPROC s_orgTreeWndProc; + + void init(); + void set_header(); + bool create_header(HWND parent, int id); + + bool calc_widths(bool anyway); + void calc_single_width(int col); + void draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol=-1); + + void insert_entries(Entry* dir, int idx); + BOOL command(UINT cmd); + LRESULT Notify(NMHDR* pnmh); + +protected: + void calc_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str); + void calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str); + MainFrame* get_frame(); + +protected: + HIMAGELIST _himl; + OutputWorker _out_wrkr; +}; + diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.cpp b/reactos/subsys/system/explorer/shell/shellbrowser.cpp new file mode 100644 index 00000000000..a169ccd0b49 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/shellbrowser.cpp @@ -0,0 +1,418 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellbrowser.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "../explorer.h" +#include "../globals.h" + +#include "../explorer_intres.h" + + +ShellBrowserChild::ShellBrowserChild(HWND hwnd) + : super(hwnd) +{ + _hWndFrame = 0; + _pShellView = NULL; + _pDropTarget = NULL; + _himlSmall = 0; +} + +ShellBrowserChild::~ShellBrowserChild() +{ + if (_pShellView) + _pShellView->Release(); + + if (_pDropTarget) { + _pDropTarget->Release(); + _pDropTarget = NULL; + } +} + + +void ShellBrowserChild::OnCreate(LPCREATESTRUCT pcs) +{ + _hWndFrame = GetParent(pcs->hwndParent); + + RECT rect; + GetClientRect(_hwnd, &rect); + + SHFILEINFO sfi; + + _himlSmall = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON); +// _himlLarge = (HIMAGELIST)SHGetFileInfo(TEXT("C:\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_LARGEICON); + + + // create explorer treeview + _left_hwnd = CreateWindowEx(0, WC_TREEVIEW, NULL, + WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_NOTOOLTIPS, + 0, rect.top, _split_pos-SPLIT_WIDTH/2, rect.bottom-rect.top, + _hwnd, (HMENU)IDC_FILETREE, g_Globals._hInstance, 0); + + if (_left_hwnd) { + InitializeTree(/*ShellChildWndInfo(TEXT("C:\\"),DesktopFolder())*/); //@@ GetCurrentDirectory() + + InitDragDrop(); + } +} + + +void ShellBrowserChild::InitializeTree(/*const FileChildWndInfo& info*/) +{ + TreeView_SetImageList(_left_hwnd, _himlSmall, TVSIL_NORMAL); + TreeView_SetScrollTime(_left_hwnd, 100); + + + _root._drive_type = DRIVE_UNKNOWN; + lstrcpy(_root._volname, TEXT("Desktop")); + _root._fs_flags = 0; + lstrcpy(_root._fs, TEXT("Shell")); + + +//@@ _root._entry->read_tree(ShellFolder(shell_info._root_shell_path), info._shell_path, SORT_NAME/*_sortOrder*/); + + //@@ fängt zunächst nur einmal mit dem Desktop-Objekt an + _root._entry = new ShellDirectory(Desktop(), DesktopFolder(), _hwnd); + _root._entry->read_directory(); + + lstrcpy(_root._entry->_data.cFileName, TEXT("Desktop")); + + + TV_ITEM tvItem; + + tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; + tvItem.lParam = (LPARAM)_root._entry; + tvItem.pszText = LPSTR_TEXTCALLBACK; + tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK; + tvItem.cChildren = 1; + + TV_INSERTSTRUCT tvInsert; + + tvInsert.hParent = 0; + tvInsert.hInsertAfter = TVI_LAST; + tvInsert.item = tvItem; + + HTREEITEM hItem = TreeView_InsertItem(_left_hwnd, &tvInsert); + TreeView_SelectItem(_left_hwnd, hItem); + TreeView_Expand(_left_hwnd, hItem, TVE_EXPAND); +} + + +bool ShellBrowserChild::InitDragDrop() +{ + _pDropTarget = new TreeDropTarget(_left_hwnd); + + if (!_pDropTarget) + return false; + + _pDropTarget->AddRef(); + + if (FAILED(RegisterDragDrop(_left_hwnd, _pDropTarget))) {//calls addref + _pDropTarget->Release(); // free TreeDropTarget + _pDropTarget = NULL; + return false; + } + else + _pDropTarget->Release(); + + FORMATETC ftetc; + + ftetc.dwAspect = DVASPECT_CONTENT; + ftetc.lindex = -1; + ftetc.tymed = TYMED_HGLOBAL; + ftetc.cfFormat = CF_HDROP; + + _pDropTarget->AddSuportedFormat(ftetc); + + return true; +} + + +void ShellBrowserChild::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh) +{ + TVHITTESTINFO tvhti; + + GetCursorPos(&tvhti.pt); + ScreenToClient(_left_hwnd, &tvhti.pt); + + tvhti.flags = LVHT_NOWHERE; + TreeView_HitTest(_left_hwnd, &tvhti); + + if (TVHT_ONITEM & tvhti.flags) { + ClientToScreen(_left_hwnd, &tvhti.pt); + Tree_DoItemMenu(_left_hwnd, tvhti.hItem , &tvhti.pt); + } +} + +void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen) +{ + TVITEM tvItem; + + tvItem.mask = TVIF_PARAM; + tvItem.hItem = hItem; + + if (TreeView_GetItem(hwndTreeView, &tvItem)) { + HWND hwndParent = ::GetParent(hwndTreeView); + Entry* entry = (Entry*)tvItem.lParam; + + IShellFolder* folder; + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + folder = static_cast(entry)->_folder; + else + folder = entry->_up? static_cast(entry->_up)->_folder: Desktop(); + + folder->AddRef(); + + if (folder) { + LPCITEMIDLIST pidl = static_cast(entry)->_pidl; + + IContextMenu* pcm; + HRESULT hr = folder->GetUIObjectOf(hwndParent, 1, &pidl, IID_IContextMenu, NULL, (LPVOID*)&pcm); + + if (SUCCEEDED(hr)) { + HMENU hPopup = CreatePopupMenu(); + + if (hPopup) { + hr = pcm->QueryContextMenu(hPopup, 0, 1, 0x7fff, CMF_NORMAL|CMF_EXPLORE); + + if (SUCCEEDED(hr)) { + IContextMenu2* pcm2; + + pcm->QueryInterface(IID_IContextMenu2, (LPVOID*)&pcm2); + + UINT idCmd = TrackPopupMenu(hPopup, + TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, + pptScreen->x, + pptScreen->y, + 0, + hwndParent, + NULL); + + if (pcm2) { + pcm2->Release(); + pcm2 = NULL; + } + + if (idCmd) { + CMINVOKECOMMANDINFO cmi; + cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); + cmi.fMask = 0; + cmi.hwnd = hwndParent; + cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1); + cmi.lpParameters = NULL; + cmi.lpDirectory = NULL; + cmi.nShow = SW_SHOWNORMAL; + cmi.dwHotKey = 0; + cmi.hIcon = NULL; + hr = pcm->InvokeCommand(&cmi); + } + } + } + + pcm->Release(); + } + + folder->Release(); + } + } +} + +void ShellBrowserChild::OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh) +{ + LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)pnmh; + ShellEntry* entry = (ShellEntry*)lpdi->item.lParam; + + if (lpdi->item.mask & TVIF_TEXT) { + /* if (SHGetFileInfo((LPCTSTR)&*entry->_pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_DISPLAYNAME)) + lstrcpy(lpdi->item.pszText, sfi.szDisplayName); */ + lstrcpy(lpdi->item.pszText, entry->_data.cFileName); + } + + if (lpdi->item.mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) { + LPITEMIDLIST pidl = entry->create_absolute_pidl(_hwnd); + SHFILEINFO sfi; + + if (lpdi->item.mask & TVIF_IMAGE) { + if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_LINKOVERLAY)) + lpdi->item.iImage = sfi.iIcon; + } + + if (lpdi->item.mask & TVIF_SELECTEDIMAGE) { + if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON)) + lpdi->item.iSelectedImage = sfi.iIcon; + } + + if (pidl != &*entry->_pidl) + ShellMalloc()->Free(pidl); + } +} + +void ShellBrowserChild::OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv) +{ + if (pnmtv->action == TVE_COLLAPSE) + TreeView_Expand(_left_hwnd, pnmtv->itemNew.hItem, TVE_COLLAPSE|TVE_COLLAPSERESET); + else if (pnmtv->action == TVE_EXPAND) { + TVITEM tvItem; + + tvItem.mask = TVIF_PARAM; + tvItem.hItem = pnmtv->itemNew.hItem; + + if (!TreeView_GetItem(_left_hwnd, &tvItem)) + return; + + WaitCursor wait; + + ShellDirectory* entry = (ShellDirectory*)tvItem.lParam; + + InsertSubitems(pnmtv->itemNew.hItem, entry, entry->_folder); + } +} + +void ShellBrowserChild::InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder) +{ + SendMessage(_left_hwnd, WM_SETREDRAW, FALSE, 0); + + if (!entry->_scanned) { + entry->free_subentries(); + entry->read_directory(SORT_NAME); // we could use IShellFolder2::GetDefaultColumn to determine sort order + } + + TV_ITEM tvItem; + TV_INSERTSTRUCT tvInsert; + + for(entry=entry->_down; entry; entry=entry->_next) { +#ifndef _LEFT_FILES + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#endif + { + ZeroMemory(&tvItem, sizeof(tvItem)); + + tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN; + tvItem.pszText = LPSTR_TEXTCALLBACK; + tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK; + tvItem.lParam= (LPARAM)entry; + tvItem.cChildren = entry->_shell_attribs & SFGAO_HASSUBFOLDER? 1: 0; + + if (entry->_shell_attribs & SFGAO_SHARE) { + tvItem.mask |= TVIF_STATE; + tvItem.stateMask |= TVIS_OVERLAYMASK; + tvItem.state |= INDEXTOOVERLAYMASK(1); + } + + tvInsert.item = tvItem; + tvInsert.hInsertAfter = TVI_LAST; + tvInsert.hParent = hParentItem; + + TreeView_InsertItem(_left_hwnd, &tvInsert); + } + } + + SendMessage(_left_hwnd, WM_SETREDRAW, TRUE, 0); +} + +void ShellBrowserChild::OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv) +{ + ShellEntry* entry = (ShellEntry*)pnmtv->itemNew.lParam; + + IShellFolder* folder; + + if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + folder = static_cast(entry)->_folder; + else + folder = entry->_up? static_cast(entry->_up)->_folder: Desktop(); + + if (!folder) { + assert(folder); + return; + } + + FOLDERSETTINGS fs; + IShellView* pLastShellView = _pShellView; + + if (pLastShellView) + pLastShellView->GetCurrentInfo(&fs); + else { + fs.fFlags = FVM_DETAILS; + fs.ViewMode = FWF_SNAPTOGRID; + } + + HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView); + + if (FAILED(hr)) { + _pShellView = NULL; + return; + } + + RECT rect = {CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT}; + hr = _pShellView->CreateViewWindow(pLastShellView, &fs, static_cast(this), &rect, &_right_hwnd/*&m_hWndListView*/); + + if (pLastShellView) { + pLastShellView->GetCurrentInfo(&fs); + pLastShellView->UIActivate(SVUIA_DEACTIVATE); + pLastShellView->DestroyViewWindow(); + pLastShellView->Release(); + + RECT clnt; + GetClientRect(_hwnd, &clnt); + resize_children(clnt.right, clnt.bottom); + } + + _pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS); +} + + +LRESULT ShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_GETISHELLBROWSER: // for Registry Explorer Plugin + return (LRESULT)static_cast(this); + + case WM_CREATE: + OnCreate((LPCREATESTRUCT)lparam); + goto def; + + default: def: + return super::WndProc(nmsg, wparam, lparam); + } + + return 0; +} + +int ShellBrowserChild::Notify(int id, NMHDR* pnmh) +{ + switch(pnmh->code) { + case TVN_GETDISPINFO: OnTreeGetDispInfo(id, pnmh); break; + case TVN_ITEMEXPANDING: OnTreeItemExpanding(id, (LPNMTREEVIEW)pnmh); break; + case TVN_SELCHANGED: OnTreeItemSelected(id, (LPNMTREEVIEW)pnmh); break; + case NM_RCLICK: OnTreeItemRClick(id, pnmh); break; + } + + return 0; +} diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h new file mode 100644 index 00000000000..e3fc7a13e51 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -0,0 +1,126 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellbrowser.h + // + // Martin Fuchs, 23.07.2003 + // + +#include "../utility/treedroptarget.h" +#include "../utility/shellbrowserimpl.h" + + +struct ShellBrowserChild : public ChildWindow, public IShellBrowserImpl +{ + typedef ChildWindow super; + + ShellBrowserChild(HWND hwnd); + ~ShellBrowserChild(); + + static ShellBrowserChild* create(HWND hmdiclient, const FileChildWndInfo& info) + { +#ifndef _NO_MDI + ChildWindow* child = ChildWindow::create(hmdiclient, info._pos.rcNormalPosition, WINDOW_CREATOR(ShellBrowserChild), CLASSNAME_CHILDWND); +#else + //TODO: SDI implementation +#endif + + ShowWindow(child->_hwnd, info._pos.showCmd); + + return static_cast(child); + } + + //IOleWindow + STDMETHOD(GetWindow)(HWND* lphwnd) + { + *lphwnd = _hwnd; + return S_OK; + } + + //IShellBrowser + STDMETHOD(QueryActiveShellView)(struct IShellView ** ppshv) + { + _pShellView->AddRef(); + *ppshv = _pShellView; + return S_OK; + } + + STDMETHOD(GetControlWindow)(UINT id, HWND * lphwnd) + { + if (!lphwnd) + return E_POINTER; + + if (id == FCW_TREE) { + *lphwnd = _left_hwnd; + return S_OK; + } + + HWND hwnd = (HWND)SendMessage(_hWndFrame, WM_GET_CONTROLWINDOW, id, 0); + + if (hwnd) { + *lphwnd = hwnd; + return S_OK; + } + + return E_NOTIMPL; + } + + STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) + { + if (!pret) + return E_POINTER; + + HWND hstatusbar = (HWND)SendMessage(_hWndFrame, WM_GET_CONTROLWINDOW, id, 0); + + if (hstatusbar) { + *pret = ::SendMessage(hstatusbar, uMsg, wParam, lParam); + return S_OK; + } + + return E_NOTIMPL; + } + +protected: + Root _root; + + HWND _hWndFrame; + + IShellView* _pShellView; // current hosted shellview + HIMAGELIST _himlSmall; // list +// HIMAGELIST _himlLarge; // shell image + TreeDropTarget* _pDropTarget; + + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + int Notify(int id, NMHDR* pnmh); + + void OnCreate(LPCREATESTRUCT); + void InitializeTree(/*const FileChildWndInfo& info*/); + void InsertSubitems(HTREEITEM hParentItem, Entry* entry, IShellFolder* pParentFolder); + bool InitDragDrop(); + + void OnTreeGetDispInfo(int idCtrl, LPNMHDR pnmh); + void OnTreeItemExpanding(int idCtrl, LPNMTREEVIEW pnmtv); + void OnTreeItemRClick(int idCtrl, LPNMHDR pnmh); + void OnTreeItemSelected(int idCtrl, LPNMTREEVIEW pnmtv); + + void Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen); +}; diff --git a/reactos/subsys/system/explorer/shell/shellfs.cpp b/reactos/subsys/system/explorer/shell/shellfs.cpp new file mode 100644 index 00000000000..1b967295017 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/shellfs.cpp @@ -0,0 +1,335 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellfs.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "../globals.h" +#include "entries.h" +#include "shellfs.h" + + +bool ShellDirectory::fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA* pw32fdata, BY_HANDLE_FILE_INFORMATION* pbhfi) +{ + bool bhfi_valid = false; + + if (!( (attribs & SFGAO_FILESYSTEM) && SUCCEEDED( + SHGetDataFromIDList(_folder, pidl, SHGDFIL_FINDDATA, pw32fdata, sizeof(WIN32_FIND_DATA))) )) { + WIN32_FILE_ATTRIBUTE_DATA fad; + IDataObject* pDataObj; + + STGMEDIUM medium = {0, {0}, 0}; + FORMATETC fmt = {g_Globals._cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + + HRESULT hr = _folder->GetUIObjectOf(0, 1, &pidl, IID_IDataObject, 0, (LPVOID*)&pDataObj); + + if (SUCCEEDED(hr)) { + hr = pDataObj->GetData(&fmt, &medium); + + pDataObj->Release(); + + if (SUCCEEDED(hr)) { + LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal)); + UINT sem_org = SetErrorMode(SEM_FAILCRITICALERRORS); + + if (GetFileAttributesEx(path, GetFileExInfoStandard, &fad)) { + pw32fdata->dwFileAttributes = fad.dwFileAttributes; + pw32fdata->ftCreationTime = fad.ftCreationTime; + pw32fdata->ftLastAccessTime = fad.ftLastAccessTime; + pw32fdata->ftLastWriteTime = fad.ftLastWriteTime; + + if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + pw32fdata->nFileSizeLow = fad.nFileSizeLow; + pw32fdata->nFileSizeHigh = fad.nFileSizeHigh; + } + } + + HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + + if (hFile != INVALID_HANDLE_VALUE) { + if (GetFileInformationByHandle(hFile, pbhfi)) + bhfi_valid = true; + + CloseHandle(hFile); + } + + SetErrorMode(sem_org); + + GlobalUnlock(medium.UNION_MEMBER(hGlobal)); + GlobalFree(medium.UNION_MEMBER(hGlobal)); + } + } + } + + if (!(attribs & SFGAO_FILESYSTEM)) // Archiv files should not be displayed as folders in explorer view. + if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER)) + pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + + if (attribs & SFGAO_READONLY) + pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; + + if (attribs & SFGAO_COMPRESSED) + pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_COMPRESSED; + + return bhfi_valid; +} + + +LPITEMIDLIST ShellEntry::create_absolute_pidl(HWND hwnd) +{ + if (_up/* && _up->_etype==ET_SHELL*/) { + LPITEMIDLIST pidl = _pidl.create_absolute_pidl(static_cast(_up)->_folder, hwnd); + + if (pidl) + return pidl; + } + + return &*_pidl; +} + + + // get full path of a shell entry +void ShellEntry::get_path(PTSTR path) +{ + path[0] = TEXT('\0'); + + IShellFolder* parent = _up? static_cast(_up)->_folder: Desktop(); + + HRESULT hr = path_from_pidl(parent, &*_pidl, path, MAX_PATH); +} + + + // get full path of a shell folder +void ShellDirectory::get_path(PTSTR path) +{ + path[0] = TEXT('\0'); + + SFGAOF attribs = 0; + HRESULT hr = S_OK; + + if (!_folder.empty()) + hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&_pidl, &attribs); + + if (SUCCEEDED(hr) && (attribs&SFGAO_FILESYSTEM)) { + IShellFolder* parent = _up? static_cast(_up)->_folder: Desktop(); + + hr = path_from_pidl(parent, &*_pidl, path, MAX_PATH); + } +} + + +BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow) +{ + BOOL ret = TRUE; + + SHELLEXECUTEINFO shexinfo; + + shexinfo.cbSize = sizeof(SHELLEXECUTEINFO); + shexinfo.fMask = SEE_MASK_IDLIST; + shexinfo.hwnd = hwnd; + shexinfo.lpVerb = NULL; + shexinfo.lpFile = NULL; + shexinfo.lpParameters = NULL; + shexinfo.lpDirectory = NULL; + shexinfo.nShow = nCmdShow; + shexinfo.lpIDList = create_absolute_pidl(hwnd); + + if (!ShellExecuteEx(&shexinfo)) { + display_error(hwnd, GetLastError()); + ret = FALSE; + } + + if (shexinfo.lpIDList != &*_pidl) + ShellMalloc()->Free(shexinfo.lpIDList); + + return ret; +} + + +static HICON extract_icon(IShellFolder* folder, LPCITEMIDLIST pidl) +{ + IExtractIcon* pExtract; + + if (SUCCEEDED(folder->GetUIObjectOf(0, 1, (LPCITEMIDLIST*)&pidl, IID_IExtractIcon, 0, (LPVOID*)&pExtract))) { + TCHAR path[_MAX_PATH]; + unsigned flags; + HICON hicon; + int idx; + + if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, _MAX_PATH, &idx, &flags))) { + if (!(flags & GIL_NOTFILENAME)) { + if (idx == -1) + idx = 0; // special case for some control panel applications + + if ((int)ExtractIconEx(path, idx, 0, &hicon, 1) > 0) + flags &= ~GIL_DONTCACHE; + } else { + HICON hIconLarge = 0; + + HRESULT hr = pExtract->Extract(path, idx, &hIconLarge, &hicon, MAKELONG(0/*GetSystemMetrics(SM_CXICON)*/,GetSystemMetrics(SM_CXSMICON))); + + if (SUCCEEDED(hr)) + DestroyIcon(hIconLarge); + } + + return hicon; + } + } + + return 0; +} + + +void ShellDirectory::read_directory() +{ + int level = _level + 1; + + Entry* first_entry = NULL; + Entry* last = NULL; + + /*if (_folder.empty()) + return;*/ + + ShellItemEnumerator enumerator(_folder, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE); + + HRESULT hr_next = S_OK; + + do { +#define FETCH_ITEM_COUNT 32 + LPITEMIDLIST pidls[FETCH_ITEM_COUNT]; + ULONG cnt = 0; + ULONG n; + + memset(pidls, 0, sizeof(pidls)); + + hr_next = enumerator->Next(FETCH_ITEM_COUNT, pidls, &cnt); + + /* don't break yet now: Registry Explorer Plugin returns E_FAIL! + if (!SUCCEEDED(hr_next)) + break; */ + + if (hr_next == S_FALSE) + break; + + for(n=0; nGetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs); + + if (SUCCEEDED(hr)) { + if (attribs != ~SFGAO_FILESYSTEM) { + bhfi_valid = fill_w32fdata_shell(pidls[n], attribs, &w32fd, &bhfi); + } else + attribs = 0; + } else + attribs = 0; + + Entry* entry; + + if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + IShellFolder* child = NULL; + + /*hr = */_folder->BindToObject(pidls[n], 0, IID_IShellFolder, (void**)&child); + + entry = new ShellDirectory(this, child, pidls[n], _hwnd); + } else + entry = new ShellEntry(this, pidls[n]); + + if (!first_entry) + first_entry = entry; + + if (last) + last->_next = entry; + + memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); + + if (bhfi_valid) + memcpy(&entry->_bhfi, &bhfi, sizeof(BY_HANDLE_FILE_INFORMATION)); + + if (!entry->_data.cFileName[0]) + /*hr = */name_from_pidl(_folder, pidls[n], entry->_data.cFileName, MAX_PATH, SHGDN_INFOLDER|0x2000/*0x2000=SHGDN_INCLUDE_NONFILESYS*/); + + // get display icons for files and virtual objects + if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || + !(attribs & SFGAO_FILESYSTEM)) { + entry->_hicon = extract_icon(_folder, pidls[n]); + + if (!entry->_hicon) + entry->_hicon = (HICON)-1; // don't try again later + } + + entry->_down = NULL; + entry->_expanded = false; + entry->_scanned = false; + entry->_level = level; + entry->_shell_attribs = attribs; + entry->_bhfi_valid = bhfi_valid; + + last = entry; + } + } while(SUCCEEDED(hr_next)); + + if (last) + last->_next = NULL; + + _down = first_entry; + _scanned = true; +} + +const void* ShellDirectory::get_next_path_component(const void* p) +{ + LPITEMIDLIST pidl = (LPITEMIDLIST)p; + + if (!pidl || !pidl->mkid.cb) + return NULL; + + // go to next element + pidl = (LPITEMIDLIST)((LPBYTE)pidl+pidl->mkid.cb); + + return pidl; +} + +Entry* ShellDirectory::find_entry(const void* p) +{ + LPITEMIDLIST pidl = (LPITEMIDLIST) p; + + for(Entry*entry=_down; entry; entry=entry->_next) { + ShellEntry* e = static_cast(entry); + + if (e->_pidl && e->_pidl->mkid.cb==pidl->mkid.cb && !memcmp(e->_pidl, pidl, e->_pidl->mkid.cb)) + return entry; + } + + return NULL; +} diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h new file mode 100644 index 00000000000..1c9addb0124 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -0,0 +1,73 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellfs.h + // + // Martin Fuchs, 23.07.2003 + // + + +struct ShellEntry : public Entry { + ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent), _pidl(shell_path) {} + ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent), _pidl(shell_path) {} + + virtual void get_path(PTSTR path); + virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow); + + LPITEMIDLIST create_absolute_pidl(HWND hwnd); + + ShellPath _pidl; + +protected: + ShellEntry(LPITEMIDLIST shell_path) : Entry(ET_SHELL), _pidl(shell_path) {} + ShellEntry(const ShellPath& shell_path) : Entry(ET_SHELL), _pidl(shell_path) {} +}; + +struct ShellDirectory : public ShellEntry, public Directory { + ShellDirectory(IShellFolder* shell_root, const ShellPath& shell_path, HWND hwnd) + : ShellEntry(shell_path), + Directory(shell_root), + _hwnd(hwnd) + { + } + + ShellDirectory(ShellDirectory* parent, IShellFolder* shell_root, LPITEMIDLIST shell_path, HWND hwnd) + : ShellEntry(parent, shell_path), + Directory(shell_root), + _folder(shell_root), + _hwnd(hwnd) + { + } + + virtual void read_directory(); + virtual const void* get_next_path_component(const void*); + virtual Entry* find_entry(const void* p); + + virtual void get_path(PTSTR path); + + ShellFolder _folder; + HWND _hwnd; + +protected: + bool fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA*, BY_HANDLE_FILE_INFORMATION*); +}; + diff --git a/reactos/subsys/system/explorer/startup.c b/reactos/subsys/system/explorer/shell/startup.c similarity index 99% rename from reactos/subsys/system/explorer/startup.c rename to reactos/subsys/system/explorer/shell/startup.c index d246081d1e3..aae1ac67c2c 100644 --- a/reactos/subsys/system/explorer/startup.c +++ b/reactos/subsys/system/explorer/shell/startup.c @@ -270,7 +270,7 @@ const WCHAR runkeys_names[][30]= * If wait is FALSE - returns 0 if successful. * If wait is TRUE - returns the program's return value. */ -static DWORD runCmd(LPWSTR cmdline, LPCWSTR dir, BOOL wait, BOOL minimized) +static int runCmd(LPWSTR cmdline, LPCWSTR dir, BOOL wait, BOOL minimized) { STARTUPINFOW si; PROCESS_INFORMATION info; diff --git a/reactos/subsys/system/explorer/shell/unixfs.cpp b/reactos/subsys/system/explorer/shell/unixfs.cpp new file mode 100644 index 00000000000..fbd2150a625 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/unixfs.cpp @@ -0,0 +1,196 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // unixfs.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#ifdef __linux__ + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "entries.h" +#include "unixfs.h" + + // for UnixDirectory::read_directory() +#include +#include +#include +#include + + +void UnixDirectory::read_directory(LPCTSTR path) +{ + Entry* first_entry = NULL; + Entry* last = NULL; + Entry* entry; + + int level = _level + 1; + + DIR* pdir = opendir(path); + + if (pdir) { + struct stat st; + struct dirent* ent; + TCHAR buffer[MAX_PATH], *p; + + for(p=buffer; *path; ) + *p++ = *path++; + + if (p==buffer || p[-1]!='/') + *p++ = '/'; + + while((ent=readdir(pdir))) { + if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + entry = new UnixDirectory(this, buffer); + else + entry = new UnixEntry(this); + + if (!first_entry) + first_entry = entry; + + if (last) + last->next = entry; + + lstrcpy(entry->data.cFileName, ent->d_name); + entry->data.dwFileAttributes = ent->d_name[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0; + + strcpy(p, ent->d_name); + + if (!stat(buffer, &st)) { + if (S_ISDIR(st.st_mode)) + entry->data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + + entry->data.nFileSizeLow = st.st_size & 0xFFFFFFFF; + entry->data.nFileSizeHigh = st.st_size >> 32; + + memset(&entry->data.ftCreationTime, 0, sizeof(FILETIME)); + time_to_filetime(&st.st_atime, &entry->data.ftLastAccessTime); + time_to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime); + + entry->bhfi.nFileIndexLow = ent->d_ino; + entry->bhfi.nFileIndexHigh = 0; + + entry->bhfi.nNumberOfLinks = st.st_nlink; + + entry->bhfi_valid = TRUE; + } else { + entry->data.nFileSizeLow = 0; + entry->data.nFileSizeHigh = 0; + entry->bhfi_valid = FALSE; + } + + entry->down = NULL; + entry->up = dir; + entry->expanded = FALSE; + entry->scanned = FALSE; + entry->level = level; + + last = entry; + } + + last->next = NULL; + + closedir(pdir); + } + + _down = first_entry; + _scanned = true; +} + + +const void* UnixDirectory::get_next_path_component(const void* p) +{ + LPCTSTR s = (LPCTSTR) p; + + while(*s && *s!=TEXT('/')) + ++s; + + while(*s == TEXT('/')) + ++s; + + if (!*s) + return NULL; + + return s; +} + + +Entry* UnixDirectory::find_entry(const void* p) +{ + LPCTSTR name = (LPCTSTR)p; + + for(Entry*entry=_down; entry; entry=entry->next) { + LPCTSTR p = name; + LPCTSTR q = entry->data.cFileName; + + do { + if (!*p || *p==TEXT('/')) + return entry; + } while(*p++ == *q++); + } + + return NULL; +} + + + // get full path of specified directory entry +void UnixEntry::get_path(PTSTR path) +{ + int level = 0; + int len = 0; + + for(Entry* entry=this; entry; level++) { + LPCTSTR name = entry->_data.cFileName; + int l = 0; + + for(LPCTSTR s=name; *s && *s!=TEXT('/'); s++) + ++l; + + if (entry->_up) { + if (l > 0) { + memmove(path+l+1, path, len*sizeof(TCHAR)); + memcpy(path+1, name, l*sizeof(TCHAR)); + len += l+1; + + path[0] = TEXT('/'); + } + + entry = entry->_up; + } else { + memmove(path+l, path, len*sizeof(TCHAR)); + memcpy(path, name, l*sizeof(TCHAR)); + len += l; + break; + } + } + + if (!level) + path[len++] = TEXT('/'); + + path[len] = TEXT('\0'); +} + +#endif // __linux__ diff --git a/reactos/subsys/system/explorer/shell/unixfs.h b/reactos/subsys/system/explorer/shell/unixfs.h new file mode 100644 index 00000000000..bbf7ff993f8 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/unixfs.h @@ -0,0 +1,58 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // unixfs.h + // + // Martin Fuchs, 23.07.2003 + // + + +#ifdef __linux__ + +struct UnixEntry : public Entry { + UnixEntry(Entry* parent) : Entry(parent) {} + +protected: + UnixEntry() : Entry(ET_UNIX) {} + + virtual void get_path(PTSTR path); +}; + +struct UnixDirectory : public UnixEntry, public Directory { + UnixDirectory(LPCTSTR root_path) + : UnixEntry(), + Directory(_tcsdup(root_path)) + { + } + + UnixDirectory(UnixDirectory* parent, LPCTSTR path) + : UnixEntry(parent), + Directory(_tcsdup(path)) + { + } + + virtual void read_directory(); + virtual const void* get_next_path_component(const void*); + virtual Entry* find_entry(const void*); +}; + +#endif diff --git a/reactos/subsys/system/explorer/shell/winfs.cpp b/reactos/subsys/system/explorer/shell/winfs.cpp new file mode 100644 index 00000000000..bdfc6d77bf4 --- /dev/null +++ b/reactos/subsys/system/explorer/shell/winfs.cpp @@ -0,0 +1,177 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // winfs.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "../utility/utility.h" +#include "../utility/shellclasses.h" + +#include "entries.h" +#include "winfs.h" + + +void WinDirectory::read_directory() +{ + Entry* first_entry = NULL; + Entry* last = NULL; + Entry* entry; + + int level = _level + 1; + + LPCTSTR path = (LPCTSTR)_path; + TCHAR buffer[MAX_PATH], *p; + for(p=buffer; *path; ) + *p++ = *path++; + + lstrcpy(p, TEXT("\\*")); + + WIN32_FIND_DATA w32fd; + HANDLE hFind = FindFirstFile(buffer, &w32fd); + + if (hFind != INVALID_HANDLE_VALUE) { + do { + lstrcpy(p+1, w32fd.cFileName); + + if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + entry = new WinDirectory(this, buffer); + else + entry = new WinEntry(this); + + if (!first_entry) + first_entry = entry; + + if (last) + last->_next = entry; + + memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); + entry->_down = NULL; + entry->_expanded = false; + entry->_scanned = false; + entry->_level = level; + entry->_bhfi_valid = false; + + HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + + if (hFile != INVALID_HANDLE_VALUE) { + if (GetFileInformationByHandle(hFile, &entry->_bhfi)) + entry->_bhfi_valid = true; + + CloseHandle(hFile); + } + + last = entry; + } while(FindNextFile(hFind, &w32fd)); + + last->_next = NULL; + + FindClose(hFind); + } + + _down = first_entry; + _scanned = true; +} + + +const void* WinDirectory::get_next_path_component(const void* p) +{ + LPCTSTR s = (LPCTSTR) p; + + while(*s && *s!=TEXT('\\') && *s!=TEXT('/')) + ++s; + + while(*s==TEXT('\\') || *s==TEXT('/')) + ++s; + + if (!*s) + return NULL; + + return s; +} + + +Entry* WinDirectory::find_entry(const void* p) +{ + LPCTSTR name = (LPCTSTR)p; + + for(Entry*entry=_down; entry; entry=entry->_next) { + LPCTSTR p = name; + LPCTSTR q = entry->_data.cFileName; + + do { + if (!*p || *p==TEXT('\\') || *p==TEXT('/')) + return entry; + } while(tolower(*p++) == tolower(*q++)); + + p = name; + q = entry->_data.cAlternateFileName; + + do { + if (!*p || *p==TEXT('\\') || *p==TEXT('/')) + return entry; + } while(tolower(*p++) == tolower(*q++)); + } + + return NULL; +} + + + // get full path of specified directory entry +void WinEntry::get_path(PTSTR path) +{ + int level = 0; + int len = 0; + + for(Entry* entry=this; entry; level++) { + LPCTSTR name = entry->_data.cFileName; + int l = 0; + + for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++) + ++l; + + if (entry->_up) { + if (l > 0) { + memmove(path+l+1, path, len*sizeof(TCHAR)); + memcpy(path+1, name, l*sizeof(TCHAR)); + len += l+1; + + path[0] = TEXT('\\'); + } + + entry = entry->_up; + } else { + memmove(path+l, path, len*sizeof(TCHAR)); + memcpy(path, name, l*sizeof(TCHAR)); + len += l; + break; + } + } + + if (!level) + path[len++] = TEXT('\\'); + + path[len] = TEXT('\0'); +} diff --git a/reactos/subsys/system/explorer/shell/winfs.h b/reactos/subsys/system/explorer/shell/winfs.h new file mode 100644 index 00000000000..0146fd3bb5d --- /dev/null +++ b/reactos/subsys/system/explorer/shell/winfs.h @@ -0,0 +1,55 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // winfs.h + // + // Martin Fuchs, 23.07.2003 + // + + +struct WinEntry : public Entry { + WinEntry(Entry* parent) : Entry(parent) {} + +protected: + WinEntry() : Entry(ET_WINDOWS) {} + + virtual void get_path(PTSTR path); +}; + +struct WinDirectory : public WinEntry, public Directory { + WinDirectory(LPCTSTR root_path) + : WinEntry(), + Directory(_tcsdup(root_path)) + { + } + + WinDirectory(WinDirectory* parent, LPCTSTR path) + : WinEntry(parent), + Directory(_tcsdup(path)) + { + } + + virtual void read_directory(); + virtual const void* get_next_path_component(const void*); + virtual Entry* find_entry(const void*); +}; + diff --git a/reactos/subsys/system/explorer/taskbar/ex_bar.c b/reactos/subsys/system/explorer/taskbar/ex_bar.c new file mode 100644 index 00000000000..572bf31c9e1 --- /dev/null +++ b/reactos/subsys/system/explorer/taskbar/ex_bar.c @@ -0,0 +1,383 @@ +// Explorer Panel (PlugIn based) +// +// Alexander Ciobanu +// alex@prodidactica.md +// +// + +#include +#include + +#include "../utility/utility.h" + +#include "ex_bar.h" + +HFONT tf; + +#ifdef _PLUGINS +HINSTANCE PlugInsHI[4]; // PlugIns table +#else +struct PluginCalls* PlugInsCallTable[4]; // PlugIn Call table +#endif + +int PlugNumber = -1; // Number of loaded plugins + +LRESULT WINAPI ExplorerBarProc(HWND, UINT, WPARAM, LPARAM); + +// Loads a configuration style given by PInt +// FIXME : Load all these values from registry ! +// +DWORD LoadProperty(int PInt) +{ + switch(PInt) + { + case 1: // WS_EX_Style for creating the bar + return WS_EX_TOPMOST | WS_EX_DLGMODALFRAME; + break; + case 2: // WS_Style for creating the bar + return WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN; + break; + case 3: // Start X for the panel + return 0; + break; + case 4: + return 0; // Start Y for the panel + break; + case 5: + return GetSystemMetrics(SM_CXSCREEN); // XLen for the panel + break; + case 6: + return 32; // YLen for the panel + break; +} + return 0; +} + +// Initializez and creates the Explorer Panel +// HINSTANCE as a parameter +// +HWND InitializeExplorerBar(HINSTANCE hInstance, int nCmdShow) +{ + HWND ExplorerBar; + WNDCLASS ExplorerBarClass; + + ExplorerBarClass.lpszClassName = TEXT("ExplorerBar"); // ExplorerBar classname + ExplorerBarClass.lpfnWndProc = ExplorerBarProc; // Default Explorer Callback Procedure + ExplorerBarClass.style = 0; // Styles + ExplorerBarClass.hInstance = hInstance; // Instance + ExplorerBarClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Configurable ???? + ExplorerBarClass.hCursor = LoadCursor(NULL, IDC_ARROW); + ExplorerBarClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); // BackGround + ExplorerBarClass.lpszMenuName = NULL; // No Menu needed for the bar + ExplorerBarClass.cbClsExtra = 0; // Nothing YET! !! + ExplorerBarClass.cbWndExtra = 0; // + + if (RegisterClass(&ExplorerBarClass) == 0) // Cold not register anything :( + { + fprintf(stderr, "Could not register Explorer Bar. Last error was 0x%X\n",GetLastError()); + return NULL; + } + + ExplorerBar = CreateWindowEx(LoadProperty(1),TEXT("ExplorerBar"), + TEXT("ReactOS Explorer Bar"),LoadProperty(2),LoadProperty(3),LoadProperty(4), + LoadProperty(5), LoadProperty(6), 0, 0, hInstance, 0); + if (ExplorerBar == NULL) + { + fprintf(stderr, "Cold not create Explorer Bar.Last error 0x%X\n",GetLastError()); + return(NULL); + } + + tf = CreateFontA(14, 0, 0, TA_BASELINE, FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "Timmons"); + + ShowWindow(ExplorerBar, nCmdShow); // Show the bar + return ExplorerBar; +} + + +// ************************************************************************************** +// * GENERAL PLUGIN CONTROL ROUTINES * +// ************************************************************************************** + + +// Reload a plug-in's configuration +// +static int ReloadPlugInConfiguration(int ID) +{ +#ifdef _PLUGINS + PReloadConfig PP = (PReloadConfig)GetProcAddress(PlugInsHI[ID],/*"_"*/"ReloadPlugInConfiguration"); + + if (!PP) + { + fprintf(stderr,"PLUGIN %d, of Instance %0x ReloadPlugInConfig Failed\n",ID,PlugInsHI[ID]); + return 0; + } +#else + PReloadConfig PP = PlugInsCallTable[ID]->ReloadPlugInConfiguration; +#endif + + return PP(); +} + +int QuitPlugIn(int ID) +{ +#ifdef _PLUGINS + PQuitPlugIn PP = (PQuitPlugIn)GetProcAddress(PlugInsHI[ID],/*"_"*/"QuitPlugIn"); + + if (!PP) + { + fprintf(stderr,"PLUGIN %d, of Instance %0x QuitPlugIn Failed\n",ID,PlugInsHI[ID]); + return 0; + } +#else + PQuitPlugIn PP = PlugInsCallTable[ID]->QuitPlugIn; +#endif + + PP(); + +// FreeLibrary(PlugInsHI[ID]); + + return 1; +} + +int CallBackPlugIn(int ID, HWND PlgnHandle, UINT Msg, WPARAM wParam, LPARAM lParam) +{ +#ifdef _PLUGINS + PPlugInCallBack PP = (PPlugInCallBack)GetProcAddress(PlugInsHI[ID],/*"_"*/"PlugInMessageProc"); + if (!PP) + { + fprintf(stderr,"PLUGIN %d, of Instance %0x CallBackPlugIn Failed\n",ID,PlugInsHI[ID]); + return 0; + } +#else + PPlugInCallBack PP = PlugInsCallTable[ID]->PlugInMessageProc; +#endif + + return PP(PlgnHandle,Msg,wParam,lParam); +} + +int PostExplorerInfo(int ID, HWND ExplHandle) +{ + EXBARINFO Info; + RECT rect; + +#ifdef _PLUGINS + PExplorerInfo PP = (PExplorerInfo)GetProcAddress(PlugInsHI[ID],/*"_"*/"ExplorerInfo"); + + if (!PP) + { + fprintf(stderr,"PLUGIN %d, of Instance %0x PostExplorerInfo Failed\n",ID,PlugInsHI[ID]); + return 0; + } +#else + PExplorerInfo PP = PlugInsCallTable[ID]->ExplorerInfo; +#endif + + GetWindowRect(ExplHandle,&rect); + Info.x=rect.left; + Info.dx=rect.right-rect.left; + + Info.y=rect.top; + Info.dy=rect.bottom-rect.top; + + return PP(&Info); +} + + +int InitializePlugIn(int ID, HWND ExplHandle) +{ +#ifdef _PLUGINS + PInitializePlugIn PP = (PInitializePlugIn)GetProcAddress(PlugInsHI[ID],/*"_"*/"InitializePlugIn"); + if (!PP) + { + fprintf(stderr,"PLUGIN %d, of Instance %0x InitializePlugIn Failed\n",ID,PlugInsHI[ID]); + return 0; + } +#else + PInitializePlugIn PP = PlugInsCallTable[ID]->InitializePlugIn; +#endif + + return PP(ExplHandle); +} + + +int InitPlugin(int ID, HWND ExplWnd) +{ + if (!PostExplorerInfo(ID, ExplWnd)) + { + fprintf(stderr, "PLUGIN %d : WARNING : Haven't received Explorer information !\n"); + } + + if (!InitializePlugIn(ID, ExplWnd)) + { + fprintf(stderr,"PLUGIN %d : WARNING : Could not be initialized !\n",ID); + } + + if (!ReloadPlugInConfiguration(ID)) + { + fprintf(stderr,"PLUGIN %d : WARNING : Could not load configuration !\n",ID); + } + + return 1; +} + + +#ifdef _PLUGINS +int LoadLocalPlugIn(char* fname, HWND ExplWnd) +{ + PlugNumber++; + PlugInsHI[PlugNumber]=LoadLibraryA(fname); + if (!(PlugInsHI[PlugNumber])) return 0; // Could not load plugin + + InitPlugin(PlugNumber); + + return 1; +} +#endif + +// Load All Available plugins +// FIXME : Plugins MUST be listed in Registry ! not in file +// For now, it only loads the buit-in plugin +// +int LoadAvailablePlugIns(HWND ExplWnd) +{ +#ifdef _PLUGINS + + FILE* Conf; // Configuration File; + char line[80]; // Blah Blah Blah + int i; + int x; + int k; + + if (!(Conf=fopen("ex_bar.ini","r"))) // Error ! + { + fprintf(stderr,"DefaultPlugin : No PLUGIN configuration file found !\n"); + return 0; + } + + fgets(line,80,Conf); // Read how many entries are in the file + k = atoi(line); // atoi it ! We get how many plugIns do we have + + + for (i=0;i +#include +#include + +#include "ex_bar.h" + +HWND Static; +HWND Wnd; +char locstr[20]; + +int ex_x1; +int ex_y1; +int ex_dx; +int ex_dy; + +// Initialize the plugin +// +static int InitializePlugIn(HWND ExplorerHandle) +{ + SYSTEMTIME systime; + TCHAR TimeStr[20]; + + fprintf(stderr,"EX_CLOCK : INITIALIZE PLUGIN call\n"); + + SetTimer(ExplorerHandle,500,1000,NULL); + GetLocalTime(&systime); + wsprintf(TimeStr,TEXT("%02d:%02d"),systime.wHour,systime.wMinute); + + Static = CreateWindow( + TEXT("STATIC"),TimeStr,WS_VISIBLE | WS_CHILD | SS_CENTER | SS_SUNKEN, + ex_dx+ex_x1-100, 4, 50, ex_dy-14, ExplorerHandle, NULL, + (HINSTANCE) GetWindowLong(ExplorerHandle, GWL_HINSTANCE),NULL); + + return 1; +} + +// Get Information about the plugin +// +char* PlugInInfo(int InfoNmbr) +{ + static char Info[256]; + + fprintf(stderr,"EX_CLOCK : INFORMATION PLUGIN call\n"); + + switch(InfoNmbr) + { + case 0: // PlugIn Name + strcpy(Info,"ReactOSClock"); + break; + + case 1: // Version + strcpy(Info,"0.1"); + break; + + case 2: // Vendor name + strcpy(Info,"ReactOS team"); + break; + + default: // Default : Error + strcpy(Info,"-"); + break; + + } + + return Info; +} + +// Reload plugin's configuration +// +static int ReloadPlugInConfiguration() +{ + fprintf(stderr,"EX_CLOCK : RELOAD PLUGIN COFIGURATION call\n"); + return 1; +} + +// Quit plugin +// +static int QuitPlugIn() +{ + fprintf(stderr,"EX_CLOCK : QUIT PLUGIN call\n"); + return 1; +} + +// Callback procedure for plugin +// +static int PlugInMessageProc(HWND PlgnHandle, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + static int blink = 0; + + SYSTEMTIME systime; + TCHAR TimeStr[20]; + + // The plugin must decide whatever the handle passed is created by it ! + // Sorry for bad english :-) + // + switch(Msg) + { + case WM_TIMER: + GetLocalTime(&systime); + wsprintf(TimeStr, TEXT("%02d%c%02d"), systime.wHour, blink?':':' ', systime.wMinute); + blink ^= 1; + SendMessage(Static,WM_SETTEXT,0,(LPARAM)TimeStr); + break; + } + + return 1; +} + +static int ExplorerInfo(EXBARINFO* info) +{ + fprintf(stderr,"EX_CLOCK : EXPLORER INFO PLUGIN call\n"); + ex_x1=info->x; + ex_y1=info->y; + ex_dx=info->dx; + ex_dy=info->dy; + return 1; +} + +#ifdef _PLUGIN +BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +{ + fprintf(stderr,"EX_CLOCK PlugIn loaded succesefully\n"); + return TRUE; +} +#endif + + +struct PluginCalls plugincalls_Clock = { + InitializePlugIn, + QuitPlugIn, + ReloadPlugInConfiguration, + PlugInInfo, + ExplorerInfo, + PlugInMessageProc +}; + diff --git a/reactos/subsys/system/explorer/taskbar/ex_menu.c b/reactos/subsys/system/explorer/taskbar/ex_menu.c new file mode 100644 index 00000000000..d59b5b8cf4c --- /dev/null +++ b/reactos/subsys/system/explorer/taskbar/ex_menu.c @@ -0,0 +1,196 @@ +// +// Explorer Start Menu PlugIn (Example) +// +// Alexander Ciobanu +// alex@prodidactica.md +// + +#include +#include + +#include "ex_bar.h" + +HWND epl_AppButtons[10]; +char epl_line[10][80]; +int epl_Buttons; + +int ex_x1; +int ex_y1; +int ex_dx; +int ex_dy; + +// Initialize the plugin +// +static int InitializePlugIn(HWND ExplorerHandle) +{ + FILE* Conf; // Configuration File; + char line[80]; // Blah Blah Blah + char ttl[80]; // Title of the button + int i; + int x; + + fprintf(stderr,"EX_MENU : INITIALIZE PLUGIN call\n"); + + if (!(Conf=fopen("explorer.lst","r"))) // Error ! + { + fprintf(stderr,"DefaultPlugin : No configuration file found !\n"); + return 0; + } + + fgets(line,80,Conf); // Read how many entries are in the file + epl_Buttons=atoi(line); // atoi it ! + + + for (i=0;ix; + ex_y1=info->y; + ex_dx=info->dx; + ex_dy=info->dy; + + return 1; +} + + +#ifdef _PLUGIN +BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +{ + fprintf(stderr,"EX_MENU PlugIn loaded succesefully\n"); + return TRUE; +} +#endif + + +struct PluginCalls plugincalls_Menu = { + InitializePlugIn, + QuitPlugIn, + ReloadPlugInConfiguration, + PlugInInfo, + ExplorerInfo, + PlugInMessageProc +}; + diff --git a/reactos/subsys/system/explorer/taskbar/ex_shutdwn.c b/reactos/subsys/system/explorer/taskbar/ex_shutdwn.c new file mode 100644 index 00000000000..ab989e20bf1 --- /dev/null +++ b/reactos/subsys/system/explorer/taskbar/ex_shutdwn.c @@ -0,0 +1,132 @@ +// +// Explorer Shutdown PlugIn +// +// Alexander Ciobanu +// alex@prodidactica.md +// + +#include +#include + +#include "ex_bar.h" + +HWND ShwButton; +HWND Wnd; + +int ex_x1; +int ex_y1; +int ex_dx; +int ex_dy; + +// Initialize the plugin +// +static int InitializePlugIn(HWND ExplorerHandle) +{ + fprintf(stderr,"EX_SHUTDWN : INITIALIZE PLUGIN call\n"); + + ShwButton = CreateWindow( + TEXT("BUTTON"),TEXT("+"),WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, + ex_dx+ex_x1-33, 4, 25, ex_dy-14, ExplorerHandle, NULL, + (HINSTANCE) GetWindowLong(ExplorerHandle, GWL_HINSTANCE),NULL); + + return 1; +} + +// Get Information about the plugin +// +static char* PlugInInfo(int InfoNmbr) +{ + static char Info[256]; + + fprintf(stderr,"EX_SHUTDWN : INFORMATION PLUGIN call\n"); + + switch(InfoNmbr) + { + case 0: // PlugIn Name + strcpy(Info,"ReactOSShutdown"); + break; + + case 1: // Version + strcpy(Info,"0.1"); + break; + + case 2: // Vendor name + strcpy(Info,"ReactOS team"); + break; + + default: // Default : Error + strcpy(Info,"-"); + break; + + } + + return Info; +} + +// Reload plugin's configuration +// +static int ReloadPlugInConfiguration() +{ + fprintf(stderr,"EX_SHUTDWN : RELOAD PLUGIN COFIGURATION call\n"); + return 1; +} + +// Quit plugin +// +static int QuitPlugIn() +{ + fprintf(stderr,"EX_SHUTDWN : QUIT PLUGIN call\n"); + return 1; +} + +// Callback procedure for plugin +// +static int PlugInMessageProc(HWND PlgnHandle, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + + // The plugin must decide whatever the handle passed is created by it ! + // Sorry for bad english :-) + // + switch(Msg) + { + case WM_COMMAND: + if ((HWND)lParam==ShwButton) + { + printf("Pressed ShutDown Button : \n"); + DestroyWindow(PlgnHandle); + } + break; + } + + return 1; +} + +static int ExplorerInfo(EXBARINFO* info) +{ + fprintf(stderr,"EX_SHUTDWN : EXPLORER INFO PLUGIN call\n"); + ex_x1=info->x; + ex_y1=info->y; + ex_dx=info->dx; + ex_dy=info->dy; + + return 1; +} + +#ifdef _PLUGIN +BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +{ + fprintf(stderr,"EX_SHUTDWN PlugIn loaded succesefully\n"); + return TRUE; +} +#endif + + +struct PluginCalls plugincalls_Shutdown = { + InitializePlugIn, + QuitPlugIn, + ReloadPlugInConfiguration, + PlugInInfo, + ExplorerInfo, + PlugInMessageProc +}; + diff --git a/reactos/subsys/system/explorer/utility/.cvsignore b/reactos/subsys/system/explorer/utility/.cvsignore new file mode 100644 index 00000000000..a20095ddb2f --- /dev/null +++ b/reactos/subsys/system/explorer/utility/.cvsignore @@ -0,0 +1,15 @@ +*.coff +*.exe +*.d +*.o +*.sym +*.map +Debug +Release +UDebug +URelease +*.ncb +*.opt +*.aps +*.ncb +*.plg diff --git a/reactos/subsys/system/explorer/utility/dragdropimpl.cpp b/reactos/subsys/system/explorer/utility/dragdropimpl.cpp new file mode 100644 index 00000000000..dca5f300031 --- /dev/null +++ b/reactos/subsys/system/explorer/utility/dragdropimpl.cpp @@ -0,0 +1,592 @@ +/************************************************************************** + THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF + ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + PARTICULAR PURPOSE. + Author: Leon Finker 11/2000 + Modifications: replaced ATL by STL, Martin Fuchs 7/2003 +**************************************************************************/ + +// dragdropimp.cpp: implementation of the IDataObjectImpl class. +////////////////////////////////////////////////////////////////////// +#include +#include + +#include "dragdropimpl.h" + +////////////////////////////////////////////////////////////////////// +// IDataObjectImpl Class +////////////////////////////////////////////////////////////////////// + +IDataObjectImpl::IDataObjectImpl(IDropSourceImpl* pDropSource): + m_cRefCount(0), + m_pDropSource(pDropSource) +{ +} + +IDataObjectImpl::~IDataObjectImpl() +{ + for(StorageArray::iterator it=_storage.begin(); it!=_storage.end(); ++it) + ReleaseStgMedium(it->_medium); +} + +STDMETHODIMP IDataObjectImpl::QueryInterface(/* [in] */ REFIID riid, +/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = NULL; + if (IID_IUnknown==riid || IID_IDataObject==riid) + *ppvObject=this; + /*if (riid == IID_IAsyncOperation) + *ppvObject=(IAsyncOperation*)this;*/ + if (NULL!=*ppvObject) + { + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) IDataObjectImpl::AddRef() +{ + return ++m_cRefCount; +} + +STDMETHODIMP_(ULONG) IDataObjectImpl::Release() +{ + long nTemp = --m_cRefCount; + + if (nTemp == 0) + delete this; + + return nTemp; +} + +STDMETHODIMP IDataObjectImpl::GetData( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn, + /* [out] */ STGMEDIUM __RPC_FAR *pmedium) +{ + if (pformatetcIn == NULL || pmedium == NULL) + return E_INVALIDARG; + + pmedium->hGlobal = NULL; + + for(StorageArray::iterator it=_storage.begin(); it!=_storage.end(); ++it) + { + if (pformatetcIn->tymed & it->_format->tymed && + pformatetcIn->dwAspect == it->_format->dwAspect && + pformatetcIn->cfFormat == it->_format->cfFormat) + { + CopyMedium(pmedium, it->_medium, it->_format); + return S_OK; + } + } + + return DV_E_FORMATETC; +} + +STDMETHODIMP IDataObjectImpl::GetDataHere( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc, + /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium) +{ + return E_NOTIMPL; +} + +STDMETHODIMP IDataObjectImpl::QueryGetData( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc) +{ + if (pformatetc == NULL) + return E_INVALIDARG; + + //support others if needed DVASPECT_THUMBNAIL //DVASPECT_ICON //DVASPECT_DOCPRINT + if (!(DVASPECT_CONTENT & pformatetc->dwAspect)) + return (DV_E_DVASPECT); + + HRESULT hr = DV_E_TYMED; + + for(StorageArray::iterator it=_storage.begin(); it!=_storage.end(); ++it) + { + if (pformatetc->tymed & it->_format->tymed) + { + if (pformatetc->cfFormat == it->_format->cfFormat) + return S_OK; + else + hr = DV_E_CLIPFORMAT; + } + else + hr = DV_E_TYMED; + } + return hr; +} + +STDMETHODIMP IDataObjectImpl::GetCanonicalFormatEtc( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn, + /* [out] */ FORMATETC __RPC_FAR *pformatetcOut) +{ + if (pformatetcOut == NULL) + return E_INVALIDARG; + + return DATA_S_SAMEFORMATETC; +} + +STDMETHODIMP IDataObjectImpl::SetData( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc, + /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium, + /* [in] */ BOOL fRelease) +{ + if (pformatetc == NULL || pmedium == NULL) + return E_INVALIDARG; + + assert(pformatetc->tymed == pmedium->tymed); + FORMATETC* fetc=new FORMATETC; + STGMEDIUM* pStgMed = new STGMEDIUM; + + if (fetc == NULL || pStgMed == NULL) + return E_OUTOFMEMORY; + + ZeroMemory(fetc, sizeof(FORMATETC)); + ZeroMemory(pStgMed, sizeof(STGMEDIUM)); + + *fetc = *pformatetc; + + if (fRelease) + *pStgMed = *pmedium; + else + CopyMedium(pStgMed, pmedium, pformatetc); + + DataStorage storage; + + storage._format = fetc; + storage._medium = pStgMed; + + _storage.push_back(storage); + + return S_OK; +} + +void IDataObjectImpl::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc) +{ + switch(pMedSrc->tymed) + { + case TYMED_HGLOBAL: + pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal, pFmtSrc->cfFormat, 0); + break; + case TYMED_GDI: + pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap, pFmtSrc->cfFormat, 0); + break; + case TYMED_MFPICT: + pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict, pFmtSrc->cfFormat, 0); + break; + case TYMED_ENHMF: + pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile, pFmtSrc->cfFormat, 0); + break; + case TYMED_FILE: + pMedDest->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName, pFmtSrc->cfFormat, 0); + break; + case TYMED_ISTREAM: + pMedDest->pstm = pMedSrc->pstm; + pMedSrc->pstm->AddRef(); + break; + case TYMED_ISTORAGE: + pMedDest->pstg = pMedSrc->pstg; + pMedSrc->pstg->AddRef(); + break; + case TYMED_NULL: + default: + break; + } + pMedDest->tymed = pMedSrc->tymed; + pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease; +} + +STDMETHODIMP IDataObjectImpl::EnumFormatEtc( + /* [in] */ DWORD dwDirection, + /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc) +{ + if (ppenumFormatEtc == NULL) + return E_POINTER; + + *ppenumFormatEtc=NULL; + switch (dwDirection) + { + case DATADIR_GET: + *ppenumFormatEtc = new EnumFormatEtcImpl(_storage); + + if (!*ppenumFormatEtc) + return E_OUTOFMEMORY; + + (*ppenumFormatEtc)->AddRef(); + break; + + case DATADIR_SET: + default: + return E_NOTIMPL; + break; + } + + return S_OK; +} + +STDMETHODIMP IDataObjectImpl::DAdvise( + /* [in] */ FORMATETC __RPC_FAR *pformatetc, + /* [in] */ DWORD advf, + /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink, + /* [out] */ DWORD __RPC_FAR *pdwConnection) +{ + return OLE_E_ADVISENOTSUPPORTED; +} + +STDMETHODIMP IDataObjectImpl::DUnadvise( + /* [in] */ DWORD dwConnection) +{ + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE IDataObjectImpl::EnumDAdvise( + /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise) +{ + return OLE_E_ADVISENOTSUPPORTED; +} + +////////////////////////////////////////////////////////////////////// +// IDropSourceImpl Class +////////////////////////////////////////////////////////////////////// + +STDMETHODIMP IDropSourceImpl::QueryInterface(/* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = NULL; + if (IID_IUnknown==riid || IID_IDropSource==riid) + *ppvObject=this; + + if (*ppvObject != NULL) + { + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) IDropSourceImpl::AddRef() +{ + return ++m_cRefCount; +} + +STDMETHODIMP_(ULONG) IDropSourceImpl::Release() +{ + long nTemp = --m_cRefCount; + + assert(nTemp >= 0); + + if (nTemp == 0) + delete this; + + return nTemp; +} + +STDMETHODIMP IDropSourceImpl::QueryContinueDrag( + /* [in] */ BOOL fEscapePressed, + /* [in] */ DWORD grfKeyState) +{ + if (fEscapePressed) + return DRAGDROP_S_CANCEL; + if (!(grfKeyState & (MK_LBUTTON|MK_RBUTTON))) + { + m_bDropped = true; + return DRAGDROP_S_DROP; + } + + return S_OK; + +} + +STDMETHODIMP IDropSourceImpl::GiveFeedback( + /* [in] */ DWORD dwEffect) +{ + return DRAGDROP_S_USEDEFAULTCURSORS; +} + +////////////////////////////////////////////////////////////////////// +// EnumFormatEtcImpl Class +////////////////////////////////////////////////////////////////////// + +EnumFormatEtcImpl::EnumFormatEtcImpl(const FormatArray& ArrFE) + : m_cRefCount(0), + m_iCur(0) +{ + for(FormatArray::const_iterator it=ArrFE.begin(); it!=ArrFE.end(); ++it) + m_pFmtEtc.push_back(*it); +} + +EnumFormatEtcImpl::EnumFormatEtcImpl(const StorageArray& ArrFE) + : m_cRefCount(0), + m_iCur(0) +{ + for(StorageArray::const_iterator it=ArrFE.begin(); it!=ArrFE.end(); ++it) + m_pFmtEtc.push_back(*it->_format); +} + +STDMETHODIMP EnumFormatEtcImpl::QueryInterface(REFIID refiid, void FAR* FAR* ppv) +{ + *ppv = NULL; + if (IID_IUnknown==refiid || IID_IEnumFORMATETC==refiid) + *ppv=this; + + if (*ppv != NULL) + { + ((LPUNKNOWN)*ppv)->AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) EnumFormatEtcImpl::AddRef(void) +{ + return ++m_cRefCount; +} + +STDMETHODIMP_(ULONG) EnumFormatEtcImpl::Release(void) +{ + long nTemp = --m_cRefCount; + + assert(nTemp >= 0); + + if (nTemp == 0) + delete this; + + return nTemp; +} + +STDMETHODIMP EnumFormatEtcImpl::Next( ULONG celt,LPFORMATETC lpFormatEtc, ULONG FAR *pceltFetched) +{ + if (pceltFetched != NULL) + *pceltFetched=0; + + ULONG cReturn = celt; + + if (celt <= 0 || lpFormatEtc == NULL || m_iCur >= m_pFmtEtc.size()) + return S_FALSE; + + if (pceltFetched == NULL && celt != 1) // pceltFetched can be NULL only for 1 item request + return S_FALSE; + + while (m_iCur < m_pFmtEtc.size() && cReturn > 0) + { + *lpFormatEtc++ = m_pFmtEtc[m_iCur++]; + --cReturn; + } + if (pceltFetched != NULL) + *pceltFetched = celt - cReturn; + + return (cReturn == 0) ? S_OK : S_FALSE; +} + +STDMETHODIMP EnumFormatEtcImpl::Skip(ULONG celt) +{ + if ((m_iCur + int(celt)) >= m_pFmtEtc.size()) + return S_FALSE; + + m_iCur += celt; + return S_OK; +} + +STDMETHODIMP EnumFormatEtcImpl::Reset(void) +{ + m_iCur = 0; + return S_OK; +} + +STDMETHODIMP EnumFormatEtcImpl::Clone(IEnumFORMATETC FAR * FAR*ppCloneEnumFormatEtc) +{ + if (ppCloneEnumFormatEtc == NULL) + return E_POINTER; + + EnumFormatEtcImpl* newEnum = new EnumFormatEtcImpl(m_pFmtEtc); + + if (!newEnum) + return E_OUTOFMEMORY; + + newEnum->AddRef(); + newEnum->m_iCur = m_iCur; + *ppCloneEnumFormatEtc = newEnum; + + return S_OK; +} + +////////////////////////////////////////////////////////////////////// +// IDropTargetImpl Class +////////////////////////////////////////////////////////////////////// +IDropTargetImpl::IDropTargetImpl(HWND hTargetWnd): + m_hTargetWnd(hTargetWnd), + m_cRefCount(0), m_bAllowDrop(false), + m_pDropTargetHelper(NULL), m_pSupportedFrmt(NULL) +{ + assert(m_hTargetWnd != NULL); + + if (FAILED(CoCreateInstance(CLSID_DragDropHelper,NULL,CLSCTX_INPROC_SERVER, + IID_IDropTargetHelper,(LPVOID*)&m_pDropTargetHelper))) + m_pDropTargetHelper = NULL; +} + +IDropTargetImpl::~IDropTargetImpl() +{ + if (m_pDropTargetHelper != NULL) + { + m_pDropTargetHelper->Release(); + m_pDropTargetHelper = NULL; + } +} + +HRESULT STDMETHODCALLTYPE IDropTargetImpl::QueryInterface( /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = NULL; + if (IID_IUnknown==riid || IID_IDropTarget==riid) + *ppvObject=this; + + if (*ppvObject != NULL) + { + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE IDropTargetImpl::Release() +{ + long nTemp = --m_cRefCount; + + assert(nTemp >= 0); + + if (nTemp == 0) + delete this; + + return nTemp; +} + +bool IDropTargetImpl::QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect) +{ + DWORD dwOKEffects = *pdwEffect; + + if (!m_bAllowDrop) + { + *pdwEffect = DROPEFFECT_NONE; + return false; + } + //CTRL+SHIFT -- DROPEFFECT_LINK + //CTRL -- DROPEFFECT_COPY + //SHIFT -- DROPEFFECT_MOVE + //no modifier -- DROPEFFECT_MOVE or whatever is allowed by src + *pdwEffect = (grfKeyState & MK_CONTROL) ? + ( (grfKeyState & MK_SHIFT) ? DROPEFFECT_LINK : DROPEFFECT_COPY ): + ( (grfKeyState & MK_SHIFT) ? DROPEFFECT_MOVE : 0 ); + if (*pdwEffect == 0) + { + // No modifier keys used by user while dragging. + if (DROPEFFECT_COPY & dwOKEffects) + *pdwEffect = DROPEFFECT_COPY; + else if (DROPEFFECT_MOVE & dwOKEffects) + *pdwEffect = DROPEFFECT_MOVE; + else if (DROPEFFECT_LINK & dwOKEffects) + *pdwEffect = DROPEFFECT_LINK; + else + { + *pdwEffect = DROPEFFECT_NONE; + } + } + else + { + // Check if the drag source application allows the drop effect desired by user. + // The drag source specifies this in DoDragDrop + if (!(*pdwEffect & dwOKEffects)) + *pdwEffect = DROPEFFECT_NONE; + } + + return (DROPEFFECT_NONE == *pdwEffect)?false:true; +} + +HRESULT STDMETHODCALLTYPE IDropTargetImpl::DragEnter( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect) +{ + if (pDataObj == NULL) + return E_INVALIDARG; + + if (m_pDropTargetHelper) + m_pDropTargetHelper->DragEnter(m_hTargetWnd, pDataObj, (LPPOINT)&pt, *pdwEffect); + //IEnumFORMATETC* pEnum; + //pDataObj->EnumFormatEtc(DATADIR_GET,&pEnum); + //FORMATETC ftm; + //for() + //pEnum->Next(1,&ftm,0); + //pEnum->Release(); + m_pSupportedFrmt = NULL; + + for(FormatArray::iterator it=m_formatetc.begin(); it!=m_formatetc.end(); ++it) + { + m_bAllowDrop = (pDataObj->QueryGetData(&*it) == S_OK)? true: false; + + if (m_bAllowDrop) + { + m_pSupportedFrmt = &*it; + break; + } + } + + QueryDrop(grfKeyState, pdwEffect); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE IDropTargetImpl::DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect) +{ + if (m_pDropTargetHelper) + m_pDropTargetHelper->DragOver((LPPOINT)&pt, *pdwEffect); + QueryDrop(grfKeyState, pdwEffect); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE IDropTargetImpl::DragLeave() +{ + if (m_pDropTargetHelper) + m_pDropTargetHelper->DragLeave(); + + m_bAllowDrop = false; + m_pSupportedFrmt = NULL; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE IDropTargetImpl::Drop( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect) +{ + if (pDataObj == NULL) + return E_INVALIDARG; + + if (m_pDropTargetHelper) + m_pDropTargetHelper->Drop(pDataObj, (LPPOINT)&pt, *pdwEffect); + + if (QueryDrop(grfKeyState, pdwEffect)) + { + if (m_bAllowDrop && m_pSupportedFrmt != NULL) + { + STGMEDIUM medium; + + if (pDataObj->GetData(m_pSupportedFrmt, &medium) == S_OK) + { + if (OnDrop(m_pSupportedFrmt, medium, pdwEffect)) //does derive class wants us to free medium? + ReleaseStgMedium(&medium); + } + } + } + + m_bAllowDrop = false; + *pdwEffect = DROPEFFECT_NONE; + m_pSupportedFrmt = NULL; + + return S_OK; +} diff --git a/reactos/subsys/system/explorer/utility/dragdropimpl.h b/reactos/subsys/system/explorer/utility/dragdropimpl.h new file mode 100644 index 00000000000..dfcf8855f93 --- /dev/null +++ b/reactos/subsys/system/explorer/utility/dragdropimpl.h @@ -0,0 +1,263 @@ +// IDataObjectImpl.h: interface for the CIDataObjectImpl class. +/************************************************************************** + THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF + ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + PARTICULAR PURPOSE. + Author: Leon Finker 11/2000 + Modifications: replaced ATL by STL, Martin Fuchs 7/2003 +**************************************************************************/ + +#include +using std::vector; + + +typedef vector FormatArray; + +struct DataStorage { + FORMATETC* _format; + STGMEDIUM* _medium; +}; + +typedef vector StorageArray; + + +class EnumFormatEtcImpl : public IEnumFORMATETC +{ + private: + ULONG m_cRefCount; + FormatArray m_pFmtEtc; + int m_iCur; + + public: + EnumFormatEtcImpl(const FormatArray& ArrFE); + EnumFormatEtcImpl(const StorageArray& ArrFE); + + //IUnknown members + STDMETHOD(QueryInterface)(REFIID, void FAR* FAR*); + STDMETHOD_(ULONG, AddRef)(void); + STDMETHOD_(ULONG, Release)(void); + + //IEnumFORMATETC members + STDMETHOD(Next)(ULONG, LPFORMATETC, ULONG FAR *); + STDMETHOD(Skip)(ULONG); + STDMETHOD(Reset)(void); + STDMETHOD(Clone)(IEnumFORMATETC FAR * FAR*); +}; + +/////////////////////////////////////////////////////////////////////////////////////////////// +class IDropSourceImpl : public IDropSource +{ + long m_cRefCount; +public: + bool m_bDropped; + + IDropSourceImpl::IDropSourceImpl() : m_cRefCount(0), m_bDropped(false) {} + + //IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + //IDropSource + virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag( + /* [in] */ BOOL fEscapePressed, + /* [in] */ DWORD grfKeyState); + + virtual HRESULT STDMETHODCALLTYPE GiveFeedback( + /* [in] */ DWORD dwEffect); +}; + +/////////////////////////////////////////////////////////////////////////////////////////////// +class IDataObjectImpl : public IDataObject//,public IAsyncOperation +{ + IDropSourceImpl* m_pDropSource; + long m_cRefCount; + + StorageArray _storage; + +public: + IDataObjectImpl(IDropSourceImpl* pDropSource); + ~IDataObjectImpl(); + + void CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc); + + //IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + //IDataObject + virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetData( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn, + /* [out] */ STGMEDIUM __RPC_FAR *pmedium); + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDataHere( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc, + /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium); + + virtual HRESULT STDMETHODCALLTYPE QueryGetData( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc); + + virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn, + /* [out] */ FORMATETC __RPC_FAR *pformatetcOut); + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetData( + /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc, + /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium, + /* [in] */ BOOL fRelease); + + virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc( + /* [in] */ DWORD dwDirection, + /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc); + + virtual HRESULT STDMETHODCALLTYPE DAdvise( + /* [in] */ FORMATETC __RPC_FAR *pformatetc, + /* [in] */ DWORD advf, + /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink, + /* [out] */ DWORD __RPC_FAR *pdwConnection); + + virtual HRESULT STDMETHODCALLTYPE DUnadvise( + /* [in] */ DWORD dwConnection); + + virtual HRESULT STDMETHODCALLTYPE EnumDAdvise( + /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise); + + //IAsyncOperation + //virtual HRESULT STDMETHODCALLTYPE SetAsyncMode( + // /* [in] */ BOOL fDoOpAsync) + //{ + // return E_NOTIMPL; + //} + // + //virtual HRESULT STDMETHODCALLTYPE GetAsyncMode( + // /* [out] */ BOOL __RPC_FAR *pfIsOpAsync) + //{ + // return E_NOTIMPL; + //} + // + //virtual HRESULT STDMETHODCALLTYPE StartOperation( + // /* [optional][unique][in] */ IBindCtx __RPC_FAR *pbcReserved) + //{ + // return E_NOTIMPL; + //} + // + //virtual HRESULT STDMETHODCALLTYPE InOperation( + // /* [out] */ BOOL __RPC_FAR *pfInAsyncOp) + //{ + // return E_NOTIMPL; + //} + // + //virtual HRESULT STDMETHODCALLTYPE EndOperation( + // /* [in] */ HRESULT hResult, + // /* [unique][in] */ IBindCtx __RPC_FAR *pbcReserved, + // /* [in] */ DWORD dwEffects) + //{ + // return E_NOTIMPL; + //}*/ +}; + +/////////////////////////////////////////////////////////////////////////////////////////////// +class IDropTargetImpl : public IDropTarget +{ + DWORD m_cRefCount; + bool m_bAllowDrop; + IDropTargetHelper* m_pDropTargetHelper; + + FormatArray m_formatetc; + FORMATETC* m_pSupportedFrmt; + +protected: + HWND m_hTargetWnd; + +public: + IDropTargetImpl(HWND m_hTargetWnd); + virtual ~IDropTargetImpl(); + void AddSuportedFormat(FORMATETC& ftetc) {m_formatetc.push_back(ftetc);} + + //return values: true - release the medium. false - don't release the medium + virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD *pdwEffect) = 0; + + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef() {return ++m_cRefCount;} + virtual ULONG STDMETHODCALLTYPE Release(); + + bool QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect); + virtual HRESULT STDMETHODCALLTYPE DragEnter( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + virtual HRESULT STDMETHODCALLTYPE DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + virtual HRESULT STDMETHODCALLTYPE DragLeave(); + virtual HRESULT STDMETHODCALLTYPE Drop( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); +}; + +class DragSourceHelper +{ + IDragSourceHelper* pDragSourceHelper; + +public: + DragSourceHelper() + { + if (FAILED(CoCreateInstance(CLSID_DragDropHelper, + NULL, + CLSCTX_INPROC_SERVER, + IID_IDragSourceHelper, + (void**)&pDragSourceHelper))) + pDragSourceHelper = NULL; + } + + virtual ~DragSourceHelper() + { + if ( pDragSourceHelper!= NULL ) + { + pDragSourceHelper->Release(); + pDragSourceHelper=NULL; + } + } + + // IDragSourceHelper + HRESULT InitializeFromBitmap(HBITMAP hBitmap, + POINT& pt, // cursor position in client coords of the window + RECT& rc, // selected item's bounding rect + IDataObject* pDataObject, + COLORREF crColorKey=GetSysColor(COLOR_WINDOW)// color of the window used for transparent effect. + ) + { + if (pDragSourceHelper == NULL) + return E_FAIL; + + SHDRAGIMAGE di; + BITMAP bm; + GetObject(hBitmap, sizeof(bm), &bm); + di.sizeDragImage.cx = bm.bmWidth; + di.sizeDragImage.cy = bm.bmHeight; + di.hbmpDragImage = hBitmap; + di.crColorKey = crColorKey; + di.ptOffset.x = pt.x - rc.left; + di.ptOffset.y = pt.y - rc.top; + return pDragSourceHelper->InitializeFromBitmap(&di, pDataObject); + } + + HRESULT InitializeFromWindow(HWND hwnd, POINT& pt,IDataObject* pDataObject) + { + if (pDragSourceHelper == NULL) + return E_FAIL; + return pDragSourceHelper->InitializeFromWindow(hwnd, &pt, pDataObject); + } +}; diff --git a/reactos/subsys/system/explorer/utility/shellbrowserimpl.h b/reactos/subsys/system/explorer/utility/shellbrowserimpl.h new file mode 100644 index 00000000000..d558383572c --- /dev/null +++ b/reactos/subsys/system/explorer/utility/shellbrowserimpl.h @@ -0,0 +1,99 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellbrowserimpl.h + // + // Martin Fuchs, 23.07.2003 + // + // Credits: Thanks to Leon Finker for his explorer window example + // + + +struct IShellBrowserImpl : public IShellBrowser, public ICommDlgBrowser +{ + IShellBrowserImpl() + : _dwRef(0) + { + } + + STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) + { + if (!ppvObject) + return E_POINTER; + + if (iid == IID_IUnknown) + *ppvObject = (IUnknown*)static_cast(this); + else if (iid == IID_IOleWindow) + *ppvObject = static_cast(this); + else if (iid == IID_IShellBrowser) + *ppvObject = static_cast(this); + else if (iid == IID_ICommDlgBrowser) + *ppvObject = static_cast(this); + else { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + return S_OK; + } + + STDMETHOD_(ULONG, AddRef)() {return ++_dwRef;} + STDMETHOD_(ULONG, Release)() {return --_dwRef;} //not heap based + + // *** IOleWindow methods *** + STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) {return E_NOTIMPL;} + + // *** ICommDlgBrowser methods *** + STDMETHOD(OnDefaultCommand)(THIS_ struct IShellView* ppshv) + { //handle double click and ENTER key if needed + return E_NOTIMPL; + } + + STDMETHOD(OnStateChange)(THIS_ struct IShellView* ppshv, ULONG uChange) + { //handle selection, rename, focus if needed + return E_NOTIMPL; + } + + STDMETHOD(IncludeObject)(THIS_ struct IShellView* ppshv, LPCITEMIDLIST pidl) + { //filter files if needed + return S_OK; + } + + // *** IShellBrowser methods *** (same as IOleInPlaceFrame) + STDMETHOD(InsertMenusSB)(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) {return E_NOTIMPL;} + STDMETHOD(SetMenuSB)(HMENU hmenuShared, HOLEMENU holemenuReserved,HWND hwndActiveObject) {return E_NOTIMPL;} + STDMETHOD(RemoveMenusSB)(HMENU hmenuShared) {return E_NOTIMPL;} + STDMETHOD(SetStatusTextSB)(LPCOLESTR lpszStatusText) {return E_NOTIMPL;} + STDMETHOD(EnableModelessSB)(BOOL fEnable) {return E_NOTIMPL;} + STDMETHOD(BrowseObject)(LPCITEMIDLIST pidl, UINT wFlags) {return E_NOTIMPL;} + STDMETHOD(GetViewStateStream)(DWORD grfMode,LPSTREAM *ppStrm) {return E_NOTIMPL;} + STDMETHOD(OnViewWindowActive)(struct IShellView *ppshv) {return E_NOTIMPL;} + STDMETHOD(SetToolbarItems)(LPTBBUTTON lpButtons, UINT nButtons,UINT uFlags) {return E_NOTIMPL;} + STDMETHOD(TranslateAcceleratorSB)(LPMSG lpmsg, WORD wID) {return S_OK;} + +protected: + DWORD _dwRef; +}; + +#ifndef WM_GETISHELLBROWSER +#define WM_GETISHELLBROWSER (WM_USER+7) +#endif diff --git a/reactos/subsys/system/explorer/utility/shellclasses.cpp b/reactos/subsys/system/explorer/utility/shellclasses.cpp new file mode 100644 index 00000000000..d4e7385b75c --- /dev/null +++ b/reactos/subsys/system/explorer/utility/shellclasses.cpp @@ -0,0 +1,243 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellclasses.cpp + // + // C++ wrapper classes for COM interfaces and shell objects + // + // Martin Fuchs, 20.07.2003 + // + + +#include "utility.h" +#include "shellclasses.h" + + +#pragma comment(lib, "shell32") // link to shell32.dll + + + // Exception Handler for COM exceptions + +void HandleException(COMException& e, HWND hwnd) +{ + MessageBox(hwnd, e.ErrorMessage(), TEXT("ShellClasses COM Exception"), MB_ICONHAND|MB_OK); +} + + + // common IMalloc object + +CommonShellMalloc ShellMalloc::s_cmn_shell_malloc; + + + // common desktop object + +ShellFolder& Desktop() +{ + static CommonDesktop s_desktop; + + // initialize s_desktop + s_desktop.init(); + + return s_desktop; +} + + +void CommonDesktop::init() +{ + if (!_desktop) + _desktop = new ShellFolder; +} + +CommonDesktop::~CommonDesktop() +{ + if (_desktop) + delete _desktop; +} + + +HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len) +{ + StrRetA str; + + HRESULT hr = folder->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &str); + + if (SUCCEEDED(hr)) + str.GetString(pidl->mkid, buffer, len); + else + buffer[0] = '\0'; + + return hr; +} + +HRESULT path_from_pidlW(IShellFolder* folder, LPITEMIDLIST pidl, LPWSTR buffer, int len) +{ + StrRetW str; + + HRESULT hr = folder->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &str); + + if (SUCCEEDED(hr)) + str.GetString(pidl->mkid, buffer, len); + else + buffer[0] = '\0'; + + return hr; +} + +HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags) +{ + StrRet str; + + HRESULT hr = folder->GetDisplayNameOf(pidl, flags, &str); + + if (SUCCEEDED(hr)) + str.GetString(pidl->mkid, buffer, len); + else + buffer[0] = '\0'; + + return hr; +} + + +#ifndef _NO_COMUTIL + +ShellFolder::ShellFolder() +{ + IShellFolder* desktop; + + CheckError(SHGetDesktopFolder(&desktop)); + + super::Attach(desktop); +} + +ShellFolder::ShellFolder(IShellFolder* p) + : IShellFolderPtr(p) +{ +} + +ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl) +{ + IShellFolder* ptr; + + if (pidl->mkid.cb) + CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr)); + else + ptr = parent; + + super::Attach(ptr); +} + +ShellFolder::ShellFolder(LPCITEMIDLIST pidl) +{ + IShellFolder* ptr; + IShellFolder* parent = Desktop(); + + if (pidl->mkid.cb) + CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr)); + else + ptr = parent; + + super::Attach(Desktop()); +} + +void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl) +{ + IShellFolder* ptr; + + if (pidl->mkid.cb) + CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&ptr)); + else + ptr = parent; + + super::Attach(ptr); +} + +string ShellFolder::get_name(LPITEMIDLIST pidl, SHGDNF flags) +{ + char buffer[MAX_PATH]; + StrRetA strret; + + CheckError(((IShellFolder*)*this)->GetDisplayNameOf(pidl, flags, &strret)); + strret.GetString(pidl->mkid, buffer, MAX_PATH); + + return buffer; +} + +#else // _com_ptr not available -> use SIfacePtr + +ShellFolder::ShellFolder() +{ + CheckError(SHGetDesktopFolder(&_p)); +} + +ShellFolder::ShellFolder(IShellFolder* p) + : SIfacePtr(p) +{ +} + +ShellFolder::ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl) +{ + CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p)); +} + +ShellFolder::ShellFolder(LPCITEMIDLIST pidl) +{ + if (pidl->mkid.cb) + CheckError(Desktop()->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p)); + else + _p = Desktop(); +} + +void ShellFolder::attach(IShellFolder* parent, LPCITEMIDLIST pidl) +{ + IShellFolder* h = _p; + + CheckError(parent->BindToObject(pidl, 0, IID_IShellFolder, (LPVOID*)&_p)); + + h->Release(); +} + +#endif + + + // helper function 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; +} diff --git a/reactos/subsys/system/explorer/utility/shellclasses.h b/reactos/subsys/system/explorer/utility/shellclasses.h new file mode 100644 index 00000000000..b22570b8ef8 --- /dev/null +++ b/reactos/subsys/system/explorer/utility/shellclasses.h @@ -0,0 +1,777 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // shellclasses.h + // + // C++ wrapper classes for COM interfaces and shell objects + // + // Martin Fuchs, 20.07.2003 + // + + + // windows shell headers +#include +#include + +#ifndef _INC_COMUTIL // is comutil.h of MS headers available? +#define _NO_COMUTIL +#endif + + + // COM Exception Handling + +#ifndef _NO_COMUTIL + +#define COMException _com_error + +#else + +struct COMException { + COMException(HRESULT hr) + : _hr(hr) + { + _msg = NULL; + } + + LPCTSTR ErrorMessage() const + { + if (!_msg) + _msg = TEXT("COM Exception"); //TODO: use FormatMessage() + + return _msg; + } + +protected: + HRESULT _hr; + mutable LPCTSTR _msg; +}; + +inline void CheckError(HRESULT hr) +{ + if (FAILED(hr)) { + throw COMException(hr); + } +} + +#endif + + + // COM Initialisation + +struct ComInit +{ + ComInit() + { + CheckError(CoInitialize(0)); + } + +#if (_WIN32_WINNT>=0x0400) || defined(_WIN32_DCOM) + ComInit(DWORD flag) + { + CheckError(CoInitializeEx(0, flag)); + } +#endif + + ~ComInit() + { + CoUninitialize(); + } +}; + + + // OLE initialisation for drag drop support + +struct OleInit +{ + OleInit() + { + CheckError(OleInitialize(0)); + } + + ~OleInit() + { + OleUninitialize(); + } +}; + + + // Exception Handler for COM exceptions + +extern void HandleException(COMException& e, HWND hwnd); + + + // We use a common IMalloc object for all shell memory allocations. + +struct CommonShellMalloc +{ + CommonShellMalloc() + { + _p = 0; + } + + void init() + { + if (!_p) + CheckError(SHGetMalloc(&_p)); + } + + ~CommonShellMalloc() + { + if (_p) + _p->Release(); + } + + operator IMalloc*() + { + return _p; + } + + IMalloc* _p; +}; + + + // wrapper class for IMalloc with usage of common allocator + +struct ShellMalloc +{ + ShellMalloc() + { + // initialize s_cmn_shell_malloc + s_cmn_shell_malloc.init(); + } + + IMalloc* operator->() + { + return s_cmn_shell_malloc; + } + + static CommonShellMalloc s_cmn_shell_malloc; +}; + + + // wrapper template class for pointers to shell objects managed by IMalloc + +template struct SShellPtr +{ + ~SShellPtr() + { + _malloc->Free(_p); + } + + T* operator->() + { + return _p; + } + + T const* operator->() const + { + return _p; + } + + operator T const *() const + { + return _p; + } + + const T& operator*() const + { + return *_p; + } + + T& operator*() + { + return *_p; + } + +protected: + SShellPtr() + : _p(0) + { + } + + SShellPtr(T* p) + : _p(p) + { + } + + void Free() + { + _malloc->Free(_p); + _p = 0; + } + + T* _p; + ShellMalloc _malloc; // IMalloc memory management object + +private: + // disallow copying of SShellPtr objects + SShellPtr(const SShellPtr&) {} + void operator=(SShellPtr const&) {} +}; + + + // wrapper class for COM interface pointers + +template struct SIfacePtr +{ + SIfacePtr() + : _p(0) + { + } + + SIfacePtr(T* p) : _p(p) + { + if (p) + p->AddRef(); + } + + ~SIfacePtr() + { + Free(); + } + + T* operator->() + { + return _p; + } + + const T* operator->() const + { + return _p; + } + +/* not GCC compatible + operator const T*() const + { + return _p; + } */ + + operator T*() + { + return _p; + } + + T** operator&() + { + return &_p; + } + + bool empty() const //NOTE: GCC seems not to work correctly when defining operator bool() AND operator T*() + { + return !_p; + } + + SIfacePtr& operator=(T* p) + { + Free(); + p->AddRef(); + _p = p; + + return *this; + } + + void operator=(SIfacePtr const& o) + { + T* h = _p; + + if (o._p) + o._p->AddRef(); + + _p = o._p; + + if (h) + h->Release(); + } + + void Free() + { + T* h = _p; + _p = 0; + + if (h) + h->Release(); + } + +protected: + SIfacePtr(const SIfacePtr& o) + : _p(o._p) + { + if (_p) + _p->AddRef(); + } + + T* _p; +}; + + + + // caching of desktop ShellFolder object + +struct ShellFolder; + +struct CommonDesktop +{ + CommonDesktop() + { + _desktop = 0; + } + + ~CommonDesktop(); + + void init(); + + operator struct ShellFolder&() + { + return *_desktop; + } + +protected: + ShellFolder* _desktop; +}; + + +#ifndef _NO_COMUTIL // _com_ptr available? + +struct ShellFolder : public IShellFolderPtr // IShellFolderPtr uses intrinsic extensions of the vc++ compiler. +{ + typedef IShellFolderPtr super; + + ShellFolder(); + ShellFolder(IShellFolder* p); + ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl); + ShellFolder(LPCITEMIDLIST pidl); + + void attach(IShellFolder* parent, LPCITEMIDLIST pidl); + string get_name(LPITEMIDLIST pidl, SHGDNF flags=SHGDN_NORMAL); + + bool empty() const {return !operator bool();} //NOTE: see SIfacePtr::empty() +}; + +#else // _com_ptr not available -> use SIfacePtr + +struct ShellFolder : public SIfacePtr +{ + typedef SIfacePtr super; + + ShellFolder(); + ShellFolder(IShellFolder* p); + ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl); + ShellFolder(LPCITEMIDLIST pidl); + + void attach(IShellFolder* parent, LPCITEMIDLIST pidl); +}; + +#endif + + +extern ShellFolder& Desktop(); + + +#ifdef UNICODE +#define path_from_pidl path_from_pidlW +#else +#define path_from_pidl path_from_pidlA +#endif + +extern HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len); +extern HRESULT path_from_pidlW(IShellFolder* folder, LPITEMIDLIST pidl, LPWSTR buffer, int len); +extern HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags); + + + // wrapper class for item ID lists + +struct ShellPath : public SShellPtr +{ + typedef SShellPtr super; + + ShellPath() + { + } + + ShellPath(IShellFolder* folder, LPCWSTR path) + { + ULONG l; + CheckError(folder->ParseDisplayName(0, 0, (LPOLESTR)path, &l, &_p, 0)); + } + + ShellPath(LPCWSTR path) + { + ULONG l; + CheckError(Desktop()->ParseDisplayName(0, 0, (LPOLESTR)path, &l, &_p, 0)); + } + + ShellPath(IShellFolder* folder, LPCSTR path) + { + ULONG l; + WCHAR b[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, b, MAX_PATH); + CheckError(folder->ParseDisplayName(0, 0, b, &l, &_p, 0)); + } + + ShellPath(LPCSTR path) + { + ULONG l; + WCHAR b[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, b, MAX_PATH); + CheckError(Desktop()->ParseDisplayName(0, 0, b, &l, &_p, 0)); + } + + ShellPath(const ShellPath& o) + : super(NULL) + { + if (o._p) { + int l = _malloc->GetSize(o._p); + _p = (ITEMIDLIST*) _malloc->Alloc(l); + memcpy(_p, o._p, l); + } + } + + ShellPath(ITEMIDLIST* p) + : SShellPtr(p) + { + } + + void operator=(const ShellPath& o) + { + ITEMIDLIST* h = _p; + + if (o._p) { + int l = _malloc->GetSize(o._p); + + _p = (ITEMIDLIST*)_malloc->Alloc(l); + memcpy(_p, o._p, l); + } + else + _p = 0; + + _malloc->Free(h); + } + + void operator=(ITEMIDLIST* p) + { + ITEMIDLIST* h = _p; + + if (p) { + int l = _malloc->GetSize(p); + + _p = (ITEMIDLIST*)_malloc->Alloc(l); + memcpy(_p, p, l); + } + else + _p = 0; + + _malloc->Free(h); + } + + void operator=(const SHITEMID& o) + { + ITEMIDLIST* h = _p; + + LPBYTE p = (LPBYTE)_malloc->Alloc(o.cb+2); + *(PWORD)((LPBYTE)memcpy(p, &o, o.cb)+o.cb) = 0; + _p = (ITEMIDLIST*)p; + + _malloc->Free(h); + } + + void operator+=(const SHITEMID& o) + { + int l0 = _malloc->GetSize(_p); + LPBYTE p = (LPBYTE)_malloc->Alloc(l0+o.cb); + int l = l0 - 2; + + memcpy(p, _p, l); + *(PWORD)((LPBYTE)memcpy(p+l, &o, o.cb)+o.cb) = 0; + + _malloc->Free(_p); + _p = (ITEMIDLIST*)p; + } + + void assign(ITEMIDLIST* pidl, size_t size) + { + ITEMIDLIST* h = _p; + + _p = (ITEMIDLIST*) _malloc->Alloc(size+sizeof(USHORT/*SHITEMID::cb*/)); + memcpy(_p, pidl, size); + ((ITEMIDLIST*)((LPBYTE)_p+size))->mkid.cb = 0; // terminator + + _malloc->Free(h); + } + + void assign(ITEMIDLIST* pidl) + { + ITEMIDLIST* h = _p; + + if (pidl) { + int l = _malloc->GetSize(pidl); + _p = (ITEMIDLIST*)_malloc->Alloc(l); + memcpy(_p, pidl, l); + } else + _p = 0; + + _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 + + 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)); + } + + ShellFolder get_folder() + { + return ShellFolder(_p); + } + + + // convert an item id list from relative to absolute (=relative to the desktop) format + LPITEMIDLIST create_absolute_pidl(IShellFolder* parent_folder, HWND hwnd) + { + WCHAR buffer[MAX_PATH]; + + HRESULT hr = path_from_pidlW(parent_folder, _p, buffer, MAX_PATH); + + if (SUCCEEDED(hr)) { + LPITEMIDLIST pidl; + ULONG len; + + hr = Desktop()->ParseDisplayName(hwnd, NULL, buffer, &len, &pidl, NULL); + + if (SUCCEEDED(hr)) + return pidl; + } + + return NULL; + } +}; + + +#ifdef __GCC__ // Wine doesn't know of unnamed union members and uses some macros instead. +#define UNION_MEMBER(x) DUMMYUNIONNAME.##x +#else +#define UNION_MEMBER(x) x +#endif + + + // encapsulation of STRRET structure for easy string retrieval with conversion + +#ifdef UNICODE +#define StrRet StrRetW +#define tcscpyn wcscpyn +#else +#define StrRet StrRetA +#define tcscpyn strcpyn +#endif + +extern LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count); +extern LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count); + +struct StrRetA : public STRRET +{ + ~StrRetA() + { + if (uType == STRRET_WSTR) + ShellMalloc()->Free(pOleStr); + } + + void GetString(const SHITEMID& shiid, LPSTR b, int l) + { + switch(uType) { + case STRRET_WSTR: + WideCharToMultiByte(CP_ACP, 0, UNION_MEMBER(pOleStr), -1, b, l, NULL, NULL); + break; + + case STRRET_OFFSET: + strcpyn(b, (LPCSTR)&shiid+UNION_MEMBER(uOffset), l); + break; + + case STRRET_CSTR: + strcpyn(b, UNION_MEMBER(cStr), l); + } + } +}; + +struct StrRetW : public STRRET +{ + ~StrRetW() + { + if (uType == STRRET_WSTR) + ShellMalloc()->Free(pOleStr); + } + + void GetString(const SHITEMID& shiid, LPWSTR b, int l) + { + switch(uType) { + case STRRET_WSTR: + wcscpyn(b, UNION_MEMBER(pOleStr), l); + break; + + case STRRET_OFFSET: + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&shiid+UNION_MEMBER(uOffset), -1, b, l); + break; + + case STRRET_CSTR: + MultiByteToWideChar(CP_ACP, 0, UNION_MEMBER(cStr), -1, b, l); + } + } +}; + + +class FileSysShellPath : public ShellPath +{ + TCHAR _fullpath[MAX_PATH]; + +protected: + FileSysShellPath() {_fullpath[0] = '\0';} + +public: + FileSysShellPath(const ShellPath& o) : ShellPath(o) {_fullpath[0] = '\0';} + + operator LPCTSTR() {SHGetPathFromIDList(_p, _fullpath); return _fullpath;} +}; + + +struct FolderBrowser : public FileSysShellPath +{ + FolderBrowser(HWND owner, UINT flags, LPCTSTR title, LPCITEMIDLIST root=0) + { + _displayname[0] = '\0'; + _browseinfo.hwndOwner = owner; + _browseinfo.pidlRoot = root; + _browseinfo.pszDisplayName = _displayname; + _browseinfo.lpszTitle = title; + _browseinfo.ulFlags = flags; + _browseinfo.lpfn = 0; + _browseinfo.lParam = 0; + _browseinfo.iImage = 0; + + _p = SHBrowseForFolder(&_browseinfo); + } + + LPCTSTR GetDisplayName() + { + return _displayname; + } + + bool IsOK() + { + return _p != 0; + } + +private: + BROWSEINFO _browseinfo; + TCHAR _displayname[MAX_PATH]; +}; + + +struct SpecialFolder : public ShellPath +{ + SpecialFolder(int folder, HWND hwnd) + { + SHGetSpecialFolderLocation(hwnd, folder, &_p); + } +}; + +struct DesktopFolder : public SpecialFolder +{ + DesktopFolder() + : SpecialFolder(CSIDL_DESKTOP, 0) + { + } +}; + + +#if _WIN32_IE>=0x400 // is SHGetSpecialFolderPath() available? + +struct SpecialFolderPath +{ + SpecialFolderPath(int folder/*e.g. CSIDL_DESKTOP*/, HWND hwnd) + { + _fullpath[0] = '\0'; + + SHGetSpecialFolderPath(hwnd, _fullpath, folder, TRUE); + } + + operator LPCTSTR() + { + return _fullpath; + } + +protected: + TCHAR _fullpath[MAX_PATH]; +}; + +#else // _WIN32_IE<0x400 -> use SHGetSpecialFolderLocation() + +struct SpecialFolderPath : public FileSysShellPath +{ + SpecialFolderPath(int folder, HWND hwnd) + { + SHGetSpecialFolderLocation(hwnd, folder, &_p); + } +}; + +#endif + + + // wrapper class for enumerating shell namespace objects + +struct ShellItemEnumerator : public SIfacePtr +{ + ShellItemEnumerator(IShellFolder* folder, DWORD flags=SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN) + { + CheckError(folder->EnumObjects(0, flags, &_p)); + } +}; diff --git a/reactos/subsys/system/explorer/utility/shelltests.cpp b/reactos/subsys/system/explorer/utility/shelltests.cpp new file mode 100644 index 00000000000..8362de8d797 --- /dev/null +++ b/reactos/subsys/system/explorer/utility/shelltests.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // shelltests.cpp + // + // Examples for usage of shellclasses.cpp, shellclasses.h + // + // Martin Fuchs, 20.07.2003 + // + + +#define WIN32_LEAN_AND_MEAN +#define WIN32_EXTRA_LEAN +#include + +#include "shellclasses.h" + + +static void dump_shell_namespace(ShellFolder& folder) +{ + ShellItemEnumerator enumerator(folder, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE); + + LPITEMIDLIST pidl; + HRESULT hr = S_OK; + + do { + ULONG cnt = 0; + + HRESULT hr = enumerator->Next(1, &pidl, &cnt); + + if (!SUCCEEDED(hr)) + break; + + if (hr == S_FALSE) // no more entries? + break; + + if (pidl) { + ULONG attribs = -1; + + HRESULT hr = folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidl, &attribs); + + if (SUCCEEDED(hr)) { + if (attribs == -1) + attribs = 0; + + const string& name = folder.get_name(pidl); + + if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER)) + cout << "folder: "; + else + cout << "file: "; + + cout << "\"" << name << "\"\n attribs=" << hex << attribs << endl; + } + } + } while(SUCCEEDED(hr)); +} + + +int main() +{ + // initialize COM + ComInit usingCOM; + + + HWND hwnd = 0; + + + try { + + // example for retrieval of special folder paths + + SpecialFolderPath programs(CSIDL_PROGRAM_FILES, hwnd); + SpecialFolderPath autostart(CSIDL_STARTUP, hwnd); + + cout << "program files path = " << (LPCTSTR)programs << endl; + cout << "autostart folder path = " << (LPCTSTR)autostart << endl; + + cout << endl; + + + // example for enumerating shell namespace objects + + cout << "Desktop:\n"; + dump_shell_namespace(Desktop()); + cout << endl; + + cout << "C:\\\n"; + dump_shell_namespace(ShellPath("C:\\").get_folder()); + cout << endl; + + + // example for calling a browser dialog for the whole desktop + + FolderBrowser desktop_browser(hwnd, + BIF_RETURNONLYFSDIRS|BIF_EDITBOX|BIF_NEWDIALOGSTYLE, + TEXT("Please select the path:")); + + if (desktop_browser.IsOK()) + MessageBox(hwnd, desktop_browser, TEXT("Your selected path"), MB_OK); + + + // example for calling a rooted browser dialog + + ShellPath browseRoot("C:\\"); + FolderBrowser rooted_browser(hwnd, + BIF_RETURNONLYFSDIRS|BIF_EDITBOX|BIF_VALIDATE, + TEXT("Please select the path:"), + browseRoot); + + if (rooted_browser.IsOK()) + MessageBox(hwnd, rooted_browser, TEXT("Your selected path"), MB_OK); + + } catch(COMException& e) { + + //HandleException(e, hwnd); + cerr << e.ErrorMessage() << endl; + + } + + return 0; +} diff --git a/reactos/subsys/system/explorer/splitpath.c b/reactos/subsys/system/explorer/utility/splitpath.c similarity index 99% rename from reactos/subsys/system/explorer/splitpath.c rename to reactos/subsys/system/explorer/utility/splitpath.c index b08a81e10de..157bed49107 100644 --- a/reactos/subsys/system/explorer/splitpath.c +++ b/reactos/subsys/system/explorer/utility/splitpath.c @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "include/winefile.h" +#include "utility.h" #ifdef UNICODE diff --git a/reactos/subsys/system/explorer/utility/treedroptarget.h b/reactos/subsys/system/explorer/utility/treedroptarget.h new file mode 100644 index 00000000000..753f2ad3367 --- /dev/null +++ b/reactos/subsys/system/explorer/utility/treedroptarget.h @@ -0,0 +1,79 @@ +/************************************************************************** + THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF + ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + PARTICULAR PURPOSE. + Author: Leon Finker 01/2001 + Modifications: removed ATL dependencies, Martin Fuchs 7/2003 +**************************************************************************/ + +#include "dragdropimpl.h" + +class TreeDropTarget : public IDropTargetImpl +{ +public: + TreeDropTarget(HWND hTargetWnd) : IDropTargetImpl(hTargetWnd) {} + + virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD *pdwEffect) + { + if (pFmtEtc->cfFormat == CF_HDROP && medium.tymed == TYMED_HGLOBAL) + { + HDROP hDrop = (HDROP)GlobalLock(medium.hGlobal); + if (hDrop != NULL) + { + TCHAR szFileName[MAX_PATH]; + + UINT cFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); + + for(UINT i = 0; i < cFiles; ++i) + { + DragQueryFile(hDrop, i, szFileName, sizeof(szFileName)); + + if (DROPEFFECT_COPY & *pdwEffect) + { + // copy the file or dir + + //TODO: Add the code to handle Copy + + } + else if (DROPEFFECT_MOVE & *pdwEffect) + { + // move the file or dir + + //TODO: Add the code to handle Move + + } + } + //DragFinish(hDrop); // base class calls ReleaseStgMedium + } + GlobalUnlock(medium.hGlobal); + } + TreeView_SelectDropTarget(m_hTargetWnd, NULL); + return true; //let base free the medium + } + + virtual HRESULT STDMETHODCALLTYPE DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect) + { + TVHITTESTINFO hit; + hit.pt = (POINT&)pt; + ScreenToClient(m_hTargetWnd,&hit.pt); + hit.flags = TVHT_ONITEM; + HTREEITEM hItem = TreeView_HitTest(m_hTargetWnd,&hit); + + if (hItem != NULL) + { + TreeView_SelectDropTarget(m_hTargetWnd, hItem); + } + + return IDropTargetImpl::DragOver(grfKeyState, pt, pdwEffect); + } + + virtual HRESULT STDMETHODCALLTYPE DragLeave(void) + { + TreeView_SelectDropTarget(m_hTargetWnd, NULL); + return IDropTargetImpl::DragLeave(); + } +}; diff --git a/reactos/subsys/system/explorer/utility/utility.cpp b/reactos/subsys/system/explorer/utility/utility.cpp new file mode 100644 index 00000000000..4cf5d6e914d --- /dev/null +++ b/reactos/subsys/system/explorer/utility/utility.cpp @@ -0,0 +1,123 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // utility.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "utility.h" +#include + +#include + + +void display_error(HWND hwnd, DWORD error) +{ + PTSTR msg; + + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) + MessageBox(hwnd, msg, TEXT("Winefile"), MB_OK); + else + MessageBox(hwnd, TEXT("Error"), TEXT("Winefile"), MB_OK); + + LocalFree(msg); +} + + +BOOL time_to_filetime(const time_t* t, FILETIME* ftime) +{ + struct tm* tm = gmtime(t); + SYSTEMTIME stime; + + if (!tm) + return FALSE; + + stime.wYear = tm->tm_year+1900; + stime.wMonth = tm->tm_mon+1; + /* stime.wDayOfWeek */ + stime.wDay = tm->tm_mday; + stime.wHour = tm->tm_hour; + stime.wMinute = tm->tm_min; + stime.wSecond = tm->tm_sec; + + return SystemTimeToFileTime(&stime, ftime); +} + + +BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow) +{ + HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, NULL/*parameters*/, NULL/*dir*/, nCmdShow); + + if ((int)hinst <= 32) { + display_error(hwnd, GetLastError()); + return FALSE; + } + + return TRUE; +} + +#ifdef UNICODE +BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow) +{ + HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, NULL/*parameters*/, NULL/*dir*/, nCmdShow); + + if ((int)hinst <= 32) { + display_error(hwnd, GetLastError()); + return FALSE; + } + + return TRUE; +} +#endif + + +/* search for already running win[e]files */ + +static int g_foundPrevInstance = 0; + +static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lparam) +{ + TCHAR cls[128]; + + GetClassName(hwnd, cls, 128); + + if (!lstrcmp(cls, (LPCTSTR)lparam)) { + g_foundPrevInstance++; + return FALSE; + } + + return TRUE; +} + +/* search for window of given class name to allow only one running instance */ +int find_window_class(LPCTSTR classname) +{ + EnumWindows(EnumWndProc, (LPARAM)classname); + + if (g_foundPrevInstance) + return 1; + + return 0; +} diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h new file mode 100644 index 00000000000..91d565b1fa2 --- /dev/null +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -0,0 +1,157 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // utility.h + // + // Martin Fuchs, 23.07.2003 + // + + + // standard windows headers +#define WIN32_LEAN_AND_MEAN +#define WIN32_EXTRA_LEAN +#include + + // Unicode support +#ifdef UNICODE +#define _UNICODE +#endif +#include + +#include // for SelectBrush(), ListBox_SetSel(), SubclassWindow(), ... +#include + +#include // for alloca() +#include +#include + + +#ifdef __cplusplus + + // STL headers for strings and streams +#include +#include +using namespace std; + +#if defined(_MSC_VER) && !defined(_NO_COMUTIL) + + // COM utility headers +#include +using namespace _com_util; + +#endif // _MSC_VER + + +struct CommonControlInit +{ + CommonControlInit(DWORD flags=ICC_LISTVIEW_CLASSES) + { + INITCOMMONCONTROLSEX icc = {sizeof(INITCOMMONCONTROLSEX), flags}; + + InitCommonControlsEx(&icc); + } +}; + + +struct WaitCursor +{ + WaitCursor() + { + _old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + } + + ~WaitCursor() + { + SetCursor(_old_cursor); + } + +protected: + HCURSOR _old_cursor; +}; + + +struct FullScreenParameters { + FullScreenParameters() + : _mode(FALSE) + { + } + + BOOL _mode; + RECT _orgPos; + BOOL _wasZoomed; +}; + + +#endif // __cplusplus + + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef _MSC_VER +#define LONGLONGARG TEXT("I64") +#else +#define LONGLONGARG TEXT("L") +#endif + + +#ifndef _tcsrchr +#ifdef UNICODE +#define _tcsrchr wcsrchr +#else +#define _tcsrchr strrchr +#endif +#endif + +#ifndef _stprintf +#ifdef UNICODE +#define _stprintf wcsrintf +#else +#define _stprintf sprintf +#endif +#endif + + + // display +extern void display_error(HWND hwnd, DWORD error); + + // convert time_t to WIN32 FILETIME +extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime); + + // search for windows of a specific classname +extern int find_window_class(LPCTSTR classname); + + // launch a program or document file +extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow); +#ifdef UNICODE +extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow); +#else +#define launch_fileA launch_file +#endif + + +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp new file mode 100644 index 00000000000..1fd2479a43a --- /dev/null +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -0,0 +1,333 @@ +/* + * Copyright 2003 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // + // Explorer clone + // + // window.cpp + // + // Martin Fuchs, 23.07.2003 + // + + +#include "utility.h" +#include "window.h" + +#include "../globals.h" + + +WindowClass::WindowClass(LPCTSTR classname, WNDPROC wndproc) +{ + memset(this, 0, sizeof(WNDCLASSEX)); + + cbSize = sizeof(WNDCLASSEX); + hInstance = g_Globals._hInstance; + + lpszClassName = classname; + lpfnWndProc = wndproc; +} + + +HHOOK Window::s_hcbthook = 0; +Window::WindowCreatorFunc Window::s_window_creator = NULL; +const void* Window::s_new_info = NULL; + + +HWND Window::Create(WindowCreatorFunc creator, + DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, + DWORD dwStyle, int x, int y, int w, int h, + HWND hwndParent, HMENU hMenu, LPVOID lpParam) +{ + s_window_creator = creator; + s_new_info = NULL; + + return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, + x, y, w, h, + hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); +} + +HWND Window::Create(WindowCreatorFunc creator, const void* info, + DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, + DWORD dwStyle, int x, int y, int w, int h, + HWND hwndParent, HMENU hMenu, LPVOID lpParam) +{ + s_window_creator = creator; + s_new_info = info; + + return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, + x, y, w, h, + hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); +} + + +static Window* s_new_child_wnd = NULL; + +Window* Window::create_mdi_child(HWND hmdiclient, const MDICREATESTRUCT& mcs, WindowCreatorFunc creator, const void* info) +{ + s_window_creator = creator; + s_new_info = info; + s_new_child_wnd = NULL; + + s_hcbthook = SetWindowsHookEx(WH_CBT, CBTHookProc, 0, GetCurrentThreadId()); + + HWND hwnd = (HWND) SendMessage(hmdiclient, WM_MDICREATE, 0, (LPARAM)&mcs); + + UnhookWindowsHookEx(s_hcbthook); + + Window* child = s_new_child_wnd; + s_new_info = NULL; + s_new_child_wnd = NULL; + + if (!hwnd || !child || !child->_hwnd) + child = NULL; + + return child; +} + +LRESULT CALLBACK Window::CBTHookProc(int code, WPARAM wparam, LPARAM lparam) +{ + if (code == HCBT_CREATEWND) { + // create Window controller and associate it with the window handle + Window* child = get_window((HWND)wparam); + + if (child) + s_new_child_wnd = child; + } + + return CallNextHookEx(s_hcbthook, code, wparam, lparam); +} + + + // get window controller from window handle + // if not already present, create a new controller + +Window* Window::get_window(HWND hwnd) +{ + Window* wnd = (Window*) GetWindowLong(hwnd, GWL_USERDATA); + + if (wnd) + return wnd; + + if (s_window_creator) { // protect for recursion + const void* info = s_new_info; + s_new_info = NULL; + + WindowCreatorFunc window_creator = s_window_creator; + s_window_creator = NULL; + + wnd = window_creator(hwnd, info); + } + + return wnd; +} + + +LRESULT CALLBACK Window::WndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + Window* pThis = get_window(hwnd); + + if (pThis) { + switch(nmsg) { + case WM_NCDESTROY: + delete pThis; + return 0; + + case WM_COMMAND: + pThis->Command(LOWORD(wparam), HIWORD(wparam)); + return 0; + + case WM_NOTIFY: + return pThis->Notify(wparam, (NMHDR*)lparam); + } + + return pThis->WndProc(nmsg, wparam, lparam); + } + else + return DefWindowProc(hwnd, nmsg, wparam, lparam); +} + +LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + return DefWindowProc(_hwnd, nmsg, wparam, lparam); +} + +int Window::Command(int id, int code) +{ + return 0; +} + +int Window::Notify(int id, NMHDR* pnmh) +{ + return 0; +} + + +ChildWindow::ChildWindow(HWND hwnd) + : Window(hwnd) +{ + _left_hwnd = 0; + _right_hwnd = 0; + + _focus_pane = 0; + _split_pos = DEFAULT_SPLIT_POS; + _last_split = DEFAULT_SPLIT_POS; +} + + +ChildWindow* ChildWindow::create(HWND hmdiclient, const RECT& rect, WindowCreatorFunc creator, LPCTSTR classname, LPCTSTR title) +{ + MDICREATESTRUCT mcs; + + mcs.szClass = classname; + mcs.szTitle = title; + mcs.hOwner = g_Globals._hInstance; + mcs.x = rect.left, + mcs.y = rect.top; + mcs.cx = rect.right - rect.left; + mcs.cy = rect.bottom - rect.top; + mcs.style = 0; + mcs.lParam = 0; + + return static_cast(create_mdi_child(hmdiclient, mcs, creator)); +} + + +LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_PAINT: { + PAINTSTRUCT ps; + HBRUSH lastBrush; + RECT rt; + GetClientRect(_hwnd, &rt); + BeginPaint(_hwnd, &ps); + rt.left = _split_pos-SPLIT_WIDTH/2; + rt.right = _split_pos+SPLIT_WIDTH/2+1; + lastBrush = SelectBrush(ps.hdc, (HBRUSH)GetStockObject(COLOR_SPLITBAR)); + Rectangle(ps.hdc, rt.left, rt.top-1, rt.right, rt.bottom+1); + SelectObject(ps.hdc, lastBrush); + EndPaint(_hwnd, &ps); + break;} + + case WM_SETCURSOR: + if (LOWORD(lparam) == HTCLIENT) { + POINT pt; + GetCursorPos(&pt); + ScreenToClient(_hwnd, &pt); + + if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) { + SetCursor(LoadCursor(0, IDC_SIZEWE)); + return TRUE; + } + } + goto def; + + case WM_SIZE: + if (wparam != SIZE_MINIMIZED) + resize_children(LOWORD(lparam), HIWORD(lparam)); + goto def; + + case WM_GETMINMAXINFO: + DefMDIChildProc(_hwnd, nmsg, wparam, lparam); + + {LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam; + + lpmmi->ptMaxTrackSize.x <<= 1; // 2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN + lpmmi->ptMaxTrackSize.y <<= 1; // 2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN + break;} + + case WM_LBUTTONDOWN: { + RECT rt; + int x = LOWORD(lparam); + + GetClientRect(_hwnd, &rt); + + if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) { + _last_split = _split_pos; + SetCapture(_hwnd); + } + + break;} + + case WM_LBUTTONUP: + if (GetCapture() == _hwnd) + ReleaseCapture(); + break; + + case WM_KEYDOWN: + if (wparam == VK_ESCAPE) + if (GetCapture() == _hwnd) { + _split_pos = _last_split; + RECT rt; GetClientRect(_hwnd, &rt); + resize_children(rt.right, rt.bottom); + _last_split = -1; + ReleaseCapture(); + SetCursor(LoadCursor(0, IDC_ARROW)); + } + break; + + case WM_MOUSEMOVE: + if (GetCapture() == _hwnd) { + int x = LOWORD(lparam); + + RECT rt; + GetClientRect(_hwnd, &rt); + + if (x>=0 && x struct WindowCreator +{ + static WND_CLASS* window_creator(HWND hwnd) + { + return new WND_CLASS(hwnd); + } +}; + +#define WINDOW_CREATOR(WND_CLASS) \ + (Window::WindowCreatorFunc) WindowCreator::window_creator + + +template struct WindowCreatorInfo +{ + static WND_CLASS* window_creator(HWND hwnd, const void* info) + { + return new WND_CLASS(hwnd, *static_cast(info)); + } +}; + +#define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \ + (Window::WindowCreatorFunc) WindowCreatorInfo::window_creator + + +struct WindowClass : public WNDCLASSEX +{ + WindowClass(LPCTSTR classname, WNDPROC wndproc=Window::WndProc); + + ATOM Register() + { + return RegisterClassEx(this); + } +}; + + +#define WM_DISPATCH_COMMAND (WM_APP+0) + + +#define SPLIT_WIDTH 5 +#define DEFAULT_SPLIT_POS 300 +#define COLOR_SPLITBAR LTGRAY_BRUSH + + +struct MenuInfo +{ + HMENU _hMenuView; + HMENU _hMenuOptions; +}; + +#define FRM_GET_MENUINFO (WM_APP+1) + +#define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, FRM_GET_MENUINFO, 0, 0)) + + +struct ChildWindow : public Window +{ + typedef Window super; + + ChildWindow(HWND hwnd); + + static ChildWindow* create(HWND hmdiclient, const RECT& rect, + WindowCreatorFunc creator, LPCTSTR classname, LPCTSTR title=NULL); + +protected: + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + + virtual void resize_children(int cx, int cy); + +protected: + MenuInfo*_menu_info; + + HWND _left_hwnd; + HWND _right_hwnd; + int _focus_pane; // 0: left 1: right + + int _split_pos; + int _last_split; +}; diff --git a/reactos/subsys/system/explorer/De.rc b/reactos/subsys/system/explorer/winefile/de.rc similarity index 100% rename from reactos/subsys/system/explorer/De.rc rename to reactos/subsys/system/explorer/winefile/de.rc diff --git a/reactos/subsys/system/explorer/desktop.c b/reactos/subsys/system/explorer/winefile/desktop.c similarity index 61% rename from reactos/subsys/system/explorer/desktop.c rename to reactos/subsys/system/explorer/winefile/desktop.c index 23bc86b362a..f977731d081 100644 --- a/reactos/subsys/system/explorer/desktop.c +++ b/reactos/subsys/system/explorer/winefile/desktop.c @@ -8,14 +8,34 @@ #include #include -#include "include/explorer.h" +#include "../utility/utility.h" + +#include "../externals.h" -const TCHAR DesktopClassName[] = TEXT("DesktopWindow"); +/* GetShellWindow is already present in the header files +static HWND (WINAPI*GetShellWindow)(); */ +static BOOL (WINAPI*SetShellWindow)(HWND); -HWND (WINAPI*GetShellWindow)(); -void (WINAPI*SetShellWindow)(HWND); +BOOL IsAnyDesktopRunning() +{ +/* POINT pt;*/ + HINSTANCE shell32 = GetModuleHandle(TEXT("user32")); + + SetShellWindow = (BOOL(WINAPI*)(HWND)) GetProcAddress(shell32, "SetShellWindow"); + +/* GetShellWindow is already present in the header files + GetShellWindow = (HWND(WINAPI*)()) GetProcAddress(shell32, "GetShellWindow"); + + if (GetShellWindow) */ + return GetShellWindow() != 0; +/* + pt.x = 0; + pt.y = 0; + + return WindowFromPoint(pt) != GetDesktopWindow(); */ +} LRESULT CALLBACK DeskWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -66,7 +86,7 @@ LRESULT CALLBACK DeskWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } case WM_LBUTTONDBLCLK: - ShowFileMgr(hwnd, SW_SHOWNORMAL); + explorer_show_frame(hwnd, SW_SHOWNORMAL); break; case WM_DESTROY: @@ -82,70 +102,78 @@ LRESULT CALLBACK DeskWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } -BOOL IsAnyDesktopRunning() +const TCHAR DesktopClassName[] = TEXT("DesktopWindow"); + + +HWND create_desktop_window(HINSTANCE hInstance) { - POINT pt; - HINSTANCE shell32 = GetModuleHandle(TEXT("user32")); + WNDCLASSEX wc; + HWND hwndDesktop; + int Width, Height; - GetShellWindow = (HWND(WINAPI*)()) GetProcAddress(shell32, "GetShellWindow"); - SetShellWindow = (void(WINAPI*)(HWND)) GetProcAddress(shell32, "SetShellWindow"); + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_DBLCLKS; + wc.lpfnWndProc = &DeskWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground= (HBRUSH) GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName= DesktopClassName; + wc.hIconSm = NULL; - if (GetShellWindow) - return GetShellWindow() != 0; + if (!RegisterClassEx(&wc)) + return 0; - pt.x = 0; - pt.y = 0; + Width = GetSystemMetrics(SM_CXSCREEN); + Height = GetSystemMetrics(SM_CYSCREEN); - return WindowFromPoint(pt) != GetDesktopWindow(); + hwndDesktop = CreateWindowEx(0, DesktopClassName, TEXT("Desktop"), + WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN, + 0, 0, Width, Height, + NULL, NULL, hInstance, NULL); + + if (SetShellWindow) + SetShellWindow(hwndDesktop); + + return hwndDesktop; } +#ifdef _CONSOLE int main(int argc, char *argv[]) +#else +int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) +#endif { - int Width, Height; - WNDCLASSEX wc; + int ret; HWND hwndDesktop = 0; +#ifdef _CONSOLE STARTUPINFO startupinfo; - int nCmdShow = SW_SHOWNORMAL; + int nShowCmd = SW_SHOWNORMAL; HINSTANCE hInstance = GetModuleHandle(NULL); +#endif // create desktop window and task bar only, if there is no other shell and we are // the first explorer instance (just in case SetShellWindow() is not supported by the OS) BOOL startup_desktop = !IsAnyDesktopRunning() && !find_window_class(DesktopClassName); +#ifdef _CONSOLE if (argc>1 && !strcmp(argv[1],"-desktop")) +#else + if (!lstrcmp(lpCmdLine,TEXT("-desktop"))) +#endif startup_desktop = TRUE; if (startup_desktop) { HWND hwndExplorerBar; - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_DBLCLKS; - wc.lpfnWndProc = &DeskWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground= (HBRUSH) GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName= DesktopClassName; - wc.hIconSm = NULL; - - if (!RegisterClassEx(&wc)) - return 1; // error - - - Width = GetSystemMetrics(SM_CXSCREEN); - Height = GetSystemMetrics(SM_CYSCREEN); - - hwndDesktop = CreateWindowEx(0, DesktopClassName, TEXT("Desktop"), - WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN, - 0, 0, Width, Height, - NULL, NULL, hInstance, NULL); + hwndDesktop = create_desktop_window(hInstance); if (!hwndDesktop) { @@ -153,32 +181,42 @@ int main(int argc, char *argv[]) return 1; // error } - if (SetShellWindow) - SetShellWindow(hwndDesktop); - +#ifdef _CONSOLE // call winefile startup routine GetStartupInfo(&startupinfo); if (startupinfo.dwFlags & STARTF_USESHOWWINDOW) - nCmdShow = startupinfo.wShowWindow; + nShowCmd = startupinfo.wShowWindow; +#endif // Initializing the Explorer Bar - if (!(hwndExplorerBar=InitializeExplorerBar(hInstance, nCmdShow))) + if (!(hwndExplorerBar=InitializeExplorerBar(hInstance, nShowCmd))) { fprintf(stderr,"FATAL: Explorer bar could not be initialized properly ! Exiting !\n"); return 1; } // Load plugins - if (!ExplorerLoadPlugins(hwndExplorerBar)) + if (!LoadAvailablePlugIns(hwndExplorerBar)) { fprintf(stderr,"WARNING: No plugin for desktop bar could be loaded.\n"); } #ifndef _DEBUG //MF: disabled for debugging +#ifdef _CONSOLE startup(argc, argv); // invoke the startup groups +#else + { + char* argv[] = {""}; + startup(1, argv); + } +#endif #endif } - return winefile_main(hInstance, hwndDesktop, nCmdShow); + ret = explorer_main(hInstance, hwndDesktop, nShowCmd); + + ReleaseAvailablePlugIns(); + + return ret; } diff --git a/reactos/subsys/system/explorer/En.rc b/reactos/subsys/system/explorer/winefile/en.rc similarity index 100% rename from reactos/subsys/system/explorer/En.rc rename to reactos/subsys/system/explorer/winefile/en.rc diff --git a/reactos/subsys/system/explorer/winefile/explorer.rc b/reactos/subsys/system/explorer/winefile/explorer.rc new file mode 100644 index 00000000000..197bd89c8f7 --- /dev/null +++ b/reactos/subsys/system/explorer/winefile/explorer.rc @@ -0,0 +1,39 @@ +#include +#include +#include "winefile.rc" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "ReactOS Explorer\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "explorer\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "explorer.exe\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/reactos/subsys/system/explorer/license.c b/reactos/subsys/system/explorer/winefile/license.c similarity index 100% rename from reactos/subsys/system/explorer/license.c rename to reactos/subsys/system/explorer/winefile/license.c diff --git a/reactos/subsys/system/explorer/include/license.h b/reactos/subsys/system/explorer/winefile/license.h similarity index 100% rename from reactos/subsys/system/explorer/include/license.h rename to reactos/subsys/system/explorer/winefile/license.h diff --git a/reactos/subsys/system/explorer/winefile/make_winefile.dsp b/reactos/subsys/system/explorer/winefile/make_winefile.dsp new file mode 100644 index 00000000000..0fa9ff0947d --- /dev/null +++ b/reactos/subsys/system/explorer/winefile/make_winefile.dsp @@ -0,0 +1,89 @@ +# Microsoft Developer Studio Project File - Name="make_explorer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=make_explorer - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "make_explorer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "make_explorer.mak" CFG="make_explorer - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "make_explorer - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "make_explorer - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "make_explorer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f make_explorer.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "make_explorer.exe" +# PROP BASE Bsc_Name "make_explorer.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "make 2>&1 | perl d:\tools\gSTLFilt.pl | javac2vc " +# PROP Rebuild_Opt "clean all" +# PROP Target_File "explorer.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "make_explorer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f make_explorer.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "make_explorer.exe" +# PROP BASE Bsc_Name "make_explorer.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "make 2>&1 | perl d:\tools\gSTLFilt.pl | javac2vc " +# PROP Rebuild_Opt "clean all" +# PROP Target_File "explorer.exe" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "make_explorer - Win32 Release" +# Name "make_explorer - Win32 Debug" + +!IF "$(CFG)" == "make_explorer - Win32 Release" + +!ELSEIF "$(CFG)" == "make_explorer - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\makefile +# End Source File +# End Target +# End Project diff --git a/reactos/subsys/system/explorer/winefile/makefile b/reactos/subsys/system/explorer/winefile/makefile new file mode 100644 index 00000000000..13c45b79072 --- /dev/null +++ b/reactos/subsys/system/explorer/winefile/makefile @@ -0,0 +1,58 @@ +# +# ReactOS winfile explorer +# +# Makefile +# + +PATH_TO_TOP = ../../../.. + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = explorer + +TARGET_CFLAGS = -fexceptions -O2 -DNDEBUG -DWIN32 -D_ROS_ -W + +TARGET_RCFLAGS = -DNDEBUG -DWIN32 -D_ROS_ + +ifdef UNICODE +TARGET_CFLAGS += -DUNICODE +TARGET_CPPFLAGS += -DUNICODE +MK_DEFENTRY := _wWinMain@16 +endif + +VPATH += ../utility +VPATH += ../shell +VPATH += ../taskbar + +WINE_MODE = yes + +WINE_RC = $(TARGET_NAME) + +WINE_INCLUDE = ./ + +TARGET_GCCLIBS = comctl32 ole32 uuid + +TARGET_SDKLIBS = \ + kernel32.a \ + user32.a \ + gdi32.a \ + advapi32.a \ + version.a + +TARGET_OBJECTS = \ + desktop.o \ + ex_bar.o \ + ex_clock.o \ + ex_menu.o \ + ex_shutdwn.o \ + license.o \ + startup.o \ + winefile.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/reactos/subsys/system/explorer/include/resource.h b/reactos/subsys/system/explorer/winefile/resource.h similarity index 95% rename from reactos/subsys/system/explorer/include/resource.h rename to reactos/subsys/system/explorer/winefile/resource.h index 6996df2bcad..4fa91ee2c91 100644 --- a/reactos/subsys/system/explorer/include/resource.h +++ b/reactos/subsys/system/explorer/winefile/resource.h @@ -58,18 +58,20 @@ #define ID_HELP_USING 0xE144 #define ID_HELP 0xE146 -/* range for drive bar command ids: 0x9000..0x90FF */ -#define ID_DRIVE_FIRST 0x9001 - /* winefile extensions */ #define ID_ABOUT_WINE 0x8000 -#define ID_LICENSE 0x8001 +#define ID_LICENSE 0x8001 #define ID_NO_WARRANTY 0x8002 #define ID_WINDOW_AUTOSORT 0x8003 #define ID_VIEW_FULLSCREEN 0x8004 #define ID_PREFERED_SIZES 0x8005 + +/* range for drive bar command ids: 0x9000..0x90FF */ #ifdef __linux__ #define ID_DRIVE_UNIX_FS 0x9000 #endif +#define ID_DRIVE_SHELL_NS 0x9001 + +#define ID_DRIVE_FIRST 0x9002 diff --git a/reactos/subsys/system/explorer/resource.rc b/reactos/subsys/system/explorer/winefile/resource.rc similarity index 99% rename from reactos/subsys/system/explorer/resource.rc rename to reactos/subsys/system/explorer/winefile/resource.rc index 5446e639c15..a9c7f579682 100644 --- a/reactos/subsys/system/explorer/resource.rc +++ b/reactos/subsys/system/explorer/winefile/resource.rc @@ -30,7 +30,7 @@ IDA_WINEFILE ACCELERATORS DISCARDABLE IDI_WINEFILE ICON DISCARDABLE #ifdef _WIN32 - "res/winefile.ico" + "../res/winefile.ico" #else { '00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02' @@ -86,7 +86,7 @@ IDI_WINEFILE ICON DISCARDABLE IDB_TOOLBAR BITMAP DISCARDABLE #ifdef _WIN32 - "res/toolbar.bmp" + "../res/toolbar.bmp" #else { '42 4D BE 03 00 00 00 00 00 00 76 00 00 00 28 00' @@ -154,7 +154,7 @@ IDB_TOOLBAR BITMAP DISCARDABLE IDB_DRIVEBAR BITMAP DISCARDABLE #ifdef _WIN32 - "res/drivebar.bmp" + "../res/drivebar.bmp" #else { '42 4D E6 02 00 00 00 00 00 00 76 00 00 00 28 00' @@ -209,7 +209,7 @@ IDB_DRIVEBAR BITMAP DISCARDABLE IDB_IMAGES BITMAP DISCARDABLE #ifdef _WIN32 - "res/images.bmp" + "../res/images.bmp" #else { '42 4D 86 04 00 00 00 00 00 00 76 00 00 00 28 00' diff --git a/reactos/subsys/system/explorer/winefile/wine_explore.dsp b/reactos/subsys/system/explorer/winefile/wine_explore.dsp new file mode 100644 index 00000000000..a62c3487857 --- /dev/null +++ b/reactos/subsys/system/explorer/winefile/wine_explore.dsp @@ -0,0 +1,343 @@ +# Microsoft Developer Studio Project File - Name="wine_explore" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=wine_explore - Win32 Unicode Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "wine_explore.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "wine_explore.mak" CFG="wine_explore - Win32 Unicode Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "wine_explore - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "wine_explore - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "wine_explore - Win32 Debug Release" (based on "Win32 (x86) Console Application") +!MESSAGE "wine_explore - Win32 Unicode Release" (based on "Win32 (x86) Console Application") +!MESSAGE "wine_explore - Win32 Unicode Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.cmd +RSC=rc.exe + +!IF "$(CFG)" == "wine_explore - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /YX /FD /c +# ADD BASE RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /i ".." /d "NDEBUG" /d "_WINEFILE_" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.cmd +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x407 /d "_DEBUG" +# ADD RSC /l 0x407 /i ".." /d "_DEBUG" /d "_WINEFILE_" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.cmd +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "wineExplorer___Win32_Debug_Release" +# PROP BASE Intermediate_Dir "wineExplorer___Win32_Debug_Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "DRelease" +# PROP Intermediate_Dir "DRelease" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /YX /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /FR /YX /FD /c +# ADD BASE RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /i ".." /d "NDEBUG" /d "_WINEFILE_" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.cmd +# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "wineExplorer___Win32_Unicode_Release" +# PROP BASE Intermediate_Dir "wineExplorer___Win32_Unicode_Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "." +# PROP Intermediate_Dir "URelease" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c +# ADD BASE RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /i ".." /d "NDEBUG" /d "_WINEFILE_" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.cmd +# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "wineExplorer___Win32_Unicode_Debug" +# PROP BASE Intermediate_Dir "wineExplorer___Win32_Unicode_Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "UDebug" +# PROP Intermediate_Dir "UDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x407 /d "_DEBUG" +# ADD RSC /l 0x407 /i ".." /d "_DEBUG" /d "_WINEFILE_" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.cmd +# ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "wine_explore - Win32 Release" +# Name "wine_explore - Win32 Debug" +# Name "wine_explore - Win32 Debug Release" +# Name "wine_explore - Win32 Unicode Release" +# Name "wine_explore - Win32 Unicode Debug" +# Begin Group "resources" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\de.rc + +!IF "$(CFG)" == "wine_explore - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Release" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\res\drivebar.bmp +# End Source File +# Begin Source File + +SOURCE=.\en.rc + +!IF "$(CFG)" == "wine_explore - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Release" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\res\images.bmp +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc + +!IF "$(CFG)" == "wine_explore - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Debug Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Release" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "wine_explore - Win32 Unicode Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\res\toolbar.bmp +# End Source File +# Begin Source File + +SOURCE=..\res\winefile.ico +# End Source File +# Begin Source File + +SOURCE=.\winefile.rc +# End Source File +# End Group +# Begin Group "plugins" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\taskbar\ex_bar.c +# End Source File +# Begin Source File + +SOURCE=..\taskbar\ex_bar.h +# End Source File +# Begin Source File + +SOURCE=..\taskbar\ex_clock.c +# End Source File +# Begin Source File + +SOURCE=..\taskbar\ex_menu.c +# End Source File +# Begin Source File + +SOURCE=..\taskbar\ex_shutdwn.c +# End Source File +# End Group +# Begin Source File + +SOURCE=.\desktop.c +# End Source File +# Begin Source File + +SOURCE=..\externals.h +# End Source File +# Begin Source File + +SOURCE=..\explorer.h +# End Source File +# Begin Source File + +SOURCE=.\makefile +# End Source File +# Begin Source File + +SOURCE=..\shell\startup.c +# End Source File +# Begin Source File + +SOURCE=..\utility\utility.h +# End Source File +# Begin Source File + +SOURCE=.\winefile.c +# End Source File +# Begin Source File + +SOURCE=.\winefile.h +# End Source File +# End Target +# End Project diff --git a/reactos/subsys/system/explorer/winefile/wine_explore.dsw b/reactos/subsys/system/explorer/winefile/wine_explore.dsw new file mode 100644 index 00000000000..159609927fa --- /dev/null +++ b/reactos/subsys/system/explorer/winefile/wine_explore.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "make_explorer"=.\make_winefile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "wine_explore"=.\wine_explore.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/reactos/subsys/system/explorer/winefile.c b/reactos/subsys/system/explorer/winefile/winefile.c similarity index 70% rename from reactos/subsys/system/explorer/winefile.c rename to reactos/subsys/system/explorer/winefile/winefile.c index cff853d7336..631be58c16f 100644 --- a/reactos/subsys/system/explorer/winefile.c +++ b/reactos/subsys/system/explorer/winefile/winefile.c @@ -23,10 +23,14 @@ #include "wine/port.h" #endif -#include "include/winefile.h" -#include "include/resource.h" +#include -#include "include/explorer.h" +#include "winefile.h" +#include "resource.h" + +#ifdef _ROS_ +#include "../externals.h" +#endif /* for read_directory_unix() */ @@ -49,26 +53,53 @@ #define _MAX_PATH 260 #endif +#ifdef __linux__ +#define UNION_MEMBER(x) DUMMYUNIONNAME.##x +#else +#define UNION_MEMBER(x) x +#endif + + +#ifdef _SHELL_FOLDERS +#define DEFAULT_SPLIT_POS 300 +#else +#define DEFAULT_SPLIT_POS 200 +#endif + + WINEFILE_GLOBALS Globals; extern void WineLicense(HWND hwnd); extern void WineWarranty(HWND hwnd); +enum ENTRY_TYPE { + ET_WINDOWS, + ET_UNIX, +#ifdef _SHELL_FOLDERS + ET_SHELL +#endif +}; + typedef struct _Entry { struct _Entry* next; struct _Entry* down; struct _Entry* up; - BOOL expanded; - BOOL scanned; - int level; + BOOL expanded; + BOOL scanned; + int level; WIN32_FIND_DATA data; #ifndef _NO_EXTENSIONS BY_HANDLE_FILE_INFORMATION bhfi; - BOOL bhfi_valid; - BOOL unix_dir; + BOOL bhfi_valid; + enum ENTRY_TYPE etype; +#endif +#ifdef _SHELL_FOLDERS + LPITEMIDLIST pidl; + IShellFolder* folder; + HICON hicon; #endif } Entry; @@ -139,8 +170,8 @@ typedef struct { } ChildWnd; -static void read_directory(Entry* parent, LPCTSTR path, int sortOrder); -static void set_curdir(ChildWnd* child, Entry* entry); +static void read_directory(Entry* dir, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd); +static void set_curdir(ChildWnd* child, Entry* entry, HWND hwnd); LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam); @@ -153,19 +184,72 @@ static void display_error(HWND hwnd, DWORD error) if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) - MessageBox(hwnd, msg, _T("Winefile"), MB_OK); + MessageBox(hwnd, msg, TEXT("Winefile"), MB_OK); else - MessageBox(hwnd, _T("Error"), _T("Winefile"), MB_OK); + MessageBox(hwnd, TEXT("Error"), TEXT("Winefile"), MB_OK); LocalFree(msg); } -static void read_directory_win(Entry* parent, LPCTSTR path) +/* allocate and initialise a directory entry */ +static Entry* alloc_entry() { Entry* entry = (Entry*) malloc(sizeof(Entry)); - int level = parent->level + 1; - Entry* last = 0; + +#ifdef _SHELL_FOLDERS + entry->pidl = NULL; + entry->folder = NULL; + entry->hicon = 0; +#endif + + return entry; +} + +/* free a directory entry */ +static void free_entry(Entry* entry) +{ +#ifdef _SHELL_FOLDERS + if (entry->hicon && entry->hicon!=(HICON)-1) + DestroyIcon(entry->hicon); + + if (entry->folder && entry->folder!=Globals.iDesktop) + (*entry->folder->lpVtbl->Release)(entry->folder); + + if (entry->pidl) + (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, entry->pidl); +#endif + + free(entry); +} + +/* recursively free all child entries */ +static void free_entries(Entry* dir) +{ + Entry *entry, *next=dir->down; + + if (next) { + dir->down = 0; + + do { + entry = next; + next = entry->next; + + free_entries(entry); + free_entry(entry); + } while(next); + } +} + + +static void read_directory_win(Entry* dir, LPCTSTR path) +{ + Entry* first_entry = NULL; + Entry* last = NULL; + Entry* entry; + + int level = dir->level + 1; + WIN32_FIND_DATA w32fd; HANDLE hFind; #ifndef _NO_EXTENSIONS HANDLE hFile; @@ -175,16 +259,23 @@ static void read_directory_win(Entry* parent, LPCTSTR path) for(p=buffer; *path; ) *p++ = *path++; - lstrcpy(p, _T("\\*")); + lstrcpy(p, TEXT("\\*")); - hFind = FindFirstFile(buffer, &entry->data); + hFind = FindFirstFile(buffer, &w32fd); if (hFind != INVALID_HANDLE_VALUE) { - parent->down = entry; - do { - entry->down = 0; - entry->up = parent; + entry = alloc_entry(); + + if (!first_entry) + first_entry = entry; + + if (last) + last->next = entry; + + memcpy(&entry->data, &w32fd, sizeof(WIN32_FIND_DATA)); + entry->down = NULL; + entry->up = dir; entry->expanded = FALSE; entry->scanned = FALSE; entry->level = level; @@ -198,7 +289,7 @@ static void read_directory_win(Entry* parent, LPCTSTR path) continue; } #else - entry->unix_dir = FALSE; + entry->etype = ET_WINDOWS; entry->bhfi_valid = FALSE; lstrcpy(p+1, entry->data.cFileName); @@ -215,35 +306,28 @@ static void read_directory_win(Entry* parent, LPCTSTR path) #endif last = entry; - - entry = (Entry*) malloc(sizeof(Entry)); - - if (last) - last->next = entry; } while(FindNextFile(hFind, &entry->data)); - last->next = 0; + last->next = NULL; FindClose(hFind); - } else - parent->down = 0; + } - free(entry); - - parent->scanned = TRUE; + dir->down = first_entry; + dir->scanned = TRUE; } -static Entry* find_entry_win(Entry* parent, LPCTSTR name) +static Entry* find_entry_win(Entry* dir, LPCTSTR name) { Entry* entry; - for(entry=parent->down; entry; entry=entry->next) { + for(entry=dir->down; entry; entry=entry->next) { LPCTSTR p = name; LPCTSTR q = entry->data.cFileName; do { - if (!*p || *p==_T('\\') || *p==_T('/')) + if (!*p || *p==TEXT('\\') || *p==TEXT('/')) return entry; } while(tolower(*p++) == tolower(*q++)); @@ -251,7 +335,7 @@ static Entry* find_entry_win(Entry* parent, LPCTSTR name) q = entry->data.cAlternateFileName; do { - if (!*p || *p==_T('\\') || *p==_T('/')) + if (!*p || *p==TEXT('\\') || *p==TEXT('/')) return entry; } while(tolower(*p++) == tolower(*q++)); } @@ -260,28 +344,30 @@ static Entry* find_entry_win(Entry* parent, LPCTSTR name) } -static Entry* read_tree_win(Root* root, LPCTSTR path, int sortOrder) +static Entry* read_tree_win(Root* root, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd) { TCHAR buffer[MAX_PATH]; Entry* entry = &root->entry; LPCTSTR s = path; PTSTR d = buffer; + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + #ifndef _NO_EXTENSIONS - entry->unix_dir = FALSE; + entry->etype = ET_WINDOWS; #endif while(entry) { - while(*s && *s!=_T('\\') && *s!=_T('/')) + while(*s && *s!=TEXT('\\') && *s!=TEXT('/')) *d++ = *s++; - while(*s==_T('\\') || *s==_T('/')) + while(*s==TEXT('\\') || *s==TEXT('/')) s++; - *d++ = _T('\\'); - *d = _T('\0'); + *d++ = TEXT('\\'); + *d = TEXT('\0'); - read_directory(entry, buffer, sortOrder); + read_directory(entry, buffer, sortOrder, hwnd); if (entry->down) entry->expanded = TRUE; @@ -292,40 +378,25 @@ static Entry* read_tree_win(Root* root, LPCTSTR path, int sortOrder) entry = find_entry_win(entry, s); } + SetCursor(old_cursor); + return entry; } #if !defined(_NO_EXTENSIONS) && defined(__linux__) -BOOL to_filetime(const time_t* t, FILETIME* ftime) +static void read_directory_unix(Entry* dir, LPCTSTR path) { - struct tm* tm = gmtime(t); - SYSTEMTIME stime; + Entry* first_entry = NULL; + Entry* last = NULL; + Entry* entry; - if (!tm) - return FALSE; + int level = dir->level + 1; - stime.wYear = tm->tm_year+1900; - stime.wMonth = tm->tm_mon+1; - /* stime.wDayOfWeek */ - stime.wDay = tm->tm_mday; - stime.wHour = tm->tm_hour; - stime.wMinute = tm->tm_min; - stime.wSecond = tm->tm_sec; + DIR* pdir = opendir(path); - return SystemTimeToFileTime(&stime, ftime); -} - -static void read_directory_unix(Entry* parent, LPCTSTR path) -{ - Entry* entry = (Entry*) malloc(sizeof(Entry)); - int level = parent->level + 1; - Entry* last = 0; - - DIR* dir = opendir(path); - - if (dir) { + if (pdir) { struct stat st; struct dirent* ent; TCHAR buffer[MAX_PATH], *p; @@ -336,10 +407,17 @@ static void read_directory_unix(Entry* parent, LPCTSTR path) if (p==buffer || p[-1]!='/') *p++ = '/'; - parent->down = entry; + while((ent=readdir(pdir))) { + entry = alloc_entry(); + + if (!first_entry) + first_entry = entry; + + if (last) + last->next = entry; + + entry->etype = ET_UNIX; - while((ent=readdir(dir))) { - entry->unix_dir = TRUE; lstrcpy(entry->data.cFileName, ent->d_name); entry->data.dwFileAttributes = ent->d_name[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0; @@ -353,8 +431,8 @@ static void read_directory_unix(Entry* parent, LPCTSTR path) entry->data.nFileSizeHigh = st.st_size >> 32; memset(&entry->data.ftCreationTime, 0, sizeof(FILETIME)); - to_filetime(&st.st_atime, &entry->data.ftLastAccessTime); - to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime); + time_to_filetime(&st.st_atime, &entry->data.ftLastAccessTime); + time_to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime); entry->bhfi.nFileIndexLow = ent->d_ino; entry->bhfi.nFileIndexHigh = 0; @@ -368,41 +446,34 @@ static void read_directory_unix(Entry* parent, LPCTSTR path) entry->bhfi_valid = FALSE; } - entry->down = 0; - entry->up = parent; + entry->down = NULL; + entry->up = dir; entry->expanded = FALSE; entry->scanned = FALSE; entry->level = level; last = entry; - - entry = (Entry*) malloc(sizeof(Entry)); - - if (last) - last->next = entry; } - last->next = 0; + last->next = NULL; - closedir(dir); - } else - parent->down = 0; + closedir(pdir); + } - free(entry); - - parent->scanned = TRUE; + dir->down = first_entry; + dir->scanned = TRUE; } -static Entry* find_entry_unix(Entry* parent, LPCTSTR name) +static Entry* find_entry_unix(Entry* dir, LPCTSTR name) { Entry* entry; - for(entry=parent->down; entry; entry=entry->next) { + for(entry=dir->down; entry; entry=entry->next) { LPCTSTR p = name; LPCTSTR q = entry->data.cFileName; do { - if (!*p || *p==_T('/')) + if (!*p || *p==TEXT('/')) return entry; } while(*p++ == *q++); } @@ -410,26 +481,28 @@ static Entry* find_entry_unix(Entry* parent, LPCTSTR name) return 0; } -static Entry* read_tree_unix(Root* root, LPCTSTR path, int sortOrder) +static Entry* read_tree_unix(Root* root, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd) { TCHAR buffer[MAX_PATH]; Entry* entry = &root->entry; LPCTSTR s = path; PTSTR d = buffer; - entry->unix_dir = TRUE; + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + + entry->etype = ET_UNIX; while(entry) { - while(*s && *s!=_T('/')) + while(*s && *s!=TEXT('/')) *d++ = *s++; - while(*s == _T('/')) + while(*s == TEXT('/')) s++; - *d++ = _T('/'); - *d = _T('\0'); + *d++ = TEXT('/'); + *d = TEXT('\0'); - read_directory(entry, buffer, sortOrder); + read_directory(entry, buffer, sortOrder, hwnd); if (entry->down) entry->expanded = TRUE; @@ -440,12 +513,455 @@ static Entry* read_tree_unix(Root* root, LPCTSTR path, int sortOrder) entry = find_entry_unix(entry, s); } + SetCursor(old_cursor); + return entry; } +#endif // !defined(_NO_EXTENSIONS) && defined(__linux__) + + +#ifdef _SHELL_FOLDERS + +#ifdef UNICODE +#define tcscpyn strcpyn +#define get_strret get_strretW +#define path_from_pidl path_from_pidlW +#else +#define tcscpyn wcscpyn +#define get_strret get_strretA +#define path_from_pidl path_from_pidlA #endif +static LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count) +{ + LPCSTR s; + LPSTR d = dest; + + for(s=source; count&&(*d++=*s++); ) + count--; + + return dest; +} + +static LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count) +{ + LPCWSTR s; + LPWSTR d = dest; + + for(s=source; count&&(*d++=*s++); ) + count--; + + return dest; +} + + +static void get_strretA(STRRET* str, const SHITEMID* shiid, LPSTR buffer, int len) +{ + switch(str->uType) { + case STRRET_WSTR: + WideCharToMultiByte(CP_ACP, 0, str->UNION_MEMBER(pOleStr), -1, buffer, len, NULL, NULL); + break; + + case STRRET_OFFSET: + strcpyn(buffer, (LPCSTR)shiid+str->UNION_MEMBER(uOffset), len); + break; + + case STRRET_CSTR: + strcpyn(buffer, str->UNION_MEMBER(cStr), len); + } +} + +static void get_strretW(STRRET* str, const SHITEMID* shiid, LPWSTR buffer, int len) +{ + switch(str->uType) { + case STRRET_WSTR: + wcscpyn(buffer, str->UNION_MEMBER(pOleStr), len); + break; + + case STRRET_OFFSET: + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)shiid+str->UNION_MEMBER(uOffset), -1, buffer, len); + break; + + case STRRET_CSTR: + MultiByteToWideChar(CP_ACP, 0, str->UNION_MEMBER(cStr), -1, buffer, len); + } +} + + +static void free_strret(STRRET* str) +{ + if (str->uType == STRRET_WSTR) + (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, str->UNION_MEMBER(pOleStr)); +} + + +HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags) +{ + STRRET str; + + HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, flags, &str); + + if (SUCCEEDED(hr)) { + get_strret(&str, &pidl->mkid, buffer, len); + free_strret(&str); + } else + buffer[0] = '\0'; + + return hr; +} + + +HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len) +{ + STRRET str; + + // SHGDN_FORPARSING: get full path of id list + HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, SHGDN_FORPARSING, &str); + + if (SUCCEEDED(hr)) { + get_strretA(&str, &pidl->mkid, buffer, len); + free_strret(&str); + } else + buffer[0] = '\0'; + + return hr; +} + +HRESULT path_from_pidlW(IShellFolder* folder, LPITEMIDLIST pidl, LPWSTR buffer, int len) +{ + STRRET str; + + // SHGDN_FORPARSING: get full path of id list + HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, SHGDN_FORPARSING, &str); + + if (SUCCEEDED(hr)) { + get_strretW(&str, &pidl->mkid, buffer, len); + free_strret(&str); + } else + buffer[0] = '\0'; + + return hr; +} + + + /* create an item id list from a file system path */ + +static LPITEMIDLIST get_path_pidl(LPTSTR path, HWND hwnd) +{ + LPITEMIDLIST pidl; + HRESULT hr; + ULONG len; + +#ifdef UNICODE + LPWSTR buffer = path; +#else + WCHAR buffer[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, path, -1, buffer, MAX_PATH); +#endif + + hr = (*Globals.iDesktop->lpVtbl->ParseDisplayName)(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL); + if (FAILED(hr)) + return NULL; + + return pidl; +} + + + /* convert an item id list from relative to absolute (=relative to the desktop) format */ + +static LPITEMIDLIST get_to_absolute_pidl(Entry* entry, HWND hwnd) +{ + if (entry->up && entry->up->etype==ET_SHELL) { + IShellFolder* folder = entry->up->folder; + WCHAR buffer[MAX_PATH]; + + HRESULT hr = path_from_pidlW(folder, entry->pidl, buffer, MAX_PATH); + + if (SUCCEEDED(hr)) { + LPITEMIDLIST pidl; + ULONG len; + + hr = (*Globals.iDesktop->lpVtbl->ParseDisplayName)(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL); + + if (SUCCEEDED(hr)) + return pidl; + } + } + + return entry->pidl; +} + + +HICON extract_icon(IShellFolder* folder, LPCITEMIDLIST pidl) +{ + IExtractIcon* pExtract; + + if (SUCCEEDED((*folder->lpVtbl->GetUIObjectOf)(folder, 0, 1, (LPCITEMIDLIST*)&pidl, &IID_IExtractIcon, 0, (LPVOID*)&pExtract))) { + TCHAR path[_MAX_PATH]; + unsigned flags; + HICON hicon; + int idx; + + if (SUCCEEDED((*pExtract->lpVtbl->GetIconLocation)(pExtract, GIL_FORSHELL, path, _MAX_PATH, &idx, &flags))) { + if (!(flags & GIL_NOTFILENAME)) { + if (idx == -1) + idx = 0; /* special case for some control panel applications */ + + if ((int)ExtractIconEx(path, idx, 0, &hicon, 1) > 0) + flags &= ~GIL_DONTCACHE; + } else { + HICON hIconLarge = 0; + + HRESULT hr = (*pExtract->lpVtbl->Extract)(pExtract, path, idx, &hIconLarge, &hicon, MAKELONG(0/*GetSystemMetrics(SM_CXICON)*/,GetSystemMetrics(SM_CXSMICON))); + + if (SUCCEEDED(hr)) + DestroyIcon(hIconLarge); + } + + return hicon; + } + } + + return 0; +} + + +static Entry* find_entry_shell(Entry* dir, LPITEMIDLIST pidl) +{ + Entry* entry; + + for(entry=dir->down; entry; entry=entry->next) { + if (entry->pidl->mkid.cb == pidl->mkid.cb && + !memcmp(entry->pidl, pidl, entry->pidl->mkid.cb)) + return entry; + } + + return 0; +} + +static Entry* read_tree_shell(Root* root, LPITEMIDLIST pidl, SORT_ORDER sortOrder, HWND hwnd) +{ + Entry* entry = &root->entry; + Entry* next; + LPITEMIDLIST next_pidl = pidl; + IShellFolder* folder; + IShellFolder* child = NULL; + HRESULT hr; + + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); + +#ifndef _NO_EXTENSIONS + entry->etype = ET_SHELL; +#endif + + folder = Globals.iDesktop; + + while(entry) { + entry->pidl = next_pidl; + entry->folder = folder; + + if (!pidl->mkid.cb) + break; + + // copy first element of item idlist + next_pidl = (*Globals.iMalloc->lpVtbl->Alloc)(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT)); + memcpy(next_pidl, pidl, pidl->mkid.cb); + ((LPITEMIDLIST)((LPBYTE)next_pidl+pidl->mkid.cb))->mkid.cb = 0; + + hr = (*folder->lpVtbl->BindToObject)(folder, next_pidl, 0, &IID_IShellFolder, (void**)&child); + if (!SUCCEEDED(hr)) + break; + + read_directory(entry, NULL, sortOrder, hwnd); + + if (entry->down) + entry->expanded = TRUE; + + next = find_entry_shell(entry, next_pidl); + if (!next) + break; + + folder = child; + entry = next; + + // go to next element + pidl = (LPITEMIDLIST) ((LPBYTE)pidl+pidl->mkid.cb); + } + + SetCursor(old_cursor); + + return entry; +} + + +static void fill_w32fdata_shell(IShellFolder* folder, LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA* w32fdata) +{ + if (!(attribs & SFGAO_FILESYSTEM) || + FAILED(SHGetDataFromIDList(folder, pidl, SHGDFIL_FINDDATA, w32fdata, sizeof(WIN32_FIND_DATA)))) { + WIN32_FILE_ATTRIBUTE_DATA fad; + IDataObject* pDataObj; + + STGMEDIUM medium = {0, {0}, 0}; + FORMATETC fmt = {Globals.cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + + HRESULT hr = (*folder->lpVtbl->GetUIObjectOf)(folder, 0, 1, &pidl, &IID_IDataObject, 0, (LPVOID*)&pDataObj); + + if (SUCCEEDED(hr)) { + hr = (*pDataObj->lpVtbl->GetData)(pDataObj, &fmt, &medium); + + (*pDataObj->lpVtbl->Release)(pDataObj); + + if (SUCCEEDED(hr)) { + LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal)); + UINT sem_org = SetErrorMode(SEM_FAILCRITICALERRORS); + + if (GetFileAttributesEx(path, GetFileExInfoStandard, &fad)) { + w32fdata->dwFileAttributes = fad.dwFileAttributes; + w32fdata->ftCreationTime = fad.ftCreationTime; + w32fdata->ftLastAccessTime = fad.ftLastAccessTime; + w32fdata->ftLastWriteTime = fad.ftLastWriteTime; + + if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + w32fdata->nFileSizeLow = fad.nFileSizeLow; + w32fdata->nFileSizeHigh = fad.nFileSizeHigh; + } + } + + SetErrorMode(sem_org); + + GlobalUnlock(medium.UNION_MEMBER(hGlobal)); + GlobalFree(medium.UNION_MEMBER(hGlobal)); + } + } + } + + if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER)) + w32fdata->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + + if (attribs & SFGAO_READONLY) + w32fdata->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; + + if (attribs & SFGAO_COMPRESSED) + w32fdata->dwFileAttributes |= FILE_ATTRIBUTE_COMPRESSED; +} + + +static void read_directory_shell(Entry* dir, HWND hwnd) +{ + IShellFolder* folder = dir->folder; + int level = dir->level + 1; + HRESULT hr; + + IShellFolder* child; + IEnumIDList* idlist; + + Entry* first_entry = NULL; + Entry* last = NULL; + Entry* entry; + + if (!folder) + return; + + hr = (*folder->lpVtbl->EnumObjects)(folder, hwnd, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE, &idlist); + + if (SUCCEEDED(hr)) { + for(;;) { +#define FETCH_ITEM_COUNT 32 + LPITEMIDLIST pidls[FETCH_ITEM_COUNT]; + SFGAOF attribs; + ULONG cnt = 0; + ULONG n; + + memset(pidls, 0, sizeof(pidls)); + + hr = (*idlist->lpVtbl->Next)(idlist, FETCH_ITEM_COUNT, pidls, &cnt); + if (!SUCCEEDED(hr)) + break; + + if (hr == S_FALSE) + break; + + for(n=0; nnext = entry; + + memset(&entry->data, 0, sizeof(WIN32_FIND_DATA)); + entry->bhfi_valid = FALSE; + + attribs = ~SFGAO_FILESYSTEM; //SFGAO_HASSUBFOLDER|SFGAO_FOLDER; SFGAO_FILESYSTEM sorgt dafür, daß "My Documents" anstatt von "Martin's Documents" angezeigt wird + + hr = (*folder->lpVtbl->GetAttributesOf)(folder, 1, (LPCITEMIDLIST*)&pidls[n], &attribs); + + if (SUCCEEDED(hr)) { + if (attribs != (SFGAOF)~SFGAO_FILESYSTEM) { + fill_w32fdata_shell(folder, pidls[n], attribs, &entry->data); + + entry->bhfi_valid = TRUE; + } else + attribs = 0; + } else + attribs = 0; + + entry->pidl = pidls[n]; + + if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + hr = (*folder->lpVtbl->BindToObject)(folder, pidls[n], 0, &IID_IShellFolder, (void**)&child); + + if (SUCCEEDED(hr)) + entry->folder = child; + else + entry->folder = NULL; + } + else + entry->folder = NULL; + + if (!entry->data.cFileName[0]) + /*hr = */name_from_pidl(folder, pidls[n], entry->data.cFileName, MAX_PATH, /*SHGDN_INFOLDER*/0x2000/*0x2000=SHGDN_INCLUDE_NONFILESYS*/); + + /* get display icons for files and virtual objects */ + if (!(entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || + !(attribs & SFGAO_FILESYSTEM)) { + entry->hicon = extract_icon(folder, pidls[n]); + + if (!entry->hicon) + entry->hicon = (HICON)-1; /* don't try again later */ + } + + entry->down = NULL; + entry->up = dir; + entry->expanded = FALSE; + entry->scanned = FALSE; + entry->level = level; + +#ifndef _NO_EXTENSIONS + entry->etype = ET_SHELL; + entry->bhfi_valid = FALSE; +#endif + + last = entry; + } + } + + (*idlist->lpVtbl->Release)(idlist); + } + + if (last) + last->next = NULL; + + dir->down = first_entry; + dir->scanned = TRUE; +} + +#endif // _SHELL_FOLDERS + + /* directories first... */ static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2) { @@ -481,18 +997,18 @@ static int compareExt(const void* arg1, const void* arg2) name1 = fd1->cFileName; name2 = fd2->cFileName; - ext1 = _tcsrchr(name1, _T('.')); - ext2 = _tcsrchr(name2, _T('.')); + ext1 = _tcsrchr(name1, TEXT('.')); + ext2 = _tcsrchr(name2, TEXT('.')); if (ext1) ext1++; else - ext1 = _T(""); + ext1 = TEXT(""); if (ext2) ext2++; else - ext2 = _T(""); + ext2 = TEXT(""); cmp = lstrcmpi(ext1, ext2); if (cmp) @@ -536,34 +1052,34 @@ static int compareDate(const void* arg1, const void* arg2) static int (*sortFunctions[])(const void* arg1, const void* arg2) = { - compareName, /* SORT_NAME */ + compareName, /* SORT_NAME */ compareExt, /* SORT_EXT */ compareSize, /* SORT_SIZE */ compareDate /* SORT_DATE */ }; -static void SortDirectory(Entry* parent, SORT_ORDER sortOrder) +static void SortDirectory(Entry* dir, SORT_ORDER sortOrder) { - Entry* entry = parent->down; + Entry* entry = dir->down; Entry** array, **p; int len; len = 0; - for(entry=parent->down; entry; entry=entry->next) + for(entry=dir->down; entry; entry=entry->next) len++; if (len) { array = (Entry**) alloca(len*sizeof(Entry*)); p = array; - for(entry=parent->down; entry; entry=entry->next) + for(entry=dir->down; entry; entry=entry->next) *p++ = entry; /* call qsort with the appropriate compare function */ qsort(array, len, sizeof(array[0]), sortFunctions[sortOrder]); - parent->down = array[0]; + dir->down = array[0]; for(p=array; --len; p++) p[0]->next = p[1]; @@ -573,17 +1089,17 @@ static void SortDirectory(Entry* parent, SORT_ORDER sortOrder) } -static void read_directory(Entry* parent, LPCTSTR path, int sortOrder) +static void read_directory(Entry* dir, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd) { TCHAR buffer[MAX_PATH]; Entry* entry; LPCTSTR s; PTSTR d; -#if !defined(_NO_EXTENSIONS) && defined(__linux__) - if (parent->unix_dir) +#ifdef _SHELL_FOLDERS + if (dir->etype == ET_SHELL) { - read_directory_unix(parent, path); + read_directory_shell(dir, hwnd); if (Globals.prescan_node) { s = path; @@ -592,9 +1108,32 @@ static void read_directory(Entry* parent, LPCTSTR path, int sortOrder) while(*s) *d++ = *s++; - *d++ = _T('/'); + *d++ = TEXT('\\'); - for(entry=parent->down; entry; entry=entry->next) + for(entry=dir->down; entry; entry=entry->next) + if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + read_directory_shell(entry, hwnd); + SortDirectory(entry, sortOrder); + } + } + } + else +#endif +#if !defined(_NO_EXTENSIONS) && defined(__linux__) + if (dir->etype == ET_UNIX) + { + read_directory_unix(dir, path); + + if (Globals.prescan_node) { + s = path; + d = buffer; + + while(*s) + *d++ = *s++; + + *d++ = TEXT('/'); + + for(entry=dir->down; entry; entry=entry->next) if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { lstrcpy(d, entry->data.cFileName); read_directory_unix(entry, buffer); @@ -605,7 +1144,7 @@ static void read_directory(Entry* parent, LPCTSTR path, int sortOrder) else #endif { - read_directory_win(parent, path); + read_directory_win(dir, path); if (Globals.prescan_node) { s = path; @@ -614,9 +1153,9 @@ static void read_directory(Entry* parent, LPCTSTR path, int sortOrder) while(*s) *d++ = *s++; - *d++ = _T('\\'); + *d++ = TEXT('\\'); - for(entry=parent->down; entry; entry=entry->next) + for(entry=dir->down; entry; entry=entry->next) if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { lstrcpy(d, entry->data.cFileName); read_directory_win(entry, buffer); @@ -625,11 +1164,11 @@ static void read_directory(Entry* parent, LPCTSTR path, int sortOrder) } } - SortDirectory(parent, sortOrder); + SortDirectory(dir, sortOrder); } -static ChildWnd* alloc_child_window(LPCTSTR path) +static ChildWnd* alloc_child_window(LPCTSTR path, LPITEMIDLIST pidl, HWND hwnd) { TCHAR drv[_MAX_DRIVE+1], dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT]; ChildWnd* child = (ChildWnd*) malloc(sizeof(ChildWnd)); @@ -657,70 +1196,75 @@ static ChildWnd* alloc_child_window(LPCTSTR path) child->pos.rcNormalPosition.bottom = CW_USEDEFAULT; child->focus_pane = 0; - child->split_pos = 200; + child->split_pos = DEFAULT_SPLIT_POS; child->sortOrder = SORT_NAME; child->header_wdths_ok = FALSE; - lstrcpy(child->path, path); + if (path) + { + lstrcpy(child->path, path); - _tsplitpath(path, drv, dir, name, ext); + _tsplitpath(path, drv, dir, name, ext); + } + root->entry.level = 0; + +#ifdef _SHELL_FOLDERS + if (pidl) + { + root->drive_type = DRIVE_UNKNOWN; + lstrcpy(drv, TEXT("\\")); + lstrcpy(root->volname, TEXT("Desktop")); + root->fs_flags = 0; + lstrcpy(root->fs, TEXT("Shell")); + + entry = read_tree_shell(root, pidl, child->sortOrder, hwnd); + } + else +#endif #if !defined(_NO_EXTENSIONS) && defined(__linux__) if (*path == '/') { root->drive_type = GetDriveType(path); - lstrcat(drv, _T("/")); - lstrcpy(root->volname, _T("root fs")); + lstrcat(drv, TEXT("/")); + lstrcpy(root->volname, TEXT("root fs")); root->fs_flags = 0; - lstrcpy(root->fs, _T("unixfs")); + lstrcpy(root->fs, TEXT("unixfs")); - lstrcpy(root->path, _T("/")); - entry = read_tree_unix(root, path, child->sortOrder); + lstrcpy(root->path, TEXT("/")); + entry = read_tree_unix(root, path, child->sortOrder, hwnd); } else #endif { root->drive_type = GetDriveType(path); - lstrcat(drv, _T("\\")); + lstrcat(drv, TEXT("\\")); GetVolumeInformation(drv, root->volname, _MAX_FNAME, 0, 0, &root->fs_flags, root->fs, _MAX_DIR); lstrcpy(root->path, drv); - entry = read_tree_win(root, path, child->sortOrder); + entry = read_tree_win(root, path, child->sortOrder, hwnd); } - /*FIXME lstrcpy(root->entry.data.cFileName, drv); */ - wsprintf(root->entry.data.cFileName, _T("%s - %s"), drv, root->fs); +#ifdef _SHELL_FOLDERS + if (root->entry.etype == ET_SHELL) + lstrcpy(root->entry.data.cFileName, TEXT("Desktop")); + else +#endif + wsprintf(root->entry.data.cFileName, TEXT("%s - %s"), drv, root->fs); root->entry.data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; child->left.root = &root->entry; + child->right.root = NULL; - set_curdir(child, entry); + set_curdir(child, entry, hwnd); return child; } -/* recursively free all child entries */ -static void free_entries(Entry* parent) -{ - Entry *entry, *next=parent->down; - - if (next) { - parent->down = 0; - - do { - entry = next; - next = entry->next; - - free_entries(entry); - free(entry); - } while(next); - } -} - /* free all memory associated with a child window */ static void free_child_window(ChildWnd* child) { @@ -736,45 +1280,75 @@ static void get_path(Entry* dir, PTSTR path) int len = 0; int level = 0; - for(entry=dir; entry; level++) { - LPCTSTR name = entry->data.cFileName; - LPCTSTR s = name; - int l; +#ifdef _SHELL_FOLDERS + if (dir->etype == ET_SHELL) + { + SFGAOF attribs; + HRESULT hr = S_OK; - for(l=0; *s && *s!=_T('/') && *s!=_T('\\'); s++) - l++; + path[0] = TEXT('\0'); - if (entry->up) { - memmove(path+l+1, path, len*sizeof(TCHAR)); - memcpy(path+1, name, l*sizeof(TCHAR)); - len += l+1; + attribs = 0; -#ifndef _NO_EXTENSIONS - if (entry->unix_dir) - path[0] = _T('/'); - else -#endif - path[0] = _T('\\'); + if (dir->folder) + hr = (*dir->folder->lpVtbl->GetAttributesOf)(dir->folder, 1, (LPCITEMIDLIST*)&dir->pidl, &attribs); - entry = entry->up; - } else { - memmove(path+l, path, len*sizeof(TCHAR)); - memcpy(path, name, l*sizeof(TCHAR)); - len += l; - break; + if (SUCCEEDED(hr) && (attribs&SFGAO_FILESYSTEM)) { + IShellFolder* parent = dir->up? dir->up->folder: Globals.iDesktop; + + hr = path_from_pidl(parent, dir->pidl, path, MAX_PATH); } } - - if (!level) { -#ifndef _NO_EXTENSIONS - if (entry->unix_dir) - path[len++] = _T('/'); - else + else #endif - path[len++] = _T('\\'); - } + { + for(entry=dir; entry; level++) { + LPCTSTR name; + int l; - path[len] = _T('\0'); + { + LPCTSTR s; + name = entry->data.cFileName; + s = name; + + for(l=0; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++) + l++; + } + + if (entry->up) { + if (l > 0) { + memmove(path+l+1, path, len*sizeof(TCHAR)); + memcpy(path+1, name, l*sizeof(TCHAR)); + len += l+1; + +#ifndef _NO_EXTENSIONS + if (entry->etype == ET_UNIX) + path[0] = TEXT('/'); + else +#endif + path[0] = TEXT('\\'); + } + + entry = entry->up; + } else { + memmove(path+l, path, len*sizeof(TCHAR)); + memcpy(path, name, l*sizeof(TCHAR)); + len += l; + break; + } + } + + if (!level) { +#ifndef _NO_EXTENSIONS + if (entry->etype == ET_UNIX) + path[len++] = TEXT('/'); + else +#endif + path[len++] = TEXT('\\'); + } + + path[len] = TEXT('\0'); + } } @@ -868,8 +1442,10 @@ static HWND create_child_window(ChildWnd* child) newchild = child; child->hwnd = (HWND) SendMessage(Globals.hmdiclient, WM_MDICREATE, 0, (LPARAM)&mcs); - if (!child->hwnd) + if (!child->hwnd) { + UnhookWindowsHookEx(hcbthook); return 0; + } UnhookWindowsHookEx(hcbthook); @@ -920,7 +1496,9 @@ static struct FullScreenParameters { RECT orgPos; BOOL wasZoomed; } g_fullscreen = { - FALSE /* mode */ + FALSE, /* mode */ + {0, 0, 0, 0}, + FALSE }; void frame_get_clientspace(HWND hwnd, PRECT prect) @@ -1052,6 +1630,29 @@ BOOL activate_drive_window(LPCTSTR path) return FALSE; } +BOOL activate_fs_window(LPCTSTR filesys) +{ + HWND child_wnd; + + /* search for a already open window of the given file system name */ + for(child_wnd=GetNextWindow(Globals.hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) { + ChildWnd* child = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA); + + if (child) { + if (!lstrcmpi(child->root.fs, filesys)) { + SendMessage(Globals.hmdiclient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0); + + if (IsMinimized(child_wnd)) + ShowWindow(child_wnd, SW_SHOWNORMAL); + + return TRUE; + } + } + } + + return FALSE; +} + LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) { switch(nmsg) { @@ -1068,7 +1669,7 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam break; case WM_DESTROY: - // dont't exit desktop when closing file manager window + // don't exit desktop when closing file manager window if (!Globals.hwndParent) PostQuitMessage(0); break; @@ -1101,13 +1702,13 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam } GetCurrentDirectory(MAX_PATH, path); /*TODO: store last directory per drive */ - child = alloc_child_window(path); + child = alloc_child_window(path, NULL, hwnd); if (!create_child_window(child)) free(child); } else switch(cmd) { case ID_FILE_EXIT: - PostQuitMessage(0); + SendMessage(hwnd, WM_CLOSE, 0, 0); break; case ID_WINDOW_NEW: { @@ -1115,7 +1716,7 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam ChildWnd* child; GetCurrentDirectory(MAX_PATH, path); - child = alloc_child_window(path); + child = alloc_child_window(path, NULL, hwnd); if (!create_child_window(child)) free(child); @@ -1150,7 +1751,10 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam break; case ID_EXECUTE: { - struct ExecuteDialog dlg = {{0}}; + struct ExecuteDialog dlg; + + memset(&dlg, 0, sizeof(struct ExecuteDialog)); + if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_EXECUTE), hwnd, ExecuteDialogWndProg, (LPARAM)&dlg) == IDOK) { HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, dlg.cmd/*file*/, NULL/*parameters*/, NULL/*dir*/, dlg.cmdshow); @@ -1160,7 +1764,7 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam break;} case ID_HELP: - WinHelp(hwnd, _T("winfile"), HELP_INDEX, 0); + WinHelp(hwnd, TEXT("winfile"), HELP_INDEX, 0); break; #ifndef _NO_EXTENSIONS @@ -1173,11 +1777,26 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam TCHAR path[MAX_PATH]; ChildWnd* child; - if (activate_drive_window(_T("/"))) + if (activate_fs_window(TEXT("unixfs"))) break; getcwd(path, MAX_PATH); - child = alloc_child_window(path); + child = alloc_child_window(path, NULL, hwnd); + + if (!create_child_window(child)) + free(child); + break;} +#endif +#ifdef _SHELL_FOLDERS + case ID_DRIVE_SHELL_NS: { + TCHAR path[MAX_PATH]; + ChildWnd* child; + + if (activate_fs_window(TEXT("Shell"))) + break; + + GetCurrentDirectory(MAX_PATH, path); + child = alloc_child_window(path, get_path_pidl(path,hwnd), hwnd); if (!create_child_window(child)) free(child); @@ -1199,11 +1818,11 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam #endif case ID_ABOUT_WINE: - ShellAbout(hwnd, _T("WINE"), _T("Winefile"), 0); + ShellAbout(hwnd, TEXT("WINE"), TEXT("Winefile"), 0); break; case ID_ABOUT: //ID_ABOUT_WINE: - ShellAbout(hwnd, _T("Winefile"), NULL, 0); + ShellAbout(hwnd, TEXT("Winefile"), NULL, 0); break; #endif // _NO_EXTENSIONS @@ -1212,7 +1831,7 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam STRING_SelectLanguageByNumber(wParam - PM_FIRST_LANGUAGE); else */if ((cmd=IDW_FIRST_CHILD+0x100) && (cmdSC_RESTORE)) - MessageBox(hwnd, _T("Not yet implemented"), _T("Winefile"), MB_OK); + MessageBox(hwnd, TEXT("Not yet implemented"), TEXT("Winefile"), MB_OK); return DefFrameProc(hwnd, Globals.hmdiclient, nmsg, wparam, lparam); } @@ -1243,24 +1862,24 @@ LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam } -const static LPTSTR g_pos_names[COLUMNS] = { - _T(""), /* symbol */ - _T("Name"), - _T("Size"), - _T("CDate"), +static const LPTSTR g_pos_names[COLUMNS] = { + TEXT(""), /* symbol */ + TEXT("Name"), + TEXT("Size"), + TEXT("CDate"), #ifndef _NO_EXTENSIONS - _T("ADate"), - _T("MDate"), - _T("Index/Inode"), - _T("Links"), + TEXT("ADate"), + TEXT("MDate"), + TEXT("Index/Inode"), + TEXT("Links"), #endif // _NO_EXTENSIONS - _T("Attributes"), + TEXT("Attributes"), #ifndef _NO_EXTENSIONS - _T("Security") + TEXT("Security") #endif }; -const static int g_pos_align[] = { +static const int g_pos_align[] = { 0, HDF_LEFT, /* Name */ HDF_RIGHT, /* Size */ @@ -1317,7 +1936,7 @@ static void resize_tree(ChildWnd* child, int cx, int cy) static HWND create_header(HWND parent, Pane* pane, int id) { - HD_ITEM hdi = {HDI_TEXT|HDI_WIDTH|HDI_FORMAT}; + HD_ITEM hdi; int idx; HWND hwnd = CreateWindow(WC_HEADER, 0, WS_CHILD|WS_VISIBLE|HDS_HORZ/*TODO: |HDS_BUTTONS + sort orders*/, @@ -1327,6 +1946,8 @@ static HWND create_header(HWND parent, Pane* pane, int id) SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), FALSE); + hdi.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT; + for(idx=0; idx 4) + if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4) Globals.num_sep = b[1]; else - Globals.num_sep = _T('.'); + Globals.num_sep = TEXT('.'); old_font = SelectFont(hdc, Globals.hfont); - GetTextExtentPoint32(hdc, _T(" "), 1, &Globals.spaceSize); + GetTextExtentPoint32(hdc, TEXT(" "), 1, &Globals.spaceSize); SelectFont(hdc, old_font); ReleaseDC(hwnd, hdc); } @@ -1509,9 +2130,9 @@ static void calc_single_width(Pane* pane, int col) /* insert listbox entries after index idx */ -static void insert_entries(Pane* pane, Entry* parent, int idx) +static void insert_entries(Pane* pane, Entry* dir, int idx) { - Entry* entry = parent; + Entry* entry = dir; if (!entry) return; @@ -1526,12 +2147,12 @@ static void insert_entries(Pane* pane, Entry* parent, int idx) /* don't display entries "." and ".." in the left pane */ if (pane->treePane && (entry->data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) - && entry->data.cFileName[0]==_T('.')) + && entry->data.cFileName[0]==TEXT('.')) if ( #ifndef _NO_EXTENSIONS - entry->data.cFileName[1]==_T('\0') || + entry->data.cFileName[1]==TEXT('\0') || #endif - (entry->data.cFileName[1]==_T('.') && entry->data.cFileName[2]==_T('\0'))) + (entry->data.cFileName[1]==TEXT('.') && entry->data.cFileName[2]==TEXT('\0'))) continue; if (idx != -1) @@ -1554,7 +2175,7 @@ static void create_tree_window(HWND parent, Pane* pane, int id, int id_header) static int s_init = 0; Entry* entry = pane->root; - pane->hwnd = CreateWindow(_T("ListBox"), _T(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL| + pane->hwnd = CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL| LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY, 0, 0, 0, 0, parent, (HMENU)id, Globals.hInstance, 0); @@ -1594,13 +2215,13 @@ static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols) FILETIME lft; int len = 0; - *buffer = _T('\0'); + *buffer = TEXT('\0'); if (!ft->dwLowDateTime && !ft->dwHighDateTime) return; if (!FileTimeToLocalFileTime(ft, &lft)) - {err: _tcscpy(buffer,_T("???")); return;} + {err: _tcscpy(buffer,TEXT("???")); return;} if (!FileTimeToSystemTime(&lft, &systime)) goto err; @@ -1618,14 +2239,14 @@ static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols) buffer[len++] = ' '; if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer+len, BUFFER_LEN-len)) - buffer[len] = _T('\0'); + buffer[len] = TEXT('\0'); } } static void calc_width(Pane* pane, LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) { - RECT rt = {0}; + RECT rt = {0, 0, 0, 0}; DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX); @@ -1635,7 +2256,7 @@ static void calc_width(Pane* pane, LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) static void calc_tabbed_width(Pane* pane, LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) { - RECT rt = {0}; + RECT rt = {0, 0, 0, 0}; /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ @@ -1711,15 +2332,15 @@ static void output_number(Pane* pane, LPDRAWITEMSTRUCT dis, int col, LPCTSTR str static int is_exe_file(LPCTSTR ext) { - const static LPCTSTR executable_extensions[] = { - _T("COM"), - _T("EXE"), - _T("BAT"), - _T("CMD"), + static const LPCTSTR executable_extensions[] = { + TEXT("COM"), + TEXT("EXE"), + TEXT("BAT"), + TEXT("CMD"), #ifndef _NO_EXTENSIONS - _T("CMM"), - _T("BTM"), - _T("AWK"), + TEXT("CMM"), + TEXT("BTM"), + TEXT("AWK"), #endif // _NO_EXTENSIONS 0 }; @@ -1763,11 +2384,11 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi attrs = entry->data.dwFileAttributes; if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - if (entry->data.cFileName[0]==_T('.') && entry->data.cFileName[1]==_T('.') - && entry->data.cFileName[2]==_T('\0')) + if (entry->data.cFileName[0]==TEXT('.') && entry->data.cFileName[1]==TEXT('.') + && entry->data.cFileName[2]==TEXT('\0')) img = IMG_FOLDER_UP; #ifndef _NO_EXTENSIONS - else if (entry->data.cFileName[0]==_T('.') && entry->data.cFileName[1]==_T('\0')) + else if (entry->data.cFileName[0]==TEXT('.') && entry->data.cFileName[1]==TEXT('\0')) img = IMG_FOLDER_CUR; #endif else if ( @@ -1781,7 +2402,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi } else { LPCTSTR ext = _tcsrchr(entry->data.cFileName, '.'); if (!ext) - ext = _T(""); + ext = TEXT(""); if (is_exe_file(ext)) img = IMG_EXECUTABLE; @@ -1819,7 +2440,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi hrgn_org = 0; } - /* HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN)); */ + /* HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN)); */ ExtSelectClipRgn(dis->hDC, hrgn, RGN_AND); DeleteObject(hrgn); @@ -1834,7 +2455,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi if (up->next #ifndef _LEFT_FILES - && (up->next->data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + && (up->next->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) #endif ) { MoveToEx(dis->hDC, x, dis->rcItem.top, 0); @@ -1863,7 +2484,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi SelectClipRgn(dis->hDC, hrgn_org); if (hrgn_org) DeleteObject(hrgn_org); - /* SelectObject(dis->hDC, holdPen); */ + /* SelectObject(dis->hDC, holdPen); */ } else if (calcWidthCol==col || calcWidthCol==COLUMNS) { int right = img_pos + IMAGE_WIDTH - Globals.spaceSize.cx; @@ -1919,9 +2540,14 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi if (cx > IMAGE_WIDTH) cx = IMAGE_WIDTH; - ImageList_DrawEx(Globals.himl, img, dis->hDC, - img_pos, dis->rcItem.top, cx, - IMAGE_HEIGHT, bkcolor, CLR_DEFAULT, ILD_NORMAL); +#ifdef _SHELL_FOLDERS + if (entry->hicon && entry->hicon!=(HICON)-1) + DrawIconEx(dis->hDC, img_pos, dis->rcItem.top, entry->hicon, cx, GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL); + else +#endif + ImageList_DrawEx(Globals.himl, img, dis->hDC, + img_pos, dis->rcItem.top, cx, + IMAGE_HEIGHT, bkcolor, CLR_DEFAULT, ILD_NORMAL); } } @@ -1957,7 +2583,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi size = ((ULONGLONG)entry->data.nFileSizeHigh << 32) | entry->data.nFileSizeLow; - _stprintf(buffer, _T("%") LONGLONGARG _T("d"), size); + _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("d"), size); if (calcWidthCol == -1) output_number(pane, dis, col, buffer); @@ -1999,7 +2625,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi ULONGLONG index = ((ULONGLONG)entry->bhfi.nFileIndexHigh << 32) | entry->bhfi.nFileIndexLow; if (visible_cols & COL_INDEX) { - _stprintf(buffer, _T("%") LONGLONGARG _T("X"), index); + _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("X"), index); if (calcWidthCol == -1) output_text(pane, dis, col, buffer, DT_RIGHT); else if (calcWidthCol==col || calcWidthCol==COLUMNS) @@ -2008,7 +2634,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi } if (visible_cols & COL_LINKS) { - wsprintf(buffer, _T("%d"), entry->bhfi.nNumberOfLinks); + wsprintf(buffer, TEXT("%d"), entry->bhfi.nNumberOfLinks); if (calcWidthCol == -1) output_text(pane, dis, col, buffer, DT_CENTER); else if (calcWidthCol==col || calcWidthCol==COLUMNS) @@ -2022,9 +2648,9 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi /* show file attributes */ if (visible_cols & COL_ATTRIBUTES) { #ifdef _NO_EXTENSIONS - _tcscpy(buffer, _T(" \t \t \t \t ")); + _tcscpy(buffer, TEXT(" \t \t \t \t ")); #else - _tcscpy(buffer, _T(" \t \t \t \t \t \t \t \t \t \t \t ")); + _tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t ")); #endif if (attrs & FILE_ATTRIBUTE_NORMAL) buffer[ 0] = 'N'; @@ -2057,7 +2683,7 @@ static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWi if (flags.security) { DWORD rights = get_access_mask(); - tcscpy(buffer, _T(" \t \t \t \t \t \t \t \t \t \t \t ")); + tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t ")); if (rights & FILE_READ_DATA) buffer[ 0] = 'R'; if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W'; @@ -2233,11 +2859,11 @@ static LRESULT pane_notify(Pane* pane, NMHDR* pnmh) #endif // _NO_EXTENSIONS -static void scan_entry(ChildWnd* child, Entry* entry) +static void scan_entry(ChildWnd* child, Entry* entry, HWND hwnd) { TCHAR path[MAX_PATH]; int idx = ListBox_GetCurSel(child->left.hwnd); - HCURSOR crsrOld = SetCursor(LoadCursor(0, IDC_WAIT)); + HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); /* delete sub entries in left pane */ for(;;) { @@ -2257,8 +2883,17 @@ static void scan_entry(ChildWnd* child, Entry* entry) free_entries(entry); /* read contents from disk */ - get_path(entry, path); - read_directory(entry, path, child->sortOrder); +#ifdef _SHELL_FOLDERS + if (entry->etype == ET_SHELL) + { + read_directory(entry, NULL, child->sortOrder, hwnd); + } + else +#endif + { + get_path(entry, path); + read_directory(entry, path, child->sortOrder, hwnd); + } /* insert found entries in right pane */ insert_entries(&child->right, entry->down, -1); @@ -2269,7 +2904,7 @@ static void scan_entry(ChildWnd* child, Entry* entry) child->header_wdths_ok = FALSE; - SetCursor(crsrOld); + SetCursor(old_cursor); } @@ -2341,16 +2976,18 @@ static void collapse_entry(Pane* pane, Entry* dir) } -static void set_curdir(ChildWnd* child, Entry* entry) +static void set_curdir(ChildWnd* child, Entry* entry, HWND hwnd) { TCHAR path[MAX_PATH]; + path[0] = '\0'; + child->left.cur = entry; - child->right.root = entry->down; + child->right.root = entry->down? entry->down: entry; child->right.cur = entry; if (!entry->scanned) - scan_entry(child, entry); + scan_entry(child, entry, hwnd); else { ListBox_ResetContent(child->right.hwnd); insert_entries(&child->right, entry->down, -1); @@ -2366,7 +3003,8 @@ static void set_curdir(ChildWnd* child, Entry* entry) if (child->hwnd) /* only change window title, if the window already exists */ SetWindowText(child->hwnd, path); - SetCurrentDirectory(path); + if (path[0]) + SetCurrentDirectory(path); } @@ -2397,7 +3035,42 @@ BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow) #endif -static void activate_entry(ChildWnd* child, Pane* pane) +BOOL launch_entry(Entry* entry, HWND hwnd, UINT nCmdShow) +{ + TCHAR cmd[MAX_PATH]; + +#ifdef _SHELL_FOLDERS + if (entry->etype == ET_SHELL) { + BOOL ret = TRUE; + + SHELLEXECUTEINFO shexinfo; + + shexinfo.cbSize = sizeof(SHELLEXECUTEINFO); + shexinfo.fMask = SEE_MASK_IDLIST; + shexinfo.hwnd = hwnd; + shexinfo.nShow = nCmdShow; + shexinfo.lpIDList = get_to_absolute_pidl(entry, hwnd); + + if (!ShellExecuteEx(&shexinfo)) { + display_error(hwnd, GetLastError()); + ret = FALSE; + } + + if (shexinfo.lpIDList != entry->pidl) + (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, shexinfo.lpIDList); + + return ret; + } +#endif + + get_path(entry, cmd); + + /* start program, open document... */ + return launch_file(hwnd, cmd, nCmdShow); +} + + +static void activate_entry(ChildWnd* child, Pane* pane, HWND hwnd) { Entry* entry = pane->cur; @@ -2408,7 +3081,7 @@ static void activate_entry(ChildWnd* child, Pane* pane) int scanned_old = entry->scanned; if (!scanned_old) - scan_entry(child, entry); + scan_entry(child, entry, hwnd); #ifndef _NO_EXTENSIONS if (entry->data.cFileName[0]=='.' && entry->data.cFileName[1]=='\0') @@ -2427,7 +3100,7 @@ static void activate_entry(ChildWnd* child, Pane* pane) if (!pane->treePane) focus_entry: { int idx = ListBox_FindItemData(child->left.hwnd, ListBox_GetCurSel(child->left.hwnd), entry); ListBox_SetCurSel(child->left.hwnd, idx); - set_curdir(child, entry); + set_curdir(child, entry, hwnd); } } @@ -2439,12 +3112,7 @@ static void activate_entry(ChildWnd* child, Pane* pane) #endif } } else { - TCHAR cmd[MAX_PATH]; - - get_path(entry, cmd); - - /* start program, open document... */ - launch_file(child->hwnd, cmd, SW_SHOWNORMAL); + launch_entry(entry, child->hwnd, SW_SHOWNORMAL); } } @@ -2669,7 +3337,7 @@ LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam switch(LOWORD(wparam)) { case ID_WINDOW_NEW: { - ChildWnd* new_child = alloc_child_window(child->path); + ChildWnd* new_child = alloc_child_window(child->path, NULL, hwnd); if (!create_child_window(new_child)) free(new_child); @@ -2677,11 +3345,11 @@ LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam break;} case ID_REFRESH: - scan_entry(child, pane->cur); + scan_entry(child, pane->cur, hwnd); break; case ID_ACTIVATE: - activate_entry(child, pane); + activate_entry(child, pane, hwnd); break; default: @@ -2699,13 +3367,13 @@ LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam Entry* entry = (Entry*) ListBox_GetItemData(pane->hwnd, idx); if (pane == &child->left) - set_curdir(child, entry); + set_curdir(child, entry, hwnd); else pane->cur = entry; break;} case LBN_DBLCLK: - activate_entry(child, pane); + activate_entry(child, pane, hwnd); break; } break;} @@ -2772,30 +3440,36 @@ static void InitInstance(HINSTANCE hinstance) HDC hdc = GetDC(0); + setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName + InitCommonControlsEx(&icc); + + /* register frame window class */ + wcFrame.cbSize = sizeof(WNDCLASSEX); wcFrame.style = 0; wcFrame.lpfnWndProc = FrameWndProc; wcFrame.cbClsExtra = 0; wcFrame.cbWndExtra = 0; wcFrame.hInstance = hinstance; - wcFrame.hIcon = LoadIcon(hinstance, - MAKEINTRESOURCE(IDI_WINEFILE)); + wcFrame.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_WINEFILE)); wcFrame.hCursor = LoadCursor(0, IDC_ARROW); wcFrame.hbrBackground = 0; wcFrame.lpszMenuName = 0; wcFrame.lpszClassName = WINEFILEFRAME; wcFrame.hIconSm = (HICON)LoadImage(hinstance, - MAKEINTRESOURCE(IDI_WINEFILE), - IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - LR_SHARED); + MAKEINTRESOURCE(IDI_WINEFILE), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_SHARED); - /* register frame window class */ Globals.hframeClass = RegisterClassEx(&wcFrame); + + /* register tree windows class */ + wcChild.style = CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW; wcChild.lpfnWndProc = ChildWndProc; wcChild.cbClsExtra = 0; @@ -2807,20 +3481,27 @@ static void InitInstance(HINSTANCE hinstance) wcChild.lpszMenuName = 0; wcChild.lpszClassName = WINEFILETREE; - /* register tree windows class */ hChildClass = RegisterClass(&wcChild); + Globals.haccel = LoadAccelerators(hinstance, MAKEINTRESOURCE(IDA_WINEFILE)); - Globals.hfont = CreateFont(-MulDiv(8,GetDeviceCaps(hdc,LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _T("MS Sans Serif")); + Globals.hfont = CreateFont(-MulDiv(8,GetDeviceCaps(hdc,LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Sans Serif")); ReleaseDC(0, hdc); Globals.hInstance = hinstance; + +#ifdef _SHELL_FOLDERS + CoInitialize(NULL); + CoGetMalloc(MEMCTX_TASK, &Globals.iMalloc); + SHGetDesktopFolder(&Globals.iDesktop); + Globals.cfStrFName = RegisterClipboardFormat(CFSTR_FILENAME); +#endif } -void ShowFileMgr(HWND hwndParent, int cmdshow) +void explorer_show_frame(HWND hwndParent, int cmdshow) { TCHAR path[MAX_PATH]; ChildWnd* child; @@ -2845,19 +3526,19 @@ void ShowFileMgr(HWND hwndParent, int cmdshow) /* create main window */ - Globals.hMainWnd = CreateWindowEx(0, (LPCTSTR)(int)Globals.hframeClass, _T("Wine File"), WS_OVERLAPPEDWINDOW, + Globals.hMainWnd = CreateWindowEx(0, (LPCTSTR)(int)Globals.hframeClass, TEXT("Wine File"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndParent, Globals.hMenuFrame, Globals.hInstance, 0/*lpParam*/); - Globals.hmdiclient = CreateWindowEx(0, _T("MDICLIENT"), NULL, + Globals.hmdiclient = CreateWindowEx(0, TEXT("MDICLIENT"), NULL, WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER, 0, 0, 0, 0, Globals.hMainWnd, 0, Globals.hInstance, &ccs); { - TBBUTTON drivebarBtn = {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}; + TBBUTTON drivebarBtn = {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0}; int btn = 1; PTSTR p; @@ -2873,12 +3554,20 @@ void ShowFileMgr(HWND hwndParent, int cmdshow) #ifndef _NO_EXTENSIONS #ifdef __linux__ /* insert unix file system button */ - SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)_T("/\0")); + SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("/\0")); drivebarBtn.idCommand = ID_DRIVE_UNIX_FS; SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); drivebarBtn.iString++; #endif +#ifdef _SHELL_FOLDERS + /* insert shell namespace button */ + SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("Shell\0")); + + drivebarBtn.idCommand = ID_DRIVE_SHELL_NS; + SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn); + drivebarBtn.iString++; +#endif /* register windows drive root strings */ SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)Globals.drives); @@ -2910,14 +3599,15 @@ void ShowFileMgr(HWND hwndParent, int cmdshow) { TBBUTTON toolbarBtns[] = { - {0, 0, 0, TBSTYLE_SEP}, - {0, ID_WINDOW_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON}, - {1, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON}, - {2, ID_WINDOW_TILE_HORZ, TBSTATE_ENABLED, TBSTYLE_BUTTON}, - {3, ID_WINDOW_TILE_VERT, TBSTATE_ENABLED, TBSTYLE_BUTTON}, - {4, 2/*TODO: ID_...*/, TBSTATE_ENABLED, TBSTYLE_BUTTON}, - {5, 2/*TODO: ID_...*/, TBSTATE_ENABLED, TBSTYLE_BUTTON}, - }; + {0, 0, 0, TBSTYLE_SEP, {0, 0}, 0, 0}, + {0, ID_WINDOW_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {1, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {2, ID_WINDOW_TILE_HORZ, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {3, ID_WINDOW_TILE_VERT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, +/*TODO + {4, ID_... , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, + {5, ID_... , TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0}, +*/ }; Globals.htoolbar = CreateToolbarEx(Globals.hMainWnd, WS_CHILD|WS_VISIBLE, IDW_TOOLBAR, 2, Globals.hInstance, IDB_TOOLBAR, toolbarBtns, @@ -2935,7 +3625,15 @@ void ShowFileMgr(HWND hwndParent, int cmdshow) /*TODO: read paths and window placements from registry */ GetCurrentDirectory(MAX_PATH, path); - child = alloc_child_window(path); + + ShowWindow(Globals.hMainWnd, cmdshow); + +#if defined(_SHELL_FOLDERS) && !defined(_WINE_) + // Shell Namespace as default: + child = alloc_child_window(path, get_path_pidl(path,Globals.hMainWnd), Globals.hMainWnd); +#else + child = alloc_child_window(path, NULL, Globals.hMainWnd); +#endif child->pos.showCmd = SW_SHOWMAXIMIZED; child->pos.rcNormalPosition.left = 0; @@ -2952,12 +3650,17 @@ void ShowFileMgr(HWND hwndParent, int cmdshow) Globals.prescan_node = FALSE; - ShowWindow(Globals.hMainWnd, cmdshow); UpdateWindow(Globals.hMainWnd); } void ExitInstance() { +#ifdef _SHELL_FOLDERS + (*Globals.iDesktop->lpVtbl->Release)(Globals.iDesktop); + (*Globals.iMalloc->lpVtbl->Release)(Globals.iMalloc); + CoUninitialize(); +#endif + ImageList_Destroy(Globals.himl); } @@ -2980,9 +3683,9 @@ static BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lparam) return TRUE; } +/* search for window of given class name to allow only one running instance */ int find_window_class(LPCTSTR classname) { - /* allow only one running instance */ EnumWindows(EnumWndProc, (LPARAM)classname); if (g_foundPrevInstance) @@ -2992,7 +3695,7 @@ int find_window_class(LPCTSTR classname) } -int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow) +int explorer_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow) { MSG msg; @@ -3004,7 +3707,7 @@ int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow) cmdshow = SW_MAXIMIZE; #endif - ShowFileMgr(hwndParent, cmdshow); + explorer_show_frame(hwndParent, cmdshow); while(GetMessage(&msg, 0, 0, 0)) { if (Globals.hmdiclient && TranslateMDISysAccel(Globals.hmdiclient, &msg)) @@ -3035,7 +3738,7 @@ int APIENTRY WinMain(HINSTANCE hinstance, return 1; #endif - winefile_main(hinstance, 0, cmdshow); + explorer_main(hinstance, 0, cmdshow); return 0; } diff --git a/reactos/subsys/system/explorer/WineFile.dsp b/reactos/subsys/system/explorer/winefile/winefile.dsp similarity index 75% rename from reactos/subsys/system/explorer/WineFile.dsp rename to reactos/subsys/system/explorer/winefile/winefile.dsp index 711101922fb..5af5b7e0193 100644 --- a/reactos/subsys/system/explorer/WineFile.dsp +++ b/reactos/subsys/system/explorer/winefile/winefile.dsp @@ -1,26 +1,26 @@ -# Microsoft Developer Studio Project File - Name="WineFile" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="winefile" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 -CFG=WineFile - Win32 Unicode Debug +CFG=winefile - Win32 Unicode Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "WineFile.mak". +!MESSAGE NMAKE /f "winefile.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "WineFile.mak" CFG="WineFile - Win32 Unicode Debug" +!MESSAGE NMAKE /f "winefile.mak" CFG="winefile - Win32 Unicode Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "WineFile - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE "WineFile - Win32 Unicode Debug" (based on "Win32 (x86) Application") -!MESSAGE "WineFile - Win32 UNICODE Release" (based on "Win32 (x86) Application") -!MESSAGE "WineFile - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "winefile - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "winefile - Win32 Unicode Debug" (based on "Win32 (x86) Application") +!MESSAGE "winefile - Win32 UNICODE Release" (based on "Win32 (x86) Application") +!MESSAGE "winefile - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE # Begin Project @@ -31,7 +31,7 @@ CPP=cl.cmd MTL=midl.exe RSC=rc.exe -!IF "$(CFG)" == "WineFile - Win32 Debug" +!IF "$(CFG)" == "winefile - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 @@ -40,8 +40,8 @@ RSC=rc.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir "WineFileDebug" -# PROP Intermediate_Dir "WineFileDebug" +# PROP Output_Dir "winefileDebug" +# PROP Intermediate_Dir "winefileDebug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c @@ -49,7 +49,7 @@ RSC=rc.exe # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" +# ADD RSC /l 0x407 /i ".." /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -57,7 +57,7 @@ LINK32=link.cmd # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept # ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib comdlg32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -!ELSEIF "$(CFG)" == "WineFile - Win32 Unicode Debug" +!ELSEIF "$(CFG)" == "winefile - Win32 Unicode Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 @@ -66,8 +66,8 @@ LINK32=link.cmd # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir "WineFileUDebug" -# PROP Intermediate_Dir "WineFileUDebug" +# PROP Output_Dir "winefileUDebug" +# PROP Intermediate_Dir "winefileUDebug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c @@ -75,7 +75,7 @@ LINK32=link.cmd # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" +# ADD RSC /l 0x407 /i ".." /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -83,18 +83,18 @@ LINK32=link.cmd # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept # ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib comdlg32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -!ELSEIF "$(CFG)" == "WineFile - Win32 UNICODE Release" +!ELSEIF "$(CFG)" == "winefile - Win32 UNICODE Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "WineFile___Win32_UNICODE_Release" -# PROP BASE Intermediate_Dir "WineFile___Win32_UNICODE_Release" +# PROP BASE Output_Dir "winefile___Win32_UNICODE_Release" +# PROP BASE Intermediate_Dir "winefile___Win32_UNICODE_Release" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "WineFileURelease" -# PROP Intermediate_Dir "WineFileURelease" +# PROP Output_Dir "." +# PROP Intermediate_Dir "winefileURelease" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c @@ -102,7 +102,7 @@ LINK32=link.cmd # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /i ".." /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -110,18 +110,18 @@ LINK32=link.cmd # ADD BASE LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib comdlg32.lib /nologo /subsystem:windows /machine:I386 # ADD LINK32 user32.lib gdi32.lib advapi32.lib comctl32.lib shell32.lib comdlg32.lib ole32.lib /nologo /subsystem:windows /machine:I386 -!ELSEIF "$(CFG)" == "WineFile - Win32 Release" +!ELSEIF "$(CFG)" == "winefile - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "WineFile___Win32_Release" -# PROP BASE Intermediate_Dir "WineFile___Win32_Release" +# PROP BASE Output_Dir "winefile___Win32_Release" +# PROP BASE Intermediate_Dir "winefile___Win32_Release" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "WineFileRelease" -# PROP Intermediate_Dir "WineFileRelease" +# PROP Output_Dir "winefileRelease" +# PROP Intermediate_Dir "winefileRelease" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "UNICODE" /D WINE_UNUSED= /YX /FD /c @@ -129,7 +129,7 @@ LINK32=link.cmd # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /i ".." /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -141,30 +141,34 @@ LINK32=link.cmd # Begin Target -# Name "WineFile - Win32 Debug" -# Name "WineFile - Win32 Unicode Debug" -# Name "WineFile - Win32 UNICODE Release" -# Name "WineFile - Win32 Release" +# Name "winefile - Win32 Debug" +# Name "winefile - Win32 Unicode Debug" +# Name "winefile - Win32 UNICODE Release" +# Name "winefile - Win32 Release" # Begin Group "Resources" # PROP Default_Filter "" # Begin Source File -SOURCE=.\De.rc +SOURCE=.\de.rc # PROP Exclude_From_Build 1 # End Source File # Begin Source File -SOURCE=.\res\drivebar.bmp +SOURCE=..\res\drivebar.bmp # End Source File # Begin Source File -SOURCE=.\En.rc +SOURCE=.\en.rc # PROP Exclude_From_Build 1 # End Source File # Begin Source File -SOURCE=.\res\images.bmp +SOURCE=..\res\images.bmp +# End Source File +# Begin Source File + +SOURCE=.\resource.h # End Source File # Begin Source File @@ -173,11 +177,11 @@ SOURCE=.\resource.rc # End Source File # Begin Source File -SOURCE=.\res\toolbar.bmp +SOURCE=..\res\toolbar.bmp # End Source File # Begin Source File -SOURCE=.\res\winefile.ico +SOURCE=..\res\winefile.ico # End Source File # Begin Source File @@ -194,23 +198,11 @@ SOURCE=.\license.h # End Source File # Begin Source File -SOURCE=.\Makefile.in -# End Source File -# Begin Source File - -SOURCE=.\include\resource.h -# End Source File -# Begin Source File - -SOURCE=.\splitpath.c -# End Source File -# Begin Source File - SOURCE=.\winefile.c # End Source File # Begin Source File -SOURCE=.\include\winefile.h +SOURCE=.\winefile.h # End Source File # End Target # End Project diff --git a/reactos/subsys/system/explorer/winefile.dsw b/reactos/subsys/system/explorer/winefile/winefile.dsw similarity index 89% rename from reactos/subsys/system/explorer/winefile.dsw rename to reactos/subsys/system/explorer/winefile/winefile.dsw index 1903a7a7546..40c89183e09 100644 --- a/reactos/subsys/system/explorer/winefile.dsw +++ b/reactos/subsys/system/explorer/winefile/winefile.dsw @@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "WineFile"=.\WineFile.dsp - Package Owner=<4> +Project: "winefile"=.\winefile.dsp - Package Owner=<4> Package=<5> {{{ diff --git a/reactos/subsys/system/explorer/include/winefile.h b/reactos/subsys/system/explorer/winefile/winefile.h similarity index 87% rename from reactos/subsys/system/explorer/include/winefile.h rename to reactos/subsys/system/explorer/winefile/winefile.h index 51afba56230..c916f00c6e2 100644 --- a/reactos/subsys/system/explorer/include/winefile.h +++ b/reactos/subsys/system/explorer/winefile/winefile.h @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -46,6 +45,14 @@ #include /* for alloca() */ #endif +#ifndef _NO_EXTENSIONS +#define _SHELL_FOLDERS + +#include +#include +#include +#endif + #ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED #define FILE_ATTRIBUTE_ENCRYPTED 0x00000040 #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 @@ -61,9 +68,9 @@ #endif #ifdef _MSC_VER -#define LONGLONGARG _T("I64") +#define LONGLONGARG TEXT("I64") #else -#define LONGLONGARG _T("L") +#define LONGLONGARG TEXT("L") #endif #define BUFFER_LEN 1024 @@ -100,10 +107,10 @@ enum IMAGE { #define COLOR_SPLITBAR LTGRAY_BRUSH #endif -#define WINEFILEFRAME _T("WFS_Frame") -#define WINEFILETREE _T("WFS_Tree") -#define WINEFILEDRIVES _T("WFS_Drives") -#define WINEFILEMDICLIENT _T("WFS_MdiClient") +#define WINEFILEFRAME TEXT("WFS_Frame") +#define WINEFILETREE TEXT("WFS_Tree") +#define WINEFILEDRIVES TEXT("WFS_Drives") +#define WINEFILEMDICLIENT TEXT("WFS_MdiClient") #define FRM_CALC_CLIENT 0xBF83 #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt)) @@ -135,7 +142,13 @@ typedef struct TCHAR drives[BUFFER_LEN]; BOOL prescan_node; /*TODO*/ - UINT wStringTableOffset; +//UINT wStringTableOffset; + +#ifdef _SHELL_FOLDERS + IShellFolder* iDesktop; + IMalloc* iMalloc; + UINT cfStrFName; +#endif } WINEFILE_GLOBALS; extern WINEFILE_GLOBALS Globals; diff --git a/reactos/subsys/system/explorer/winefile.rc b/reactos/subsys/system/explorer/winefile/winefile.rc similarity index 93% rename from reactos/subsys/system/explorer/winefile.rc rename to reactos/subsys/system/explorer/winefile/winefile.rc index 117d2e95df0..23bc0ee1c48 100644 --- a/reactos/subsys/system/explorer/winefile.rc +++ b/reactos/subsys/system/explorer/winefile/winefile.rc @@ -17,7 +17,7 @@ */ #include "windows.h" -#include "include/resource.h" +#include "resource.h" /* define language neutral resources */ @@ -27,5 +27,5 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL /* include localised resources */ -#include "De.rc" -#include "En.rc" +#include "de.rc" +#include "en.rc" diff --git a/reactos/tools/helper.mk b/reactos/tools/helper.mk index a46ee497e51..f9eb9933861 100644 --- a/reactos/tools/helper.mk +++ b/reactos/tools/helper.mk @@ -1,4 +1,4 @@ -# $Id: helper.mk,v 1.41 2003/07/27 14:08:38 hbirr Exp $ +# $Id: helper.mk,v 1.42 2003/08/09 17:08:14 mf Exp $ # # Helper makefile for ReactOS modules # Variables this makefile accepts: @@ -318,6 +318,10 @@ ifeq ($(TARGET_TYPE),gdi_driver) endif +# can be overidden with $(CXX) for linkage of c++ executables +LD_CC = $(CC) + + ifeq ($(TARGET_TYPE),program) ifeq ($(TARGET_APPTYPE),windows) MK_DEFENTRY := _WinMainCRTStartup @@ -581,7 +585,7 @@ endif $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) ifeq ($(MK_EXETYPE),dll) - $(CC) -Wl,--base-file,base.tmp \ + $(LD_CC) -Wl,--base-file,base.tmp \ -Wl,--entry,$(TARGET_ENTRY) \ $(TARGET_LFLAGS) \ -o junk.tmp \ @@ -591,7 +595,7 @@ ifeq ($(MK_EXETYPE),dll) --base-file base.tmp \ --output-exp temp.exp $(MK_EXTRACMD) - $(RM) base.tmp - $(CC) -Wl,--base-file,base.tmp \ + $(LD_CC) -Wl,--base-file,base.tmp \ -Wl,--entry,$(TARGET_ENTRY) \ $(TARGET_LFLAGS) \ temp.exp \ @@ -603,7 +607,7 @@ ifeq ($(MK_EXETYPE),dll) --output-exp temp.exp $(MK_EXTRACMD) - $(RM) base.tmp endif - $(CC) $(TARGET_LFLAGS) \ + $(LD_CC) $(TARGET_LFLAGS) \ -Wl,--entry,$(TARGET_ENTRY) $(MK_EXTRACMD2) \ -o $(MK_NOSTRIPNAME) \ $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS) @@ -619,7 +623,7 @@ $(MK_FULLNAME): $(MK_NOSTRIPNAME) $(MK_EXTRADEP) $(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS) $(STRIP) --strip-debug $(MK_STRIPPED_OBJECT) ifeq ($(MK_EXETYPE),dll) - $(CC) -Wl,--base-file,base.tmp \ + $(LD_CC) -Wl,--base-file,base.tmp \ -Wl,--entry,$(TARGET_ENTRY) \ -Wl,--strip-debug \ $(TARGET_LFLAGS) \ @@ -630,7 +634,7 @@ ifeq ($(MK_EXETYPE),dll) --base-file base.tmp \ --output-exp temp.exp $(MK_EXTRACMD) - $(RM) base.tmp - $(CC) -Wl,--base-file,base.tmp \ + $(LD_CC) -Wl,--base-file,base.tmp \ -Wl,--entry,$(TARGET_ENTRY) \ -Wl,--strip-debug \ $(TARGET_LFLAGS) \ @@ -643,7 +647,7 @@ ifeq ($(MK_EXETYPE),dll) --output-exp temp.exp $(MK_EXTRACMD) - $(RM) base.tmp endif - $(CC) $(TARGET_LFLAGS) \ + $(LD_CC) $(TARGET_LFLAGS) \ -Wl,--entry,$(TARGET_ENTRY) \ -Wl,--strip-debug \ $(MK_EXTRACMD2) \ @@ -665,7 +669,7 @@ else endif $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) - $(CC) -Wl,--base-file,base.tmp \ + $(LD_CC) -Wl,--base-file,base.tmp \ -Wl,--entry,$(TARGET_ENTRY) \ $(TARGET_LFLAGS) \ -nostartfiles -nostdlib \ @@ -676,7 +680,7 @@ $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) --base-file base.tmp \ --output-exp temp.exp $(MK_EXTRACMD) - $(RM) base.tmp - $(CC) $(TARGET_LFLAGS) \ + $(LD_CC) $(TARGET_LFLAGS) \ -Wl,--subsystem,native \ -Wl,--image-base,$(TARGET_BASE) \ -Wl,--file-alignment,0x1000 \ @@ -697,7 +701,7 @@ endif $(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) $(MK_NOSTRIPNAME) $(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS) $(STRIP) --strip-debug $(MK_STRIPPED_OBJECT) - $(CC) -Wl,--base-file,base.tmp \ + $(LD_CC) -Wl,--base-file,base.tmp \ -Wl,--entry,$(TARGET_ENTRY) \ $(TARGET_LFLAGS) \ -nostartfiles -nostdlib \ @@ -708,7 +712,7 @@ $(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) $(MK_N --base-file base.tmp \ --output-exp temp.exp $(MK_EXTRACMD) - $(RM) base.tmp - $(CC) $(TARGET_LFLAGS) \ + $(LD_CC) $(TARGET_LFLAGS) \ -Wl,--subsystem,native \ -Wl,--image-base,$(TARGET_BASE) \ -Wl,--file-alignment,0x1000 \ @@ -879,9 +883,9 @@ endif # ROS_USE_PCH %.o: %.c $(MK_PCHNAME) $(CC) $(TARGET_CFLAGS) -c $< -o $@ %.o: %.cc - $(CC) $(TARGET_CPPFLAGS) -c $< -o $@ + $(CXX) $(TARGET_CPPFLAGS) -c $< -o $@ %.o: %.cpp - $(CC) $(TARGET_CPPFLAGS) -c $< -o $@ + $(CXX) $(TARGET_CPPFLAGS) -c $< -o $@ %.o: %.S $(AS) $(TARGET_ASFLAGS) -c $< -o $@ %.o: %.s