diff --git a/reactos/subsys/system/explorer/desktop/desktop.cpp b/reactos/subsys/system/explorer/desktop/desktop.cpp index 7f5d8b9ffc2..075cc460eaf 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.cpp +++ b/reactos/subsys/system/explorer/desktop/desktop.cpp @@ -35,6 +35,7 @@ #include "../taskbar/desktopbar.h" #include "../shell/mainframe.h" // for MainFrame::Create() +#include "../globals.h" #include "../externals.h" #include "../explorer_intres.h" @@ -289,10 +290,10 @@ LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) switch(nmsg) { case WM_CONTEXTMENU: if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam))) - goto def; ///@todo desktop context menu + DoDesktopContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)); break; - default: def: + default: return super::WndProc(nmsg, wparam, lparam); } @@ -347,3 +348,47 @@ bool DesktopShellView::DoContextMenu(int x, int y) return true; } + +HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y) +{ + IContextMenu* pcm; + + HRESULT hr = DesktopFolder()->GetUIObjectOf(_hwnd, 0, NULL, IID_IContextMenu, NULL, (LPVOID*)&pcm); + + if (SUCCEEDED(hr)) { + HMENU hmenu = CreatePopupMenu(); + + if (hmenu) { + hr = pcm->QueryContextMenu(hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST-1, CMF_NORMAL|CMF_EXPLORE); + + if (SUCCEEDED(hr)) { + AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); + AppendMenu(hmenu, 0, FCIDM_SHVIEWLAST-1, ResString(IDS_ABOUT_EXPLORER)); + + UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, _hwnd, NULL); + + if (idCmd == FCIDM_SHVIEWLAST-1) { + explorer_about(_hwnd); + } else if (idCmd) { + CMINVOKECOMMANDINFO cmi; + + cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); + cmi.fMask = 0; + cmi.hwnd = _hwnd; + cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - FCIDM_SHVIEWFIRST); + cmi.lpParameters = NULL; + cmi.lpDirectory = NULL; + cmi.nShow = SW_SHOWNORMAL; + cmi.dwHotKey = 0; + cmi.hIcon = 0; + + hr = pcm->InvokeCommand(&cmi); + } + } + } + + pcm->Release(); + } + + return hr; +} diff --git a/reactos/subsys/system/explorer/desktop/desktop.h b/reactos/subsys/system/explorer/desktop/desktop.h index 26d02b65377..e4fe235a2de 100644 --- a/reactos/subsys/system/explorer/desktop/desktop.h +++ b/reactos/subsys/system/explorer/desktop/desktop.h @@ -97,4 +97,5 @@ protected: int Notify(int id, NMHDR* pnmh); bool DoContextMenu(int x, int y); + HRESULT DoDesktopContextMenu(int x, int y); }; diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index 7589f4cd0b2..3c818c46435 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -136,8 +136,19 @@ void explorer_show_frame(HWND hwndDesktop, int cmdshow, LPTSTR lpCmdLine) ShowWindow(hMainFrame, cmdshow); UpdateWindow(hMainFrame); + bool valid_dir = false; + + if (lpCmdLine) { + DWORD attribs = GetFileAttributes(lpCmdLine); + + if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY)) + valid_dir = true; + else if (*lpCmdLine==':' || *lpCmdLine=='"') + valid_dir = true; + } + // Open the first child window after initializing the application - if (lpCmdLine) + if (valid_dir) PostMessage(hMainFrame, PM_OPEN_WINDOW, 0, (LPARAM)lpCmdLine); else PostMessage(hMainFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0); @@ -145,6 +156,69 @@ void explorer_show_frame(HWND hwndDesktop, int cmdshow, LPTSTR lpCmdLine) } + /// "About Explorer" Dialog +struct ExplorerAboutDlg : public + CtlColorParent< + OwnerDrawParent + > +{ + typedef CtlColorParent< + OwnerDrawParent + > super; + + ExplorerAboutDlg(HWND hwnd) + : super(hwnd) + { + SetWindowIcon(hwnd, IDI_REACTOS); + + new FlatButton(hwnd, IDOK); + + _hfont = CreateFont(20, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, TEXT("Sans Serif")); + new ColorStatic(hwnd, IDC_ROS_EXPLORER, RGB(32,32,128), 0, _hfont); + + new HyperlinkCtrl(hwnd, IDC_WWW); + + CenterWindow(hwnd); + } + + ~ExplorerAboutDlg() + { + DeleteObject(_hfont); + } + + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) + { + switch(nmsg) { + case WM_PAINT: + Paint(); + break; + + default: + return super::WndProc(nmsg, wparam, lparam); + } + + return 0; + } + + void Paint() + { + PaintCanvas canvas(_hwnd); + + HICON hicon = (HICON) LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(IDI_REACTOS_BIG), IMAGE_ICON, 0, 0, LR_SHARED); + + DrawIconEx(canvas, 20, 10, hicon, 0, 0, 0, 0, DI_NORMAL); + } + +protected: + HFONT _hfont; +}; + +void explorer_about(HWND hwndParent) +{ + Dialog::DoModal(IDD_ABOUT_EXPLORER, WINDOW_CREATOR(ExplorerAboutDlg), hwndParent); +} + + static void InitInstance(HINSTANCE hInstance) { CONTEXT("InitInstance"); diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index a6305167805..f137aef0b85 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -727,5 +727,9 @@ SOURCE=.\globals.h SOURCE=".\i386-stub-win32.c" # End Source File +# Begin Source File + +SOURCE=".\res\ros-big.ico" +# End Source File # End Target # End Project diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index 1110b92b203..a6d159f0df1 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -28,6 +28,7 @@ #define IDS_SEARCH_PRG 24 #define IDS_ALL_USERS 25 #define IDS_SEARCH 26 +#define IDS_ABOUT_EXPLORER 27 #define IDI_REACTOS 100 #define IDI_EXPLORER 101 #define IDI_STARTMENU 102 @@ -51,16 +52,20 @@ #define IDA_SEARCH_PROGRAM 133 #define IDI_APPICON 134 #define IDI_FLOATING 135 +#define IDD_ABOUT_EXPLORER 135 +#define IDI_REACTOS_BIG 137 #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 IDC_ROS_EXPLORER 1000 +#define IDC_WWW 1012 #define IDC_TOPIC 1017 #define IDC_MAILS_FOUND 1018 #define ID_REFRESH 1704 -#define ID_ABOUT 1803 +#define ID_ABOUT_WINEFILE 1705 #define IDC_FILETREE 10001 #define ID_EXPLORER_FAQ 10002 #define ID_WINDOW_AUTOSORT 0x8003 @@ -70,6 +75,8 @@ #define ID_DRIVE_SHELL_NS 0x9001 #define ID_DRIVE_UNIX_FS 0x9002 #define ID_DRIVE_FIRST 0x9003 +#define ID_ABOUT_WINDOWS 40002 +#define ID_ABOUT_EXPLORER 40003 #define ID_WINDOW_NEW 0xE130 #define ID_WINDOW_ARRANGE 0xE131 #define ID_WINDOW_CASCADE 0xE132 @@ -86,9 +93,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 135 -#define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_RESOURCE_VALUE 138 +#define _APS_NEXT_COMMAND_VALUE 40004 +#define _APS_NEXT_CONTROL_VALUE 1001 #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 index d2422b00017..cd16567ad68 100644 --- a/reactos/subsys/system/explorer/explorer_intres.rc +++ b/reactos/subsys/system/explorer/explorer_intres.rc @@ -50,7 +50,8 @@ BEGIN POPUP "&Ajutor" BEGIN MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ - MENUITEM "&Despre Explorer...", ID_ABOUT + MENUITEM "&Despre Explorer...", ID_ABOUT_EXPLORER + MENUITEM "Despre &OS...", ID_ABOUT_WINDOWS END END @@ -99,7 +100,6 @@ BEGIN IDS_EMPTY "(Empty)" IDS_RECENT "Documente Recente" IDS_ADMIN "Administrare" - IDS_SEARCH "Căutare..." END STRINGTABLE DISCARDABLE @@ -114,6 +114,8 @@ BEGIN IDS_BROWSE "Browse Files" IDS_SEARCH_PRG "Search Programm..." IDS_ALL_USERS "All Users\\" + IDS_SEARCH "Căutare..." + IDS_ABOUT_EXPLORER "&Despre Explorer..." END #endif // Romanian resources @@ -280,7 +282,7 @@ BEGIN MENUITEM "&Suchen...\tF1", ID_HELP MENUITEM "Hilfe &verwenden\tF1", ID_HELP_USING MENUITEM SEPARATOR - MENUITEM "Info about &Winefile...", ID_ABOUT + MENUITEM "Info about &Winefile...", ID_ABOUT_WINEFILE END END @@ -306,6 +308,19 @@ BEGIN PUSHBUTTON "&Hilfe",254,158,43,47,14 END +IDD_ABOUT_EXPLORER DIALOG DISCARDABLE 0, 0, 196, 109 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About ReactOS Explorer" +FONT 10, "MS Sans Serif" +BEGIN + LTEXT "ReactOS Explorer",IDC_ROS_EXPLORER,91,29,90,11 + LTEXT "(c) 2003 Martin Fuchs",IDC_STATIC,90,50,70,8 + LTEXT "http://www.sky.franken.de/explorer/",IDC_WWW,21,84,104, + 8 + CONTROL "OK",IDOK,"Button",BS_OWNERDRAW | BS_FLAT | WS_GROUP,151, + 90,38,12 +END + #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -348,6 +363,26 @@ IDI_ARROW ICON DISCARDABLE "res/arrow.ico" IDI_ARROW_SELECTED ICON DISCARDABLE "res/arrowsel.ico" IDI_APPICON ICON DISCARDABLE "res/appicon.ico" IDI_FLOATING ICON DISCARDABLE "res/floating.ico" +IDI_REACTOS_BIG ICON DISCARDABLE "res\\ros-big.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUT_EXPLORER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 189 + TOPMARGIN, 7 + BOTTOMMARGIN, 102 + END +END +#endif // APSTUDIO_INVOKED + ///////////////////////////////////////////////////////////////////////////// // @@ -371,7 +406,6 @@ BEGIN IDS_EMPTY "(Empty)" IDS_RECENT "Aktuelle Dokumente" IDS_ADMIN "Verwaltung" - IDS_SEARCH "Suche" END STRINGTABLE DISCARDABLE @@ -386,6 +420,8 @@ BEGIN IDS_BROWSE "Dateien" IDS_SEARCH_PRG "Suche Programm..." IDS_ALL_USERS "Alle Benutzer\\" + IDS_SEARCH "Suche" + IDS_ABOUT_EXPLORER "&Über Explorer..." END #endif // German (Germany) resources @@ -430,7 +466,8 @@ BEGIN POPUP "&Help" BEGIN MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ - MENUITEM "&About Explorer...", ID_ABOUT + MENUITEM "&About Explorer...", ID_ABOUT_EXPLORER + MENUITEM "About &OS...", ID_ABOUT_WINDOWS END END @@ -539,7 +576,7 @@ BEGIN MENUITEM "Help &Search...\tF1", ID_HELP MENUITEM "&Using Help\tF1", ID_HELP_USING MENUITEM SEPARATOR - MENUITEM "Info about &Winefile...", ID_ABOUT + MENUITEM "Info about &Winefile...", ID_ABOUT_WINEFILE END END @@ -621,7 +658,6 @@ BEGIN IDS_EMPTY "(Empty)" IDS_RECENT "Recent Documents" IDS_ADMIN "Administration" - IDS_SEARCH "Search" END STRINGTABLE DISCARDABLE @@ -636,6 +672,8 @@ BEGIN IDS_BROWSE "Browse Files" IDS_SEARCH_PRG "Search Programm..." IDS_ALL_USERS "All Users\\" + IDS_SEARCH "Search" + IDS_ABOUT_EXPLORER "&About Explorer..." END #endif // English (U.S.) resources @@ -658,14 +696,14 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH IDM_MAINFRAME MENU PRELOAD DISCARDABLE BEGIN - POPUP "Fichier" + POPUP "&Fichier" BEGIN - MENUITEM "Fermer", ID_FILE_EXIT + MENUITEM "&Fermer", ID_FILE_EXIT END - POPUP "Affichage" + POPUP "&Affichage" BEGIN - MENUITEM "Barre d'outils", ID_VIEW_TOOL_BAR - MENUITEM "Barre d'état", ID_VIEW_STATUSBAR + MENUITEM "Barre d'&outils", ID_VIEW_TOOL_BAR + MENUITEM "Barre d'&état", ID_VIEW_STATUSBAR END POPUP "&Window" BEGIN @@ -677,10 +715,11 @@ BEGIN MENUITEM "Arrange &Symbols", ID_WINDOW_ARRANGE MENUITEM "&Refresh\tF5", ID_REFRESH END - POPUP "Aide" + POPUP "A&ide" BEGIN - MENUITEM "FAQ Explorateur...", ID_EXPLORER_FAQ - MENUITEM "A propos de l'explorateur...", ID_ABOUT + MENUITEM "&FAQ Explorateur...", ID_EXPLORER_FAQ + MENUITEM "A propos de l'&explorateur...", ID_ABOUT_WINDOWS + MENUITEM "A propos de l'&OS...", ID_ABOUT_EXPLORER END END @@ -729,7 +768,6 @@ BEGIN IDS_EMPTY "(Vide)" IDS_RECENT "Documents récents" IDS_ADMIN "Administration" - IDS_SEARCH "Rechercher" END STRINGTABLE DISCARDABLE @@ -744,6 +782,8 @@ BEGIN IDS_BROWSE "Parcourir" IDS_SEARCH_PRG "Recherche Programme..." IDS_ALL_USERS "Tous les utilisateurs\\" + IDS_SEARCH "Rechercher" + IDS_ABOUT_EXPLORER "A propos de l'explorateur..." END #endif // French (France) resources diff --git a/reactos/subsys/system/explorer/externals.h b/reactos/subsys/system/explorer/externals.h index 81ca8d70b86..579a1941aa0 100644 --- a/reactos/subsys/system/explorer/externals.h +++ b/reactos/subsys/system/explorer/externals.h @@ -40,6 +40,9 @@ extern int explorer_main(HINSTANCE hinstance, HWND hwndDesktop, LPTSTR lpCmdLine // display explorer/file manager window extern void explorer_show_frame(HWND hwndDesktop, int cmdshow, LPTSTR lpCmdLine=NULL); + // display explorer "About" dialog +extern void explorer_about(HWND hwndParent); + // test for already running desktop instance extern BOOL IsAnyDesktopRunning(); diff --git a/reactos/subsys/system/explorer/res/ros-big.ico b/reactos/subsys/system/explorer/res/ros-big.ico new file mode 100644 index 00000000000..7721efe24bd Binary files /dev/null and b/reactos/subsys/system/explorer/res/ros-big.ico differ diff --git a/reactos/subsys/system/explorer/shell/mainframe.cpp b/reactos/subsys/system/explorer/shell/mainframe.cpp index ee8bed88865..4d5783bfa1c 100644 --- a/reactos/subsys/system/explorer/shell/mainframe.cpp +++ b/reactos/subsys/system/explorer/shell/mainframe.cpp @@ -30,6 +30,7 @@ #include "../explorer.h" #include "../globals.h" +#include "../externals.h" #include "../explorer_intres.h" @@ -526,10 +527,14 @@ int MainFrame::Command(int id, int code) ///@todo There are even more menu items! - case ID_ABOUT: + case ID_ABOUT_WINDOWS: ShellAbout(_hwnd, ResString(IDS_TITLE), NULL, 0); break; + case ID_ABOUT_EXPLORER: + explorer_about(_hwnd); + break; + case ID_EXPLORER_FAQ: launch_file(_hwnd, TEXT("http://www.sky.franken.de/explorer/"), SW_SHOWNORMAL); break; diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index 4180a392b40..7c225aa0277 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -975,7 +975,7 @@ void StartMenuRoot::ShowLaunchDialog(HWND hwndDesktopBar) static LPCSTR szTitle = "Create New Task"; static LPCSTR szText = "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you."; - static DynamicFct RunFileDlg(TEXT("SHELL32"), 61); + static DynamicFct RunFileDlg(TEXT("WSHELL32"), 61); // Show "Run..." dialog if (RunFileDlg) { @@ -1116,10 +1116,12 @@ int SearchMenu::Command(int id, int code) break; case IDC_SEARCH_FILES: + CloseStartMenu(id); ShowSearchDialog(); break; case IDC_SEARCH_COMPUTER: + CloseStartMenu(id); ShowSearchComputer(); break; diff --git a/reactos/subsys/system/explorer/utility/shellclasses.cpp b/reactos/subsys/system/explorer/utility/shellclasses.cpp index 3ab67c4bd91..d447f3e7173 100644 --- a/reactos/subsys/system/explorer/utility/shellclasses.cpp +++ b/reactos/subsys/system/explorer/utility/shellclasses.cpp @@ -434,25 +434,16 @@ HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int // HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm); if (SUCCEEDED(hr)) { - HMENU hPopup = CreatePopupMenu(); + HMENU hmenu = CreatePopupMenu(); - if (hPopup) { - hr = pcm->QueryContextMenu(hPopup, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL|CMF_EXPLORE); + if (hmenu) { + hr = pcm->QueryContextMenu(hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 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, x, y, 0, hwndParent, NULL); - - if (pcm2) { - pcm2->Release(); - pcm2 = NULL; - } + UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL); if (idCmd) { - CMINVOKECOMMANDINFO cmi; + CMINVOKECOMMANDINFO cmi; cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); cmi.fMask = 0; @@ -462,7 +453,7 @@ HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cmi.lpDirectory = NULL; cmi.nShow = SW_SHOWNORMAL; cmi.dwHotKey = 0; - cmi.hIcon = NULL; + cmi.hIcon = 0; hr = pcm->InvokeCommand(&cmi); } diff --git a/reactos/subsys/system/explorer/utility/utility.cpp b/reactos/subsys/system/explorer/utility/utility.cpp index 9630b2d3ce0..444128fdc58 100644 --- a/reactos/subsys/system/explorer/utility/utility.cpp +++ b/reactos/subsys/system/explorer/utility/utility.cpp @@ -101,10 +101,22 @@ void display_error(HWND hwnd, DWORD error) //@@ CONTEXT mit ausgeben -> display_ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL)) { LOG(FmtString(TEXT("display_error(%#x): %s"), error, msg)); + + SetLastError(0); MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK); + + if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) + MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK); } else { LOG(FmtString(TEXT("Unknown Error %#x"), error)); - MessageBox(hwnd, FmtString(TEXT("Unknown Error %#x"), error), TEXT("ROS Explorer"), MB_OK); + + FmtString msg(TEXT("Unknown Error %#x"), error); + + SetLastError(0); + MessageBox(hwnd, msg, TEXT("ROS Explorer"), MB_OK); + + if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) + MessageBox(0, msg, TEXT("ROS Explorer"), MB_OK); } LocalFree(msg); diff --git a/reactos/subsys/system/explorer/utility/utility.h b/reactos/subsys/system/explorer/utility/utility.h index 83b43499eb3..9482d341ee5 100644 --- a/reactos/subsys/system/explorer/utility/utility.h +++ b/reactos/subsys/system/explorer/utility/utility.h @@ -605,6 +605,8 @@ struct String String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;} String& operator=(const super& s) {super::assign(s); return *this;} + void assign(LPCTSTR s) {super::assign(s);} + void assign(LPCTSTR s, int l) {super::assign(s, l);} operator LPCTSTR() const {return c_str();} diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index 623d2e1c845..4dd1922ac25 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -930,6 +930,221 @@ void PictureButton::DrawItem(LPDRAWITEMSTRUCT dis) } +void FlatButton::DrawItem(LPDRAWITEMSTRUCT dis) +{ + UINT style = DFCS_BUTTONPUSH; + + if (dis->itemState & ODS_DISABLED) + style |= DFCS_INACTIVE; + + RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; + + if (dis->itemState & ODS_SELECTED) { + style |= DFCS_PUSHED; + ++textRect.left; ++textRect.top; + ++textRect.right; ++textRect.bottom; + } + + FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE)); + + // highlight the button? + if (_active) + DrawEdge(dis->hDC, &dis->rcItem, EDGE_ETCHED, BF_RECT); + else if (GetWindowStyle(_hwnd) & BS_FLAT) // Only with BS_FLAT there will be drawn a frame to show highlighting. + DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT); + + TCHAR txt[BUFFER_LEN]; + int txt_len = GetWindowText(_hwnd, txt, BUFFER_LEN); + + if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) { + COLORREF gray = GetSysColor(COLOR_GRAYTEXT); + + if (gray) { + { + TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNHIGHLIGHT)); + RECT shadowRect = {textRect.left+1, textRect.top+1, textRect.right+1, textRect.bottom+1}; + DrawText(dis->hDC, txt, txt_len, &shadowRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + } + + BkMode mode(dis->hDC, TRANSPARENT); + TextColor lcColor(dis->hDC, gray); + DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + } else { + int old_r = textRect.right; + int old_b = textRect.bottom; + DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_CALCRECT); + int x = textRect.left + (old_r-textRect.right)/2; + int y = textRect.top + (old_b-textRect.bottom)/2; + int w = textRect.right-textRect.left; + int h = textRect.bottom-textRect.top; + s_MyDrawText_Rect.right = w; + s_MyDrawText_Rect.bottom = h; + GrayString(dis->hDC, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)txt, txt_len, x, y, w, h); + } + } else { + TextColor lcColor(dis->hDC, _active? _activeColor: _textColor); + DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + } + + if (dis->itemState & ODS_FOCUS) { + RECT rect = { + dis->rcItem.left+3, dis->rcItem.top+3, + dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 + }; + if (dis->itemState & ODS_SELECTED) { + ++rect.left; ++rect.top; + ++rect.right; ++rect.bottom; + } + DrawFocusRect(dis->hDC, &rect); + } +} + +LRESULT FlatButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) +{ + switch(nmsg) { + case WM_MOUSEMOVE: { + bool active = false; + + if (IsWindowEnabled(_hwnd)) { + DWORD pid_foreground; + HWND hwnd_foreground = GetForegroundWindow(); //@@ vielleicht besser über WM_ACTIVATEAPP-Abfrage + GetWindowThreadProcessId(hwnd_foreground, &pid_foreground); + + if (GetCurrentProcessId() == pid_foreground) { + POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; + ClientRect clntRect(_hwnd); + + // highlight the button? + if (pt.x>=clntRect.left && pt.x=clntRect.top && pt.y=clntRect.right || pt.y=clntRect.bottom) + goto cancel_press; + + goto def;} + + case WM_CANCELMODE: + cancel_press: { + TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE|TME_CANCEL, _hwnd/*, HOVER_DEFAULT*/}; + _TrackMouseEvent(&tme); + _active = false; + ReleaseCapture();} + // fall through + + case WM_MOUSELEAVE: + if (_active) { + _active = false; + + InvalidateRect(_hwnd, NULL, TRUE); + } + + return 0; + + default: def: + return super::WndProc(nmsg, wparam, lparam); + } +} + + +HyperlinkCtrl::HyperlinkCtrl(HWND hwnd, COLORREF colorLink, COLORREF colorVisited) + : super(hwnd), + _textColor(colorLink), + _colorVisited(colorVisited), + _hfont(0), + _crsr_link(0), + _cmd(ResString(GetDlgCtrlID(hwnd))) +{ + init(); +} + +HyperlinkCtrl::HyperlinkCtrl(HWND owner, int id, COLORREF colorLink, COLORREF colorVisited) + : super(GetDlgItem(owner, id)), + _textColor(colorLink), + _colorVisited(colorVisited), + _hfont(0), + _crsr_link(0), + _cmd(ResString(id)) +{ + init(); +} + +void HyperlinkCtrl::init() +{ + if (_cmd.empty()) { + TCHAR txt[BUFFER_LEN]; + _cmd.assign(txt, GetWindowText(_hwnd, txt, BUFFER_LEN)); + } +} + +HyperlinkCtrl::~HyperlinkCtrl() +{ + if (_hfont) + DeleteObject(_hfont); +} + +LRESULT HyperlinkCtrl::WndProc(UINT message, WPARAM wparam, LPARAM lparam) +{ + switch(message) { + case PM_DISPATCH_CTLCOLOR: { + if (!_hfont) { + HFONT hfont = (HFONT) SendMessage(_hwnd, WM_GETFONT, 0, 0); + LOGFONT lf; GetObject(hfont, sizeof(lf), &lf); + lf.lfUnderline = TRUE; + _hfont = CreateFontIndirect(&lf); + } + + HDC hdc = (HDC) wparam; + SetTextColor(hdc, _textColor); //@@ + SelectFont(hdc, _hfont); + SetBkMode(hdc, TRANSPARENT); + return (LRESULT)GetStockObject(HOLLOW_BRUSH); + } + + case WM_SETCURSOR: + if (!_crsr_link) + _crsr_link = LoadCursor(0, IDC_HAND); + + if (_crsr_link) + SetCursor(_crsr_link); + return 0; + + case WM_NCHITTEST: + return HTCLIENT; // Aktivierung von Maus-Botschaften + + case WM_LBUTTONDOWN: + if (LaunchLink()) { + _textColor = _colorVisited; + InvalidateRect(_hwnd, NULL, FALSE); + } else + MessageBeep(0); + return 0; + + default: + return super::WndProc(message, wparam, lparam); + } +} + + ToolTip::ToolTip(HWND owner) : super(CreateWindowEx(WS_EX_TOPMOST|WS_EX_NOPARENTNOTIFY, TOOLTIPS_CLASS, 0, WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index 0d077debef0..443463d6cef 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -493,7 +493,6 @@ struct Static : public WindowHandle }; -/* // control color message routing for ColorStatic and HyperlinkCtrl #define PM_DISPATCH_CTLCOLOR (WM_APP+0x08) @@ -522,7 +521,6 @@ template struct CtlColorParent : public BASE } } }; -*/ #define PM_DISPATCH_DRAWITEM (WM_APP+0x09) @@ -596,6 +594,26 @@ protected: */ +struct FlatButton : public OwnerdrawnButton +{ + typedef OwnerdrawnButton super; + + FlatButton(HWND hwnd) + : super(hwnd), _active(false) {} + + FlatButton(HWND owner, int id) + : super(GetDlgItem(owner, IDOK)), _active(false) {} + +protected: + LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); + virtual void DrawItem(LPDRAWITEMSTRUCT dis); + + COLORREF _textColor; + COLORREF _activeColor; + bool _active; +}; + + /** Subclass button controls to paint pictures left to the labels. The buttons should have set the style bit BS_OWNERDRAW. @@ -619,6 +637,88 @@ protected: }; +struct ColorStatic : public SubclassedWindow +{ + typedef SubclassedWindow super; + + ColorStatic(HWND hwnd, COLORREF textColor=RGB(255,0,0), HBRUSH hbrush_bkgnd=0, HFONT hfont=0) + : super(hwnd), + _textColor(textColor), + _hbrush_bkgnd(hbrush_bkgnd), + _hfont(hfont) + { + } + + ColorStatic(HWND owner, int id, COLORREF textColor=RGB(255,0,0), HBRUSH hbrush_bkgnd=0, HFONT hfont=0) + : super(GetDlgItem(owner, id)), + _textColor(textColor), + _hbrush_bkgnd(hbrush_bkgnd), + _hfont(hfont) + { + } + +protected: + LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) + { + if (message == PM_DISPATCH_CTLCOLOR) { + HDC hdc = (HDC) wparam; + + SetTextColor(hdc, _textColor); + + if (_hfont) + SelectFont(hdc, _hfont); + + if (_hbrush_bkgnd) + return (LRESULT)_hbrush_bkgnd; + else { + SetBkMode(hdc, TRANSPARENT); + return (LRESULT)GetStockBrush(HOLLOW_BRUSH); + } + } else + return super::WndProc(message, wparam, lparam); + } + + COLORREF _textColor; + HBRUSH _hbrush_bkgnd; + HFONT _hfont; +}; + + + /// Hyperlink Controls + +struct HyperlinkCtrl : public SubclassedWindow +{ + typedef SubclassedWindow super; + + HyperlinkCtrl(HWND hwnd, COLORREF colorLink=RGB(0,0,255), COLORREF colorVisited=RGB(128,0,128)); + HyperlinkCtrl(HWND owner, int id, COLORREF colorLink=RGB(0,0,255), COLORREF colorVisited=RGB(128,0,128)); + + ~HyperlinkCtrl(); + + String _cmd; + +protected: + COLORREF _textColor; + COLORREF _colorVisited; + HFONT _hfont; + HCURSOR _crsr_link; + + LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam); + + void init(); + + bool LaunchLink() + { + if (!_cmd.empty()) { + HINSTANCE hinst = ShellExecute(GetParent(_hwnd), _T("open"), _cmd, 0, 0, SW_SHOWNORMAL); + return (int)hinst > HINSTANCE_ERROR; + } + + return true; + } +}; + + /// encapsulation of tool tip controls struct ToolTip : public WindowHandle {