[COMCTL32]

* Begin implementing TB_GETMETRICS/TB_SETMETRICS. Will send to wine once the button spacing setting works (after writing tests and whatever else may be necessary).

svn path=/branches/shell-experiments/; revision=65275
This commit is contained in:
David Quintana 2014-11-05 23:00:23 +00:00
parent a2cc12f3e7
commit fb929febc6

View file

@ -33,11 +33,9 @@
* - TBSTYLE_REGISTERDROP * - TBSTYLE_REGISTERDROP
* - TBSTYLE_EX_DOUBLEBUFFER * - TBSTYLE_EX_DOUBLEBUFFER
* - Messages: * - Messages:
* - TB_GETMETRICS
* - TB_GETOBJECT * - TB_GETOBJECT
* - TB_INSERTMARKHITTEST * - TB_INSERTMARKHITTEST
* - TB_SAVERESTORE * - TB_SAVERESTORE
* - TB_SETMETRICS
* - WM_WININICHANGE * - WM_WININICHANGE
* - Notifications: * - Notifications:
* - NM_CHAR * - NM_CHAR
@ -126,6 +124,8 @@ typedef struct
INT nOldHit; INT nOldHit;
INT nHotItem; /* index of the "hot" item */ INT nHotItem; /* index of the "hot" item */
SIZE szPadding; /* padding values around button */ SIZE szPadding; /* padding values around button */
SIZE szBarPadding; /* padding values around the toolbar (NOT USED BUT STORED) */
SIZE szSpacing; /* spacing values between buttons */
INT iTopMargin; /* the top margin */ INT iTopMargin; /* the top margin */
INT iListGap; /* default gap between text and image for toolbar with list style */ INT iListGap; /* default gap between text and image for toolbar with list style */
HFONT hDefaultFont; HFONT hDefaultFont;
@ -191,12 +191,18 @@ typedef enum
#define ARROW_HEIGHT 3 #define ARROW_HEIGHT 3
#define INSERTMARK_WIDTH 2 #define INSERTMARK_WIDTH 2
/* default padding inside a button */
#define DEFPAD_CX 7 #define DEFPAD_CX 7
#define DEFPAD_CY 6 #define DEFPAD_CY 6
/* default space between buttons and between rows */
#define DEFSPACE_CX 7
#define DEFSPACE_CY 6
#define DEFLISTGAP 4 #define DEFLISTGAP 4
/* vertical padding used in list mode when image is present */ /* vertical padding used in list mode when image is present */
#define LISTPAD_CY 9 #define LISTPAD_CY 2
/* how wide to treat the bitmap if it isn't present */ /* how wide to treat the bitmap if it isn't present */
#define NONLIST_NOTEXT_OFFSET 2 #define NONLIST_NOTEXT_OFFSET 2
@ -1276,11 +1282,11 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
/* When the toolbar window style is not TBSTYLE_WRAPABLE, */ /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
/* no layout is necessary. Applications may use this style */ /* no layout is necessary. Applications may use this style */
/* to perform their own layout on the toolbar. */ /* to perform their own layout on the toolbar. */
if( !(infoPtr->dwStyle & TBSTYLE_WRAPABLE) && if (!(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
!(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL) ) return; !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL)) return;
btnPtr = infoPtr->buttons; btnPtr = infoPtr->buttons;
x = infoPtr->nIndent; x = infoPtr->nIndent;
if (GetParent(infoPtr->hwndSelf)) if (GetParent(infoPtr->hwndSelf))
{ {
@ -1288,144 +1294,145 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
* this toolbar. We cannot use its height, as there may be multiple * this toolbar. We cannot use its height, as there may be multiple
* toolbars in a rebar control * toolbars in a rebar control
*/ */
GetClientRect( GetParent(infoPtr->hwndSelf), &rc ); GetClientRect(GetParent(infoPtr->hwndSelf), &rc);
infoPtr->nWidth = rc.right - rc.left; infoPtr->nWidth = rc.right - rc.left;
} }
else else
{ {
GetWindowRect( infoPtr->hwndSelf, &rc ); GetWindowRect(infoPtr->hwndSelf, &rc);
infoPtr->nWidth = rc.right - rc.left; infoPtr->nWidth = rc.right - rc.left;
} }
bButtonWrap = FALSE; bButtonWrap = FALSE;
TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n", TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth, infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth,
infoPtr->nIndent); infoPtr->nIndent);
for (i = 0; i < infoPtr->nNumButtons; i++ ) for (i = 0; i < infoPtr->nNumButtons; i++)
{ {
btnPtr[i].fsState &= ~TBSTATE_WRAP; btnPtr[i].fsState &= ~TBSTATE_WRAP;
if (btnPtr[i].fsState & TBSTATE_HIDDEN) if (btnPtr[i].fsState & TBSTATE_HIDDEN)
continue; continue;
if (btnPtr[i].cx > 0) if (btnPtr[i].cx > 0)
cx = btnPtr[i].cx; cx = btnPtr[i].cx;
/* horizontal separators are treated as buttons for width */ /* horizontal separators are treated as buttons for width */
else if ((btnPtr[i].fsStyle & BTNS_SEP) && else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
!(infoPtr->dwStyle & CCS_VERT)) !(infoPtr->dwStyle & CCS_VERT))
cx = (btnPtr[i].iBitmap > 0) ? btnPtr[i].iBitmap : SEPARATOR_WIDTH; cx = (btnPtr[i].iBitmap > 0) ? btnPtr[i].iBitmap : SEPARATOR_WIDTH;
else else
cx = infoPtr->nButtonWidth; cx = infoPtr->nButtonWidth;
/* Two or more adjacent separators form a separator group. */ /* Two or more adjacent separators form a separator group. */
/* The first separator in a group should be wrapped to the */ /* The first separator in a group should be wrapped to the */
/* next row if the previous wrapping is on a button. */ /* next row if the previous wrapping is on a button. */
if( bButtonWrap && if (bButtonWrap &&
(btnPtr[i].fsStyle & BTNS_SEP) && (btnPtr[i].fsStyle & BTNS_SEP) &&
(i + 1 < infoPtr->nNumButtons ) && (i + 1 < infoPtr->nNumButtons) &&
(btnPtr[i + 1].fsStyle & BTNS_SEP) ) (btnPtr[i + 1].fsStyle & BTNS_SEP))
{ {
TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle); TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
btnPtr[i].fsState |= TBSTATE_WRAP; btnPtr[i].fsState |= TBSTATE_WRAP;
x = infoPtr->nIndent; x = infoPtr->nIndent;
i++; i++;
bButtonWrap = FALSE; bButtonWrap = FALSE;
continue; continue;
} }
/* The layout makes sure the bitmap is visible, but not the button. */ /* The layout makes sure the bitmap is visible, but not the button. */
/* Test added to also wrap after a button that starts a row but */ /* Test added to also wrap after a button that starts a row but */
/* is bigger than the area. - GA 8/01 */ /* is bigger than the area. - GA 8/01 */
if (( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2 if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
> infoPtr->nWidth ) || > infoPtr->nWidth) ||
((x == infoPtr->nIndent) && (cx > infoPtr->nWidth))) ((x == infoPtr->nIndent) && (cx > infoPtr->nWidth)))
{ {
BOOL bFound = FALSE; BOOL bFound = FALSE;
/* If the current button is a separator and not hidden, */ /* If the current button is a separator and not hidden, */
/* go to the next until it reaches a non separator. */ /* go to the next until it reaches a non separator. */
/* Wrap the last separator if it is before a button. */ /* Wrap the last separator if it is before a button. */
while( ( ((btnPtr[i].fsStyle & BTNS_SEP) && while ((((btnPtr[i].fsStyle & BTNS_SEP) &&
!(btnPtr[i].fsStyle & BTNS_DROPDOWN)) || !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
(btnPtr[i].fsState & TBSTATE_HIDDEN) ) && (btnPtr[i].fsState & TBSTATE_HIDDEN)) &&
i < infoPtr->nNumButtons ) i < infoPtr->nNumButtons)
{ {
i++; i++;
bFound = TRUE; bFound = TRUE;
} }
if( bFound && i < infoPtr->nNumButtons ) if (bFound && i < infoPtr->nNumButtons)
{ {
i--; i--;
TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n", TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
i, btnPtr[i].fsStyle, x, cx); i, btnPtr[i].fsStyle, x, cx);
btnPtr[i].fsState |= TBSTATE_WRAP; btnPtr[i].fsState |= TBSTATE_WRAP;
x = infoPtr->nIndent; x = infoPtr->nIndent;
bButtonWrap = FALSE; bButtonWrap = FALSE;
continue; continue;
} }
else if ( i >= infoPtr->nNumButtons) else if (i >= infoPtr->nNumButtons)
break; break;
/* If the current button is not a separator, find the last */ /* If the current button is not a separator, find the last */
/* separator and wrap it. */ /* separator and wrap it. */
for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--) for (j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
{ {
if ((btnPtr[j].fsStyle & BTNS_SEP) && if ((btnPtr[j].fsStyle & BTNS_SEP) &&
!(btnPtr[j].fsState & TBSTATE_HIDDEN)) !(btnPtr[j].fsState & TBSTATE_HIDDEN))
{ {
bFound = TRUE; bFound = TRUE;
i = j; i = j;
TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n", TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
i, btnPtr[i].fsStyle, x, cx); i, btnPtr[i].fsStyle, x, cx);
x = infoPtr->nIndent; x = infoPtr->nIndent;
btnPtr[j].fsState |= TBSTATE_WRAP; btnPtr[j].fsState |= TBSTATE_WRAP;
bButtonWrap = FALSE; bButtonWrap = FALSE;
break; break;
} }
} }
/* If no separator available for wrapping, wrap one of */ /* If no separator available for wrapping, wrap one of */
/* non-hidden previous button. */ /* non-hidden previous button. */
if (!bFound) if (!bFound)
{ {
for ( j = i - 1; for (j = i - 1;
j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--) j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
{ {
if (btnPtr[j].fsState & TBSTATE_HIDDEN) if (btnPtr[j].fsState & TBSTATE_HIDDEN)
continue; continue;
bFound = TRUE; bFound = TRUE;
i = j; i = j;
TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n", TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
i, btnPtr[i].fsStyle, x, cx); i, btnPtr[i].fsStyle, x, cx);
x = infoPtr->nIndent; x = infoPtr->nIndent;
btnPtr[j].fsState |= TBSTATE_WRAP; btnPtr[j].fsState |= TBSTATE_WRAP;
bButtonWrap = TRUE; bButtonWrap = TRUE;
break; break;
} }
} }
/* If all above failed, wrap the current button. */ /* If all above failed, wrap the current button. */
if (!bFound) if (!bFound)
{ {
TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n", TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
i, btnPtr[i].fsStyle, x, cx); i, btnPtr[i].fsStyle, x, cx);
btnPtr[i].fsState |= TBSTATE_WRAP; btnPtr[i].fsState |= TBSTATE_WRAP;
x = infoPtr->nIndent; x = infoPtr->nIndent;
if (btnPtr[i].fsStyle & BTNS_SEP ) if (btnPtr[i].fsStyle & BTNS_SEP)
bButtonWrap = FALSE; bButtonWrap = FALSE;
else else
bButtonWrap = TRUE; bButtonWrap = TRUE;
} }
} }
else { else
TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n", {
i, btnPtr[i].fsStyle, x, cx); TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
x += cx; i, btnPtr[i].fsStyle, x, cx);
} x += cx;
}
} }
} }
@ -1551,9 +1558,8 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
/* ... add on the necessary padding */ /* ... add on the necessary padding */
if (bValidImageList) if (bValidImageList)
{ {
if (bHasBitmap) sizeButton.cy += infoPtr->szPadding.cy;
sizeButton.cy += DEFPAD_CY; if (!bHasBitmap)
else
sizeButton.cy += LISTPAD_CY; sizeButton.cy += LISTPAD_CY;
} }
else else
@ -1570,7 +1576,7 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
{ {
if (bHasBitmap) if (bHasBitmap)
{ {
sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY; sizeButton.cy = infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
if (sizeString.cy > 0) if (sizeString.cy > 0)
sizeButton.cy += 1 + sizeString.cy; sizeButton.cy += 1 + sizeString.cy;
sizeButton.cx = infoPtr->szPadding.cx + sizeButton.cx = infoPtr->szPadding.cx +
@ -1627,17 +1633,17 @@ static void
TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr) TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
{ {
TBUTTON_INFO *btnPtr; TBUTTON_INFO *btnPtr;
SIZE sizeButton; SIZE sizeButton;
INT i, nRows, nSepRows; INT i, nRows, nSepRows;
INT x, y, cx, cy; INT x, y, cx, cy;
BOOL bWrap; BOOL bWrap;
BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0); BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0);
BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle); BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
TOOLBAR_WrapToolbar(infoPtr); TOOLBAR_WrapToolbar(infoPtr);
x = infoPtr->nIndent; x = infoPtr->nIndent;
y = infoPtr->iTopMargin; y = infoPtr->iTopMargin;
cx = infoPtr->nButtonWidth; cx = infoPtr->nButtonWidth;
cy = infoPtr->nButtonHeight; cy = infoPtr->nButtonHeight;
@ -1652,106 +1658,112 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
TRACE("cy=%d\n", cy); TRACE("cy=%d\n", cy);
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ ) for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
{ {
bWrap = FALSE; bWrap = FALSE;
if (btnPtr->fsState & TBSTATE_HIDDEN) if (btnPtr->fsState & TBSTATE_HIDDEN)
{ {
SetRectEmpty (&btnPtr->rect); SetRectEmpty(&btnPtr->rect);
continue; continue;
} }
cy = infoPtr->nButtonHeight; cy = infoPtr->nButtonHeight;
if (btnPtr->fsStyle & BTNS_SEP) { if (btnPtr->fsStyle & BTNS_SEP)
if (infoPtr->dwStyle & CCS_VERT) { {
if (infoPtr->dwStyle & CCS_VERT)
{
cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH; cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth; cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth;
}
else
cx = (btnPtr->cx > 0) ? btnPtr->cx :
(btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
}
else
{
if (btnPtr->cx)
cx = btnPtr->cx;
else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
(btnPtr->fsStyle & BTNS_AUTOSIZE))
{
SIZE sz;
HDC hdc;
HFONT hOldFont;
hdc = GetDC (infoPtr->hwndSelf);
hOldFont = SelectObject (hdc, infoPtr->hFont);
TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
SelectObject (hdc, hOldFont);
ReleaseDC (infoPtr->hwndSelf, hdc);
sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
validImageList);
cx = sizeButton.cx;
} }
else else
cx = infoPtr->nButtonWidth; {
cx = (btnPtr->cx > 0) ? btnPtr->cx :
(btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
}
}
else
{
if (btnPtr->cx)
{
cx = btnPtr->cx;
}
else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
(btnPtr->fsStyle & BTNS_AUTOSIZE))
{
SIZE sz;
HDC hdc;
HFONT hOldFont;
hdc = GetDC(infoPtr->hwndSelf);
hOldFont = SelectObject(hdc, infoPtr->hFont);
TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
SelectObject(hdc, hOldFont);
ReleaseDC(infoPtr->hwndSelf, hdc);
sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
validImageList);
cx = sizeButton.cx;
}
else
cx = infoPtr->nButtonWidth;
/* if size has been set manually then don't add on extra space /* if size has been set manually then don't add on extra space
* for the drop down arrow */ * for the drop down arrow */
if (!btnPtr->cx && hasDropDownArrows && if (!btnPtr->cx && hasDropDownArrows &&
((btnPtr->fsStyle & BTNS_DROPDOWN) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN))) ((btnPtr->fsStyle & BTNS_DROPDOWN) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN)))
cx += DDARROW_WIDTH; cx += DDARROW_WIDTH;
} }
if (btnPtr->fsState & TBSTATE_WRAP ) if (btnPtr->fsState & TBSTATE_WRAP)
bWrap = TRUE; bWrap = TRUE;
SetRect (&btnPtr->rect, x, y, x + cx, y + cy); SetRect(&btnPtr->rect, x, y, x + cx, y + cy);
if (infoPtr->rcBound.left > x) if (infoPtr->rcBound.left > x)
infoPtr->rcBound.left = x; infoPtr->rcBound.left = x;
if (infoPtr->rcBound.right < x + cx) if (infoPtr->rcBound.right < x + cx)
infoPtr->rcBound.right = x + cx; infoPtr->rcBound.right = x + cx;
if (infoPtr->rcBound.bottom < y + cy) if (infoPtr->rcBound.bottom < y + cy)
infoPtr->rcBound.bottom = y + cy; infoPtr->rcBound.bottom = y + cy;
TOOLBAR_TooltipSetRect(infoPtr, btnPtr); TOOLBAR_TooltipSetRect(infoPtr, btnPtr);
/* btnPtr->nRow is zero based. The space between the rows is */ /* btnPtr->nRow is zero based. The space between the rows is */
/* also considered as a row. */ /* also considered as a row. */
btnPtr->nRow = nRows + nSepRows; btnPtr->nRow = nRows + nSepRows;
TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n", TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n",
i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow, i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow,
x, y, x+cx, y+cy); x, y, x + cx, y + cy);
if( bWrap ) if (bWrap)
{ {
if ( !(btnPtr->fsStyle & BTNS_SEP) ) if (!(btnPtr->fsStyle & BTNS_SEP))
y += cy; y += cy;
else else
{ {
if ( !(infoPtr->dwStyle & CCS_VERT)) if (!(infoPtr->dwStyle & CCS_VERT))
y += cy + ( (btnPtr->cx > 0 ) ? y += cy + ((btnPtr->cx > 0) ?
btnPtr->cx : SEPARATOR_WIDTH) * 2 /3; btnPtr->cx : SEPARATOR_WIDTH) * 2 / 3;
else else
y += cy; y += cy;
/* nSepRows is used to calculate the extra height following */ /* nSepRows is used to calculate the extra height following */
/* the last row. */ /* the last row. */
nSepRows++; nSepRows++;
} }
x = infoPtr->nIndent; x = infoPtr->nIndent;
/* Increment row number unless this is the last button */ /* Increment row number unless this is the last button */
/* and it has Wrap set. */ /* and it has Wrap set. */
if (i != infoPtr->nNumButtons-1) if (i != infoPtr->nNumButtons - 1)
nRows++; nRows++;
} }
else else
x += cx; x += cx;
} }
/* infoPtr->nRows is the number of rows on the toolbar */ /* infoPtr->nRows is the number of rows on the toolbar */
@ -1941,6 +1953,16 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg); SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
} }
static LRESULT
TOOLBAR_ThemeChanged(HWND hwnd)
{
HTHEME theme = GetWindowTheme(hwnd);
CloseThemeData(theme);
OpenThemeData(hwnd, themeClass);
return 0;
}
static void static void
TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button) TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
{ {
@ -3530,6 +3552,36 @@ TOOLBAR_GetMaxSize (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize)
} }
static LRESULT
TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
{
if (pMetrics == NULL)
return FALSE;
/* TODO: check if cbSize is a valid value */
if (pMetrics->dwMask & TBMF_PAD)
{
pMetrics->cxPad = infoPtr->szPadding.cx;
pMetrics->cyPad = infoPtr->szPadding.cy;
}
if (pMetrics->dwMask & TBMF_BARPAD)
{
pMetrics->cxBarPad = infoPtr->szBarPadding.cx;
pMetrics->cyBarPad = infoPtr->szBarPadding.cy;
}
if (pMetrics->dwMask & TBMF_BUTTONSPACING)
{
pMetrics->cxButtonSpacing = infoPtr->szSpacing.cx;
pMetrics->cyButtonSpacing = infoPtr->szSpacing.cy;
}
return TRUE;
}
/* << TOOLBAR_GetObject >> */ /* << TOOLBAR_GetObject >> */
@ -4711,6 +4763,43 @@ TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *infoPtr, INT nMaxRows)
} }
static LRESULT
TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
{
BOOL changed = FALSE;
if (!pMetrics)
return FALSE;
/* TODO: check if cbSize is a valid value */
if (pMetrics->dwMask & TBMF_PAD)
{
infoPtr->szPadding.cx = pMetrics->cxPad;
infoPtr->szPadding.cy = pMetrics->cyPad;
changed = TRUE;
}
if (pMetrics->dwMask & TBMF_PAD)
{
infoPtr->szBarPadding.cx = pMetrics->cxBarPad;
infoPtr->szBarPadding.cy = pMetrics->cyBarPad;
changed = TRUE;
}
if (pMetrics->dwMask & TBMF_BUTTONSPACING)
{
infoPtr->szSpacing.cx = pMetrics->cxButtonSpacing;
infoPtr->szSpacing.cy = pMetrics->cyButtonSpacing;
changed = TRUE;
}
if (changed)
TOOLBAR_CalcToolbar(infoPtr);
return TRUE;
}
/* MSDN gives slightly wrong info on padding. /* MSDN gives slightly wrong info on padding.
* 1. It is not only used on buttons with the BTNS_AUTOSIZE style * 1. It is not only used on buttons with the BTNS_AUTOSIZE style
* 2. It is not used to create a blank area between the edge of the button * 2. It is not used to create a blank area between the edge of the button
@ -5926,6 +6015,8 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
infoPtr->clrBtnShadow = CLR_DEFAULT; infoPtr->clrBtnShadow = CLR_DEFAULT;
infoPtr->szPadding.cx = DEFPAD_CX; infoPtr->szPadding.cx = DEFPAD_CX;
infoPtr->szPadding.cy = DEFPAD_CY; infoPtr->szPadding.cy = DEFPAD_CY;
infoPtr->szSpacing.cx = DEFSPACE_CX;
infoPtr->szSpacing.cy = DEFSPACE_CY;
infoPtr->iListGap = DEFLISTGAP; infoPtr->iListGap = DEFLISTGAP;
infoPtr->iTopMargin = default_top_margin(infoPtr); infoPtr->iTopMargin = default_top_margin(infoPtr);
infoPtr->dwStyle = lpcs->style; infoPtr->dwStyle = lpcs->style;
@ -6359,16 +6450,6 @@ TOOLBAR_SysColorChange (void)
} }
/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed (HWND hwnd)
{
HTHEME theme = GetWindowTheme (hwnd);
CloseThemeData (theme);
OpenThemeData (hwnd, themeClass);
return 0;
}
static LRESULT WINAPI static LRESULT WINAPI
ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
@ -6472,6 +6553,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case TB_GETMAXSIZE: case TB_GETMAXSIZE:
return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam); return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam);
case TB_GETMETRICS:
return TOOLBAR_GetMetrics (infoPtr, (TBMETRICS*)lParam);
/* case TB_GETOBJECT: */ /* 4.71 */ /* case TB_GETOBJECT: */ /* 4.71 */
@ -6488,7 +6572,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TOOLBAR_GetState (infoPtr, wParam); return TOOLBAR_GetState (infoPtr, wParam);
case TB_GETSTRINGA: case TB_GETSTRINGA:
return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam); return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam);
case TB_GETSTRINGW: case TB_GETSTRINGW:
return TOOLBAR_GetStringW (infoPtr, wParam, (LPWSTR)lParam); return TOOLBAR_GetStringW (infoPtr, wParam, (LPWSTR)lParam);
@ -6613,6 +6697,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case TB_SETMAXTEXTROWS: case TB_SETMAXTEXTROWS:
return TOOLBAR_SetMaxTextRows (infoPtr, wParam); return TOOLBAR_SetMaxTextRows (infoPtr, wParam);
case TB_SETMETRICS:
return TOOLBAR_SetMetrics (infoPtr, (TBMETRICS*)lParam);
case TB_SETPADDING: case TB_SETPADDING:
return TOOLBAR_SetPadding (infoPtr, lParam); return TOOLBAR_SetPadding (infoPtr, lParam);
@ -6738,7 +6825,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TOOLBAR_SetFocus (infoPtr); return TOOLBAR_SetFocus (infoPtr);
case WM_SETFONT: case WM_SETFONT:
return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam); return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);
case WM_SETREDRAW: case WM_SETREDRAW:
return TOOLBAR_SetRedraw (infoPtr, wParam); return TOOLBAR_SetRedraw (infoPtr, wParam);
@ -6752,8 +6839,8 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_SYSCOLORCHANGE: case WM_SYSCOLORCHANGE:
return TOOLBAR_SysColorChange (); return TOOLBAR_SysColorChange ();
case WM_THEMECHANGED: case WM_THEMECHANGED:
return theme_changed (hwnd); return TOOLBAR_ThemeChanged(hwnd);
/* case WM_WININICHANGE: */ /* case WM_WININICHANGE: */