[COMCTL32] Sync with Wine Staging 1.7.47. CORE-9924

svn path=/trunk/; revision=68553
This commit is contained in:
Amine Khaldi 2015-07-22 19:30:27 +00:00
parent 300237adee
commit 3b13364f05
14 changed files with 1557 additions and 1092 deletions

File diff suppressed because it is too large Load diff

View file

@ -426,3 +426,59 @@ void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
DSA_EnumCallback (hdsa, enumProc, lParam);
DSA_Destroy (hdsa);
}
/**************************************************************************
* DSA_Clone [COMCTL32.@]
*
* Creates a copy of a dsa
*
* PARAMS
* hdsa [I] handle to the dynamic storage array
*
* RETURNS
* Cloned dsa
*/
HDSA WINAPI DSA_Clone(HDSA hdsa)
{
HDSA dest;
INT i;
TRACE("(%p)\n", hdsa);
if (!hdsa)
return NULL;
dest = DSA_Create (hdsa->nItemSize, hdsa->nGrow);
if (!dest)
return NULL;
for (i = 0; i < hdsa->nItemCount; i++) {
void *ptr = DSA_GetItemPtr (hdsa, i);
if (DSA_InsertItem (dest, DA_LAST, ptr) == -1) {
DSA_Destroy (dest);
return NULL;
}
}
return dest;
}
/**************************************************************************
* DSA_GetSize [COMCTL32.@]
*
* Returns allocated memory size for this array
*
* PARAMS
* hdsa [I] handle to the dynamic storage array
*
* RETURNS
* Size
*/
ULONGLONG WINAPI DSA_GetSize(HDSA hdsa)
{
TRACE("(%p)\n", hdsa);
if (!hdsa) return 0;
return sizeof(*hdsa) + (ULONGLONG)hdsa->nMaxCount*hdsa->nItemSize;
}

View file

@ -55,7 +55,7 @@ typedef struct
BOOL WINAPI InitializeFlatSB(HWND hwnd)
{
TRACE("[%p]\n", hwnd);
return FALSE;
return TRUE;
}
/***********************************************************************

View file

@ -319,6 +319,7 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
INT oldBkMode;
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
NMCUSTOMDRAW nmcd;
int state = 0;
TRACE("DrawItem(iItem %d bHotTrack %d unicode flag %d)\n", iItem, bHotTrack, (infoPtr->nNotifyFormat == NFR_UNICODE));
@ -326,6 +327,9 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
if (r.right - r.left == 0)
return phdi->rect.right;
if (theme)
state = (phdi->bDown) ? HIS_PRESSED : (bHotTrack ? HIS_HOT : HIS_NORMAL);
/* Set the colors before sending NM_CUSTOMDRAW so that it can change them */
SetTextColor(hdc, (bHotTrack && !theme) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
SetBkColor(hdc, comctl32_color.clr3dFace);
@ -404,8 +408,14 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
RECT textRect;
SetRectEmpty(&textRect);
if (theme) {
GetThemeTextExtent(theme, hdc, HP_HEADERITEM, state, phdi->pszText, -1,
DT_LEFT|DT_VCENTER|DT_SINGLELINE, NULL, &textRect);
} else {
DrawTextW (hdc, phdi->pszText, -1,
&textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
}
cw = textRect.right - textRect.left + 2 * infoPtr->iMargin;
}
@ -498,8 +508,14 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
oldBkMode = SetBkMode(hdc, TRANSPARENT);
r.left = tx;
r.right = tx + tw;
if (theme) {
DrawThemeText(theme, hdc, HP_HEADERITEM, state, phdi->pszText,
-1, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE,
0, &r);
} else {
DrawTextW (hdc, phdi->pszText, -1,
&r, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE);
}
if (oldBkMode != TRANSPARENT)
SetBkMode(hdc, oldBkMode);
}

View file

@ -6,7 +6,7 @@
* Copyright 2000 Jason Mawdsley
* Copyright 2001 CodeWeavers Inc.
* Copyright 2002 Dimitrie O. Paun
* Copyright 2009-2014 Nikolay Sivov
* Copyright 2009-2015 Nikolay Sivov
* Copyright 2009 Owen Rudge for CodeWeavers
* Copyright 2012-2013 Daniel Jelinski
*
@ -54,7 +54,6 @@
* -- Support CustomDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs).
* -- LVA_SNAPTOGRID not implemented
* -- LISTVIEW_ApproximateViewRect partially implemented
* -- LISTVIEW_SetColumnWidth ignores header images & bitmap
* -- LISTVIEW_StyleChanged doesn't handle some changes too well
*
* Speedups
@ -288,7 +287,9 @@ typedef struct tagLISTVIEW_INFO
COLORREF clrBk;
COLORREF clrText;
COLORREF clrTextBk;
#ifdef __REACTOS__
BOOL bDefaultBkColor;
#endif
/* font */
HFONT hDefaultFont;
@ -1681,6 +1682,7 @@ static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpL
/* used to handle collapse main item column case */
static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
{
#ifdef __REACTOS__
BOOL Ret = FALSE;
if (infoPtr->rcFocus.left < infoPtr->rcFocus.right)
@ -1694,6 +1696,10 @@ static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
SetBkColor(hdc, dwOldTextColor);
}
return Ret;
#else
return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ?
DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE;
#endif
}
/* Listview invalidation functions: use _only_ these functions to invalidate */
@ -4543,6 +4549,7 @@ static inline BOOL LISTVIEW_FillBkgnd(const LISTVIEW_INFO *infoPtr, HDC hdc, con
static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const NMLVCUSTOMDRAW *nmlvcd, const POINT *pos)
{
RECT rcSelect, rcLabel, rcBox, rcStateIcon, rcIcon;
const RECT *background;
HIMAGELIST himl;
UINT format;
RECT *focus;
@ -4557,13 +4564,22 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N
OffsetRect(&rcIcon, pos->x, pos->y);
OffsetRect(&rcStateIcon, pos->x, pos->y);
OffsetRect(&rcLabel, pos->x, pos->y);
TRACE(" rcBox=%s, rcSelect=%s, rcIcon=%s. rcLabel=%s\n",
TRACE("%d: box=%s, select=%s, icon=%s. label=%s\n", item->iSubItem,
wine_dbgstr_rect(&rcBox), wine_dbgstr_rect(&rcSelect),
wine_dbgstr_rect(&rcIcon), wine_dbgstr_rect(&rcLabel));
/* FIXME: temporary hack */
rcSelect.left = rcLabel.left;
if (infoPtr->uView == LV_VIEW_DETAILS && item->iSubItem == 0)
{
if (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
OffsetRect(&rcSelect, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
OffsetRect(&rcIcon, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
OffsetRect(&rcStateIcon, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
OffsetRect(&rcLabel, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
}
/* in icon mode, the label rect is really what we want to draw the
* background for */
/* in detail mode, we want to paint background for label rect when
@ -4572,14 +4588,18 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N
if ( infoPtr->uView == LV_VIEW_ICON ||
(infoPtr->uView == LV_VIEW_DETAILS && (!(item->state & LVIS_SELECTED) ||
(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))))
rcSelect = rcLabel;
background = &rcLabel;
else
background = &rcSelect;
if (nmlvcd->clrTextBk != CLR_NONE)
ExtTextOutW(nmlvcd->nmcd.hdc, rcSelect.left, rcSelect.top, ETO_OPAQUE, &rcSelect, NULL, 0, NULL);
ExtTextOutW(nmlvcd->nmcd.hdc, background->left, background->top, ETO_OPAQUE, background, NULL, 0, NULL);
if (item->state & LVIS_FOCUSED)
{
if (infoPtr->uView == LV_VIEW_DETAILS && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
if (infoPtr->uView == LV_VIEW_DETAILS)
{
if (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)
{
/* we have to update left focus bound too if item isn't in leftmost column
and reduce right box bound */
@ -4589,21 +4609,21 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N
if ((leftmost = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, 0, 0)))
{
INT Originx = pos->x - LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left;
INT index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX,
INT Originx = pos->x - LISTVIEW_GetColumnInfo(infoPtr, leftmost)->rcHeader.left;
INT rightmost = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX,
DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0);
rcBox.right = LISTVIEW_GetColumnInfo(infoPtr, index)->rcHeader.right + Originx;
rcBox.right = LISTVIEW_GetColumnInfo(infoPtr, rightmost)->rcHeader.right + Originx;
rcSelect.left = LISTVIEW_GetColumnInfo(infoPtr, leftmost)->rcHeader.left + Originx;
}
}
rcSelect.right = rcBox.right;
}
/* store new focus rectangle */
infoPtr->rcFocus = rcSelect;
}
else
infoPtr->rcFocus = rcLabel;
}
/* state icons */
if (infoPtr->himlState && STATEIMAGEINDEX(item->state) && (item->iSubItem == 0))
@ -4893,9 +4913,9 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
{
INT rgntype;
RECT rcClip, rcItem;
POINT Origin, Position;
POINT Origin;
RANGES colRanges;
INT col, index;
INT col;
ITERATOR j;
TRACE("()\n");
@ -4912,7 +4932,7 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
/* narrow down the columns we need to paint */
for(col = 0; col < DPA_GetPtrCount(infoPtr->hdpaColumns); col++)
{
index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, col, 0);
INT index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, col, 0);
LISTVIEW_GetHeaderRect(infoPtr, index, &rcItem);
if ((rcItem.right + Origin.x >= rcClip.left) && (rcItem.left + Origin.x < rcClip.right))
@ -4928,10 +4948,12 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
while(iterator_next(i))
{
RANGES subitems;
POINT Position;
ITERATOR k;
SelectObject(hdc, infoPtr->hFont);
LISTVIEW_GetItemOrigin(infoPtr, i->nItem, &Position);
Position.x = Origin.x;
Position.y += Origin.y;
subitems = ranges_create(DPA_GetPtrCount(infoPtr->hdpaColumns));
@ -4940,7 +4962,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
while(iterator_next(&j))
{
LISTVIEW_GetHeaderRect(infoPtr, j.nItem, &rcItem);
Position.x = (j.nItem == 0) ? rcItem.left + Origin.x : Origin.x;
if (rgntype == COMPLEXREGION && !((infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) && j.nItem == 0))
{
@ -6489,14 +6510,9 @@ static BOOL LISTVIEW_GetColumnT(const LISTVIEW_INFO *infoPtr, INT nColumn, LPLVC
return TRUE;
}
static BOOL LISTVIEW_GetColumnOrderArray(const LISTVIEW_INFO *infoPtr, INT iCount, LPINT lpiArray)
static inline BOOL LISTVIEW_GetColumnOrderArray(const LISTVIEW_INFO *infoPtr, INT iCount, LPINT lpiArray)
{
TRACE("iCount=%d, lpiArray=%p\n", iCount, lpiArray);
if (!lpiArray)
return FALSE;
if (!infoPtr->hwndHeader) return FALSE;
return SendMessageW(infoPtr->hwndHeader, HDM_GETORDERARRAY, iCount, (LPARAM)lpiArray);
}
@ -6529,8 +6545,6 @@ static INT LISTVIEW_GetColumnWidth(const LISTVIEW_INFO *infoPtr, INT nColumn)
/* We are not using LISTVIEW_GetHeaderRect as this data is updated only after a HDN_ITEMCHANGED.
* There is an application that subclasses the listview, calls LVM_GETCOLUMNWIDTH in the
* HDN_ITEMCHANGED handler and goes into infinite recursion if it receives old data.
*
* TODO: should we do the same in LVM_GETCOLUMN?
*/
hdItem.mask = HDI_WIDTH;
if (!SendMessageW(infoPtr->hwndHeader, HDM_GETITEMW, nColumn, (LPARAM)&hdItem))
@ -8019,7 +8033,9 @@ static BOOL LISTVIEW_SetBkColor(LISTVIEW_INFO *infoPtr, COLORREF color)
{
TRACE("(color=%x)\n", color);
#ifdef __REACTOS__
infoPtr->bDefaultBkColor = FALSE;
#endif
if(infoPtr->clrBk != color) {
if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
infoPtr->clrBk = color;
@ -8303,12 +8319,8 @@ static BOOL LISTVIEW_SetColumnT(const LISTVIEW_INFO *infoPtr, INT nColumn,
*/
static BOOL LISTVIEW_SetColumnOrderArray(LISTVIEW_INFO *infoPtr, INT iCount, const INT *lpiArray)
{
TRACE("iCount %d lpiArray %p\n", iCount, lpiArray);
if (!lpiArray || !IsWindow(infoPtr->hwndHeader)) return FALSE;
if (!infoPtr->hwndHeader) return FALSE;
infoPtr->colRectsDirty = TRUE;
return SendMessageW(infoPtr->hwndHeader, HDM_SETORDERARRAY, iCount, (LPARAM)lpiArray);
}
@ -8336,9 +8348,10 @@ static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn, INT cx)
/* set column width only if in report or list mode */
if (infoPtr->uView != LV_VIEW_DETAILS && infoPtr->uView != LV_VIEW_LIST) return FALSE;
/* take care of invalid cx values */
if(infoPtr->uView == LV_VIEW_DETAILS && cx < -2) cx = LVSCW_AUTOSIZE;
else if (infoPtr->uView == LV_VIEW_LIST && cx < 1) return FALSE;
/* take care of invalid cx values - LVSCW_AUTOSIZE_* values are negative,
with _USEHEADER being the lowest */
if (infoPtr->uView == LV_VIEW_DETAILS && cx < LVSCW_AUTOSIZE_USEHEADER) cx = LVSCW_AUTOSIZE;
else if (infoPtr->uView == LV_VIEW_LIST && cx <= 0) return FALSE;
/* resize all columns if in LV_VIEW_LIST mode */
if(infoPtr->uView == LV_VIEW_LIST)
@ -8397,18 +8410,38 @@ static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn, INT cx)
cx = 0;
/* retrieve header text */
hdi.mask = HDI_TEXT;
hdi.mask = HDI_TEXT|HDI_FORMAT|HDI_IMAGE|HDI_BITMAP;
hdi.cchTextMax = DISP_TEXT_SIZE;
hdi.pszText = szDispText;
if (SendMessageW(infoPtr->hwndHeader, HDM_GETITEMW, nColumn, (LPARAM)&hdi))
{
HDC hdc = GetDC(infoPtr->hwndSelf);
HFONT old_font = SelectObject(hdc, (HFONT)SendMessageW(infoPtr->hwndHeader, WM_GETFONT, 0, 0));
HIMAGELIST himl = (HIMAGELIST)SendMessageW(infoPtr->hwndHeader, HDM_GETIMAGELIST, 0, 0);
INT bitmap_margin = 0;
SIZE size;
if (GetTextExtentPoint32W(hdc, hdi.pszText, lstrlenW(hdi.pszText), &size))
cx = size.cx + TRAILING_HEADER_PADDING;
/* FIXME: Take into account the header image, if one is present */
if (hdi.fmt & (HDF_IMAGE|HDF_BITMAP))
bitmap_margin = SendMessageW(infoPtr->hwndHeader, HDM_GETBITMAPMARGIN, 0, 0);
if ((hdi.fmt & HDF_IMAGE) && himl)
{
INT icon_cx, icon_cy;
if (!ImageList_GetIconSize(himl, &icon_cx, &icon_cy))
cx += icon_cx + 2*bitmap_margin;
}
else if (hdi.fmt & HDF_BITMAP)
{
BITMAP bmp;
GetObjectW(hdi.hbm, sizeof(BITMAP), &bmp);
cx += bmp.bmWidth + 2*bitmap_margin;
}
SelectObject(hdc, old_font);
ReleaseDC(infoPtr->hwndSelf, hdc);
}
@ -9430,7 +9463,9 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->clrText = CLR_DEFAULT;
infoPtr->clrTextBk = CLR_DEFAULT;
LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
#ifdef __REACTOS__
infoPtr->bDefaultBkColor = TRUE;
#endif
/* set default values */
infoPtr->nFocusedItem = -1;
@ -11071,7 +11106,6 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
if (wStyleType != GWL_STYLE) return 0;
infoPtr->dwStyle = lpss->styleNew;
map_style_view(infoPtr);
if (((lpss->styleOld & WS_HSCROLL) != 0)&&
((lpss->styleNew & WS_HSCROLL) == 0))
@ -11085,6 +11119,9 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
{
HIMAGELIST himl;
/* LVM_SETVIEW doesn't change window style bits within LVS_TYPEMASK,
changing style updates current view only when view bits change. */
map_style_view(infoPtr);
SendMessageW(infoPtr->hwndEdit, WM_KILLFOCUS, 0, 0);
ShowWindow(infoPtr->hwndHeader, SW_HIDE);
@ -11713,12 +11750,14 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_SYSCOLORCHANGE:
COMCTL32_RefreshSysColors();
#ifdef __REACTOS__
if (infoPtr->bDefaultBkColor)
{
LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
infoPtr->bDefaultBkColor = TRUE;
LISTVIEW_InvalidateList(infoPtr);
}
#endif
return 0;
/* case WM_TIMER: */

View file

@ -850,10 +850,16 @@ static void MONTHCAL_PaintButton(MONTHCAL_INFO *infoPtr, HDC hdc, enum nav_direc
/* paint a title with buttons and month/year string */
static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
{
static const WCHAR fmt_monthW[] = { '%','s',' ','%','l','d',0 };
static const WCHAR mmmmW[] = {'M','M','M','M',0};
static const WCHAR mmmW[] = {'M','M','M',0};
static const WCHAR mmW[] = {'M','M',0};
static const WCHAR fmtyearW[] = {'%','l','d',0};
static const WCHAR fmtmmW[] = {'%','0','2','d',0};
static const WCHAR fmtmW[] = {'%','d',0};
RECT *title = &infoPtr->calendars[calIdx].title;
const SYSTEMTIME *st = &infoPtr->calendars[calIdx].month;
WCHAR buf_month[80], buf_fmt[80];
WCHAR monthW[80], strW[80], fmtW[80], yearW[6] /* valid year range is 1601-30827 */;
int yearoffset, monthoffset, shiftX;
SIZE sz;
/* fill header box */
@ -864,21 +870,65 @@ static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRU
SetTextColor(hdc, infoPtr->colors[MCSC_TITLETEXT]);
SelectObject(hdc, infoPtr->hBoldFont);
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1 + st->wMonth - 1,
buf_month, countof(buf_month));
/* draw formatted date string */
GetDateFormatW(LOCALE_USER_DEFAULT, DATE_YEARMONTH, st, NULL, strW, countof(strW));
DrawTextW(hdc, strW, strlenW(strW), title, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
wsprintfW(buf_fmt, fmt_monthW, buf_month, st->wYear);
DrawTextW(hdc, buf_fmt, strlenW(buf_fmt), title,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SYEARMONTH, fmtW, countof(fmtW));
wsprintfW(yearW, fmtyearW, st->wYear);
/* update title rectangles with current month - used while testing hits */
GetTextExtentPoint32W(hdc, buf_fmt, strlenW(buf_fmt), &sz);
infoPtr->calendars[calIdx].titlemonth.left = title->right / 2 + title->left / 2 - sz.cx / 2;
infoPtr->calendars[calIdx].titleyear.right = title->right / 2 + title->left / 2 + sz.cx / 2;
/* month is trickier as it's possible to have different format pictures, we'll
test for M, MM, MMM, and MMMM */
if (strstrW(fmtW, mmmmW))
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1+st->wMonth-1, monthW, countof(monthW));
else if (strstrW(fmtW, mmmW))
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVMONTHNAME1+st->wMonth-1, monthW, countof(monthW));
else if (strstrW(fmtW, mmW))
wsprintfW(monthW, fmtmmW, st->wMonth);
else
wsprintfW(monthW, fmtmW, st->wMonth);
GetTextExtentPoint32W(hdc, buf_month, strlenW(buf_month), &sz);
/* update hit boxes */
yearoffset = 0;
while (strW[yearoffset])
{
if (!strncmpW(&strW[yearoffset], yearW, strlenW(yearW)))
break;
yearoffset++;
}
monthoffset = 0;
while (strW[monthoffset])
{
if (!strncmpW(&strW[monthoffset], monthW, strlenW(monthW)))
break;
monthoffset++;
}
/* for left limits use offsets */
sz.cx = 0;
if (yearoffset)
GetTextExtentPoint32W(hdc, strW, yearoffset, &sz);
infoPtr->calendars[calIdx].titleyear.left = sz.cx;
sz.cx = 0;
if (monthoffset)
GetTextExtentPoint32W(hdc, strW, monthoffset, &sz);
infoPtr->calendars[calIdx].titlemonth.left = sz.cx;
/* for right limits use actual string parts lengths */
GetTextExtentPoint32W(hdc, &strW[yearoffset], strlenW(yearW), &sz);
infoPtr->calendars[calIdx].titleyear.right = infoPtr->calendars[calIdx].titleyear.left + sz.cx;
GetTextExtentPoint32W(hdc, monthW, strlenW(monthW), &sz);
infoPtr->calendars[calIdx].titlemonth.right = infoPtr->calendars[calIdx].titlemonth.left + sz.cx;
infoPtr->calendars[calIdx].titleyear.left = infoPtr->calendars[calIdx].titlemonth.right;
/* Finally translate rectangles to match center aligned string,
hit rectangles are relative to title rectangle before translation. */
GetTextExtentPoint32W(hdc, strW, strlenW(strW), &sz);
shiftX = (title->right - title->left - sz.cx) / 2 + title->left;
OffsetRect(&infoPtr->calendars[calIdx].titleyear, shiftX, 0);
OffsetRect(&infoPtr->calendars[calIdx].titlemonth, shiftX, 0);
}
static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
@ -1002,13 +1052,7 @@ static void MONTHCAL_PaintTodayTitle(const MONTHCAL_INFO *infoPtr, HDC hdc, cons
if(infoPtr->dwStyle & MCS_NOTODAY) return;
if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW)))
{
static const WCHAR todayW[] = { 'T','o','d','a','y',':',0 };
WARN("Can't load resource\n");
strcpyW(buf_todayW, todayW);
}
LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW));
col = infoPtr->dwStyle & MCS_NOTODAYCIRCLE ? 0 : 1;
if (infoPtr->dwStyle & MCS_WEEKNUMBERS) col--;
/* label is located below first calendar last row */
@ -1968,17 +2012,12 @@ static void MONTHCAL_GoToMonth(MONTHCAL_INFO *infoPtr, enum nav_direction direct
static LRESULT
MONTHCAL_RButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam)
{
static const WCHAR todayW[] = { 'G','o',' ','t','o',' ','T','o','d','a','y',':',0 };
HMENU hMenu;
POINT menupoint;
WCHAR buf[32];
hMenu = CreatePopupMenu();
if (!LoadStringW(COMCTL32_hModule, IDM_GOTODAY, buf, countof(buf)))
{
WARN("Can't load resource\n");
strcpyW(buf, todayW);
}
LoadStringW(COMCTL32_hModule, IDM_GOTODAY, buf, countof(buf));
AppendMenuW(hMenu, MF_STRING|MF_ENABLED, 1, buf);
menupoint.x = (short)LOWORD(lParam);
menupoint.y = (short)HIWORD(lParam);

View file

@ -1380,7 +1380,7 @@ REBAR_Layout(REBAR_INFO *infoPtr)
adjcx = get_rect_cx(infoPtr, &rcAdj);
if (infoPtr->uNumBands == 0) {
TRACE("No bands - setting size to (0,%d), vert: %x\n", adjcx, infoPtr->dwStyle & CCS_VERT);
TRACE("No bands - setting size to (0,%d), style: %x\n", adjcx, infoPtr->dwStyle);
infoPtr->calcSize.cx = adjcx;
/* the calcSize.cy won't change for a 0 band rebar */
infoPtr->uNumRows = 0;
@ -1828,11 +1828,14 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
RECT cr;
COLORREF old = CLR_NONE, new;
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
#ifdef __REACTOS__
HRGN hrgn;
#endif
GetClientRect (infoPtr->hwndSelf, &cr);
#ifdef __REACTOS__
if (theme)
{
if (IsThemeBackgroundPartiallyTransparent(theme, RP_BACKGROUND, 0))
@ -1841,21 +1844,26 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
}
DrawThemeBackground (theme, hdc, 0, 0, &cr, NULL);
}
#endif
hrgn = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
#endif
oldrow = -1;
for(i=0; i<infoPtr->uNumBands; i++) {
RECT rcBand;
#ifdef __REACTOS__
RECT rcBandReal;
HRGN hrgnBand;
#endif
lpBand = REBAR_GetBand(infoPtr, i);
if (HIDDENBAND(lpBand)) continue;
translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
#ifdef __REACTOS__
rcBandReal = rcBand;
#endif
/* draw band separator between rows */
if (lpBand->iRow != oldrow) {
@ -1881,7 +1889,9 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
}
TRACE ("drawing band separator bottom (%s)\n",
wine_dbgstr_rect(&rcRowSep));
#ifdef __REACTOS__
rcBandReal = rcRowSep;
#endif
}
}
@ -1892,7 +1902,9 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
if (infoPtr->dwStyle & CCS_VERT) {
rcSep.bottom = rcSep.top;
rcSep.top -= SEP_WIDTH_SIZE;
#ifdef __REACTOS__
rcBandReal.top -= SEP_WIDTH_SIZE;
#endif
if (theme)
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_BOTTOM, NULL);
else
@ -1901,7 +1913,9 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
else {
rcSep.right = rcSep.left;
rcSep.left -= SEP_WIDTH_SIZE;
#ifdef __REACTOS__
rcBandReal.left -= SEP_WIDTH_SIZE;
#endif
if (theme)
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_RIGHT, NULL);
else
@ -1954,9 +1968,11 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
SetBkColor (hdc, old);
}
#ifdef __REACTOS__
hrgnBand = CreateRectRgn(rcBandReal.left, rcBandReal.top, rcBandReal.right, rcBandReal.bottom);
CombineRgn(hrgn, hrgn, hrgnBand, RGN_DIFF);
DeleteObject(hrgnBand);
#endif
}
#if 1

View file

@ -142,8 +142,7 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UIN
{ RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL }
};
static const int cb_size = 13;
SIZE sz;
RECT bgRect, textRect;
HFONT font, hPrevFont = NULL;
LRESULT checkState = SendMessageW(hwnd, BM_GETCHECK, 0, 0);
@ -173,15 +172,18 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UIN
hPrevFont = SelectObject(hDC, font);
}
if (FAILED(GetThemePartSize(theme, hDC, part, state, NULL, TS_DRAW, &sz)))
sz.cx = sz.cy = 13;
GetClientRect(hwnd, &bgRect);
GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect);
if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */
bgRect.top = bgRect.top + (textRect.bottom - textRect.top - cb_size) / 2;
bgRect.top = bgRect.top + (textRect.bottom - textRect.top - sz.cy) / 2;
/* adjust for the check/radio marker */
bgRect.bottom = bgRect.top + cb_size;
bgRect.right = bgRect.left + cb_size;
bgRect.bottom = bgRect.top + sz.cy;
bgRect.right = bgRect.left + sz.cx;
textRect.left = bgRect.right + 6;
DrawThemeParentBackground(hwnd, hDC, NULL);
@ -367,8 +369,10 @@ LRESULT CALLBACK THEMING_ButtonSubclassProc(HWND hwnd, UINT msg,
case WM_ENABLE:
theme = GetWindowTheme(hwnd);
if (theme) RedrawWindow(hwnd, NULL, NULL,
RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
if (theme) {
RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
} else
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
case WM_MOUSEMOVE:

View file

@ -23,11 +23,552 @@
WINE_DEFAULT_DEBUG_CHANNEL(theme_scroll);
/* Minimum size of the thumb in pixels */
#define SCROLL_MIN_THUMB 6
/* Minimum size of the rectangle between the arrows */
#define SCROLL_MIN_RECT 4
enum SCROLL_HITTEST
{
SCROLL_NOWHERE, /* Outside the scroll bar */
SCROLL_TOP_ARROW, /* Top or left arrow */
SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
SCROLL_THUMB, /* Thumb rectangle */
SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
};
static HWND tracking_win = 0;
static enum SCROLL_HITTEST tracking_hot_part = SCROLL_NOWHERE;
static void calc_thumb_dimensions(unsigned int size, SCROLLINFO *si, unsigned int *thumbpos, unsigned int *thumbsize)
{
if (size <= SCROLL_MIN_RECT)
*thumbpos = *thumbsize = 0;
else if (si->nPage > si->nMax - si->nMin)
*thumbpos = *thumbsize = 0;
else {
if (si->nPage > 0) {
*thumbsize = MulDiv(size, si->nPage, si->nMax - si->nMin + 1);
if (*thumbsize < SCROLL_MIN_THUMB) *thumbsize = SCROLL_MIN_THUMB;
}
else *thumbsize = GetSystemMetrics(SM_CXVSCROLL);
if (size < *thumbsize)
*thumbpos = *thumbsize = 0;
else {
int max = si->nMax - max(si->nPage - 1, 0);
size -= *thumbsize;
if (si->nMin >= max)
*thumbpos = 0;
else
*thumbpos = MulDiv(size, si->nTrackPos - si->nMin, max - si->nMin);
}
}
}
static enum SCROLL_HITTEST hit_test(HWND hwnd, HTHEME theme, POINT pt)
{
RECT r;
DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
BOOL vertical = style & SBS_VERT;
SIZE sz;
SCROLLINFO si;
unsigned int offset, size, upsize, downsize, thumbpos, thumbsize;
GetWindowRect(hwnd, &r);
OffsetRect(&r, -r.left, -r.top);
if (vertical) {
offset = pt.y;
size = r.bottom;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_UPNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get up arrow size.\n");
upsize = 0;
} else
upsize = sz.cy;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_DOWNNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get down arrow size.\n");
downsize = 0;
} else
downsize = sz.cy;
} else {
offset = pt.x;
size = r.right;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_LEFTNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get left arrow size.\n");
upsize = 0;
} else
upsize = sz.cx;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_RIGHTNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get right arrow size.\n");
downsize = 0;
} else
downsize = sz.cx;
}
if (pt.x < 0 || pt.x > r.right || pt.y < 0 || pt.y > r.bottom)
return SCROLL_NOWHERE;
if (size < SCROLL_MIN_RECT + upsize + downsize)
upsize = downsize = (size - SCROLL_MIN_RECT)/2;
if (offset < upsize)
return SCROLL_TOP_ARROW;
if (offset > size - downsize)
return SCROLL_BOTTOM_ARROW;
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
if (!GetScrollInfo(hwnd, SB_CTL, &si)) {
WARN("GetScrollInfo failed.\n");
return SCROLL_NOWHERE;
}
calc_thumb_dimensions(size - upsize - downsize, &si, &thumbpos, &thumbsize);
if (offset < upsize + thumbpos)
return SCROLL_TOP_RECT;
else if (offset < upsize + thumbpos + thumbsize)
return SCROLL_THUMB;
else
return SCROLL_BOTTOM_RECT;
}
static void redraw_part(HWND hwnd, HTHEME theme, enum SCROLL_HITTEST part)
{
DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
BOOL vertical = style & SBS_VERT;
SIZE sz;
RECT r, partrect;
unsigned int size, upsize, downsize;
if (part == SCROLL_NOWHERE) { /* redraw everything */
InvalidateRect(hwnd, NULL, TRUE);
return;
}
GetWindowRect(hwnd, &r);
OffsetRect(&r, -r.left, -r.top);
if (vertical) {
size = r.bottom;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_UPNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get up arrow size.\n");
upsize = 0;
} else
upsize = sz.cy;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_DOWNNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get down arrow size.\n");
downsize = 0;
} else
downsize = sz.cy;
} else {
size = r.right;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_LEFTNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get left arrow size.\n");
upsize = 0;
} else
upsize = sz.cx;
if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_RIGHTNORMAL, NULL, TS_DRAW, &sz))) {
WARN("Could not get right arrow size.\n");
downsize = 0;
} else
downsize = sz.cx;
}
if (size < SCROLL_MIN_RECT + upsize + downsize)
upsize = downsize = (size - SCROLL_MIN_RECT)/2;
partrect = r;
if (part == SCROLL_TOP_ARROW) {
if (vertical)
partrect.bottom = partrect.top + upsize;
else
partrect.right = partrect.left + upsize;
} else if (part == SCROLL_BOTTOM_ARROW) {
if (vertical)
partrect.top = partrect.bottom - downsize;
else
partrect.left = partrect.right - downsize;
} else {
unsigned int thumbpos, thumbsize;
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
if (!GetScrollInfo(hwnd, SB_CTL, &si)) {
WARN("GetScrollInfo failed.\n");
return;
}
calc_thumb_dimensions(size - upsize - downsize, &si, &thumbpos, &thumbsize);
if (part == SCROLL_TOP_RECT) {
if (vertical) {
partrect.top = r.top + upsize;
partrect.bottom = partrect.top + thumbpos;
} else {
partrect.left = r.left + upsize;
partrect.right = partrect.left + thumbpos;
}
} else if (part == SCROLL_THUMB) {
if (vertical) {
partrect.top = r.top + upsize + thumbpos;
partrect.bottom = partrect.top + thumbsize;
} else {
partrect.left = r.left + upsize + thumbpos;
partrect.right = partrect.left + thumbsize;
}
} else if (part == SCROLL_BOTTOM_RECT) {
if (vertical) {
partrect.top = r.top + upsize + thumbpos + thumbsize;
partrect.bottom = r.bottom - downsize;
} else {
partrect.left = r.left + upsize + thumbpos + thumbsize;
partrect.right = r.right - downsize;
}
}
}
InvalidateRect(hwnd, &partrect, TRUE);
}
static void scroll_event(HWND hwnd, HTHEME theme, UINT msg, POINT pt)
{
enum SCROLL_HITTEST hittest;
TRACKMOUSEEVENT tme;
if (GetWindowLongW(hwnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX))
return;
hittest = hit_test(hwnd, theme, pt);
switch (msg)
{
case WM_MOUSEMOVE:
hittest = hit_test(hwnd, theme, pt);
tracking_win = hwnd;
break;
case WM_MOUSELEAVE:
if (tracking_win == hwnd) {
hittest = SCROLL_NOWHERE;
}
break;
}
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_QUERY;
TrackMouseEvent(&tme);
if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) {
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
TrackMouseEvent(&tme);
}
if (tracking_win != hwnd && msg == WM_MOUSELEAVE) {
redraw_part(hwnd, theme, SCROLL_NOWHERE);
return;
}
if (tracking_win == hwnd && hittest != tracking_hot_part) {
enum SCROLL_HITTEST oldhotpart = tracking_hot_part;
tracking_hot_part = hittest;
if (hittest != SCROLL_NOWHERE)
redraw_part(hwnd, theme, hittest);
else
tracking_win = 0;
if (oldhotpart != SCROLL_NOWHERE)
redraw_part(hwnd, theme, oldhotpart);
}
}
static void paint_scrollbar(HWND hwnd, HTHEME theme)
{
HDC dc;
PAINTSTRUCT ps;
RECT r;
DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
BOOL vertical = style & SBS_VERT;
BOOL disabled = !IsWindowEnabled(hwnd);
GetWindowRect(hwnd, &r);
OffsetRect(&r, -r.left, -r.top);
dc = BeginPaint(hwnd, &ps);
if (style & SBS_SIZEBOX || style & SBS_SIZEGRIP) {
int state;
if (style & SBS_SIZEBOXTOPLEFTALIGN)
state = SZB_TOPLEFTALIGN;
else
state = SZB_RIGHTALIGN;
DrawThemeBackground(theme, dc, SBP_SIZEBOX, state, &r, NULL);
} else {
SCROLLBARINFO sbi;
SCROLLINFO si;
unsigned int thumbpos, thumbsize;
int uppertrackstate, lowertrackstate, thumbstate;
RECT partrect, trackrect;
SIZE grippersize;
sbi.cbSize = sizeof(sbi);
GetScrollBarInfo(hwnd, OBJID_CLIENT, &sbi);
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_CTL, &si);
trackrect = r;
if (disabled) {
uppertrackstate = SCRBS_DISABLED;
lowertrackstate = SCRBS_DISABLED;
thumbstate = SCRBS_DISABLED;
} else {
uppertrackstate = SCRBS_NORMAL;
lowertrackstate = SCRBS_NORMAL;
thumbstate = SCRBS_NORMAL;
if (tracking_win == hwnd) {
if (tracking_hot_part == SCROLL_TOP_RECT)
uppertrackstate = SCRBS_HOT;
else if (tracking_hot_part == SCROLL_BOTTOM_RECT)
lowertrackstate = SCRBS_HOT;
else if (tracking_hot_part == SCROLL_THUMB)
thumbstate = SCRBS_HOT;
}
}
if (vertical) {
SIZE upsize, downsize;
int uparrowstate, downarrowstate;
if (disabled) {
uparrowstate = ABS_UPDISABLED;
downarrowstate = ABS_DOWNDISABLED;
} else {
uparrowstate = ABS_UPNORMAL;
downarrowstate = ABS_DOWNNORMAL;
if (tracking_win == hwnd) {
if (tracking_hot_part == SCROLL_TOP_ARROW)
uparrowstate = ABS_UPHOT;
else if (tracking_hot_part == SCROLL_BOTTOM_ARROW)
downarrowstate = ABS_DOWNHOT;
}
}
if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, uparrowstate, NULL, TS_DRAW, &upsize))) {
WARN("Could not get up arrow size.\n");
return;
}
if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, downarrowstate, NULL, TS_DRAW, &downsize))) {
WARN("Could not get down arrow size.\n");
return;
}
if (r.bottom - r.top - upsize.cy - downsize.cy < SCROLL_MIN_RECT)
upsize.cy = downsize.cy = (r.bottom - r.top - SCROLL_MIN_RECT)/2;
partrect = r;
partrect.bottom = partrect.top + upsize.cy;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, uparrowstate, &partrect, NULL);
trackrect.top = partrect.bottom;
partrect.bottom = r.bottom;
partrect.top = partrect.bottom - downsize.cy;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, downarrowstate, &partrect, NULL);
trackrect.bottom = partrect.top;
calc_thumb_dimensions(trackrect.bottom - trackrect.top, &si, &thumbpos, &thumbsize);
if (thumbpos > 0) {
partrect.top = trackrect.top;
partrect.bottom = partrect.top + thumbpos;
DrawThemeBackground(theme, dc, SBP_UPPERTRACKVERT, uppertrackstate, &partrect, NULL);
}
if (thumbsize > 0) {
partrect.top = trackrect.top + thumbpos;
partrect.bottom = partrect.top + thumbsize;
DrawThemeBackground(theme, dc, SBP_THUMBBTNVERT, thumbstate, &partrect, NULL);
if (SUCCEEDED(GetThemePartSize(theme, dc, SBP_GRIPPERVERT, thumbstate, NULL, TS_DRAW, &grippersize))) {
MARGINS margins;
if (SUCCEEDED(GetThemeMargins(theme, dc, SBP_THUMBBTNVERT, thumbstate, TMT_CONTENTMARGINS, &partrect, &margins))) {
if (grippersize.cy <= (thumbsize - margins.cyTopHeight - margins.cyBottomHeight))
DrawThemeBackground(theme, dc, SBP_GRIPPERVERT, thumbstate, &partrect, NULL);
}
}
}
if (thumbpos + thumbsize < trackrect.bottom - trackrect.top) {
partrect.bottom = trackrect.bottom;
partrect.top = trackrect.top + thumbsize + thumbpos;
DrawThemeBackground(theme, dc, SBP_LOWERTRACKVERT, lowertrackstate, &partrect, NULL);
}
} else {
SIZE leftsize, rightsize;
int leftarrowstate, rightarrowstate;
if (disabled) {
leftarrowstate = ABS_LEFTDISABLED;
rightarrowstate = ABS_RIGHTDISABLED;
} else {
leftarrowstate = ABS_LEFTNORMAL;
rightarrowstate = ABS_RIGHTNORMAL;
if (tracking_win == hwnd) {
if (tracking_hot_part == SCROLL_TOP_ARROW)
leftarrowstate = ABS_LEFTHOT;
else if (tracking_hot_part == SCROLL_BOTTOM_ARROW)
rightarrowstate = ABS_RIGHTHOT;
}
}
if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, leftarrowstate, NULL, TS_DRAW, &leftsize))) {
WARN("Could not get left arrow size.\n");
return;
}
if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, rightarrowstate, NULL, TS_DRAW, &rightsize))) {
WARN("Could not get right arrow size.\n");
return;
}
if (r.right - r.left - leftsize.cx - rightsize.cx < SCROLL_MIN_RECT)
leftsize.cx = rightsize.cx = (r.right - r.left - SCROLL_MIN_RECT)/2;
partrect = r;
partrect.right = partrect.left + leftsize.cx;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, leftarrowstate, &partrect, NULL);
trackrect.left = partrect.right;
partrect.right = r.right;
partrect.left = partrect.right - rightsize.cx;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, rightarrowstate, &partrect, NULL);
trackrect.right = partrect.left;
calc_thumb_dimensions(trackrect.right - trackrect.left, &si, &thumbpos, &thumbsize);
if (thumbpos > 0) {
partrect.left = trackrect.left;
partrect.right = partrect.left + thumbpos;
DrawThemeBackground(theme, dc, SBP_UPPERTRACKHORZ, uppertrackstate, &partrect, NULL);
}
if (thumbsize > 0) {
partrect.left = trackrect.left + thumbpos;
partrect.right = partrect.left + thumbsize;
DrawThemeBackground(theme, dc, SBP_THUMBBTNHORZ, thumbstate, &partrect, NULL);
if (SUCCEEDED(GetThemePartSize(theme, dc, SBP_GRIPPERHORZ, thumbstate, NULL, TS_DRAW, &grippersize))) {
MARGINS margins;
if (SUCCEEDED(GetThemeMargins(theme, dc, SBP_THUMBBTNHORZ, thumbstate, TMT_CONTENTMARGINS, &partrect, &margins))) {
if (grippersize.cx <= (thumbsize - margins.cxLeftWidth - margins.cxRightWidth))
DrawThemeBackground(theme, dc, SBP_GRIPPERHORZ, thumbstate, &partrect, NULL);
}
}
}
if (thumbpos + thumbsize < trackrect.right - trackrect.left) {
partrect.right = trackrect.right;
partrect.left = trackrect.left + thumbsize + thumbpos;
DrawThemeBackground(theme, dc, SBP_LOWERTRACKHORZ, lowertrackstate, &partrect, NULL);
}
}
}
EndPaint(hwnd, &ps);
}
LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam,
ULONG_PTR dwRefData)
{
const WCHAR* themeClass = WC_SCROLLBARW;
HTHEME theme;
LRESULT result;
POINT pt;
TRACE("(%p, 0x%x, %lu, %lu, %lu)\n", hwnd, msg, wParam, lParam, dwRefData);
return THEMING_CallOriginalClass (hwnd, msg, wParam, lParam);
switch (msg) {
case WM_CREATE:
result = THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
OpenThemeData(hwnd, themeClass);
return result;
case WM_DESTROY:
theme = GetWindowTheme(hwnd);
CloseThemeData(theme);
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
case WM_THEMECHANGED:
theme = GetWindowTheme(hwnd);
CloseThemeData(theme);
OpenThemeData(hwnd, themeClass);
break;
case WM_SYSCOLORCHANGE:
theme = GetWindowTheme(hwnd);
if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
/* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
* which will do the repaint. */
break;
case WM_PAINT:
theme = GetWindowTheme(hwnd);
if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
paint_scrollbar(hwnd, theme);
break;
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
theme = GetWindowTheme(hwnd);
if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
scroll_event(hwnd, theme, msg, pt);
break;
default:
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
}
return 0;
}

View file

@ -103,7 +103,6 @@ typedef struct
typedef struct
{
DWORD dwStructSize; /* size of TBBUTTON struct */
INT nWidth; /* width of the toolbar */
RECT client_rect;
RECT rcBound; /* bounding rectangle */
INT nButtonHeight;
@ -124,8 +123,10 @@ typedef struct
INT nOldHit;
INT nHotItem; /* index of the "hot" item */
SIZE szPadding; /* padding values around button */
#ifdef __REACTOS__
SIZE szBarPadding; /* padding values around the toolbar (NOT USED BUT STORED) */
SIZE szSpacing; /* spacing values between buttons */
#endif
INT iTopMargin; /* the top margin */
INT iListGap; /* default gap between text and image for toolbar with list style */
HFONT hDefaultFont;
@ -195,14 +196,20 @@ typedef enum
#define DEFPAD_CX 7
#define DEFPAD_CY 6
#ifdef __REACTOS__
/* default space between buttons and between rows */
#define DEFSPACE_CX 7
#define DEFSPACE_CY 6
#endif
#define DEFLISTGAP 4
/* vertical padding used in list mode when image is present */
#ifdef __REACTOS__
#define LISTPAD_CY 2
#else
#define LISTPAD_CY 9
#endif
/* how wide to treat the bitmap if it isn't present */
#define NONLIST_NOTEXT_OFFSET 2
@ -240,6 +247,8 @@ static LRESULT TOOLBAR_AutoSize(TOOLBAR_INFO *infoPtr);
static void TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr);
static void TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button);
static void TOOLBAR_TooltipSetRect(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button);
static LRESULT TOOLBAR_SetButtonInfo(TOOLBAR_INFO *infoPtr, INT Id,
const TBBUTTONINFOW *lptbbi, BOOL isW);
static inline int default_top_margin(const TOOLBAR_INFO *infoPtr)
@ -257,6 +266,12 @@ static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle)
return (exStyle & TBSTYLE_EX_DRAWDDARROWS) != 0;
}
static inline BOOL button_has_ddarrow(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
{
return (TOOLBAR_HasDropDownArrows( infoPtr->dwExStyle ) && (btnPtr->fsStyle & BTNS_DROPDOWN)) ||
(btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
}
static LPWSTR
TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
{
@ -320,6 +335,37 @@ TOOLBAR_ButtonHasString(const TBUTTON_INFO *btnPtr)
return HIWORD(btnPtr->iString) && btnPtr->iString != -1;
}
static void set_string_index( TBUTTON_INFO *btn, INT_PTR str, BOOL unicode )
{
if (!IS_INTRESOURCE( str ) && str != -1)
{
if (!TOOLBAR_ButtonHasString( btn )) btn->iString = 0;
if (unicode)
Str_SetPtrW( (WCHAR **)&btn->iString, (WCHAR *)str );
else
Str_SetPtrAtoW( (WCHAR **)&btn->iString, (char *)str );
}
else
{
if (TOOLBAR_ButtonHasString( btn )) Free( (WCHAR *)btn->iString );
btn->iString = str;
}
}
static void set_stringT( TBUTTON_INFO *btn, const WCHAR *str, BOOL unicode )
{
if (IS_INTRESOURCE( (DWORD_PTR)str ) || (DWORD_PTR)str == -1) return;
set_string_index( btn, (DWORD_PTR)str, unicode );
}
static void free_string( TBUTTON_INFO *btn )
{
set_string_index( btn, 0, TRUE );
}
/***********************************************************************
* TOOLBAR_CheckStyle
*
@ -700,8 +746,10 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
INT index;
INT offset = 0;
UINT draw_flags = ILD_TRANSPARENT;
#ifdef __REACTOS__
IMAGEINFO info = {0};
BITMAP bm = {0};
#endif
if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
{
@ -710,6 +758,7 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
{
himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
#ifdef __REACTOS__
ImageList_GetImageInfo(himl, index, &info);
GetObjectW(info.hbmImage, sizeof(bm), &bm);
@ -721,6 +770,9 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
{
draw_masked = TRUE;
}
#else
draw_masked = TRUE;
#endif
}
}
else if (tbcd->nmcd.uItemState & CDIS_CHECKED ||
@ -859,9 +911,7 @@ static void
TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, DWORD dwBaseCustDraw)
{
DWORD dwStyle = infoPtr->dwStyle;
BOOL hasDropDownArrow = (TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
(btnPtr->fsStyle & BTNS_DROPDOWN)) ||
(btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
BOOL hasDropDownArrow = button_has_ddarrow( infoPtr, btnPtr );
BOOL drawSepDropDownArrow = hasDropDownArrow &&
(~btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
RECT rc, rcArrow, rcBitmap, rcText;
@ -1327,41 +1377,26 @@ static void
TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
{
TBUTTON_INFO *btnPtr;
INT x, cx, i, j;
RECT rc;
INT x, cx, i, j, width;
BOOL bButtonWrap;
/* When the toolbar window style is not TBSTYLE_WRAPABLE, */
/* no layout is necessary. Applications may use this style */
/* to perform their own layout on the toolbar. */
if (!(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
!(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL)) return;
if( !(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
!(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL) ) return;
btnPtr = infoPtr->buttons;
x = infoPtr->nIndent;
if (GetParent(infoPtr->hwndSelf))
{
/* this can get the parents width, to know how far we can extend
* this toolbar. We cannot use its height, as there may be multiple
* toolbars in a rebar control
*/
GetClientRect(GetParent(infoPtr->hwndSelf), &rc);
infoPtr->nWidth = rc.right - rc.left;
}
else
{
GetWindowRect(infoPtr->hwndSelf, &rc);
infoPtr->nWidth = rc.right - rc.left;
}
width = infoPtr->client_rect.right - infoPtr->client_rect.left;
bButtonWrap = FALSE;
TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth,
TRACE("start ButtonWidth=%d, BitmapWidth=%d, width=%d, nIndent=%d\n",
infoPtr->nButtonWidth, infoPtr->nBitmapWidth, width,
infoPtr->nIndent);
for (i = 0; i < infoPtr->nNumButtons; i++)
for (i = 0; i < infoPtr->nNumButtons; i++ )
{
btnPtr[i].fsState &= ~TBSTATE_WRAP;
@ -1377,13 +1412,16 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
else
cx = infoPtr->nButtonWidth;
if (!btnPtr[i].cx && button_has_ddarrow( infoPtr, btnPtr + i ))
cx += DDARROW_WIDTH;
/* Two or more adjacent separators form a separator group. */
/* The first separator in a group should be wrapped to the */
/* next row if the previous wrapping is on a button. */
if (bButtonWrap &&
if( bButtonWrap &&
(btnPtr[i].fsStyle & BTNS_SEP) &&
(i + 1 < infoPtr->nNumButtons) &&
(btnPtr[i + 1].fsStyle & BTNS_SEP))
(i + 1 < infoPtr->nNumButtons ) &&
(btnPtr[i + 1].fsStyle & BTNS_SEP) )
{
TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
btnPtr[i].fsState |= TBSTATE_WRAP;
@ -1396,25 +1434,24 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
/* 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 */
/* is bigger than the area. - GA 8/01 */
if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
> infoPtr->nWidth) ||
((x == infoPtr->nIndent) && (cx > infoPtr->nWidth)))
if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2 > width) ||
((x == infoPtr->nIndent) && (cx > width)))
{
BOOL bFound = FALSE;
/* If the current button is a separator and not hidden, */
/* go to the next until it reaches a non separator. */
/* 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].fsState & TBSTATE_HIDDEN)) &&
i < infoPtr->nNumButtons)
(btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
i < infoPtr->nNumButtons )
{
i++;
bFound = TRUE;
}
if (bFound && i < infoPtr->nNumButtons)
if( bFound && i < infoPtr->nNumButtons )
{
i--;
TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
@ -1424,12 +1461,12 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
bButtonWrap = FALSE;
continue;
}
else if (i >= infoPtr->nNumButtons)
else if ( i >= infoPtr->nNumButtons)
break;
/* If the current button is not a separator, find the last */
/* 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) &&
!(btnPtr[j].fsState & TBSTATE_HIDDEN))
@ -1449,7 +1486,7 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
/* non-hidden previous button. */
if (!bFound)
{
for (j = i - 1;
for ( j = i - 1;
j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
{
if (btnPtr[j].fsState & TBSTATE_HIDDEN)
@ -1473,14 +1510,13 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
i, btnPtr[i].fsStyle, x, cx);
btnPtr[i].fsState |= TBSTATE_WRAP;
x = infoPtr->nIndent;
if (btnPtr[i].fsStyle & BTNS_SEP)
if (btnPtr[i].fsStyle & BTNS_SEP )
bButtonWrap = FALSE;
else
bButtonWrap = TRUE;
}
}
else
{
else {
TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
i, btnPtr[i].fsStyle, x, cx);
x += cx;
@ -1610,8 +1646,14 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
/* ... add on the necessary padding */
if (bValidImageList)
{
#ifdef __REACTOS__
sizeButton.cy += infoPtr->szPadding.cy;
if (!bHasBitmap)
#else
if (bHasBitmap)
sizeButton.cy += DEFPAD_CY;
else
#endif
sizeButton.cy += LISTPAD_CY;
}
else
@ -1628,7 +1670,11 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
{
if (bHasBitmap)
{
#ifdef __REACTOS__
sizeButton.cy = infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
#else
sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY;
#endif
if (sizeString.cy > 0)
sizeButton.cy += 1 + sizeString.cy;
sizeButton.cx = infoPtr->szPadding.cx +
@ -1690,7 +1736,6 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
INT x, y, cx, cy;
BOOL bWrap;
BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0);
BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
TOOLBAR_WrapToolbar(infoPtr);
@ -1710,50 +1755,43 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
TRACE("cy=%d\n", cy);
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
{
bWrap = FALSE;
if (btnPtr->fsState & TBSTATE_HIDDEN)
{
SetRectEmpty(&btnPtr->rect);
SetRectEmpty (&btnPtr->rect);
continue;
}
cy = infoPtr->nButtonHeight;
if (btnPtr->fsStyle & BTNS_SEP)
{
if (infoPtr->dwStyle & CCS_VERT)
{
if (btnPtr->fsStyle & BTNS_SEP) {
if (infoPtr->dwStyle & CCS_VERT) {
cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
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))
else if (btnPtr->fsStyle & BTNS_AUTOSIZE)
{
SIZE sz;
HDC hdc;
HFONT hOldFont;
hdc = GetDC(infoPtr->hwndSelf);
hOldFont = SelectObject(hdc, infoPtr->hFont);
hdc = GetDC (infoPtr->hwndSelf);
hOldFont = SelectObject (hdc, infoPtr->hFont);
TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
SelectObject(hdc, hOldFont);
ReleaseDC(infoPtr->hwndSelf, hdc);
SelectObject (hdc, hOldFont);
ReleaseDC (infoPtr->hwndSelf, hdc);
sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
@ -1765,14 +1803,13 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
/* if size has been set manually then don't add on extra space
* for the drop down arrow */
if (!btnPtr->cx && hasDropDownArrows &&
((btnPtr->fsStyle & BTNS_DROPDOWN) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN)))
if (!btnPtr->cx && button_has_ddarrow( infoPtr, btnPtr ))
cx += DDARROW_WIDTH;
}
if (btnPtr->fsState & TBSTATE_WRAP)
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)
infoPtr->rcBound.left = x;
@ -1789,17 +1826,17 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
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,
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;
else
{
if (!(infoPtr->dwStyle & CCS_VERT))
y += cy + ((btnPtr->cx > 0) ?
btnPtr->cx : SEPARATOR_WIDTH) * 2 / 3;
if ( !(infoPtr->dwStyle & CCS_VERT))
y += cy + ( (btnPtr->cx > 0 ) ?
btnPtr->cx : SEPARATOR_WIDTH) * 2 /3;
else
y += cy;
@ -1811,7 +1848,7 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
/* Increment row number unless this is the last button */
/* and it has Wrap set. */
if (i != infoPtr->nNumButtons - 1)
if (i != infoPtr->nNumButtons-1)
nRows++;
}
else
@ -1881,6 +1918,7 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto
/* insert new buttons data */
for (iButton = 0; iButton < nAddButtons; iButton++) {
TBUTTON_INFO *btnPtr = &infoPtr->buttons[iIndex + iButton];
INT_PTR str;
TOOLBAR_DumpTBButton(lpTbb + iButton, fUnicode);
@ -1891,18 +1929,13 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto
btnPtr->fsState = lpTbb[iButton].fsState;
btnPtr->fsStyle = lpTbb[iButton].fsStyle;
btnPtr->dwData = lpTbb[iButton].dwData;
if (btnPtr->fsStyle & BTNS_SEP)
btnPtr->iString = -1;
else if(!IS_INTRESOURCE(lpTbb[iButton].iString) && lpTbb[iButton].iString != -1)
{
if (fUnicode)
Str_SetPtrW((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[iButton].iString );
str = -1;
else
Str_SetPtrAtoW((LPWSTR*)&btnPtr->iString, (LPSTR)lpTbb[iButton].iString);
fHasString = TRUE;
}
else
btnPtr->iString = lpTbb[iButton].iString;
str = lpTbb[iButton].iString;
set_string_index( btnPtr, str, fUnicode );
fHasString |= TOOLBAR_ButtonHasString( btnPtr );
TOOLBAR_TooltipAddTool(infoPtr, btnPtr);
}
@ -2005,7 +2038,7 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}
#ifdef __REACTOS__
static LRESULT
TOOLBAR_ThemeChanged(HWND hwnd)
{
@ -2014,6 +2047,7 @@ TOOLBAR_ThemeChanged(HWND hwnd)
OpenThemeData(hwnd, themeClass);
return 0;
}
#endif
static void
TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
@ -3079,12 +3113,15 @@ TOOLBAR_AddStringA (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam)
static LRESULT
TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr)
{
RECT parent_rect;
HWND parent;
INT x, y;
INT cx, cy;
TRACE("auto sizing, style=%x!\n", infoPtr->dwStyle);
TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight);
if (!(infoPtr->dwStyle & CCS_NORESIZE))
{
RECT window_rect, parent_rect;
UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE;
HWND parent;
INT x, y, cx, cy;
parent = GetParent (infoPtr->hwndSelf);
@ -3096,22 +3133,9 @@ TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr)
x = parent_rect.left;
y = parent_rect.top;
TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight);
cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER;
cx = parent_rect.right - parent_rect.left;
if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))
{
TOOLBAR_LayoutToolbar(infoPtr);
InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
}
if (!(infoPtr->dwStyle & CCS_NORESIZE))
{
RECT window_rect;
UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE;
if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_NOMOVEY)
{
GetWindowRect(infoPtr->hwndSelf, &window_rect);
@ -3139,6 +3163,12 @@ TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr)
SetWindowPos(infoPtr->hwndSelf, NULL, x, y, cx, cy, uPosFlags);
}
if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))
{
TOOLBAR_LayoutToolbar(infoPtr);
InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
}
return 0;
}
@ -3281,8 +3311,7 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
if (infoPtr->nNumButtons == 1) {
TRACE(" simple delete!\n");
if (TOOLBAR_ButtonHasString(infoPtr->buttons))
Free((LPWSTR)infoPtr->buttons[0].iString);
free_string( infoPtr->buttons );
Free (infoPtr->buttons);
infoPtr->buttons = NULL;
infoPtr->nNumButtons = 0;
@ -3303,8 +3332,7 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
(infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
}
if (TOOLBAR_ButtonHasString(&oldButtons[nIndex]))
Free((LPWSTR)oldButtons[nIndex].iString);
free_string( oldButtons + nIndex );
Free (oldButtons);
}
@ -3425,8 +3453,7 @@ TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTb
if (nIndex == -1)
return -1;
if (!(btnPtr = &infoPtr->buttons[nIndex])) return -1;
btnPtr = &infoPtr->buttons[nIndex];
if (lpTbInfo->dwMask & TBIF_COMMAND)
lpTbInfo->idCommand = btnPtr->idCommand;
if (lpTbInfo->dwMask & TBIF_IMAGE)
@ -3603,9 +3630,9 @@ TOOLBAR_GetMaxSize (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize)
return TRUE;
}
#ifdef __REACTOS__
static LRESULT
TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
TOOLBAR_GetMetrics(const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
{
if (pMetrics == NULL)
return FALSE;
@ -3632,7 +3659,7 @@ TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
return TRUE;
}
#endif
/* << TOOLBAR_GetObject >> */
@ -4155,12 +4182,55 @@ TOOLBAR_ReplaceBitmap (TOOLBAR_INFO *infoPtr, const TBREPLACEBITMAP *lpReplace)
/* helper for TOOLBAR_SaveRestoreW */
static BOOL
TOOLBAR_Save(const TBSAVEPARAMSW *lpSave)
TOOLBAR_Save(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *params)
{
FIXME("save to %s %s\n", debugstr_w(lpSave->pszSubKey),
debugstr_w(lpSave->pszValueName));
NMTBSAVE save;
INT ret, i;
BOOL alloced = FALSE;
HKEY key;
return FALSE;
TRACE( "save to %s %s\n", debugstr_w(params->pszSubKey), debugstr_w(params->pszValueName) );
memset( &save, 0, sizeof(save) );
save.cbData = infoPtr->nNumButtons * sizeof(DWORD);
save.iItem = -1;
save.cButtons = infoPtr->nNumButtons;
save.tbButton.idCommand = -1;
TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE );
if (!save.pData)
{
save.pData = Alloc( save.cbData );
if (!save.pData) return FALSE;
alloced = TRUE;
}
if (!save.pCurrent) save.pCurrent = save.pData;
for (i = 0; i < infoPtr->nNumButtons; i++)
{
save.iItem = i;
save.tbButton.iBitmap = infoPtr->buttons[i].iBitmap;
save.tbButton.idCommand = infoPtr->buttons[i].idCommand;
save.tbButton.fsState = infoPtr->buttons[i].fsState;
save.tbButton.fsStyle = infoPtr->buttons[i].fsStyle;
memset( save.tbButton.bReserved, 0, sizeof(save.tbButton.bReserved) );
save.tbButton.dwData = infoPtr->buttons[i].dwData;
save.tbButton.iString = infoPtr->buttons[i].iString;
*save.pCurrent++ = save.tbButton.idCommand;
TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE );
}
ret = RegCreateKeyW( params->hkr, params->pszSubKey, &key );
if (ret == ERROR_SUCCESS)
{
ret = RegSetValueExW( key, params->pszValueName, 0, REG_BINARY, (BYTE *)save.pData, save.cbData );
RegCloseKey( key );
}
if (alloced) Free( save.pData );
return !ret;
}
@ -4172,6 +4242,7 @@ TOOLBAR_DeleteAllButtons(TOOLBAR_INFO *infoPtr)
for (i = 0; i < infoPtr->nNumButtons; i++)
{
free_string( infoPtr->buttons + i );
TOOLBAR_TooltipDelTool(infoPtr, &infoPtr->buttons[i]);
}
@ -4191,6 +4262,7 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
DWORD dwType;
DWORD dwSize = 0;
NMTBRESTORE nmtbr;
NMHDR hdr;
/* restore toolbar information */
TRACE("restore from %s %s\n", debugstr_w(lpSave->pszSubKey),
@ -4223,30 +4295,30 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
if (!TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE))
{
INT i;
INT i, count = nmtbr.cButtons;
/* remove all existing buttons as this function is designed to
* restore the toolbar to a previously saved state */
TOOLBAR_DeleteAllButtons(infoPtr);
for (i = 0; i < nmtbr.cButtons; i++)
for (i = 0; i < count; i++)
{
nmtbr.iItem = i;
nmtbr.tbButton.iBitmap = -1;
nmtbr.tbButton.fsState = 0;
nmtbr.tbButton.fsStyle = 0;
nmtbr.tbButton.idCommand = 0;
if (*nmtbr.pCurrent == (DWORD)-1)
nmtbr.tbButton.dwData = 0;
nmtbr.tbButton.iString = 0;
if (*nmtbr.pCurrent & 0x80000000)
{
/* separator */
nmtbr.tbButton.fsStyle = TBSTYLE_SEP;
/* when inserting separators, iBitmap controls its size.
0 sets default size (width) */
nmtbr.tbButton.iBitmap = 0;
}
else if (*nmtbr.pCurrent == (DWORD)-2)
/* hidden button */
nmtbr.tbButton.iBitmap = SEPARATOR_WIDTH;
nmtbr.tbButton.idCommand = 0;
nmtbr.tbButton.fsStyle = BTNS_SEP;
if (*nmtbr.pCurrent != (DWORD)-1)
nmtbr.tbButton.fsState = TBSTATE_HIDDEN;
}
else
nmtbr.tbButton.idCommand = (int)*nmtbr.pCurrent;
@ -4254,21 +4326,51 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE);
/* can't contain real string as we don't know whether
* the client put an ANSI or Unicode string in there */
/* All returned ptrs and -1 are ignored */
if (!IS_INTRESOURCE(nmtbr.tbButton.iString))
nmtbr.tbButton.iString = 0;
TOOLBAR_InsertButtonT(infoPtr, -1, &nmtbr.tbButton, TRUE);
}
/* do legacy notifications */
if (infoPtr->iVersion < 5)
TOOLBAR_SendNotify( &hdr, infoPtr, TBN_BEGINADJUST );
for (i = 0; ; i++)
{
/* FIXME: send TBN_BEGINADJUST */
FIXME("send TBN_GETBUTTONINFO for each button\n");
/* FIXME: send TBN_ENDADJUST */
NMTOOLBARW tb;
TBBUTTONINFOW bi;
WCHAR buf[128];
UINT code = infoPtr->bUnicode ? TBN_GETBUTTONINFOW : TBN_GETBUTTONINFOA;
INT idx;
memset( &tb, 0, sizeof(tb) );
tb.iItem = i;
tb.cchText = sizeof(buf) / sizeof(buf[0]);
tb.pszText = buf;
/* Use the same struct for both A and W versions since the layout is the same. */
if (!TOOLBAR_SendNotify( &tb.hdr, infoPtr, code ))
break;
idx = TOOLBAR_GetButtonIndex( infoPtr, tb.tbButton.idCommand, FALSE );
if (idx == -1) continue;
/* tb.pszText is ignored - the string comes from tb.tbButton.iString, which may
be an index or a ptr. Either way it is simply copied. There is no api to change
the string index, so we set it manually. The other properties can be set with SetButtonInfo. */
free_string( infoPtr->buttons + idx );
infoPtr->buttons[idx].iString = tb.tbButton.iString;
memset( &bi, 0, sizeof(bi) );
bi.cbSize = sizeof(bi);
bi.dwMask = TBIF_IMAGE | TBIF_STATE | TBIF_STYLE | TBIF_LPARAM;
bi.iImage = tb.tbButton.iBitmap;
bi.fsState = tb.tbButton.fsState;
bi.fsStyle = tb.tbButton.fsStyle;
bi.lParam = tb.tbButton.dwData;
TOOLBAR_SetButtonInfo( infoPtr, tb.tbButton.idCommand, &bi, TRUE );
}
TOOLBAR_SendNotify( &hdr, infoPtr, TBN_ENDADJUST );
/* remove all uninitialised buttons
* note: loop backwards to avoid having to fixup i on a
@ -4294,7 +4396,7 @@ TOOLBAR_SaveRestoreW (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSW
if (lpSave == NULL) return 0;
if (wParam)
return TOOLBAR_Save(lpSave);
return TOOLBAR_Save(infoPtr, lpSave);
else
return TOOLBAR_Restore(infoPtr, lpSave);
}
@ -4312,7 +4414,7 @@ TOOLBAR_SaveRestoreA (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSA
len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, NULL, 0);
pszSubKey = Alloc(len * sizeof(WCHAR));
if (pszSubKey) goto exit;
if (!pszSubKey) goto exit;
MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, pszSubKey, len);
len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszValueName, -1, NULL, 0);
@ -4429,15 +4531,8 @@ TOOLBAR_SetButtonInfo (TOOLBAR_INFO *infoPtr, INT Id,
if (lptbbi->dwMask & TBIF_STYLE)
btnPtr->fsStyle = lptbbi->fsStyle;
if ((lptbbi->dwMask & TBIF_TEXT) && ((INT_PTR)lptbbi->pszText != -1)) {
/* iString is index, zero it to make Str_SetPtr succeed */
if (!TOOLBAR_ButtonHasString(btnPtr)) btnPtr->iString = 0;
if (isW)
Str_SetPtrW ((LPWSTR *)&btnPtr->iString, lptbbi->pszText);
else
Str_SetPtrAtoW ((LPWSTR *)&btnPtr->iString, (LPSTR)lptbbi->pszText);
}
if (lptbbi->dwMask & TBIF_TEXT)
set_stringT( btnPtr, lptbbi->pszText, isW );
/* save the button rect to see if we need to redraw the whole toolbar */
oldBtnRect = btnPtr->rect;
@ -4456,6 +4551,7 @@ static LRESULT
TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam)
{
INT cx = (short)LOWORD(lParam), cy = (short)HIWORD(lParam);
int top = default_top_margin(infoPtr);
if ((cx < 0) || (cy < 0))
{
@ -4482,11 +4578,16 @@ TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam)
cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth);
cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight);
if (cx != infoPtr->nButtonWidth || cy != infoPtr->nButtonHeight ||
top != infoPtr->iTopMargin)
{
infoPtr->nButtonWidth = cx;
infoPtr->nButtonHeight = cy;
infoPtr->iTopMargin = top;
infoPtr->iTopMargin = default_top_margin(infoPtr);
TOOLBAR_LayoutToolbar(infoPtr);
TOOLBAR_LayoutToolbar( infoPtr );
InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
}
return TRUE;
}
@ -4814,9 +4915,9 @@ TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *infoPtr, INT nMaxRows)
return TRUE;
}
#ifdef __REACTOS__
static LRESULT
TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
TOOLBAR_SetMetrics(TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
{
BOOL changed = FALSE;
@ -4851,6 +4952,7 @@ TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
return TRUE;
}
#endif
/* MSDN gives slightly wrong info on padding.
* 1. It is not only used on buttons with the BTNS_AUTOSIZE style
@ -5041,11 +5143,45 @@ TOOLBAR_SetState (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam)
return TRUE;
}
static inline void unwrap(TOOLBAR_INFO *info)
{
int i;
for (i = 0; i < info->nNumButtons; i++)
info->buttons[i].fsState &= ~TBSTATE_WRAP;
}
static LRESULT
TOOLBAR_SetStyle (TOOLBAR_INFO *infoPtr, DWORD style)
{
DWORD dwOldStyle = infoPtr->dwStyle;
TRACE("new style 0x%08x\n", style);
if (style & TBSTYLE_LIST)
infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
else
infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS;
infoPtr->dwStyle = style;
TOOLBAR_CheckStyle(infoPtr);
if ((dwOldStyle ^ style) & TBSTYLE_WRAPABLE)
{
if (dwOldStyle & TBSTYLE_WRAPABLE)
unwrap(infoPtr);
TOOLBAR_CalcToolbar(infoPtr);
}
else if ((dwOldStyle ^ style) & CCS_VERT)
TOOLBAR_LayoutToolbar(infoPtr);
/* only resize if one of the CCS_* styles was changed */
if ((dwOldStyle ^ style) & COMMON_STYLES)
{
TOOLBAR_AutoSize(infoPtr);
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
}
return 0;
}
@ -5319,8 +5455,7 @@ TOOLBAR_Destroy (TOOLBAR_INFO *infoPtr)
/* delete button data */
for (i = 0; i < infoPtr->nNumButtons; i++)
if (TOOLBAR_ButtonHasString(&infoPtr->buttons[i]))
Free ((LPWSTR)infoPtr->buttons[i].iString);
free_string( infoPtr->buttons + i );
Free (infoPtr->buttons);
/* delete strings */
@ -6035,7 +6170,6 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
/* paranoid!! */
infoPtr->dwStructSize = sizeof(TBBUTTON);
infoPtr->nRows = 1;
infoPtr->nWidth = 0;
/* initialize info structure */
infoPtr->nButtonWidth = 23;
@ -6462,30 +6596,7 @@ static LRESULT
TOOLBAR_StyleChanged (TOOLBAR_INFO *infoPtr, INT nType, const STYLESTRUCT *lpStyle)
{
if (nType == GWL_STYLE)
{
DWORD dwOldStyle = infoPtr->dwStyle;
if (lpStyle->styleNew & TBSTYLE_LIST)
infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
else
infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS;
TRACE("new style 0x%08x\n", lpStyle->styleNew);
infoPtr->dwStyle = lpStyle->styleNew;
TOOLBAR_CheckStyle (infoPtr);
if ((dwOldStyle ^ lpStyle->styleNew) & (TBSTYLE_WRAPABLE | CCS_VERT))
TOOLBAR_LayoutToolbar(infoPtr);
/* only resize if one of the CCS_* styles was changed */
if ((dwOldStyle ^ lpStyle->styleNew) & COMMON_STYLES)
{
TOOLBAR_AutoSize (infoPtr);
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
}
}
return TOOLBAR_SetStyle(infoPtr, lpStyle->styleNew);
return 0;
}
@ -6499,6 +6610,16 @@ TOOLBAR_SysColorChange (void)
return 0;
}
#ifndef __REACTOS__
/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed (HWND hwnd)
{
HTHEME theme = GetWindowTheme (hwnd);
CloseThemeData (theme);
OpenThemeData (hwnd, themeClass);
return 0;
}
#endif
static LRESULT WINAPI
ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@ -6603,9 +6724,10 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case TB_GETMAXSIZE:
return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam);
#ifdef __REACTOS__
case TB_GETMETRICS:
return TOOLBAR_GetMetrics (infoPtr, (TBMETRICS*)lParam);
#endif
/* case TB_GETOBJECT: */ /* 4.71 */
@ -6747,8 +6869,10 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case TB_SETMAXTEXTROWS:
return TOOLBAR_SetMaxTextRows (infoPtr, wParam);
#ifdef __REACTOS__
case TB_SETMETRICS:
return TOOLBAR_SetMetrics (infoPtr, (TBMETRICS*)lParam);
#endif
case TB_SETPADDING:
return TOOLBAR_SetPadding (infoPtr, lParam);
@ -6890,7 +7014,11 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TOOLBAR_SysColorChange ();
case WM_THEMECHANGED:
#ifdef __REACTOS__
return TOOLBAR_ThemeChanged(hwnd);
#else
return theme_changed (hwnd);
#endif
/* case WM_WININICHANGE: */

View file

@ -98,6 +98,7 @@ static HICON hTooltipIcons[TTI_ERROR+1];
typedef struct
{
UINT uFlags;
UINT uInternalFlags;
HWND hwnd;
BOOL bNotifyUnicode;
UINT_PTR uId;
@ -471,13 +472,12 @@ TOOLTIPS_GetTipText (const TOOLTIPS_INFO *infoPtr, INT nTool, WCHAR *buffer)
{
TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
/* always NULL-terminate the buffer, just in case we fail to load the string */
buffer[0] = '\0';
if (IS_INTRESOURCE(toolPtr->lpszText)) {
HINSTANCE hinst = toolPtr->hinst ? toolPtr->hinst : GetModuleHandleW(NULL);
/* load a resource */
TRACE("load res string %p %x\n", hinst, LOWORD(toolPtr->lpszText));
LoadStringW (hinst, LOWORD(toolPtr->lpszText), buffer, INFOTIPSIZE);
TRACE("load res string %p %x\n",
toolPtr->hinst, LOWORD(toolPtr->lpszText));
if (!LoadStringW (toolPtr->hinst, LOWORD(toolPtr->lpszText), buffer, INFOTIPSIZE))
buffer[0] = '\0';
}
else if (toolPtr->lpszText) {
if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW) {
@ -493,6 +493,7 @@ TOOLTIPS_GetTipText (const TOOLTIPS_INFO *infoPtr, INT nTool, WCHAR *buffer)
}
else {
/* no text available */
buffer[0] = '\0';
}
TRACE("%s\n", debugstr_w(buffer));
@ -1045,6 +1046,7 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
/* copy tool data */
toolPtr->uFlags = ti->uFlags;
toolPtr->uInternalFlags = (ti->uFlags & (TTF_SUBCLASS | TTF_IDISHWND));
toolPtr->hwnd = ti->hwnd;
toolPtr->uId = ti->uId;
toolPtr->rect = ti->rect;
@ -1079,8 +1081,8 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
toolPtr->lParam = ti->lParam;
/* install subclassing hook */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
if (toolPtr->uInternalFlags & TTF_IDISHWND) {
SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
(DWORD_PTR)infoPtr->hwndSelf);
}
@ -1139,8 +1141,8 @@ TOOLTIPS_DelToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
}
/* remove subclassing */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
if (toolPtr->uInternalFlags & TTF_IDISHWND) {
RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
}
else {
@ -1905,8 +1907,8 @@ TOOLTIPS_Destroy (TOOLTIPS_INFO *infoPtr)
}
/* remove subclassing */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
if (toolPtr->uInternalFlags & TTF_IDISHWND) {
RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
}
else {
@ -1994,6 +1996,7 @@ TOOLTIPS_NCHitTest (const TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT
TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
#ifdef __REACTOS__
TTTOOL_INFO *toolPtr = infoPtr->tools;
LRESULT nResult;
@ -2020,6 +2023,9 @@ TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
}
return nResult;
}
#else
FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
#endif
return 0;
}

View file

@ -29,7 +29,7 @@
*
* TODO:
* missing notifications: TVN_GETINFOTIP, TVN_KEYDOWN,
* TVN_SETDISPINFO, TVN_SINGLEEXPAND
* TVN_SETDISPINFO
*
* missing styles: TVS_FULLROWSELECT, TVS_INFOTIP, TVS_RTLREADING,
*
@ -2869,11 +2869,13 @@ TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
}
//
// This is correct, but is causes and infinite loop of WM_PAINT messages, resulting
// in continuous painting of the scroll bar in reactos. Comment out until the real
// bug is found
// FIXME: This is correct, but is causes and infinite loop of WM_PAINT
// messages, resulting in continuous painting of the scroll bar in reactos.
// Comment out until the real bug is found
//
//TREEVIEW_UpdateScrollBars(infoPtr);
#ifndef __REACTOS__
TREEVIEW_UpdateScrollBars(infoPtr);
#endif
if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
infoPtr->cdmode =
@ -3491,47 +3493,31 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item,
static void TREEVIEW_SingleExpand(TREEVIEW_INFO *infoPtr,
HTREEITEM selection, HTREEITEM item)
{
TREEVIEW_ITEM *SelItem;
TREEVIEW_ITEM *prev, *curr;
if ((infoPtr->dwStyle & TVS_SINGLEEXPAND) == 0 || infoPtr->hwndEdit || !item) return;
TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SINGLEEXPAND, TVC_UNKNOWN, TVIF_HANDLE | TVIF_PARAM, item, 0);
/*
* Close the previous selection all the way to the root
* as long as the new selection is not a child
* Close the previous item and its ancestors as long as they are not
* ancestors of the current item
*/
if(selection && (selection != item))
for (prev = selection; prev && TREEVIEW_ValidItem(infoPtr, prev); prev = prev->parent)
{
BOOL closeit = TRUE;
SelItem = item;
/* determine if the hitItem is a child of the currently selected item */
while(closeit && SelItem && TREEVIEW_ValidItem(infoPtr, SelItem) &&
(SelItem->parent != infoPtr->root))
for (curr = item; curr && TREEVIEW_ValidItem(infoPtr, curr); curr = curr->parent)
{
closeit = (SelItem != selection);
SelItem = SelItem->parent;
}
if(closeit)
{
if(TREEVIEW_ValidItem(infoPtr, selection))
SelItem = selection;
while(SelItem && (SelItem != item) && TREEVIEW_ValidItem(infoPtr, SelItem) &&
SelItem->parent != infoPtr->root)
{
TREEVIEW_Collapse(infoPtr, SelItem, FALSE, FALSE);
SelItem = SelItem->parent;
}
}
if (curr == prev)
goto finish;
}
TREEVIEW_Collapse(infoPtr, prev, FALSE, TRUE);
}
finish:
/*
* Expand the current item
*/
TREEVIEW_Expand(infoPtr, item, FALSE, FALSE);
TREEVIEW_Expand(infoPtr, item, FALSE, TRUE);
}
static BOOL
@ -4474,6 +4460,9 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
if (item && !TREEVIEW_ValidItem(infoPtr, item))
return FALSE;
if (item == infoPtr->selectedItem)
return TRUE;
TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam);
if (!TREEVIEW_DoSelectItem(infoPtr, wParam, item, TVC_UNKNOWN))
@ -4659,7 +4648,7 @@ TREEVIEW_EnsureVisible(TREEVIEW_INFO *infoPtr, HTREEITEM item, BOOL bHScroll)
while (parent != infoPtr->root)
{
if (!(parent->state & TVIS_EXPANDED))
TREEVIEW_Expand(infoPtr, parent, FALSE, FALSE);
TREEVIEW_Expand(infoPtr, parent, FALSE, TRUE);
parent = parent->parent;
}

View file

@ -351,12 +351,18 @@ static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
*/
static BOOL UPDOWN_DrawBuddyBackground (const UPDOWN_INFO *infoPtr, HDC hdc)
{
RECT br;
RECT br, r;
HTHEME buddyTheme = GetWindowTheme (infoPtr->Buddy);
if (!buddyTheme) return FALSE;
GetClientRect (infoPtr->Buddy, &br);
MapWindowPoints (infoPtr->Buddy, infoPtr->Self, (POINT*)&br, 2);
GetWindowRect (infoPtr->Buddy, &br);
MapWindowPoints (NULL, infoPtr->Self, (POINT*)&br, 2);
GetClientRect (infoPtr->Self, &r);
if (infoPtr->dwStyle & UDS_ALIGNLEFT)
br.left = r.left;
else if (infoPtr->dwStyle & UDS_ALIGNRIGHT)
br.right = r.right;
/* FIXME: take disabled etc. into account */
DrawThemeBackground (buddyTheme, hdc, 0, 0, &br, NULL);
return TRUE;

View file

@ -55,7 +55,7 @@ reactos/dll/win32/browseui # Out of sync
reactos/dll/win32/cabinet # Synced to WineStaging-1.7.37
reactos/dll/win32/clusapi # Synced to WineStaging-1.7.37
reactos/dll/win32/comcat # Synced to WineStaging-1.7.37
reactos/dll/win32/comctl32 # Synced to WineStaging-1.7.37
reactos/dll/win32/comctl32 # Synced to WineStaging-1.7.47
reactos/dll/win32/comdlg32 # Synced to WineStaging-1.7.37
reactos/dll/win32/compstui # Synced to WineStaging-1.7.37
reactos/dll/win32/credui # Synced to WineStaging-1.7.37