mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 15:02:59 +00:00
[EXPLORER] Add fullscreen handling (#8105)
Adds support for handling fullscreen applications (a.k.a. “rude apps”) so the taskbar can hide or show appropriately. JIRA issue: CORE-11242, CORE-15681, CORE-16056, CORE-16063, CORE-16131, CORE-16132, CORE-16192, CORE-16196, CORE-16249, CORE-16290, CORE-16313, CORE-16320, CORE-16322, CORE-16347, CORE-16584, CORE-19795, CORE-9862, CORE-16230, CORE-10738, and CORE-12263. - Removes legacy pulse/timer logic in the tray window and adds a fullscreen notification workflow. - Implements fullscreen detection across monitors in the task switcher, using a sequence of validation timers. - Defines a new ITrayWindow:: NotifyFullScreenToAppBars interface method to broadcast fullscreen state to appbars.
This commit is contained in:
parent
7ec3a7e98b
commit
4e7702a6a9
3 changed files with 258 additions and 77 deletions
|
@ -133,7 +133,6 @@ HRESULT WINAPI _CBandSite_CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void
|
||||||
#define TWM_OPENSTARTMENU (WM_USER + 260)
|
#define TWM_OPENSTARTMENU (WM_USER + 260)
|
||||||
#define TWM_SETTINGSCHANGED (WM_USER + 300)
|
#define TWM_SETTINGSCHANGED (WM_USER + 300)
|
||||||
#define TWM_SETZORDER (WM_USER + 338)
|
#define TWM_SETZORDER (WM_USER + 338)
|
||||||
#define TWM_PULSE (WM_USER + 400)
|
|
||||||
|
|
||||||
extern const GUID IID_IShellDesktopTray;
|
extern const GUID IID_IShellDesktopTray;
|
||||||
|
|
||||||
|
@ -154,6 +153,7 @@ DECLARE_INTERFACE_(ITrayWindow, IUnknown)
|
||||||
STDMETHOD_(BOOL, ExecContextMenuCmd) (THIS_ UINT uiCmd) PURE;
|
STDMETHOD_(BOOL, ExecContextMenuCmd) (THIS_ UINT uiCmd) PURE;
|
||||||
STDMETHOD_(BOOL, Lock) (THIS_ BOOL bLock) PURE;
|
STDMETHOD_(BOOL, Lock) (THIS_ BOOL bLock) PURE;
|
||||||
STDMETHOD_(BOOL, IsTaskWnd) (THIS_ HWND hWnd) PURE;
|
STDMETHOD_(BOOL, IsTaskWnd) (THIS_ HWND hWnd) PURE;
|
||||||
|
STDMETHOD_(HRESULT, NotifyFullScreenToAppBars)(THIS_ HMONITOR hMonitor, BOOL bFullOpening) PURE;
|
||||||
};
|
};
|
||||||
#undef INTERFACE
|
#undef INTERFACE
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ DECLARE_INTERFACE_(ITrayWindow, IUnknown)
|
||||||
#define ITrayWindow_ExecContextMenuCmd(p,a) (p)->lpVtbl->ExecContextMenuCmd(p,a)
|
#define ITrayWindow_ExecContextMenuCmd(p,a) (p)->lpVtbl->ExecContextMenuCmd(p,a)
|
||||||
#define ITrayWindow_Lock(p,a) (p)->lpVtbl->Lock(p,a)
|
#define ITrayWindow_Lock(p,a) (p)->lpVtbl->Lock(p,a)
|
||||||
#define ITrayWindow_IsTaskWnd(p,a) (p)->lpVtbl->IsTaskWnd(p,a)
|
#define ITrayWindow_IsTaskWnd(p,a) (p)->lpVtbl->IsTaskWnd(p,a)
|
||||||
|
#define ITrayWindow_NotifyFullScreenToAppBars(p,a,b) (p)->lpVtbl->NotifyFullScreenToAppBars(p,a,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HRESULT CreateTrayWindow(ITrayWindow ** ppTray);
|
HRESULT CreateTrayWindow(ITrayWindow ** ppTray);
|
||||||
|
|
|
@ -31,6 +31,89 @@
|
||||||
#define MAX_TASKS_COUNT (0x7FFF)
|
#define MAX_TASKS_COUNT (0x7FFF)
|
||||||
#define TASK_ITEM_ARRAY_ALLOC 64
|
#define TASK_ITEM_ARRAY_ALLOC 64
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Fullscreen windows (a.k.a. rude apps) checker
|
||||||
|
|
||||||
|
#define TIMER_ID_VALIDATE_RUDE_APP 5
|
||||||
|
#define VALIDATE_RUDE_INTERVAL 1000
|
||||||
|
#define VALIDATE_RUDE_MAX_COUNT 5
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
SHELL_GetMonitorRect(
|
||||||
|
_In_opt_ HMONITOR hMonitor,
|
||||||
|
_Out_opt_ PRECT prcDest,
|
||||||
|
_In_ BOOL bWorkAreaOnly)
|
||||||
|
{
|
||||||
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
|
if (!hMonitor || !::GetMonitorInfoW(hMonitor, &mi))
|
||||||
|
{
|
||||||
|
if (!prcDest)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (bWorkAreaOnly)
|
||||||
|
::SystemParametersInfoW(SPI_GETWORKAREA, 0, prcDest, 0);
|
||||||
|
else
|
||||||
|
::SetRect(prcDest, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prcDest)
|
||||||
|
*prcDest = (bWorkAreaOnly ? mi.rcWork : mi.rcMonitor);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
SHELL_IsParentOwnerOrSelf(_In_ HWND hwndTarget, _In_ HWND hWnd)
|
||||||
|
{
|
||||||
|
for (; hWnd; hWnd = ::GetParent(hWnd))
|
||||||
|
{
|
||||||
|
if (hWnd == hwndTarget)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
SHELL_IsRudeWindowActive(_In_ HWND hWnd)
|
||||||
|
{
|
||||||
|
HWND hwndFore = ::GetForegroundWindow();
|
||||||
|
DWORD dwThreadId = ::GetWindowThreadProcessId(hWnd, NULL);
|
||||||
|
return dwThreadId == ::GetWindowThreadProcessId(hwndFore, NULL) ||
|
||||||
|
SHELL_IsParentOwnerOrSelf(hWnd, hwndFore);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
SHELL_IsRudeWindow(_In_opt_ HMONITOR hMonitor, _In_ HWND hWnd, _In_ BOOL bDontCheckActive)
|
||||||
|
{
|
||||||
|
if (!::IsWindowVisible(hWnd) || hWnd == ::GetDesktopWindow())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
RECT rcMonitor;
|
||||||
|
SHELL_GetMonitorRect(hMonitor, &rcMonitor, FALSE);
|
||||||
|
|
||||||
|
DWORD style = ::GetWindowLongPtrW(hWnd, GWL_STYLE);
|
||||||
|
|
||||||
|
RECT rcWnd;
|
||||||
|
enum { CHECK_STYLE = WS_THICKFRAME | WS_DLGFRAME | WS_BORDER };
|
||||||
|
if ((style & CHECK_STYLE) == CHECK_STYLE)
|
||||||
|
{
|
||||||
|
::GetClientRect(hWnd, &rcWnd); // Ignore frame
|
||||||
|
::MapWindowPoints(hWnd, NULL, (PPOINT)&rcWnd, sizeof(RECT) / sizeof(POINT));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::GetWindowRect(hWnd, &rcWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT rcUnion;
|
||||||
|
::UnionRect(&rcUnion, &rcWnd, &rcMonitor);
|
||||||
|
|
||||||
|
return ::EqualRect(&rcUnion, &rcWnd) && (bDontCheckActive || SHELL_IsRudeWindowActive(hWnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const WCHAR szTaskSwitchWndClass[] = L"MSTaskSwWClass";
|
const WCHAR szTaskSwitchWndClass[] = L"MSTaskSwWClass";
|
||||||
const WCHAR szRunningApps[] = L"Running Applications";
|
const WCHAR szRunningApps[] = L"Running Applications";
|
||||||
|
|
||||||
|
@ -322,6 +405,8 @@ class CTaskSwitchWnd :
|
||||||
BOOL m_IsGroupingEnabled;
|
BOOL m_IsGroupingEnabled;
|
||||||
BOOL m_IsDestroying;
|
BOOL m_IsDestroying;
|
||||||
|
|
||||||
|
INT m_nRudeAppValidationCounter;
|
||||||
|
|
||||||
SIZE m_ButtonSize;
|
SIZE m_ButtonSize;
|
||||||
|
|
||||||
UINT m_uHardErrorMsg;
|
UINT m_uHardErrorMsg;
|
||||||
|
@ -340,7 +425,8 @@ public:
|
||||||
m_ButtonCount(0),
|
m_ButtonCount(0),
|
||||||
m_ImageList(NULL),
|
m_ImageList(NULL),
|
||||||
m_IsGroupingEnabled(FALSE),
|
m_IsGroupingEnabled(FALSE),
|
||||||
m_IsDestroying(FALSE)
|
m_IsDestroying(FALSE),
|
||||||
|
m_nRudeAppValidationCounter(0)
|
||||||
{
|
{
|
||||||
ZeroMemory(&m_ButtonSize, sizeof(m_ButtonSize));
|
ZeroMemory(&m_ButtonSize, sizeof(m_ButtonSize));
|
||||||
m_uHardErrorMsg = RegisterWindowMessageW(L"HardError");
|
m_uHardErrorMsg = RegisterWindowMessageW(L"HardError");
|
||||||
|
@ -1464,6 +1550,8 @@ public:
|
||||||
{
|
{
|
||||||
m_IsDestroying = TRUE;
|
m_IsDestroying = TRUE;
|
||||||
|
|
||||||
|
KillTimer(TIMER_ID_VALIDATE_RUDE_APP);
|
||||||
|
|
||||||
/* Unregister the shell hook */
|
/* Unregister the shell hook */
|
||||||
RegisterShellHook(m_hWnd, FALSE);
|
RegisterShellHook(m_hWnd, FALSE);
|
||||||
|
|
||||||
|
@ -1472,12 +1560,6 @@ public:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID SendPulseToTray(BOOL bDelete, HWND hwndActive)
|
|
||||||
{
|
|
||||||
HWND hwndTray = m_Tray->GetHWND();
|
|
||||||
::SendMessage(hwndTray, TWM_PULSE, bDelete, (LPARAM)hwndActive);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL InvokeRegistryAppKeyCommand(UINT uAppCmd)
|
static BOOL InvokeRegistryAppKeyCommand(UINT uAppCmd)
|
||||||
{
|
{
|
||||||
BOOL bResult = FALSE;
|
BOOL bResult = FALSE;
|
||||||
|
@ -1554,19 +1636,18 @@ public:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HSHELL_WINDOWCREATED:
|
case HSHELL_WINDOWCREATED:
|
||||||
SendPulseToTray(FALSE, (HWND)lParam);
|
|
||||||
AddTask((HWND) lParam);
|
AddTask((HWND) lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HSHELL_WINDOWDESTROYED:
|
case HSHELL_WINDOWDESTROYED:
|
||||||
/* The window still exists! Delay destroying it a bit */
|
/* The window still exists! Delay destroying it a bit */
|
||||||
SendPulseToTray(TRUE, (HWND)lParam);
|
OnWindowDestroyed((HWND)lParam);
|
||||||
DeleteTask((HWND)lParam);
|
DeleteTask((HWND)lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HSHELL_RUDEAPPACTIVATED:
|
case HSHELL_RUDEAPPACTIVATED:
|
||||||
case HSHELL_WINDOWACTIVATED:
|
case HSHELL_WINDOWACTIVATED:
|
||||||
SendPulseToTray(FALSE, (HWND)lParam);
|
OnWindowActivated((HWND)lParam);
|
||||||
ActivateTask((HWND)lParam);
|
ActivateTask((HWND)lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1674,7 +1755,6 @@ public:
|
||||||
TaskItem = FindTaskItemByIndex((INT) wIndex);
|
TaskItem = FindTaskItemByIndex((INT) wIndex);
|
||||||
if (TaskItem != NULL)
|
if (TaskItem != NULL)
|
||||||
{
|
{
|
||||||
SendPulseToTray(FALSE, TaskItem->hWnd);
|
|
||||||
HandleTaskItemClick(TaskItem);
|
HandleTaskItemClick(TaskItem);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1810,6 +1890,130 @@ public:
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal structure for IsRudeEnumProc
|
||||||
|
typedef struct tagRUDEAPPDATA
|
||||||
|
{
|
||||||
|
HMONITOR hTargetMonitor;
|
||||||
|
HWND hwndFound;
|
||||||
|
HWND hwndFirstCheck;
|
||||||
|
} RUDEAPPDATA, *PRUDEAPPDATA;
|
||||||
|
|
||||||
|
// Find any rude app
|
||||||
|
static BOOL CALLBACK
|
||||||
|
IsRudeEnumProc(_In_ HWND hwnd, _In_ LPARAM lParam)
|
||||||
|
{
|
||||||
|
PRUDEAPPDATA pData = (PRUDEAPPDATA)lParam;
|
||||||
|
|
||||||
|
HMONITOR hMon = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||||
|
if (!hMon ||
|
||||||
|
(pData->hTargetMonitor && pData->hTargetMonitor != hMon) ||
|
||||||
|
!SHELL_IsRudeWindow(hMon, hwnd, (hwnd == pData->hwndFirstCheck)))
|
||||||
|
{
|
||||||
|
return TRUE; // Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
pData->hwndFound = hwnd;
|
||||||
|
return FALSE; // Finish
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal structure for FullScreenEnumProc
|
||||||
|
typedef struct tagFULLSCREENDATA
|
||||||
|
{
|
||||||
|
const RECT *pRect;
|
||||||
|
HMONITOR hTargetMonitor;
|
||||||
|
ITrayWindow *pTray;
|
||||||
|
} FULLSCREENDATA, *PFULLSCREENDATA;
|
||||||
|
|
||||||
|
// Notify ABN_FULLSCREENAPP for each monitor
|
||||||
|
static BOOL CALLBACK
|
||||||
|
FullScreenEnumProc(_In_ HMONITOR hMonitor, _In_opt_ HDC hDC, _In_ LPRECT prc, _In_ LPARAM lParam)
|
||||||
|
{
|
||||||
|
PFULLSCREENDATA pData = (PFULLSCREENDATA)lParam;
|
||||||
|
|
||||||
|
BOOL bFullOpening = (pData->hTargetMonitor == hMonitor);
|
||||||
|
if (!bFullOpening && pData->pRect)
|
||||||
|
{
|
||||||
|
RECT rc, rcMon;
|
||||||
|
SHELL_GetMonitorRect(hMonitor, &rcMon, FALSE);
|
||||||
|
::IntersectRect(&rc, &rcMon, pData->pRect);
|
||||||
|
bFullOpening = ::EqualRect(&rc, &rcMon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify ABN_FULLSCREENAPP to appbars
|
||||||
|
pData->pTray->NotifyFullScreenToAppBars(hMonitor, bFullOpening);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleFullScreenApp(_In_opt_ HWND hwndRude)
|
||||||
|
{
|
||||||
|
// Notify ABN_FULLSCREENAPP for every monitor
|
||||||
|
RECT rc;
|
||||||
|
FULLSCREENDATA Data = { NULL, NULL, NULL };
|
||||||
|
if (hwndRude && ::GetWindowRect(hwndRude, &rc))
|
||||||
|
{
|
||||||
|
Data.pRect = &rc;
|
||||||
|
Data.hTargetMonitor = ::MonitorFromWindow(hwndRude, MONITOR_DEFAULTTONULL);
|
||||||
|
}
|
||||||
|
Data.pTray = m_Tray;
|
||||||
|
::EnumDisplayMonitors(NULL, NULL, FullScreenEnumProc, (LPARAM)&Data);
|
||||||
|
|
||||||
|
// Make the taskbar bottom or top
|
||||||
|
UINT uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER;
|
||||||
|
HWND hwndTray = m_Tray->GetHWND();
|
||||||
|
::SetWindowPos(hwndTray, (hwndRude ? HWND_BOTTOM : HWND_TOP), 0, 0, 0, 0, uFlags);
|
||||||
|
|
||||||
|
if (hwndRude)
|
||||||
|
{
|
||||||
|
DWORD exstyle = (DWORD)::GetWindowLongPtrW(hwndRude, GWL_EXSTYLE);
|
||||||
|
if (!(exstyle & WS_EX_TOPMOST) && !SHELL_IsRudeWindowActive(hwndRude))
|
||||||
|
::SwitchToThisWindow(hwndRude, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: NIN_BALLOONHIDE
|
||||||
|
// FIXME: NIN_POPUPCLOSE
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND FindRudeApp(_In_opt_ HWND hwndFirstCheck)
|
||||||
|
{
|
||||||
|
// Quick check
|
||||||
|
HMONITOR hMon = MonitorFromWindow(hwndFirstCheck, MONITOR_DEFAULTTONEAREST);
|
||||||
|
RUDEAPPDATA data = { hMon, NULL, hwndFirstCheck };
|
||||||
|
if (::IsWindow(hwndFirstCheck) && !IsRudeEnumProc(hwndFirstCheck, (LPARAM)&data))
|
||||||
|
return hwndFirstCheck;
|
||||||
|
|
||||||
|
// Slow check
|
||||||
|
::EnumWindows(IsRudeEnumProc, (LPARAM)&data);
|
||||||
|
|
||||||
|
return data.hwndFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WM_WINDOWPOSCHANGED
|
||||||
|
LRESULT OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
|
{
|
||||||
|
// Re-start rude app validation
|
||||||
|
KillTimer(TIMER_ID_VALIDATE_RUDE_APP);
|
||||||
|
SetTimer(TIMER_ID_VALIDATE_RUDE_APP, VALIDATE_RUDE_INTERVAL, NULL);
|
||||||
|
m_nRudeAppValidationCounter = 0;
|
||||||
|
bHandled = FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HSHELL_WINDOWACTIVATED, HSHELL_RUDEAPPACTIVATED
|
||||||
|
void OnWindowActivated(_In_ HWND hwndTarget)
|
||||||
|
{
|
||||||
|
// Re-start rude app validation
|
||||||
|
KillTimer(TIMER_ID_VALIDATE_RUDE_APP);
|
||||||
|
SetTimer(TIMER_ID_VALIDATE_RUDE_APP, VALIDATE_RUDE_INTERVAL, NULL);
|
||||||
|
m_nRudeAppValidationCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HSHELL_WINDOWDESTROYED
|
||||||
|
void OnWindowDestroyed(_In_ HWND hwndTarget)
|
||||||
|
{
|
||||||
|
HWND hwndRude = FindRudeApp(hwndTarget);
|
||||||
|
HandleFullScreenApp(hwndRude);
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
{
|
{
|
||||||
HDC hdc = (HDC) wParam;
|
HDC hdc = (HDC) wParam;
|
||||||
|
@ -1963,14 +2167,32 @@ public:
|
||||||
|
|
||||||
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
{
|
{
|
||||||
#if DUMP_TASKS != 0
|
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
|
#if DUMP_TASKS != 0
|
||||||
case 1:
|
case 1:
|
||||||
DumpTasks();
|
DumpTasks();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
case TIMER_ID_VALIDATE_RUDE_APP:
|
||||||
|
{
|
||||||
|
// Real activation of rude app might take some time after HSHELL_...ACTIVATED.
|
||||||
|
// Wait up to 5 seconds with validating the rude app at each second.
|
||||||
|
HWND hwndRude = FindRudeApp(NULL);
|
||||||
|
HandleFullScreenApp(hwndRude);
|
||||||
|
|
||||||
|
KillTimer(wParam);
|
||||||
|
++m_nRudeAppValidationCounter;
|
||||||
|
if (m_nRudeAppValidationCounter < VALIDATE_RUDE_MAX_COUNT && !hwndRude)
|
||||||
|
SetTimer(wParam, VALIDATE_RUDE_INTERVAL, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
WARN("Unknown timer ID: %p\n", wParam);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2054,6 +2276,7 @@ public:
|
||||||
MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
|
MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
|
||||||
MESSAGE_HANDLER(WM_KLUDGEMINRECT, OnKludgeItemRect)
|
MESSAGE_HANDLER(WM_KLUDGEMINRECT, OnKludgeItemRect)
|
||||||
MESSAGE_HANDLER(WM_COPYDATA, OnCopyData)
|
MESSAGE_HANDLER(WM_COPYDATA, OnCopyData)
|
||||||
|
MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
|
||||||
END_MSG_MAP()
|
END_MSG_MAP()
|
||||||
|
|
||||||
DECLARE_NOT_AGGREGATABLE(CTaskSwitchWnd)
|
DECLARE_NOT_AGGREGATABLE(CTaskSwitchWnd)
|
||||||
|
|
|
@ -300,7 +300,6 @@ public:
|
||||||
BEGIN_MSG_MAP(CStartButton)
|
BEGIN_MSG_MAP(CStartButton)
|
||||||
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
||||||
END_MSG_MAP()
|
END_MSG_MAP()
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CTrayWindow :
|
class CTrayWindow :
|
||||||
|
@ -362,7 +361,6 @@ public:
|
||||||
DWORD InSizeMove : 1;
|
DWORD InSizeMove : 1;
|
||||||
DWORD IsDragging : 1;
|
DWORD IsDragging : 1;
|
||||||
DWORD NewPosSize : 1;
|
DWORD NewPosSize : 1;
|
||||||
DWORD IgnorePulse : 1;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -391,7 +389,6 @@ public:
|
||||||
ZeroMemory(&m_TraySize, sizeof(m_TraySize));
|
ZeroMemory(&m_TraySize, sizeof(m_TraySize));
|
||||||
ZeroMemory(&m_AutoHideOffset, sizeof(m_AutoHideOffset));
|
ZeroMemory(&m_AutoHideOffset, sizeof(m_AutoHideOffset));
|
||||||
ZeroMemory(&m_MouseTrackingInfo, sizeof(m_MouseTrackingInfo));
|
ZeroMemory(&m_MouseTrackingInfo, sizeof(m_MouseTrackingInfo));
|
||||||
IgnorePulse = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~CTrayWindow()
|
virtual ~CTrayWindow()
|
||||||
|
@ -2392,12 +2389,8 @@ ChangePos:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TIMER_ID_IGNOREPULSERESET 888
|
|
||||||
#define TIMER_IGNOREPULSERESET_TIMEOUT 200
|
|
||||||
|
|
||||||
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
{
|
{
|
||||||
KillTimer(TIMER_ID_IGNOREPULSERESET);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3035,39 +3028,6 @@ HandleTrayContextMenu:
|
||||||
return (LRESULT)m_TaskSwitch;
|
return (LRESULT)m_TaskSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreMinimizedNonTaskWnds(BOOL bDestroyed, HWND hwndActive)
|
|
||||||
{
|
|
||||||
for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
HWND hwnd = g_MinimizedAll[i].hwnd;
|
|
||||||
if (!hwnd || hwndActive == hwnd)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (::IsWindowVisible(hwnd) && ::IsIconic(hwnd) &&
|
|
||||||
(!IsTaskWnd(hwnd) || !::IsWindowEnabled(hwnd)))
|
|
||||||
{
|
|
||||||
::SetWindowPlacement(hwnd, &g_MinimizedAll[i].wndpl); // Restore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bDestroyed)
|
|
||||||
g_MinimizedAll.RemoveAll();
|
|
||||||
else
|
|
||||||
::SetForegroundWindow(hwndActive);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT OnPulse(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
||||||
{
|
|
||||||
if (IgnorePulse)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
KillTimer(TIMER_ID_IGNOREPULSERESET);
|
|
||||||
IgnorePulse = TRUE;
|
|
||||||
RestoreMinimizedNonTaskWnds((BOOL)wParam, (HWND)lParam);
|
|
||||||
SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TWM_SETZORDER
|
// TWM_SETZORDER
|
||||||
LRESULT OnSetZOrder(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnSetZOrder(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
{
|
{
|
||||||
|
@ -3075,6 +3035,12 @@ HandleTrayContextMenu:
|
||||||
SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP NotifyFullScreenToAppBars(HMONITOR hMonitor, BOOL bFullOpening) override
|
||||||
|
{
|
||||||
|
OnAppBarNotifyAll(hMonitor, NULL, ABN_FULLSCREENAPP, bFullOpening);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
{
|
{
|
||||||
return HandleHotKey(wParam);
|
return HandleHotKey(wParam);
|
||||||
|
@ -3126,9 +3092,6 @@ HandleTrayContextMenu:
|
||||||
|
|
||||||
VOID MinimizeAll(BOOL bShowDesktop = FALSE)
|
VOID MinimizeAll(BOOL bShowDesktop = FALSE)
|
||||||
{
|
{
|
||||||
IgnorePulse = TRUE;
|
|
||||||
KillTimer(TIMER_ID_IGNOREPULSERESET);
|
|
||||||
|
|
||||||
MINIMIZE_INFO info;
|
MINIMIZE_INFO info;
|
||||||
info.hwndDesktop = GetDesktopWindow();;
|
info.hwndDesktop = GetDesktopWindow();;
|
||||||
info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
|
info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
|
||||||
|
@ -3139,7 +3102,6 @@ HandleTrayContextMenu:
|
||||||
|
|
||||||
::SetForegroundWindow(m_DesktopWnd);
|
::SetForegroundWindow(m_DesktopWnd);
|
||||||
::SetFocus(m_DesktopWnd);
|
::SetFocus(m_DesktopWnd);
|
||||||
SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID ShowDesktop()
|
VOID ShowDesktop()
|
||||||
|
@ -3149,9 +3111,6 @@ HandleTrayContextMenu:
|
||||||
|
|
||||||
VOID RestoreAll()
|
VOID RestoreAll()
|
||||||
{
|
{
|
||||||
IgnorePulse = TRUE;
|
|
||||||
KillTimer(TIMER_ID_IGNOREPULSERESET);
|
|
||||||
|
|
||||||
for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
|
for (INT i = g_MinimizedAll.GetSize() - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
HWND hwnd = g_MinimizedAll[i].hwnd;
|
HWND hwnd = g_MinimizedAll[i].hwnd;
|
||||||
|
@ -3160,7 +3119,6 @@ HandleTrayContextMenu:
|
||||||
}
|
}
|
||||||
|
|
||||||
g_MinimizedAll.RemoveAll();
|
g_MinimizedAll.RemoveAll();
|
||||||
SetTimer(TIMER_ID_IGNOREPULSERESET, TIMER_IGNOREPULSERESET_TIMEOUT, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
|
@ -3193,18 +3151,18 @@ HandleTrayContextMenu:
|
||||||
|
|
||||||
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||||
{
|
{
|
||||||
if (wParam == TIMER_ID_MOUSETRACK)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
|
case TIMER_ID_MOUSETRACK:
|
||||||
ProcessMouseTracking();
|
ProcessMouseTracking();
|
||||||
}
|
break;
|
||||||
else if (wParam == TIMER_ID_AUTOHIDE)
|
case TIMER_ID_AUTOHIDE:
|
||||||
{
|
|
||||||
ProcessAutoHide();
|
ProcessAutoHide();
|
||||||
}
|
break;
|
||||||
else if (wParam == TIMER_ID_IGNOREPULSERESET)
|
default:
|
||||||
{
|
WARN("Invalid timer ID: %u\n", (UINT)wParam);
|
||||||
KillTimer(TIMER_ID_IGNOREPULSERESET);
|
bHandled = FALSE;
|
||||||
IgnorePulse = FALSE;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3453,7 +3411,6 @@ HandleTrayContextMenu:
|
||||||
MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows)
|
MESSAGE_HANDLER(TWM_DOEXITWINDOWS, OnDoExitWindows)
|
||||||
MESSAGE_HANDLER(TWM_GETTASKSWITCH, OnGetTaskSwitch)
|
MESSAGE_HANDLER(TWM_GETTASKSWITCH, OnGetTaskSwitch)
|
||||||
MESSAGE_HANDLER(TWM_SETZORDER, OnSetZOrder)
|
MESSAGE_HANDLER(TWM_SETZORDER, OnSetZOrder)
|
||||||
MESSAGE_HANDLER(TWM_PULSE, OnPulse)
|
|
||||||
ALT_MSG_MAP(1)
|
ALT_MSG_MAP(1)
|
||||||
END_MSG_MAP()
|
END_MSG_MAP()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue