[EXPLORER] -Use WM_POPUPSYSTEMMENU to open the system menu of a window. CORE-13400
[reactos.git] / reactos / base / shell / explorer / taskswnd.cpp
index 8341321..b673482 100644 (file)
@@ -21,9 +21,6 @@
 #include "precomp.h"
 #include <commoncontrols.h>
 
-#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
-#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
-
 /* Set DUMP_TASKS to 1 to enable a dump of the tasks and task groups every
    5 seconds */
 #define DUMP_TASKS  0
@@ -32,8 +29,8 @@
 #define MAX_TASKS_COUNT (0x7FFF)
 #define TASK_ITEM_ARRAY_ALLOC   64
 
-const WCHAR szTaskSwitchWndClass [] = TEXT("MSTaskSwWClass");
-const WCHAR szRunningApps [] = TEXT("Running Applications");
+const WCHAR szTaskSwitchWndClass[] = L"MSTaskSwWClass";
+const WCHAR szRunningApps[] = L"Running Applications";
 
 #if DEBUG_SHELL_HOOK
 const struct {
@@ -103,7 +100,7 @@ typedef struct _TASK_ITEM
 } TASK_ITEM, *PTASK_ITEM;
 
 class CTaskToolbar :
-    public CToolbar<TASK_ITEM>
+    public CWindowImplBaseT< CToolbar<TASK_ITEM>, CControlWinTraits >
 {
 public:
     INT UpdateTbButtonSpacing(IN BOOL bHorizontal, IN BOOL bThemed, IN UINT uiRows = 0, IN UINT uiBtnsPerLine = 0)
@@ -160,8 +157,29 @@ public:
         return SetButtonInfo(iButtonIndex, &tbbi) != 0;
     }
 
+    LRESULT OnNcHitTestToolbar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        POINT pt;
+
+        /* See if the mouse is on a button */
+        pt.x = GET_X_LPARAM(lParam);
+        pt.y = GET_Y_LPARAM(lParam);
+        ScreenToClient(&pt);
+
+        INT index = HitTest(&pt);
+        if (index < 0)
+        {
+            /* Make the control appear to be transparent outside of any buttons */
+            return HTTRANSPARENT;
+        }
+
+        bHandled = FALSE;
+        return 0;
+    }
+
 public:
     BEGIN_MSG_MAP(CNotifyToolbar)
+        MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTestToolbar)
     END_MSG_MAP()
 
     BOOL Initialize(HWND hWndParent)
@@ -170,7 +188,7 @@ public:
             TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_LIST | TBSTYLE_TRANSPARENT |
             CCS_TOP | CCS_NORESIZE | CCS_NODIVIDER;
 
-        return SubclassWindow(Create(hWndParent, styles));
+        return SubclassWindow(CToolbar::Create(hWndParent, styles));
     }
 };
 
@@ -220,8 +238,6 @@ public:
     }
     virtual ~CTaskSwitchWnd() { }
 
-    VOID TaskSwitchWnd_UpdateButtonsSize(IN BOOL bRedrawDisabled);
-
     INT GetWndTextFromTaskItem(IN PTASK_ITEM TaskItem, LPWSTR szBuf, DWORD cchBuf)
     {
         /* Get the window text without sending a message so we don't hang if an
@@ -420,7 +436,7 @@ public:
 
         icon = GetWndIcon(TaskItem->hWnd);
         if (!icon)
-            icon = static_cast<HICON>(LoadImage(NULL, MAKEINTRESOURCE(OIC_SAMPLE), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
+            icon = static_cast<HICON>(LoadImageW(NULL, MAKEINTRESOURCEW(OIC_SAMPLE), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
         TaskItem->IconIndex = ImageList_ReplaceIcon(m_ImageList, TaskItem->IconIndex, icon);
         tbbi.iImage = TaskItem->IconIndex;
 
@@ -565,7 +581,7 @@ public:
 
         icon = GetWndIcon(TaskItem->hWnd);
         if (!icon)
-            icon = static_cast<HICON>(LoadImage(NULL, MAKEINTRESOURCE(OIC_SAMPLE), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
+            icon = static_cast<HICON>(LoadImageW(NULL, MAKEINTRESOURCEW(OIC_SAMPLE), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE));
         TaskItem->IconIndex = ImageList_ReplaceIcon(m_ImageList, -1, icon);
 
         tbBtn.iBitmap = TaskItem->IconIndex;
@@ -977,8 +993,7 @@ public:
             TaskItem = AllocTaskItem();
             if (TaskItem != NULL)
             {
-                ZeroMemory(TaskItem,
-                    sizeof(*TaskItem));
+                ZeroMemory(TaskItem, sizeof(*TaskItem));
                 TaskItem->hWnd = hWnd;
                 TaskItem->Index = -1;
                 TaskItem->Group = AddToTaskGroup(hWnd);
@@ -1127,6 +1142,10 @@ public:
         LONG NewBtnSize;
         BOOL Horizontal;
 
+        int cx = GetSystemMetrics(SM_CXMINIMIZED);
+        int cy = m_ButtonSize.cy = GetSystemMetrics(SM_CYSIZE);
+        m_TaskBar.SetButtonSize(cx, cy);
+
         if (GetClientRect(&rcClient) && !IsRectEmpty(&rcClient))
         {
             if (m_ButtonCount > 0)
@@ -1140,7 +1159,11 @@ public:
                     tbm.dwMask = TBMF_BUTTONSPACING;
                     m_TaskBar.GetMetrics(&tbm);
 
-                    uiRows = (rcClient.bottom + tbm.cyButtonSpacing) / (m_ButtonSize.cy + tbm.cyButtonSpacing);
+                    if (m_ButtonSize.cy + tbm.cyButtonSpacing != 0)
+                        uiRows = (rcClient.bottom + tbm.cyButtonSpacing) / (m_ButtonSize.cy + tbm.cyButtonSpacing);
+                    else
+                        uiRows = 1;
+
                     if (uiRows == 0)
                         uiRows = 1;
 
@@ -1235,9 +1258,9 @@ public:
         if (::IsWindow(hWnd) && ::IsWindowVisible(hWnd) &&
             !m_Tray->IsSpecialHWND(hWnd))
         {
-            DWORD exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
+            DWORD exStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
             /* Don't list popup windows and also no tool windows */
-            if ((GetWindow(hWnd, GW_OWNER) == NULL || exStyle & WS_EX_APPWINDOW) &&
+            if ((::GetWindow(hWnd, GW_OWNER) == NULL || exStyle & WS_EX_APPWINDOW) &&
                 !(exStyle & WS_EX_TOOLWINDOW))
             {
                 TRACE("Adding task for %p...\n", hWnd);
@@ -1294,17 +1317,11 @@ public:
         m_ImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 1000);
         m_TaskBar.SetImageList(m_ImageList);
 
-        /* Calculate the default button size. Don't save this in m_ButtonSize.cx so that
-        the actual button width gets updated correctly on the first recalculation */
-        int cx = GetSystemMetrics(SM_CXMINIMIZED);
-        int cy = m_ButtonSize.cy = GetSystemMetrics(SM_CYSIZE) + (2 * GetSystemMetrics(SM_CYEDGE));
-        m_TaskBar.SetButtonSize(cx, cy);
-
         /* Set proper spacing between buttons */
         m_TaskBar.UpdateTbButtonSpacing(m_Tray->IsHorizontal(), m_Theme != NULL);
 
         /* Register the shell hook */
-        m_ShellHookMsg = RegisterWindowMessage(TEXT("SHELLHOOK"));
+        m_ShellHookMsg = RegisterWindowMessageW(L"SHELLHOOK");
 
         TRACE("ShellHookMsg got assigned number %d\n", m_ShellHookMsg);
 
@@ -1370,41 +1387,33 @@ public:
         switch ((INT) wParam)
         {
         case HSHELL_APPCOMMAND:
-            HandleAppCommand(wParam, lParam);
-            Ret = TRUE;
+            Ret = HandleAppCommand(wParam, lParam);
             break;
 
         case HSHELL_WINDOWCREATED:
-            Ret = AddTask((HWND) lParam);
+            AddTask((HWND) lParam);
             break;
 
         case HSHELL_WINDOWDESTROYED:
             /* The window still exists! Delay destroying it a bit */
             DeleteTask((HWND) lParam);
-            Ret = TRUE;
             break;
 
         case HSHELL_RUDEAPPACTIVATED:
         case HSHELL_WINDOWACTIVATED:
-            if (lParam)
-            {
-                ActivateTask((HWND) lParam);
-                Ret = TRUE;
-            }
+            ActivateTask((HWND) lParam);
             break;
 
         case HSHELL_FLASH:
             FlashTask((HWND) lParam);
-            Ret = TRUE;
             break;
 
         case HSHELL_REDRAW:
             RedrawTask((HWND) lParam);
-            Ret = TRUE;
             break;
 
         case HSHELL_TASKMAN:
-            PostMessage(m_Tray->GetHWND(), TWM_OPENSTARTMENU, 0, 0);
+            ::PostMessage(m_Tray->GetHWND(), TWM_OPENSTARTMENU, 0, 0);
             break;
 
         case HSHELL_ACTIVATESHELLWINDOW:
@@ -1420,7 +1429,7 @@ public:
         {
 #if DEBUG_SHELL_HOOK
             int i, found;
-            for (i = 0, found = 0; i != sizeof(hshell_msg) / sizeof(hshell_msg[0]); i++)
+            for (i = 0, found = 0; i != _countof(hshell_msg); i++)
             {
                 if (hshell_msg[i].msg == (INT) wParam)
                 {
@@ -1444,7 +1453,7 @@ public:
     {
         m_IsGroupingEnabled = bEnable;
 
-        /* Collapse or expand groups if neccessary */
+        /* Collapse or expand groups if necessary */
         UpdateButtonsSize(FALSE);
     }
 
@@ -1455,7 +1464,7 @@ public:
 
         if (::IsWindow(TaskItem->hWnd))
         {
-            bIsMinimized = IsIconic(TaskItem->hWnd);
+            bIsMinimized = ::IsIconic(TaskItem->hWnd);
             bIsActive = (TaskItem == m_ActiveTaskItem);
 
             TRACE("Active TaskItem %p, selected TaskItem %p\n", m_ActiveTaskItem, TaskItem);
@@ -1467,7 +1476,7 @@ public:
 
             if (!bIsMinimized && bIsActive)
             {
-                PostMessage(TaskItem->hWnd,
+                ::PostMessage(TaskItem->hWnd,
                     WM_SYSCOMMAND,
                     SC_MINIMIZE,
                     0);
@@ -1477,7 +1486,7 @@ public:
             {
                 if (bIsMinimized)
                 {
-                    PostMessage(TaskItem->hWnd,
+                    ::PostMessage(TaskItem->hWnd,
                         WM_SYSCOMMAND,
                         SC_RESTORE,
                         0);
@@ -1523,21 +1532,14 @@ public:
 
     VOID HandleTaskItemRightClick(IN OUT PTASK_ITEM TaskItem)
     {
+        POINT pt;
+        GetCursorPos(&pt);
 
-        HMENU hmenu = GetSystemMenu(TaskItem->hWnd, FALSE);
+        SetForegroundWindow(TaskItem->hWnd);
 
-        if (hmenu)
-        {
-            POINT pt;
-            int cmd;
-            GetCursorPos(&pt);
-            cmd = TrackPopupMenu(hmenu, TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, m_TaskBar.m_hWnd, NULL);
-            if (cmd)
-            {
-                SetForegroundWindow(TaskItem->hWnd);    // reactivate window after the context menu has closed
-                PostMessage(TaskItem->hWnd, WM_SYSCOMMAND, cmd, 0);
-            }
-        }
+        ActivateTask(TaskItem->hWnd);
+
+        ::SendMessageW(TaskItem->hWnd, WM_POPUPSYSTEMMENU, 0, MAKELPARAM(pt.x, pt.y));
     }
 
     VOID HandleTaskGroupRightClick(IN OUT PTASK_GROUP TaskGroup)
@@ -1585,7 +1587,7 @@ public:
 
             if (TaskItem != NULL && ::IsWindow(TaskItem->hWnd))
             {
-                /* Make the entire button flashing if neccessary */
+                /* Make the entire button flashing if necessary */
                 if (nmtbcd->nmcd.uItemState & CDIS_MARKED)
                 {
                     Ret = TBCDRF_NOBACKGROUND;
@@ -1684,26 +1686,6 @@ public:
         return TRUE;
     }
 
-    LRESULT OnNcHitTestToolbar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-    {
-        POINT pt;
-
-        /* See if the mouse is on a button */
-        pt.x = GET_X_LPARAM(lParam);
-        pt.y = GET_Y_LPARAM(lParam);
-        ScreenToClient(&pt);
-
-        INT index = m_TaskBar.HitTest(&pt);
-        if (index < 0)
-        {
-            /* Make the control appear to be transparent outside of any buttons */
-            return HTTRANSPARENT;
-        }
-
-        bHandled = FALSE;
-        return 0;
-    }
-
     LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
     {
         LRESULT Ret = TRUE;
@@ -1790,7 +1772,7 @@ public:
             RECT* prcMinRect = (RECT*) lParam;
             RECT rcItem, rcToolbar;
             m_TaskBar.GetItemRect(TaskItem->Index, &rcItem);
-            GetWindowRect(m_TaskBar.m_hWnd, &rcToolbar);
+            m_TaskBar.GetWindowRect(&rcToolbar);
 
             OffsetRect(&rcItem, rcToolbar.left, rcToolbar.top);
 
@@ -1800,6 +1782,11 @@ public:
         return FALSE;
     }
 
+    LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        return MA_NOACTIVATE;
+    }
+
     LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
     {
 #if DUMP_TASKS != 0
@@ -1813,6 +1800,22 @@ public:
         return TRUE;
     }
 
+    LRESULT OnSetFont(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        return m_TaskBar.SendMessageW(uMsg, wParam, lParam);
+    }
+
+    LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        if (wParam == SPI_SETNONCLIENTMETRICS)
+        {
+            /*  Don't update the font, this will be done when we get a WM_SETFONT from our parent */
+            UpdateButtonsSize(FALSE);
+        }
+
+        return 0;
+    }
+
     DECLARE_WND_CLASS_EX(szTaskSwitchWndClass, CS_DBLCLKS, COLOR_3DFACE)
 
     BEGIN_MSG_MAP(CTaskSwitchWnd)
@@ -1828,9 +1831,11 @@ public:
         MESSAGE_HANDLER(TSWM_UPDATETASKBARPOS, OnUpdateTaskbarPos)
         MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
         MESSAGE_HANDLER(WM_TIMER, OnTimer)
+        MESSAGE_HANDLER(WM_SETFONT, OnSetFont)
+        MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChanged)
         MESSAGE_HANDLER(m_ShellHookMsg, HandleShellHookMsg)
-    ALT_MSG_MAP(1)
-        MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTestToolbar)
+        MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
+        MESSAGE_HANDLER(WM_KLUDGEMINRECT, OnKludgeItemRect)
     END_MSG_MAP()
 
     HWND _Init(IN HWND hWndParent, IN OUT ITrayWindow *tray)