From 5b3f0e0806460bfd1ba8445c8acde64739c826f5 Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Fri, 29 Aug 2003 14:52:57 +0000 Subject: [PATCH] Now we handle start menu popups via StartMenuRoot::TrackStartmenu(). svn path=/trunk/; revision=5919 --- .../subsys/system/explorer/doc/changes.txt | 1 + reactos/subsys/system/explorer/explorer.dsp | 12 +++---- .../system/explorer/taskbar/desktopbar.cpp | 34 ++++-------------- .../system/explorer/taskbar/desktopbar.h | 4 +-- .../system/explorer/taskbar/startmenu.cpp | 36 +++++++++++++------ .../subsys/system/explorer/utility/window.cpp | 10 +++--- .../subsys/system/explorer/utility/window.h | 23 ++++++++---- 7 files changed, 64 insertions(+), 56 deletions(-) diff --git a/reactos/subsys/system/explorer/doc/changes.txt b/reactos/subsys/system/explorer/doc/changes.txt index 4e7d05f2447..59d36c5a6e8 100644 --- a/reactos/subsys/system/explorer/doc/changes.txt +++ b/reactos/subsys/system/explorer/doc/changes.txt @@ -30,3 +30,4 @@ 26.08.2003 m. fuchs implemented tooltips and launching of date/time control panel applet for clock display 27.08.2003 m. fuchs partly implemented control panel window 28.08.2003 m. fuchs control panel window in cabinet view mode +29.09.2003 m. fuchs Now we handle start menu popups via StartMenuRoot::TrackStartmenu(). diff --git a/reactos/subsys/system/explorer/explorer.dsp b/reactos/subsys/system/explorer/explorer.dsp index d7e3a1552b9..1e22e1e9559 100644 --- a/reactos/subsys/system/explorer/explorer.dsp +++ b/reactos/subsys/system/explorer/explorer.dsp @@ -46,7 +46,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 /MT /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O1 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -71,7 +71,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 /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe @@ -97,7 +97,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 /MT /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -123,7 +123,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 /MT /W3 /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe @@ -149,7 +149,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 /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe @@ -175,7 +175,7 @@ LINK32=link.cmd # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /D "_NO_COMUTIL" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /D "_NO_COMUTIL" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe diff --git a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp index ea8868f02d0..06d42d19831 100644 --- a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp @@ -151,7 +151,7 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) else return 0; // disable any other resizing } else if (wparam == SC_TASKLIST) - ToggleStartmenu(); + ShowStartMenu(); goto def; case WM_SIZE: { @@ -176,14 +176,6 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) case WM_CLOSE: break; - case PM_STARTMENU_CLOSED: - _startMenuRoot = 0; - break; - - case WM_SETFOCUS: - CloseStartMenu(); - goto def; - case WM_HOTKEY: ProcessHotKey(wparam); break; @@ -203,7 +195,7 @@ int DesktopBar::Command(int id, int code) { switch(id) { case IDC_START: //TODO: startmenu should popup for WM_LBUTTONDOWN, not for WM_COMMAND - ToggleStartmenu(); + ShowStartMenu(); break; default: @@ -215,25 +207,13 @@ int DesktopBar::Command(int id, int code) } -void DesktopBar::ToggleStartmenu() +void DesktopBar::ShowStartMenu() { - if (_startMenuRoot && IsWindow(_startMenuRoot)) { // IsWindow(): safety first - // dispose Startmenu - DestroyWindow(_startMenuRoot); - _startMenuRoot = 0; - } else { - // create Startmenu - _startMenuRoot = StartMenuRoot::Create(_hwnd); - } -} + // create Startmenu + StartMenuRoot* startMenuRoot = GET_WINDOW(StartMenuRoot, StartMenuRoot::Create(_hwnd)); -void DesktopBar::CloseStartMenu() -{ - if (_startMenuRoot) { - DestroyWindow(_startMenuRoot); - - _startMenuRoot = 0; - } + if (startMenuRoot) + startMenuRoot->TrackStartmenu(); } diff --git a/reactos/subsys/system/explorer/taskbar/desktopbar.h b/reactos/subsys/system/explorer/taskbar/desktopbar.h index 47bb4a9ed4d..4a2b56dd37b 100644 --- a/reactos/subsys/system/explorer/taskbar/desktopbar.h +++ b/reactos/subsys/system/explorer/taskbar/desktopbar.h @@ -80,12 +80,10 @@ protected: void RegisterHotkeys(); void ProcessHotKey(int id_hotkey); - void ToggleStartmenu(); - void CloseStartMenu(); + void ShowStartMenu(); LRESULT ProcessCopyData(COPYDATASTRUCT* pcd); WindowHandle _hwndTaskBar; - WindowHandle _startMenuRoot; WindowHandle _hwndNotify; WindowHandle _hwndQuickLaunch; }; diff --git a/reactos/subsys/system/explorer/taskbar/startmenu.cpp b/reactos/subsys/system/explorer/taskbar/startmenu.cpp index 111a5602ba1..ad03d712e88 100644 --- a/reactos/subsys/system/explorer/taskbar/startmenu.cpp +++ b/reactos/subsys/system/explorer/taskbar/startmenu.cpp @@ -181,9 +181,6 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) CloseStartMenu(); break; - case WM_SETFOCUS: - break; // don't post WM_CANCELMODE in Window::WndProc when focusing the startmenu - case PM_STARTENTRY_FOCUSED: { //TODO: use TrackMouseEvent() and WM_MOUSEHOVER to wait a bit before opening submenus BOOL hasSubmenu = wparam; HWND hctrl = (HWND)lparam; @@ -467,13 +464,13 @@ LRESULT StartMenuButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) case WM_SETFOCUS: PostParent(PM_STARTENTRY_FOCUSED, _hasSubmenu, (LPARAM)_hwnd); - return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam); // don't post WM_CANCELMODE in Window::WndProc when focusing the startmenu + goto def; case WM_CANCELMODE: // route WM_CANCELMODE to the startmenu window return SendParent(nmsg, wparam, lparam); - default: + default: def: return super::WndProc(nmsg, wparam, lparam); } @@ -564,11 +561,32 @@ HWND StartMenuRoot::Create(HWND hwndDesktopBar) void StartMenuRoot::TrackStartmenu() { - //TODO - MSG msg; + HWND hwnd = _hwnd; + + while(IsWindow(hwnd)) { + if (!GetMessage(&msg, 0, 0, 0)) { + PostQuitMessage(msg.wParam); + break; + } + + // Check for a mouse click on any window, which is not part of the start menu + if (msg.message==WM_LBUTTONDOWN || msg.message==WM_MBUTTONDOWN || msg.message==WM_RBUTTONDOWN) { + StartMenu* menu_wnd = NULL; + + for(HWND hwnd=msg.hwnd; hwnd; hwnd=GetParent(hwnd)) { + menu_wnd = WINDOW_DYNAMIC_CAST(StartMenu, hwnd); + + if (menu_wnd) + break; + } + + if (!menu_wnd) { + DestroyWindow(_hwnd); + break; + } + } - while(GetMessage(&msg, 0, 0, 0)) { try { if (pretranslate_msg(&msg)) continue; @@ -587,8 +605,6 @@ void StartMenuRoot::TrackStartmenu() HandleException(e, g_Globals._hMainWnd); } } - - //@@return msg.wParam; } diff --git a/reactos/subsys/system/explorer/utility/window.cpp b/reactos/subsys/system/explorer/utility/window.cpp index 0f72b1d4002..f65021b4dae 100644 --- a/reactos/subsys/system/explorer/utility/window.cpp +++ b/reactos/subsys/system/explorer/utility/window.cpp @@ -222,15 +222,16 @@ LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPAR LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { +/*@@TODO: replaced by StartMenu::TrackStartmenu() HWND hwnd = _hwnd; -/*@@TODO: replace by StartMenu::TrackStartmenu() // close startup menu and other popup menus // This functionality is for tray notification icons missing in MS Windows. if (nmsg == WM_SETFOCUS) - CancelModes((HWND)wparam); //@@ erronesly cancels desktop bar resize when switching from another process + CancelModes((HWND)wparam); // erronesly cancels desktop bar resize when switching from another process */ - return DefWindowProc(hwnd, nmsg, wparam, lparam); + + return DefWindowProc(_hwnd, nmsg, wparam, lparam); } int Window::Command(int id, int code) @@ -263,11 +264,12 @@ SubclassedWindow::SubclassedWindow(HWND hwnd) LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) { +/*@@TODO: replaced by StartMenu::TrackStartmenu() // close startup menu and other popup menus // This functionality is for tray notification icons missing in MS Windows. if (nmsg == WM_SETFOCUS) CancelModes((HWND)wparam); - +*/ return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam); } diff --git a/reactos/subsys/system/explorer/utility/window.h b/reactos/subsys/system/explorer/utility/window.h index e2be7e966dc..e5085c8968a 100644 --- a/reactos/subsys/system/explorer/utility/window.h +++ b/reactos/subsys/system/explorer/utility/window.h @@ -77,8 +77,8 @@ struct Window : public WindowHandle static Window* get_window(HWND hwnd); #ifndef _MSC_VER - template static WNDCLASS* get_window(HWND hwnd) {return static_cast(get_window(hwnd));} -#define GET_WINDOW(WNDCLASS, hwnd) Window::get_window(hwnd) + template static CLASS* get_window(HWND hwnd) {return static_cast(get_window(hwnd));} +#define GET_WINDOW(CLASS, hwnd) Window::get_window(hwnd) #endif static void register_pretranslate(HWND hwnd); @@ -122,15 +122,26 @@ protected: #ifdef _MSC_VER -template struct GetWindowHelper { - static WNDCLASS* get_window(HWND hwnd) { - return static_cast(Window::get_window(hwnd)); +template struct GetWindowHelper +{ + static CLASS* get_window(HWND hwnd) { + return static_cast(Window::get_window(hwnd)); } }; -#define GET_WINDOW(WNDCLASS, hwnd) GetWindowHelper::get_window(hwnd) +#define GET_WINDOW(CLASS, hwnd) GetWindowHelper::get_window(hwnd) #endif +template struct TypeCheck +{ + static CLASS* dyn_cast(Window* wnd) + {return dynamic_cast(wnd);} +}; + +#define WINDOW_DYNAMIC_CAST(CLASS, hwnd) \ + TypeCheck::dyn_cast(Window::get_window(hwnd)) + + /** SubclassedWindow is used to wrap already existing window handles into C++ Window objects. To construct a object, use the "new" operator