[EXPLORER][SHELL32][USER32] Implement 'Show the Desktop' action of Task Bar (#668)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Fri, 13 Jul 2018 08:34:42 +0000 (17:34 +0900)
committerHermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org>
Fri, 13 Jul 2018 08:34:42 +0000 (10:34 +0200)
The keyboard shortcuts Win+D and Win+M are also enabled.

- Implement IShellDispatch4::ToggleDesktop().
- Implement some commands in CTrayWindow.
- Add "sdk/include/reactos/traycmd.h" for tray commands.
- Fix task window switching.
- Improve the user32!SwitchToThisWindow() function and use it.

CORE-14318, CORE-13157
See also: CORE-14806 and CORE-8723

33 files changed:
base/shell/explorer/lang/bg-BG.rc
base/shell/explorer/lang/cs-CZ.rc
base/shell/explorer/lang/de-DE.rc
base/shell/explorer/lang/en-US.rc
base/shell/explorer/lang/es-ES.rc
base/shell/explorer/lang/et-EE.rc
base/shell/explorer/lang/fi-FI.rc
base/shell/explorer/lang/fr-FR.rc
base/shell/explorer/lang/he-IL.rc
base/shell/explorer/lang/it-IT.rc
base/shell/explorer/lang/ja-JP.rc
base/shell/explorer/lang/ko-KR.rc
base/shell/explorer/lang/lt-LT.rc
base/shell/explorer/lang/ms-MY.rc
base/shell/explorer/lang/nl-NL.rc
base/shell/explorer/lang/no-NO.rc
base/shell/explorer/lang/pl-PL.rc
base/shell/explorer/lang/pt-BR.rc
base/shell/explorer/lang/ro-RO.rc
base/shell/explorer/lang/ru-RU.rc
base/shell/explorer/lang/sk-SK.rc
base/shell/explorer/lang/sq-AL.rc
base/shell/explorer/lang/tr-TR.rc
base/shell/explorer/lang/uk-UA.rc
base/shell/explorer/lang/zh-CN.rc
base/shell/explorer/lang/zh-TW.rc
base/shell/explorer/precomp.h
base/shell/explorer/resource.h
base/shell/explorer/taskswnd.cpp
base/shell/explorer/traywnd.cpp
dll/win32/shell32/CShellDispatch.cpp
sdk/include/reactos/traycmd.h [new file with mode: 0644]
win32ss/user/user32/windows/window.c

index aed0ade..821b4ba 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Свойства на задачната лента и на пусковия изборник"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 784ba32..52b9e27 100644 (file)
@@ -203,4 +203,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Vlastnosti hlavního panelu a Start menu"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 9e49bb9..b904f31 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Taskleisten- und Startmenüeinstellungen"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 0f81474..abf909a 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Taskbar and Start Menu"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 7cc3d6c..c37a5fc 100644 (file)
@@ -207,4 +207,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Propiedades de la Barra de tareas y del Menú Inicio"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 8176660..7f057af 100644 (file)
@@ -204,4 +204,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Tegumiriba ja Menüü Start"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 20a0aaf..adfaeb4 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Tehtäväpalkki ja Käynnistä Valikko"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 55782f5..6654292 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Barrre des tâches et menu démarrer"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index ba0d8e2..8791b8f 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "שורת המשימות ושולחן העבודה"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 8f6adba..4d1638c 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Proprietà della Barra delle applicazioni e del Menú di avvio"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index f7036c1..3e67534 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "タスクバーとスタートメニュー"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 7223055..33c1e95 100644 (file)
@@ -199,4 +199,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Taskbar and Start Menu"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index b2b432c..347af77 100644 (file)
@@ -200,4 +200,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Taskbar and Start Menu"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 09e8cd7..5e97a72 100644 (file)
@@ -199,4 +199,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Bar Tugas dan Menu Mula"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index e72f7ef..713b311 100644 (file)
@@ -197,4 +197,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Taakbalk en menu Start eigenschappen"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 3709a28..3ceb3c1 100644 (file)
@@ -198,4 +198,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Egenskaper for oppgavelinjen og startmeny"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 48231d2..edd5f4d 100644 (file)
@@ -207,4 +207,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Właściwości paska zadań i menu Start"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 4055b5b..0bf0473 100644 (file)
@@ -199,4 +199,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Propriedades do Barra de Tarefas e Menu Iniciar"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 211837f..c7fb6e4 100644 (file)
@@ -199,4 +199,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Bara de activități și meniul „Pornire”"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 0804d1d..03f6bae 100644 (file)
@@ -199,4 +199,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Меню ""Пуск"" и панель задач"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index b49077b..f6b28db 100644 (file)
@@ -202,4 +202,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Vlastnosti panela úloh a ponuky Štart"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 4961764..a561a2f 100644 (file)
@@ -201,4 +201,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Taskbar dhe Start Menu"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 80ba2a3..59e924a 100644 (file)
@@ -199,4 +199,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Görev Çubuğu ve Başlat Seçkesi"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index a634995..865528b 100644 (file)
@@ -205,4 +205,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "Властивості меню Пуск та Панелі завдань"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 90d6032..25cdb9e 100644 (file)
@@ -206,4 +206,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "任务栏和开始菜单属性"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index c0bef07..84390ad 100644 (file)
@@ -205,4 +205,5 @@ END
 STRINGTABLE
 BEGIN
     IDS_TASKBAR_STARTMENU_PROP_CAPTION "工作列及開始功能表"
+    IDS_RESTORE_ALL "&Show Open Windows"
 END
index 914add0..ea56448 100644 (file)
@@ -29,6 +29,7 @@
 #include <atlwin.h>
 #include <atlstr.h>
 #include <atlcoll.h>
+#include <atlsimpcoll.h>
 #include <shellapi.h>
 #include <shlobj.h>
 #include <shlwapi.h>
index aed1e08..b773da6 100644 (file)
 #define IDS_PROPERTIES                     720
 #define IDS_HELP_COMMAND                   732
 #define IDS_TASKBAR_STARTMENU_PROP_CAPTION 810
+#define IDS_RESTORE_ALL                    811
 
 /*******************************************************************************\
 |*                              Control Resources                              *|
 #define ID_SHELL_CMD_CASCADE_WND        (410)
 #define ID_SHELL_CMD_CUST_NOTIF         (411)
 #define ID_SHELL_CMD_ADJUST_DAT         (412)
+#define ID_SHELL_CMD_RESTORE_ALL        (413)
index fe8ec05..3cadd49 100644 (file)
@@ -1582,25 +1582,13 @@ public:
 
             if (!bIsMinimized && bIsActive)
             {
-                ::PostMessage(TaskItem->hWnd,
-                    WM_SYSCOMMAND,
-                    SC_MINIMIZE,
-                    0);
+                ::ShowWindowAsync(TaskItem->hWnd, SW_MINIMIZE);
                 TRACE("Valid button clicked. App window Minimized.\n");
             }
             else
             {
-                if (bIsMinimized)
-                {
-                    ::PostMessage(TaskItem->hWnd,
-                        WM_SYSCOMMAND,
-                        SC_RESTORE,
-                        0);
-                    TRACE("Valid button clicked. App window Restored.\n");
-                }
-
-                SetForegroundWindow(TaskItem->hWnd);
-                TRACE("Valid button clicked. App window Activated.\n");
+                ::SwitchToThisWindow(TaskItem->hWnd, TRUE);
+                TRACE("Valid button clicked. App window Restored.\n");
             }
         }
     }
index aec731d..8fd6c55 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "precomp.h"
 #include <commoncontrols.h>
+#include <traycmd.h>
 
 HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
 
@@ -56,6 +57,78 @@ HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, ICont
 
 static const WCHAR szTrayWndClass[] = L"Shell_TrayWnd";
 
+struct EFFECTIVE_INFO
+{
+    HWND hwndFound;
+    HWND hwndDesktop;
+    HWND hwndProgman;
+    HWND hTrayWnd;
+    BOOL bMustBeInMonitor;
+};
+
+static BOOL CALLBACK
+FindEffectiveProc(HWND hwnd, LPARAM lParam)
+{
+    EFFECTIVE_INFO *pei = (EFFECTIVE_INFO *)lParam;
+
+    if (!IsWindowVisible(hwnd) || IsIconic(hwnd))
+        return TRUE;    // continue
+
+    if (pei->hTrayWnd == hwnd || pei->hwndDesktop == hwnd ||
+        pei->hwndProgman == hwnd)
+    {
+        return TRUE;    // continue
+    }
+
+    if (pei->bMustBeInMonitor)
+    {
+        // is the window in the nearest monitor?
+        HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+        if (hMon)
+        {
+            MONITORINFO info;
+            ZeroMemory(&info, sizeof(info));
+            info.cbSize = sizeof(info);
+            if (GetMonitorInfoW(hMon, &info))
+            {
+                RECT rcWindow, rcMonitor, rcIntersect;
+                rcMonitor = info.rcMonitor;
+
+                GetWindowRect(hwnd, &rcWindow);
+
+                if (!IntersectRect(&rcIntersect, &rcMonitor, &rcWindow))
+                    return TRUE;    // continue
+            }
+        }
+    }
+
+    pei->hwndFound = hwnd;
+    return FALSE;   // stop if found
+}
+
+static BOOL
+IsThereAnyEffectiveWindow(BOOL bMustBeInMonitor)
+{
+    EFFECTIVE_INFO ei;
+    ei.hwndFound = NULL;
+    ei.hwndDesktop = GetDesktopWindow();
+    ei.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
+    ei.hwndProgman = FindWindowW(L"Progman", NULL);
+    ei.bMustBeInMonitor = bMustBeInMonitor;
+
+    EnumWindows(FindEffectiveProc, (LPARAM)&ei);
+    if (ei.hwndFound && FALSE)
+    {
+        WCHAR szClass[64], szText[64];
+        GetClassNameW(ei.hwndFound, szClass, _countof(szClass));
+        GetWindowTextW(ei.hwndFound, szText, _countof(szText));
+        MessageBoxW(NULL, szText, szClass, 0);
+    }
+    return ei.hwndFound != NULL;
+}
+
+CSimpleArray<HWND>  g_MinimizedAll;
+
 /*
  * ITrayWindow
  */
@@ -486,6 +559,18 @@ public:
                      SW_SHOWNORMAL);
     }
 
+    VOID ToggleDesktop()
+    {
+        if (::IsThereAnyEffectiveWindow(TRUE))
+        {
+            ShowDesktop();
+        }
+        else
+        {
+            RestoreAll();
+        }
+    }
+
     BOOL STDMETHODCALLTYPE ExecContextMenuCmd(IN UINT uiCmd)
     {
         switch (uiCmd)
@@ -519,6 +604,7 @@ public:
             break;
 
         case ID_SHELL_CMD_SHOW_DESKTOP:
+            ShowDesktop();
             break;
 
         case ID_SHELL_CMD_TILE_WND_H:
@@ -542,6 +628,10 @@ public:
             ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
             break;
 
+        case ID_SHELL_CMD_RESTORE_ALL:
+            RestoreAll();
+            break;
+
         default:
             TRACE("ITrayWindow::ExecContextMenuCmd(%u): Unhandled Command ID!\n", uiCmd);
             return FALSE;
@@ -580,10 +670,13 @@ public:
         case IDHK_PREV_TASK:
             break;
         case IDHK_MINIMIZE_ALL:
+            MinimizeAll();
             break;
         case IDHK_RESTORE_ALL:
+            RestoreAll();
             break;
         case IDHK_DESKTOP:
+            ToggleDesktop();
             break;
         case IDHK_PAGER:
             break;
@@ -596,35 +689,80 @@ public:
     {
         switch (uCommand)
         {
-        case IDM_TASKBARANDSTARTMENU:
-            DisplayProperties();
-            break;
-
-        case IDM_SEARCH:
-            SHFindFiles(NULL, NULL);
-            break;
-
-        case IDM_HELPANDSUPPORT:
-            ExecResourceCmd(IDS_HELP_COMMAND);
-            break;
-
-        case IDM_RUN:
-            DisplayRunFileDlg();
-            break;
-
-        /* FIXME: Handle these commands as well */
-        case IDM_SYNCHRONIZE:
-        case IDM_DISCONNECT:
-        case IDM_UNDOCKCOMPUTER:
-            break;
-
-        case IDM_LOGOFF:
-            LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows?
-            break;
+            case TRAYCMD_STARTMENU:
+                // TODO:
+                break;
+            case TRAYCMD_RUN_DIALOG:
+                DisplayRunFileDlg();
+                break;
+            case TRAYCMD_LOGOFF_DIALOG:
+                LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows?
+                break;
+            case TRAYCMD_CASCADE:
+                CascadeWindows(NULL, MDITILE_SKIPDISABLED, NULL, 0, NULL);
+                break;
+            case TRAYCMD_TILE_H:
+                TileWindows(NULL, MDITILE_HORIZONTAL, NULL, 0, NULL);
+                break;
+            case TRAYCMD_TILE_V:
+                TileWindows(NULL, MDITILE_VERTICAL, NULL, 0, NULL);
+                break;
+            case TRAYCMD_TOGGLE_DESKTOP:
+                ToggleDesktop();
+                break;
+            case TRAYCMD_DATE_AND_TIME:
+                ShellExecuteW(m_hWnd, NULL, L"timedate.cpl", NULL, NULL, SW_NORMAL);
+                break;
+            case TRAYCMD_TASKBAR_PROPERTIES:
+                DisplayProperties();
+                break;
+            case TRAYCMD_MINIMIZE_ALL:
+                MinimizeAll();
+                break;
+            case TRAYCMD_RESTORE_ALL:
+                RestoreAll();
+                break;
+            case TRAYCMD_SHOW_DESKTOP:
+                ShowDesktop();
+                break;
+            case TRAYCMD_SHOW_TASK_MGR:
+                OpenTaskManager(m_hWnd);
+                break;
+            case TRAYCMD_CUSTOMIZE_TASKBAR:
+                break;
+            case TRAYCMD_LOCK_TASKBAR:
+                if (SHRestricted(REST_CLASSICSHELL) == 0)
+                {
+                    Lock(!g_TaskbarSettings.bLock);
+                }
+                break;
+            case TRAYCMD_HELP_AND_SUPPORT:
+                ExecResourceCmd(IDS_HELP_COMMAND);
+                break;
+            case TRAYCMD_CONTROL_PANEL:
+                // TODO:
+                break;
+            case TRAYCMD_SHUTDOWN_DIALOG:
+                DoExitWindows();
+                break;
+            case TRAYCMD_PRINTERS_AND_FAXES:
+                // TODO:
+                break;
+            case TRAYCMD_LOCK_DESKTOP:
+                // TODO:
+                break;
+            case TRAYCMD_SWITCH_USER_DIALOG:
+                // TODO:
+                break;
+            case TRAYCMD_SEARCH_FILES:
+                SHFindFiles(NULL, NULL);
+                break;
+            case TRAYCMD_SEARCH_COMPUTERS:
+                SHFindComputer(NULL, NULL);
+                break;
 
-        case IDM_SHUTDOWN:
-            DoExitWindows();
-            break;
+            default:
+                break;
         }
 
         return FALSE;
@@ -2668,6 +2806,88 @@ HandleTrayContextMenu:
         return HandleHotKey(wParam);
     }
 
+    struct MINIMIZE_INFO
+    {
+        HWND hwndDesktop;
+        HWND hTrayWnd;
+        HWND hwndProgman;
+        BOOL bRet;
+        CSimpleArray<HWND> *pMinimizedAll;
+        BOOL bShowDesktop;
+    };
+
+    static BOOL IsDialog(HWND hwnd)
+    {
+        WCHAR szClass[32];
+        GetClassNameW(hwnd, szClass, _countof(szClass));
+        return wcscmp(szClass, L"#32770") == 0;
+    }
+
+    static BOOL CALLBACK MinimizeWindowsProc(HWND hwnd, LPARAM lParam)
+    {
+        MINIMIZE_INFO *info = (MINIMIZE_INFO *)lParam;
+        if (hwnd == info->hwndDesktop || hwnd == info->hTrayWnd ||
+            hwnd == info->hwndProgman)
+        {
+            return TRUE;
+        }
+        if (!info->bShowDesktop)
+        {
+            if (!::IsWindowEnabled(hwnd) || IsDialog(hwnd))
+                return TRUE;
+            HWND hwndOwner = ::GetWindow(hwnd, GW_OWNER);
+            if (hwndOwner && !::IsWindowEnabled(hwndOwner))
+                return TRUE;
+        }
+        if (::IsWindowVisible(hwnd) && !::IsIconic(hwnd))
+        {
+            ::ShowWindowAsync(hwnd, SW_MINIMIZE);
+            info->bRet = TRUE;
+            info->pMinimizedAll->Add(hwnd);
+        }
+        return TRUE;
+    }
+
+    VOID MinimizeAll(BOOL bShowDesktop = FALSE)
+    {
+        MINIMIZE_INFO info;
+        info.hwndDesktop = GetDesktopWindow();;
+        info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
+        info.hwndProgman = FindWindowW(L"Progman", NULL);
+        info.bRet = FALSE;
+        info.pMinimizedAll = &g_MinimizedAll;
+        info.bShowDesktop = bShowDesktop;
+        EnumWindows(MinimizeWindowsProc, (LPARAM)&info);
+
+        // invalid handles should be cleared to avoid mismatch of handles
+        for (INT i = 0; i < g_MinimizedAll.GetSize(); ++i)
+        {
+            if (!::IsWindow(g_MinimizedAll[i]))
+                g_MinimizedAll[i] = NULL;
+        }
+
+        ::SetForegroundWindow(m_DesktopWnd);
+        ::SetFocus(m_DesktopWnd);
+    }
+
+    VOID ShowDesktop()
+    {
+        MinimizeAll(TRUE);
+    }
+
+    VOID RestoreAll()
+    {
+        for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
+        {
+            HWND hwnd = g_MinimizedAll[i];
+            if (::IsWindowVisible(hwnd) && ::IsIconic(hwnd))
+            {
+                ::ShowWindow(hwnd, SW_RESTORE);
+            }
+        }
+        g_MinimizedAll.RemoveAll();
+    }
+
     LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
     {
         LRESULT Ret = FALSE;
@@ -2738,6 +2958,24 @@ HandleTrayContextMenu:
         return 0;
     }
 
+    LRESULT OnInitMenuPopup(INT code, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+    {
+        HMENU hMenu = (HMENU)wParam;
+        if (::IsThereAnyEffectiveWindow(FALSE))
+        {
+            ::EnableMenuItem(hMenu, ID_SHELL_CMD_CASCADE_WND, MF_BYCOMMAND | MF_ENABLED);
+            ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_H, MF_BYCOMMAND | MF_ENABLED);
+            ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_V, MF_BYCOMMAND | MF_ENABLED);
+        }
+        else
+        {
+            ::EnableMenuItem(hMenu, ID_SHELL_CMD_CASCADE_WND, MF_BYCOMMAND | MF_GRAYED);
+            ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_H, MF_BYCOMMAND | MF_GRAYED);
+            ::EnableMenuItem(hMenu, ID_SHELL_CMD_TILE_WND_V, MF_BYCOMMAND | MF_GRAYED);
+        }
+        return 0;
+    }
+
     LRESULT OnRebarAutoSize(INT code, LPNMHDR nmhdr, BOOL& bHandled)
     {
 #if 0
@@ -2877,6 +3115,7 @@ HandleTrayContextMenu:
         MESSAGE_HANDLER(WM_CLOSE, OnDoExitWindows)
         MESSAGE_HANDLER(WM_HOTKEY, OnHotkey)
         MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
+        MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
         MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged)
         MESSAGE_HANDLER(TWM_OPENSTARTMENU, OnOpenStartMenu)
         MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows)
@@ -3027,8 +3266,22 @@ public:
                          UINT idCmdLast,
                          UINT uFlags)
     {
-        HMENU menubase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_TRAYWND));
-        if (!menubase)
+        HMENU hMenuBase;
+
+        hMenuBase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCEW(IDM_TRAYWND));
+
+        if (g_MinimizedAll.GetSize() != 0 && !::IsThereAnyEffectiveWindow(TRUE))
+        {
+            CStringW strRestoreAll(MAKEINTRESOURCEW(IDS_RESTORE_ALL));
+            MENUITEMINFOW mii = { sizeof(mii) };
+            mii.fMask = MIIM_ID | MIIM_TYPE;
+            mii.wID = ID_SHELL_CMD_RESTORE_ALL;
+            mii.fType = MFT_STRING;
+            mii.dwTypeData = const_cast<LPWSTR>(&strRestoreAll[0]);
+            SetMenuItemInfoW(hMenuBase, ID_SHELL_CMD_SHOW_DESKTOP, FALSE, &mii);
+        }
+
+        if (!hMenuBase)
             return HRESULT_FROM_WIN32(GetLastError());
 
         if (SHRestricted(REST_CLASSICSHELL) != 0)
@@ -3038,15 +3291,15 @@ public:
                        MF_BYCOMMAND);
         }
 
-        CheckMenuItem(menubase,
+        CheckMenuItem(hMenuBase,
                       ID_LOCKTASKBAR,
                       MF_BYCOMMAND | (g_TaskbarSettings.bLock ? MF_CHECKED : MF_UNCHECKED));
 
         UINT idCmdNext;
-        idCmdNext = Shell_MergeMenus(hPopup, menubase, indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR);
+        idCmdNext = Shell_MergeMenus(hPopup, hMenuBase, indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS | MM_ADDSEPARATOR);
         m_idCmdCmFirst = idCmdNext - idCmdFirst;
 
-        ::DestroyMenu(menubase);
+        ::DestroyMenu(hMenuBase);
 
         if (TrayWnd->m_TrayBandSite != NULL)
         {
index 259b891..b07a42f 100644 (file)
@@ -3,10 +3,12 @@
  * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
  * PURPOSE:     IShellDispatch implementation
  * COPYRIGHT:   Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
+ *              Copyright 2018 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
  */
 
 #include "precomp.h"
 #include "winsvc.h"
+#include <traycmd.h>   // tray commands
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -370,7 +372,11 @@ HRESULT STDMETHODCALLTYPE CShellDispatch::WindowsSecurity()
 HRESULT STDMETHODCALLTYPE CShellDispatch::ToggleDesktop()
 {
     TRACE("(%p)\n", this);
-    return E_NOTIMPL;
+
+    HWND hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
+    PostMessageW(hTrayWnd, WM_COMMAND, TRAYCMD_TOGGLE_DESKTOP, 0);
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CShellDispatch::ExplorerPolicy(BSTR policy, VARIANT *value)
diff --git a/sdk/include/reactos/traycmd.h b/sdk/include/reactos/traycmd.h
new file mode 100644 (file)
index 0000000..7273caa
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Tray Commands
+ *
+ * Copyright 2018 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef TRAYCMD_H_
+#define TRAYCMD_H_
+
+/* TODO: Add more and implement them */
+#define TRAYCMD_STARTMENU           305     /*              Same as IDMA_START. */
+#define TRAYCMD_RUN_DIALOG          401     /* Implemented. Same as IDM_RUN. */
+#define TRAYCMD_LOGOFF_DIALOG       402     /* Implemented. Same as IDM_LOGOFF. */
+#define TRAYCMD_CASCADE             403     /* */
+#define TRAYCMD_TILE_H              404     /* */
+#define TRAYCMD_TILE_V              405     /* */
+#define TRAYCMD_TOGGLE_DESKTOP      407     /* Implemented. */
+#define TRAYCMD_DATE_AND_TIME       408     /* Implemented. */
+#define TRAYCMD_TASKBAR_PROPERTIES  413     /* Implemented. Same as IDM_TASKBARANDSTARTMENU. */
+#define TRAYCMD_MINIMIZE_ALL        415     /* Implemented. */
+#define TRAYCMD_RESTORE_ALL         416     /* Implemented. Same as IDMA_RESTORE_OPEN. */
+#define TRAYCMD_SHOW_DESKTOP        419     /* Implemented. */
+#define TRAYCMD_SHOW_TASK_MGR       420     /* Implemented. */
+#define TRAYCMD_CUSTOMIZE_TASKBAR   421     /* */
+#define TRAYCMD_LOCK_TASKBAR        424     /* Implemented. */
+#define TRAYCMD_HELP_AND_SUPPORT    503     /* Implemented. Same as IDM_HELPANDSUPPORT. */
+#define TRAYCMD_CONTROL_PANEL       505     /*              Same as IDM_CONTROLPANEL. */
+#define TRAYCMD_SHUTDOWN_DIALOG     506     /* Implemented. Same as IDM_SHUTDOWN. */
+#define TRAYCMD_PRINTERS_AND_FAXES  510     /*              Same as IDM_PRINTERSANDFAXES. */
+#define TRAYCMD_LOCK_DESKTOP        517     /* */
+#define TRAYCMD_SWITCH_USER_DIALOG  5000    /* */
+#define TRAYCMD_SEARCH_FILES        41093   /* Implemented. Same as IDMA_SEARCH. */
+#define TRAYCMD_SEARCH_COMPUTERS    41094   /* Implemented. */
+
+#endif  /* ndef TRAYCMD_H_ */
index c95b8df..227ab9c 100644 (file)
@@ -3,7 +3,8 @@
  * PROJECT:         ReactOS user32.dll
  * FILE:            win32ss/user/user32/windows/window.c
  * PURPOSE:         Window management
- * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *                  Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
  * UPDATE HISTORY:
  *      06-06-2001  CSH  Created
  */
@@ -78,9 +79,22 @@ BringWindowToTop(HWND hWnd)
 
 
 VOID WINAPI
-SwitchToThisWindow(HWND hwnd, BOOL fUnknown)
+SwitchToThisWindow(HWND hwnd, BOOL fAltTab)
 {
-    ShowWindow(hwnd, SW_SHOW);
+    HWND hwndFG;
+    if (fAltTab)
+    {
+        if (IsIconic(hwnd))
+            ShowWindowAsync(hwnd, SW_RESTORE);
+        SetForegroundWindow(hwnd);
+    }
+    else
+    {
+        hwndFG = GetForegroundWindow();
+        ShowWindow(hwnd, SW_RESTORE | SW_SHOWNA);
+        SetWindowPos(hwnd, hwndFG, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+        SetWindowPos(hwndFG, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+    }
 }