Skip to content

Commit 2fd0af4

Browse files
authored
[EXPLORER] AppBar Part 3 (reactos#7966)
Follow-up of reactos#7946. JIRA issue: CORE-7237 - Implement ABM_GETSTATE, ABM_GETTASKBARPOS, ABM_ACTIVATE, ABM_WINDOWPOSCHANGED, ABM_GETAUTOHIDEBAR, ABM_SETAUTOHIDEBAR, and ABM_SETSTATE appbar messages. - Implement TWM_SETZORDER tray message.
1 parent 2543e21 commit 2fd0af4

File tree

4 files changed

+199
-46
lines changed

4 files changed

+199
-46
lines changed

base/shell/explorer/appbar.cpp

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
CAppBarManager::CAppBarManager()
1313
: m_hAppBarDPA(NULL)
14+
, m_ahwndAutoHideBars { 0 }
1415
{
1516
}
1617

@@ -450,13 +451,40 @@ void CAppBarManager::RecomputeAllWorkareas()
450451
::EnumDisplayMonitors(NULL, NULL, CAppBarManager::MonitorEnumProc, (LPARAM)this);
451452
}
452453

454+
BOOL CAppBarManager::SetAutoHideBar(_In_ HWND hwndTarget, _In_ BOOL bSetOrReset, _In_ UINT uSide)
455+
{
456+
ATLASSERT(uSide < _countof(m_ahwndAutoHideBars));
457+
HWND *phwndAutoHide = &m_ahwndAutoHideBars[uSide];
458+
if (!IsWindow(*phwndAutoHide))
459+
*phwndAutoHide = NULL;
460+
461+
if (bSetOrReset) // Set?
462+
{
463+
if (!*phwndAutoHide)
464+
*phwndAutoHide = hwndTarget;
465+
return *phwndAutoHide == hwndTarget;
466+
}
467+
else // Reset
468+
{
469+
if (*phwndAutoHide == hwndTarget)
470+
*phwndAutoHide = NULL;
471+
return TRUE;
472+
}
473+
}
474+
475+
void CAppBarManager::OnAppBarActivationChange2(_In_ HWND hwndNewAutoHide, _In_ UINT uSide)
476+
{
477+
HWND hwndAutoHideBar = OnAppBarGetAutoHideBar(uSide);
478+
if (hwndAutoHideBar && hwndAutoHideBar != hwndNewAutoHide)
479+
::PostMessageW(GetTrayWnd(), TWM_SETZORDER, (WPARAM)hwndAutoHideBar, uSide);
480+
}
481+
453482
PAPPBAR_COMMAND
454483
CAppBarManager::GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
455484
{
456485
PAPPBAR_COMMAND pData = (PAPPBAR_COMMAND)pCopyData->lpData;
457486

458-
if (pCopyData->cbData != sizeof(*pData) ||
459-
pData->abd.cbSize != sizeof(pData->abd))
487+
if (pCopyData->cbData != sizeof(*pData) || pData->abd.cbSize != sizeof(pData->abd))
460488
{
461489
ERR("Invalid AppBar message\n");
462490
return NULL;
@@ -465,6 +493,80 @@ CAppBarManager::GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
465493
return pData;
466494
}
467495

496+
// ABM_GETSTATE
497+
UINT CAppBarManager::OnAppBarGetState()
498+
{
499+
return (IsAutoHideState() ? ABS_AUTOHIDE : 0) | (IsAlwaysOnTop() ? ABS_ALWAYSONTOP : 0);
500+
}
501+
502+
// ABM_GETTASKBARPOS
503+
BOOL CAppBarManager::OnAppBarGetTaskbarPos(_Inout_ PAPPBAR_COMMAND pData)
504+
{
505+
PAPPBARDATAINTEROP pOutput = AppBar_LockOutput(pData);
506+
if (!pOutput)
507+
{
508+
ERR("!pOutput: %d\n", pData->dwProcessId);
509+
return FALSE;
510+
}
511+
512+
pOutput->rc = *GetTrayRect();
513+
pOutput->uEdge = GetPosition();
514+
515+
AppBar_UnLockOutput(pOutput);
516+
return TRUE;
517+
}
518+
519+
// ABM_ACTIVATE, ABM_WINDOWPOSCHANGED
520+
void CAppBarManager::OnAppBarActivationChange(_In_ const APPBAR_COMMAND *pData)
521+
{
522+
HWND hWnd = (HWND)UlongToHandle(pData->abd.hWnd32);
523+
PAPPBAR pAppBar = FindAppBar(hWnd);
524+
if (!pAppBar)
525+
{
526+
ERR("Not found: %p\n", hWnd);
527+
return;
528+
}
529+
530+
HWND hwndAppBar = pAppBar->hWnd;
531+
for (UINT uSide = ABE_LEFT; uSide <= ABE_BOTTOM; ++uSide)
532+
{
533+
if (m_ahwndAutoHideBars[uSide] == hwndAppBar && uSide != pAppBar->uEdge)
534+
return;
535+
}
536+
537+
OnAppBarActivationChange2(hwndAppBar, pAppBar->uEdge);
538+
}
539+
540+
// ABM_GETAUTOHIDEBAR
541+
HWND CAppBarManager::OnAppBarGetAutoHideBar(_In_ UINT uSide)
542+
{
543+
if (uSide >= _countof(m_ahwndAutoHideBars))
544+
return NULL;
545+
546+
if (!::IsWindow(m_ahwndAutoHideBars[uSide]))
547+
m_ahwndAutoHideBars[uSide] = NULL;
548+
return m_ahwndAutoHideBars[uSide];
549+
}
550+
551+
// ABM_SETAUTOHIDEBAR
552+
BOOL CAppBarManager::OnAppBarSetAutoHideBar(_In_ const APPBAR_COMMAND *pData)
553+
{
554+
if (pData->abd.uEdge >= _countof(m_ahwndAutoHideBars))
555+
return FALSE;
556+
HWND hwndTarget = (HWND)UlongToHandle(pData->abd.hWnd32);
557+
return SetAutoHideBar(hwndTarget, (BOOL)pData->abd.lParam64, pData->abd.uEdge);
558+
}
559+
560+
// ABM_SETSTATE
561+
void CAppBarManager::OnAppBarSetState(_In_ UINT uState)
562+
{
563+
if ((uState & ~(ABS_AUTOHIDE | ABS_ALWAYSONTOP)))
564+
return;
565+
566+
SetAutoHideState(!!(uState & ABS_AUTOHIDE));
567+
UpdateAlwaysOnTop(!!(uState & ABS_ALWAYSONTOP));
568+
}
569+
468570
// WM_COPYDATA TABDMC_APPBAR
469571
LRESULT CAppBarManager::OnAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
470572
{
@@ -485,6 +587,21 @@ LRESULT CAppBarManager::OnAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
485587
case ABM_SETPOS:
486588
OnAppBarSetPos(pData);
487589
break;
590+
case ABM_GETSTATE:
591+
return OnAppBarGetState();
592+
case ABM_GETTASKBARPOS:
593+
return OnAppBarGetTaskbarPos(pData);
594+
case ABM_ACTIVATE:
595+
case ABM_WINDOWPOSCHANGED:
596+
OnAppBarActivationChange(pData);
597+
break;
598+
case ABM_GETAUTOHIDEBAR:
599+
return (LRESULT)OnAppBarGetAutoHideBar(pData->abd.uEdge);
600+
case ABM_SETAUTOHIDEBAR:
601+
return OnAppBarSetAutoHideBar(pData);
602+
case ABM_SETSTATE:
603+
OnAppBarSetState((UINT)pData->abd.lParam64);
604+
break;
488605
default:
489606
{
490607
FIXME("0x%X\n", pData->dwMessage);

base/shell/explorer/appbar.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class CAppBarManager
5151

5252
protected:
5353
HDPA m_hAppBarDPA; // DPA (Dynamic Pointer Array)
54+
HWND m_ahwndAutoHideBars[4]; // The side --> auto-hide window
5455

5556
PAPPBAR FindAppBar(_In_ HWND hwndAppBar) const;
5657
void EliminateAppBar(_In_ INT iItem);
@@ -60,11 +61,19 @@ class CAppBarManager
6061
void ComputeHiddenRect(_Inout_ PRECT prc, _In_ UINT uSide);
6162
PAPPBAR_COMMAND GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData);
6263
void GetDockedRect(_Out_ PRECT prcDocked);
64+
BOOL SetAutoHideBar(_In_ HWND hwndTarget, _In_ BOOL bSetOrReset, _In_ UINT uSide);
65+
void OnAppBarActivationChange2(_In_ HWND hwndNewAutoHide, _In_ UINT uSide);
6366

6467
BOOL OnAppBarNew(_In_ const APPBAR_COMMAND *pData);
6568
void OnAppBarRemove(_In_ const APPBAR_COMMAND *pData);
6669
void OnAppBarQueryPos(_Inout_ PAPPBAR_COMMAND pData);
6770
void OnAppBarSetPos(_Inout_ PAPPBAR_COMMAND pData);
71+
UINT OnAppBarGetState();
72+
BOOL OnAppBarGetTaskbarPos(_Inout_ PAPPBAR_COMMAND pData);
73+
void OnAppBarActivationChange(_In_ const APPBAR_COMMAND *pData);
74+
HWND OnAppBarGetAutoHideBar(_In_ UINT uSide);
75+
BOOL OnAppBarSetAutoHideBar(_In_ const APPBAR_COMMAND *pData);
76+
void OnAppBarSetState(_In_ UINT uState);
6877

6978
void OnAppBarNotifyAll(
7079
_In_opt_ HMONITOR hMon,
@@ -89,11 +98,15 @@ class CAppBarManager
8998

9099
virtual BOOL IsAutoHideState() const = 0;
91100
virtual BOOL IsHidingState() const = 0;
92-
virtual HMONITOR GetMonitor() const = 0;
93-
virtual HMONITOR GetPreviousMonitor() const = 0;
101+
virtual BOOL IsAlwaysOnTop() const = 0;
102+
virtual HMONITOR& GetMonitor() = 0;
103+
virtual HMONITOR& GetPreviousMonitor() = 0;
94104
virtual INT GetPosition() const = 0;
95105
virtual const RECT* GetTrayRect() = 0;
106+
virtual HWND GetTrayWnd() const = 0;
96107
virtual HWND GetDesktopWnd() const = 0;
108+
virtual void SetAutoHideState(_In_ BOOL bAutoHide) = 0;
109+
virtual void UpdateAlwaysOnTop(_In_ BOOL bAlwaysOnTop) = 0;
97110

98111
static BOOL CALLBACK
99112
MonitorEnumProc(

base/shell/explorer/precomp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ HRESULT WINAPI _CBandSite_CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void
132132
#define TWM_GETTASKSWITCH (WM_USER + 236)
133133
#define TWM_OPENSTARTMENU (WM_USER + 260)
134134
#define TWM_SETTINGSCHANGED (WM_USER + 300)
135+
#define TWM_SETZORDER (WM_USER + 338)
135136
#define TWM_PULSE (WM_USER + 400)
136137

137138
extern const GUID IID_IShellDesktopTray;

0 commit comments

Comments
 (0)