[EXPLORER-NEW]

* Make use of the CToolbar<T> class to implement a CTaskToolbar.
* Change the CTaskSwitchWnd class to use CTaskToolbar instead of managing the HWND directly.
* Silence logspam in CTrayBandSite.
* Fix CNotifyToolbar to properly.
* Move the call to SetMetrics to be called only on initialization, instead of every time an icon changes.
* Make the start button a CContainedWindowT instead of a raw HWND. TODO: Make a CStartButton class to manage it.

[include/reactos/rosctrls.h]
* Some improvements needed by the taskbar.

svn path=/branches/shell-experiments/; revision=65274
This commit is contained in:
David Quintana 2014-11-05 22:58:53 +00:00
parent 2c30ae43b0
commit a2cc12f3e7
6 changed files with 520 additions and 654 deletions

View file

@ -218,7 +218,7 @@ _tWinMain(IN HINSTANCE hInstance,
#if !WIN7_COMPAT_MODE
BOOL CreateShellDesktop = FALSE;
DbgPrint("Explorer starting... Commandline: %S\n", lpCmdLine);
TRACE("Explorer starting... Commandline: %S\n", lpCmdLine);
/*
* Set our shutdown parameters: we want to shutdown the very last,

File diff suppressed because it is too large Load diff

View file

@ -262,13 +262,10 @@ public:
return E_FAIL;
/*TRACE("Calling IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p) hWndRebar=0x%p\n", hWnd, uMsg, wParam, lParam, plResult, hWndRebar);*/
hRet = WindowEventHandler->OnWinEvent(
hWnd,
uMsg,
wParam,
lParam,
plResult);
if (FAILED_UNEXPECTEDLY(hRet))
hRet = WindowEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, plResult);
#if 0
if (FAILED(hRet))
{
if (uMsg == WM_NOTIFY)
{
@ -280,6 +277,7 @@ public:
ERR("ITrayBandSite->IWinEventHandler::ProcessMessage(0x%p,0x%x,0x%p,0x%p,0x%p->0x%p) returned: 0x%x\n", hWnd, uMsg, wParam, lParam, plResult, *plResult, hRet);
}
}
#endif
return hRet;
}

View file

@ -19,7 +19,9 @@
*/
#include "precomp.h"
//#include <docobj.h>
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
/*
* SysPagerWnd
@ -86,6 +88,13 @@ public:
NOTIFYICONDATA * notifyItem;
WCHAR text [] = TEXT("");
int index = FindItemByIconData(iconData, &notifyItem);
if (index >= 0)
{
UpdateButton(iconData);
return;
}
notifyItem = new NOTIFYICONDATA();
ZeroMemory(notifyItem, sizeof(*notifyItem));
@ -203,7 +212,7 @@ public:
delete notifyItem;
}
VOID GetTooltip(int index, LPTSTR szTip, DWORD cchTip)
VOID GetTooltipText(int index, LPTSTR szTip, DWORD cchTip)
{
NOTIFYICONDATA * notifyItem;
notifyItem = GetItemData(index);
@ -242,7 +251,7 @@ private:
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
{
DbgPrint("Sending message %S from button %d to %p (msg=%x, w=%x, l=%x)...\n",
TRACE("Sending message %S from button %d to %p (msg=%x, w=%x, l=%x)...\n",
eventNames[uMsg - WM_MOUSEFIRST], wIndex,
notifyItem->hWnd, notifyItem->uCallbackMessage, notifyItem->uID, uMsg);
}
@ -269,13 +278,9 @@ private:
LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
POINT pt;
INT iBtn;
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
iBtn = (INT) SendMessageW(TB_HITTEST, 0, (LPARAM) &pt);
INT iBtn = HitTest(&pt);
if (iBtn >= 0)
{
@ -286,9 +291,64 @@ private:
return FALSE;
}
LRESULT OnTooltipShow(INT uCode, LPNMHDR hdr, BOOL& bHandled)
{
RECT rcTip, rcItem;
GetWindowRect(hdr->hwndFrom, &rcTip);
SIZE szTip = { rcTip.right - rcTip.left, rcTip.bottom - rcTip.top };
INT iBtn = GetHotItem();
if (iBtn >= 0)
{
MONITORINFO monInfo = { 0 };
HMONITOR hMon = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
monInfo.cbSize = sizeof(monInfo);
if (hMon)
GetMonitorInfo(hMon, &monInfo);
else
GetWindowRect(GetDesktopWindow(), &monInfo.rcMonitor);
GetItemRect(iBtn, &rcItem);
POINT ptItem = { rcItem.left, rcItem.top };
SIZE szItem = { rcItem.right - rcItem.left, rcItem.bottom - rcItem.top };
ClientToScreen(m_hWnd, &ptItem);
ptItem.x += szItem.cx / 2;
ptItem.y -= szTip.cy;
if (ptItem.x + szTip.cx > monInfo.rcMonitor.right)
ptItem.x = monInfo.rcMonitor.right - szTip.cx;
if (ptItem.y + szTip.cy > monInfo.rcMonitor.bottom)
ptItem.y = monInfo.rcMonitor.bottom - szTip.cy;
if (ptItem.x < monInfo.rcMonitor.left)
ptItem.x = monInfo.rcMonitor.left;
if (ptItem.y < monInfo.rcMonitor.top)
ptItem.y = monInfo.rcMonitor.top;
TRACE("ptItem { %d, %d }\n", ptItem.x, ptItem.y);
::SetWindowPos(hdr->hwndFrom, NULL, ptItem.x, ptItem.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
return TRUE;
}
bHandled = FALSE;
return 0;
}
public:
BEGIN_MSG_MAP(CNotifyToolbar)
MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseEvent)
NOTIFY_CODE_HANDLER(TTN_SHOW, OnTooltipShow)
END_MSG_MAP()
void Initialize(HWND hWndParent)
@ -298,7 +358,7 @@ public:
TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE | TBSTYLE_TRANSPARENT |
CCS_TOP | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER;
Create(hWndParent, styles);
SubclassWindow(Create(hWndParent, styles));
SetWindowTheme(m_hWnd, L"TrayNotify", NULL);
@ -398,7 +458,6 @@ public:
void GetSize(IN WPARAM wParam, IN PSIZE size)
{
INT rows = 0;
TBMETRICS tbm;
int VisibleButtonCount = Toolbar.GetVisibleButtonCount();
if (wParam) /* horizontal */
@ -415,20 +474,12 @@ public:
rows++;
size->cy = (VisibleButtonCount + rows - 1) / rows * 24;
}
tbm.cbSize = sizeof(tbm);
tbm.dwMask = TBMF_BARPAD | TBMF_BUTTONSPACING;
tbm.cxBarPad = tbm.cyBarPad = 0;
tbm.cxButtonSpacing = 0;
tbm.cyButtonSpacing = 0;
Toolbar.SetMetrics(&tbm);
}
LRESULT OnGetInfoTip(INT uCode, LPNMHDR hdr, BOOL& bHandled)
{
NMTBGETINFOTIPW * nmtip = (NMTBGETINFOTIPW *) hdr;
Toolbar.GetTooltip(nmtip->iItem, nmtip->pszText, nmtip->cchTextMax);
Toolbar.GetTooltipText(nmtip->iItem, nmtip->pszText, nmtip->cchTextMax);
return TRUE;
}
@ -457,6 +508,15 @@ public:
if (Toolbar)
{
TBMETRICS tbm;
tbm.cbSize = sizeof(tbm);
tbm.dwMask = TBMF_BARPAD | TBMF_BUTTONSPACING;
tbm.cxBarPad = tbm.cyBarPad = 0;
tbm.cxButtonSpacing = 0;
tbm.cyButtonSpacing = 0;
Toolbar.SetMetrics(&tbm);
Toolbar.SetWindowPos(NULL, 0, 0, szClient.cx, szClient.cy, SWP_NOZORDER);
Toolbar.AutoSize();

View file

@ -60,11 +60,11 @@ class CTrayWindow :
public ITrayWindow,
public IShellDesktopTray
{
CContainedWindow StartButton;
HTHEME TaskbarTheme;
HWND hWndDesktop;
HWND hwndStart;
IImageList * himlStartBtn;
SIZE StartBtnSize;
HFONT hStartBtnFont;
@ -120,9 +120,9 @@ class CTrayWindow :
public:
CTrayWindow() :
StartButton(this, 1),
TaskbarTheme(NULL),
hWndDesktop(NULL),
hwndStart(NULL),
himlStartBtn(NULL),
hStartBtnFont(NULL),
hCaptionFont(NULL),
@ -815,8 +815,7 @@ ChangePos:
ResizeWorkArea();
ApplyClipping(
TRUE);
ApplyClipping(TRUE);
}
typedef struct _TW_STUCKRECTS2
@ -1058,20 +1057,14 @@ ChangePos:
SIZE Size = { 0, 0 };
if (himlStartBtn == NULL ||
!SendMessage(hwndStart,
BCM_GETIDEALSIZE,
0,
(LPARAM) &Size))
!StartButton.SendMessage(BCM_GETIDEALSIZE, 0, (LPARAM) &Size))
{
Size.cx = GetSystemMetrics(SM_CXEDGE);
Size.cy = GetSystemMetrics(SM_CYEDGE);
if (hbmStart == NULL)
{
hbmStart = (HBITMAP) SendMessage(hwndStart,
BM_GETIMAGE,
IMAGE_BITMAP,
0);
hbmStart = (HBITMAP) StartButton.SendMessage(BM_GETIMAGE, IMAGE_BITMAP, 0);
}
if (hbmStart != NULL)
@ -1139,11 +1132,11 @@ DefSize:
if (StartSize.cx > rcClient.right)
StartSize.cx = rcClient.right;
if (hwndStart != NULL)
if (StartButton.m_hWnd != NULL)
{
/* Resize and reposition the button */
dwp = DeferWindowPos(dwp,
hwndStart,
StartButton.m_hWnd,
NULL,
0,
0,
@ -1407,6 +1400,15 @@ Cleanup:
else
TaskbarTheme = NULL;
if (TaskbarTheme)
{
SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, 0);
}
else
{
SetWindowStyle(m_hWnd, WS_THICKFRAME | WS_BORDER, WS_THICKFRAME | WS_BORDER);
}
return TRUE;
}
@ -1461,7 +1463,8 @@ Cleanup:
}
/* Create the Start button */
hwndStart = CreateWindowEx(0,
StartButton.SubclassWindow(CreateWindowEx(
0,
WC_BUTTON,
szStartCaption,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
@ -1473,14 +1476,11 @@ Cleanup:
m_hWnd,
(HMENU) IDC_STARTBTN,
hExplorerInstance,
NULL);
if (hwndStart)
NULL));
if (StartButton.m_hWnd)
{
SetWindowTheme(hwndStart, L"Start", NULL);
SendMessage(hwndStart,
WM_SETFONT,
(WPARAM) hStartBtnFont,
FALSE);
SetWindowTheme(StartButton.m_hWnd, L"Start", NULL);
StartButton.SendMessage(WM_SETFONT, (WPARAM) hStartBtnFont, FALSE);
if (CreateStartBtnImageList())
{
@ -1493,10 +1493,7 @@ Cleanup:
bil.margin.top = bil.margin.bottom = 1;
bil.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;
if (!SendMessage(hwndStart,
BCM_SETIMAGELIST,
0,
(LPARAM) &bil))
if (!StartButton.SendMessage(BCM_SETIMAGELIST, 0, (LPARAM) &bil))
{
/* Fall back to the deprecated method on older systems that don't
support Common Controls 6.0 */
@ -1508,12 +1505,9 @@ Cleanup:
/* We're using the image list, remove the BS_BITMAP style and
don't center it horizontally */
SetWindowStyle(hwndStart,
BS_BITMAP | BS_RIGHT,
0);
SetWindowStyle(StartButton.m_hWnd, BS_BITMAP | BS_RIGHT, 0);
UpdateStartButton(
NULL);
UpdateStartButton(NULL);
}
else
{
@ -1523,13 +1517,9 @@ SetStartBtnImage:
hbmStart = CreateStartButtonBitmap();
if (hbmStart != NULL)
{
UpdateStartButton(
hbmStart);
UpdateStartButton(hbmStart);
hbmOld = (HBITMAP) SendMessage(hwndStart,
BM_SETIMAGE,
IMAGE_BITMAP,
(LPARAM) hbmStart);
hbmOld = (HBITMAP) StartButton.SendMessage(BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hbmStart);
if (hbmOld != NULL)
DeleteObject(hbmOld);
@ -1657,7 +1647,7 @@ SetStartBtnImage:
HWND hwnd;
RECT posRect;
GetWindowRect(hwndStart, &posRect);
GetWindowRect(StartButton.m_hWnd, &posRect);
hwnd = CreateWindowEx(0,
WC_STATIC,
NULL,
@ -1920,7 +1910,7 @@ SetStartBtnImage:
HWND hwnd;
RECT posRect;
GetWindowRect(hwndStart, &posRect);
GetWindowRect(StartButton.m_hWnd, &posRect);
hwnd = CreateWindowEx(0,
WC_STATIC,
@ -1979,8 +1969,7 @@ SetStartBtnImage:
RECTL rcExclude;
DWORD dwFlags = 0;
if (GetWindowRect(hwndStart,
(RECT*) &rcExclude))
if (GetWindowRect(StartButton.m_hWnd, (RECT*) &rcExclude))
{
switch (Position)
{
@ -2007,7 +1996,7 @@ SetStartBtnImage:
&rcExclude,
dwFlags);
SendMessageW(hwndStart, BM_SETSTATE, TRUE, 0);
StartButton.SendMessageW(BM_SETSTATE, TRUE, 0);
}
}
}
@ -2023,7 +2012,7 @@ SetStartBtnImage:
GetWindowRect(m_hWnd, &rcCurrent);
over = PtInRect(&rcCurrent, pt);
if (SendMessage(hwndStart, BM_GETSTATE, 0, 0) != BST_UNCHECKED)
if (StartButton.SendMessage( BM_GETSTATE, 0, 0) != BST_UNCHECKED)
{
over = TRUE;
}
@ -2434,7 +2423,7 @@ SetStartBtnImage:
uId = TrackMenu(
hSysMenu,
NULL,
hwndStart,
StartButton.m_hWnd,
Position != ABE_TOP,
FALSE);
if (uId != 0)
@ -2483,16 +2472,13 @@ SetStartBtnImage:
if (pt.x != -1 || pt.y != -1)
ppt = &pt;
else
hWndExclude = hwndStart;
hWndExclude = StartButton.m_hWnd;
if ((HWND) wParam == hwndStart)
if ((HWND) wParam == StartButton.m_hWnd)
{
/* Make sure we can't track the context menu if the start
menu is currently being shown */
if (!(SendMessage(hwndStart,
BM_GETSTATE,
0,
0) & BST_PUSHED))
if (!(StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
{
TrackCtxMenu(
&StartMenuBtnCtxMenu,
@ -2511,27 +2497,18 @@ SetStartBtnImage:
POINT ptClient = *ppt;
/* Convert the coordinates to client-coordinates */
MapWindowPoints(NULL,
m_hWnd,
&ptClient,
1);
MapWindowPoints(NULL, m_hWnd, &ptClient, 1);
hWndAtPt = ChildWindowFromPoint(m_hWnd,
ptClient);
hWndAtPt = ChildWindowFromPoint(m_hWnd, ptClient);
if (hWndAtPt != NULL &&
(hWndAtPt == hwndRebar || IsChild(hwndRebar,
hWndAtPt)))
{
/* Check if the user clicked on the task switch window */
ptClient = *ppt;
MapWindowPoints(NULL,
hwndRebar,
&ptClient,
1);
MapWindowPoints(NULL, hwndRebar, &ptClient, 1);
hWndAtPt = ChildWindowFromPointEx(hwndRebar,
ptClient,
CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
hWndAtPt = ChildWindowFromPointEx(hwndRebar, ptClient, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
if (hWndAtPt == hwndTaskSwitch)
goto HandleTrayContextMenu;
@ -2572,7 +2549,7 @@ HandleTrayContextMenu:
return Ret;
}
if (TrayBandSite == NULL || FAILED_UNEXPECTEDLY(hr))
if (TrayBandSite == NULL || FAILED(hr))
{
const NMHDR *nmh = (const NMHDR *) lParam;
@ -2628,7 +2605,7 @@ HandleTrayContextMenu:
}
else
{
SendMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(BN_CLICKED, IDC_STARTBTN), reinterpret_cast<LPARAM>(hwndStart));
PopupStartMenu();
}
return TRUE;
@ -2638,7 +2615,7 @@ HandleTrayContextMenu:
{
LRESULT Ret = FALSE;
if ((HWND) lParam == hwndStart)
if ((HWND) lParam == StartButton.m_hWnd)
{
PopupStartMenu();
return FALSE;
@ -2801,9 +2778,7 @@ HandleTrayContextMenu:
Msg.wParam = wParam;
Msg.lParam = lParam;
if (StartMenuBand->TranslateMenuMessage(
&Msg,
&lRet) == S_OK)
if (StartMenuBand->TranslateMenuMessage(&Msg, &lRet) == S_OK)
{
return lRet;
}
@ -2838,6 +2813,7 @@ HandleTrayContextMenu:
MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_APP_TRAYDESTROY, OnAppTrayDestroy)
MESSAGE_HANDLER(TWM_OPENSTARTMENU, OnOpenStartMenu)
ALT_MSG_MAP(1)
END_MSG_MAP()
/*
@ -2959,10 +2935,7 @@ HandleTrayContextMenu:
while (1)
{
Ret = GetMessage(&Msg,
NULL,
0,
0);
Ret = GetMessage(&Msg, NULL, 0, 0);
if (!Ret || Ret == -1)
break;
@ -3026,7 +2999,7 @@ HandleTrayContextMenu:
virtual HRESULT RaiseStartButton()
{
SendMessageW(hwndStart, BM_SETSTATE, FALSE, 0);
StartButton.SendMessageW(BM_SETSTATE, FALSE, 0);
return S_OK;
}

View file

@ -197,9 +197,9 @@ public:
};
template<typename TItemData>
template<typename TItemData = DWORD_PTR>
class CToolbar :
public CWindow
public CWindowImplBaseT<CWindow>
{
public: // Configuration methods
@ -215,15 +215,11 @@ public: // Configuration methods
dwExStyles = WS_EX_TOOLWINDOW;
}
m_hWnd = CreateWindowEx(dwExStyles,
m_hWnd = CreateWindowExW(dwExStyles,
TOOLBARCLASSNAME,
NULL,
dwStyles,
0,
0,
0,
0,
hWndParent,
0, 0, 0, 0, hWndParent,
NULL,
_AtlBaseModule.GetModuleInstance(),
NULL);
@ -242,6 +238,21 @@ public: // Configuration methods
return SendMessageW(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
}
HWND GetTooltip()
{
return (HWND)SendMessageW(TB_GETTOOLTIPS);
}
DWORD SetTooltip(HWND hWndTooltip)
{
return SendMessageW(TB_SETTOOLTIPS, hWndTooltip, 0);
}
INT GetHotItem()
{
return SendMessageW(TB_GETHOTITEM);
}
public: // Button list management methods
int GetButtonCount()
{
@ -299,15 +310,36 @@ public: // Layout management methods
return SendMessageW(TB_AUTOSIZE);
}
DWORD GetMetrics(TBMETRICS * tbm)
{
return SendMessageW(TB_GETMETRICS, 0, (LPARAM) tbm);
}
DWORD SetMetrics(TBMETRICS * tbm)
{
return SendMessageW(TB_SETMETRICS, 0, (LPARAM) tbm);
}
DWORD GetItemRect(int index, LPRECT prcItem)
{
return SendMessageW(TB_GETITEMRECT, index, (LPARAM) prcItem);
}
DWORD SetRedraw(BOOL bEnable)
{
return SendMessageW(WM_SETREDRAW, bEnable);
}
public: // Image list management methods
DWORD SetImageList(HIMAGELIST himl)
{
return SendMessageW(TB_SETIMAGELIST, 0, (LPARAM) himl);
}
DWORD SetMetrics(TBMETRICS * tbm)
public: // Other methods
INT HitTest(PPOINT ppt)
{
return SendMessageW(TB_SETMETRICS, 0, (LPARAM) tbm);
return (INT) SendMessageW(TB_HITTEST, 0, (LPARAM) ppt);
}
public: // Utility methods