diff --git a/reactos/dll/win32/comctl32/comboex.c b/reactos/dll/win32/comctl32/comboex.c index a1b6cff23e1..d92da3d8a46 100644 --- a/reactos/dll/win32/comctl32/comboex.c +++ b/reactos/dll/win32/comctl32/comboex.c @@ -720,7 +720,7 @@ COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style) /* see if we need to change the word break proc on the edit */ if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC) SetPathWordBreakProc(infoPtr->hwndEdit, - (infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ? TRUE : FALSE); + (infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) != 0); /* test if the control's appearance has changed */ mask = CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT; @@ -1381,8 +1381,6 @@ static LRESULT COMBOEX_DrawItem (const COMBOEX_INFO *infoPtr, DRAWITEMSTRUCT con item = infoPtr->edit; if (infoPtr->hwndEdit) { - INT len; - /* free previous text of edit item */ COMBOEX_FreeText(item); item->mask &= ~CBEIF_TEXT; @@ -2076,7 +2074,6 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, * For EN_CHANGE this issues the same calls and messages * as the native seems to do. */ - WCHAR edit_text[260]; LPCWSTR lastwrk; cmp_func_t cmptext = get_cmp_func(infoPtr); @@ -2311,7 +2308,8 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return COMBOEX_WindowPosChanging (infoPtr, (WINDOWPOS *)lParam); case WM_SETFOCUS: - SetFocus(infoPtr->hwndCombo); + if (infoPtr->hwndEdit) SetFocus( infoPtr->hwndEdit ); + else SetFocus( infoPtr->hwndCombo ); return 0; case WM_SYSCOLORCHANGE: diff --git a/reactos/dll/win32/comctl32/comctl32.h b/reactos/dll/win32/comctl32/comctl32.h index 7355e82e3b2..129ab0cf0f0 100644 --- a/reactos/dll/win32/comctl32/comctl32.h +++ b/reactos/dll/win32/comctl32/comctl32.h @@ -231,6 +231,7 @@ extern void UPDOWN_Unregister(void) DECLSPEC_HIDDEN; int MONTHCAL_MonthLength(int month, int year) DECLSPEC_HIDDEN; int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace) DECLSPEC_HIDDEN; +LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) DECLSPEC_HIDDEN; extern void THEMING_Initialize(void) DECLSPEC_HIDDEN; extern void THEMING_Uninitialize(void) DECLSPEC_HIDDEN; diff --git a/reactos/dll/win32/comctl32/datetime.c b/reactos/dll/win32/comctl32/datetime.c index 785769a4a37..748e0fc3918 100644 --- a/reactos/dll/win32/comctl32/datetime.c +++ b/reactos/dll/win32/comctl32/datetime.c @@ -4,6 +4,7 @@ * Copyright 1998, 1999 Eric Kohl * Copyright 1999, 2000 Alex Priem * Copyright 2000 Chris Morgan + * Copyright 2012 Owen Rudge for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -138,6 +139,9 @@ static BOOL DATETIME_SendDateTimeChangeNotify (const DATETIME_INFO *infoPtr); static const WCHAR allowedformatchars[] = {'d', 'h', 'H', 'm', 'M', 's', 't', 'y', 'X', 0}; static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1}; +/* valid date limits */ +static const SYSTEMTIME max_allowed_date = { /* wYear */ 9999, /* wMonth */ 12, /* wDayOfWeek */ 0, /* wDay */ 31 }; +static const SYSTEMTIME min_allowed_date = { /* wYear */ 1752, /* wMonth */ 9, /* wDayOfWeek */ 0, /* wDay */ 14 }; static DWORD DATETIME_GetSystemTime (const DATETIME_INFO *infoPtr, SYSTEMTIME *systime) @@ -153,6 +157,43 @@ DATETIME_GetSystemTime (const DATETIME_INFO *infoPtr, SYSTEMTIME *systime) return GDT_VALID; } +/* Checks value is within configured date range + * + * PARAMETERS + * + * [I] infoPtr : valid pointer to control data + * [I] date : pointer to valid date data to check + * + * RETURN VALUE + * + * TRUE - date within configured range + * FALSE - date is outside configured range + */ +static BOOL DATETIME_IsDateInValidRange(const DATETIME_INFO *infoPtr, const SYSTEMTIME *date) +{ + SYSTEMTIME range[2]; + DWORD limits; + + if ((MONTHCAL_CompareSystemTime(date, &max_allowed_date) == 1) || + (MONTHCAL_CompareSystemTime(date, &min_allowed_date) == -1)) + return FALSE; + + limits = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, 0, (LPARAM)range); + + if (limits & GDTR_MAX) + { + if (MONTHCAL_CompareSystemTime(date, &range[1]) == 1) + return FALSE; + } + + if (limits & GDTR_MIN) + { + if (MONTHCAL_CompareSystemTime(date, &range[0]) == -1) + return FALSE; + } + + return TRUE; +} static BOOL DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *systime) @@ -164,7 +205,7 @@ DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *sy systime->wHour, systime->wMinute, systime->wSecond); if (flag == GDT_VALID) { - if (systime->wYear < 1601 || systime->wYear > 30827 || + if (systime->wYear == 0 || systime->wMonth < 1 || systime->wMonth > 12 || systime->wDay < 1 || systime->wDay > MONTHCAL_MonthLength(systime->wMonth, systime->wYear) || @@ -175,6 +216,10 @@ DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *sy ) return FALSE; + /* Windows returns true if the date is valid but outside the limits set */ + if (DATETIME_IsDateInValidRange(infoPtr, systime) == FALSE) + return TRUE; + infoPtr->dateValid = TRUE; infoPtr->date = *systime; /* always store a valid day of week */ @@ -462,6 +507,9 @@ static void DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number, int delta) { SYSTEMTIME *date = &infoPtr->date; + SYSTEMTIME range[2]; + DWORD limits; + BOOL min; TRACE ("%d\n", number); if ((number > infoPtr->nrFields) || (number < 0)) return; @@ -472,7 +520,13 @@ DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number, int delta) case ONEDIGITYEAR: case TWODIGITYEAR: case FULLYEAR: - date->wYear = wrap(date->wYear, delta, 1752, 9999); + if (delta == INT_MIN) + date->wYear = 1752; + else if (delta == INT_MAX) + date->wYear = 9999; + else + date->wYear = max(min(date->wYear + delta, 9999), 1752); + if (date->wDay > MONTHCAL_MonthLength(date->wMonth, date->wYear)) /* This can happen when moving away from a leap year. */ date->wDay = MONTHCAL_MonthLength(date->wMonth, date->wYear); @@ -529,8 +583,28 @@ DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number, int delta) date->wMinute = 0; date->wHour = 0; } -} + /* Ensure time is within bounds */ + limits = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, 0, (LPARAM)range); + min = delta < 0; + + if (limits & (min ? GDTR_MIN : GDTR_MAX)) + { + int i = (min ? 0 : 1); + + if (MONTHCAL_CompareSystemTime(date, &range[i]) == (min ? -1 : 1)) + { + date->wYear = range[i].wYear; + date->wMonth = range[i].wMonth; + date->wDayOfWeek = range[i].wDayOfWeek; + date->wDay = range[i].wDay; + date->wHour = range[i].wHour; + date->wMinute = range[i].wMinute; + date->wSecond = range[i].wSecond; + date->wMilliseconds = range[i].wMilliseconds; + } + } +} static void DATETIME_ReturnFieldWidth (const DATETIME_INFO *infoPtr, HDC hdc, int count, SHORT *width) @@ -774,25 +848,43 @@ DATETIME_ApplySelectedField (DATETIME_INFO *infoPtr) int fieldNum = infoPtr->select & DTHT_DATEFIELD; int i, val=0, clamp_day=0; SYSTEMTIME date = infoPtr->date; + int oldyear; if (infoPtr->select == -1 || infoPtr->nCharsEntered == 0) return; - for (i=0; inCharsEntered; i++) - val = val * 10 + infoPtr->charsEntered[i] - '0'; + if ((infoPtr->fieldspec[fieldNum] == ONELETTERAMPM) || + (infoPtr->fieldspec[fieldNum] == TWOLETTERAMPM)) + val = infoPtr->charsEntered[0]; + else { + for (i=0; inCharsEntered; i++) + val = val * 10 + infoPtr->charsEntered[i] - '0'; + } infoPtr->nCharsEntered = 0; switch (infoPtr->fieldspec[fieldNum]) { case ONEDIGITYEAR: case TWODIGITYEAR: + oldyear = date.wYear; date.wYear = date.wYear - (date.wYear%100) + val; - clamp_day = 1; + + if (DATETIME_IsDateInValidRange(infoPtr, &date)) + clamp_day = 1; + else + date.wYear = oldyear; + break; case INVALIDFULLYEAR: case FULLYEAR: + oldyear = date.wYear; date.wYear = val; - clamp_day = 1; + + if (DATETIME_IsDateInValidRange(infoPtr, &date)) + clamp_day = 1; + else + date.wYear = oldyear; + break; case ONEDIGITMONTH: case TWODIGITMONTH: @@ -805,9 +897,20 @@ DATETIME_ApplySelectedField (DATETIME_INFO *infoPtr) break; case ONEDIGIT12HOUR: case TWODIGIT12HOUR: + if (val >= 24) + val -= 20; + + if (val >= 13) + date.wHour = val; + else if (val != 0) { + if (date.wHour >= 12) /* preserve current AM/PM state */ + date.wHour = (val == 12 ? 12 : val + 12); + else + date.wHour = (val == 12 ? 0 : val); + } + break; case ONEDIGIT24HOUR: case TWODIGIT24HOUR: - /* FIXME: Preserve AM/PM for 12HOUR? */ date.wHour = val; break; case ONEDIGITMINUTE: @@ -818,6 +921,16 @@ DATETIME_ApplySelectedField (DATETIME_INFO *infoPtr) case TWODIGITSECOND: date.wSecond = val; break; + case ONELETTERAMPM: + case TWOLETTERAMPM: + if (val == 'a' || val == 'A') { + if (date.wHour >= 12) + date.wHour -= 12; + } else if (val == 'p' || val == 'P') { + if (date.wHour < 12) + date.wHour += 12; + } + break; } if (clamp_day && date.wDay > MONTHCAL_MonthLength(date.wMonth, date.wYear)) @@ -1111,24 +1224,40 @@ DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode) static LRESULT DATETIME_Char (DATETIME_INFO *infoPtr, WPARAM vkCode) { - int fieldNum = infoPtr->select & DTHT_DATEFIELD; + int fieldNum, fieldSpec; - if (vkCode >= '0' && vkCode <= '9') { + fieldNum = infoPtr->select & DTHT_DATEFIELD; + fieldSpec = infoPtr->fieldspec[fieldNum]; + + if (fieldSpec == ONELETTERAMPM || fieldSpec == TWOLETTERAMPM) { + infoPtr->charsEntered[0] = vkCode; + infoPtr->nCharsEntered = 1; + + DATETIME_ApplySelectedField(infoPtr); + } else if (vkCode >= '0' && vkCode <= '9') { int maxChars; - int fieldSpec; infoPtr->charsEntered[infoPtr->nCharsEntered++] = vkCode; - fieldSpec = infoPtr->fieldspec[fieldNum]; - if (fieldSpec == INVALIDFULLYEAR || fieldSpec == FULLYEAR) maxChars = 4; else maxChars = 2; + if ((fieldSpec == ONEDIGIT12HOUR || + fieldSpec == TWODIGIT12HOUR || + fieldSpec == ONEDIGIT24HOUR || + fieldSpec == TWODIGIT24HOUR) && + (infoPtr->nCharsEntered == 1)) + { + if (vkCode >= '3') + maxChars = 1; + } + if (maxChars == infoPtr->nCharsEntered) DATETIME_ApplySelectedField(infoPtr); } + return 0; } @@ -1316,7 +1445,7 @@ DATETIME_StyleChanged(DATETIME_INFO *infoPtr, WPARAM wStyleType, const STYLESTRU infoPtr->hwndCheckbut = CreateWindowExW (0, WC_BUTTONW, 0, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 2, 2, 13, 13, infoPtr->hwndSelf, 0, (HINSTANCE)GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_HINSTANCE), 0); - SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0); + SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, infoPtr->dateValid ? 1 : 0, 0); } if ( (lpss->styleOld & DTS_SHOWNONE) && !(lpss->styleNew & DTS_SHOWNONE) ) { DestroyWindow(infoPtr->hwndCheckbut); diff --git a/reactos/dll/win32/comctl32/header.c b/reactos/dll/win32/comctl32/header.c index ce95d58eed4..d1386e35e7b 100644 --- a/reactos/dll/win32/comctl32/header.c +++ b/reactos/dll/win32/comctl32/header.c @@ -727,17 +727,9 @@ static void HEADER_DrawTrackLine (const HEADER_INFO *infoPtr, HDC hdc, INT x) { RECT rect; - HPEN hOldPen; - INT oldRop; GetClientRect (infoPtr->hwndSelf, &rect); - - hOldPen = SelectObject (hdc, GetStockObject (BLACK_PEN)); - oldRop = SetROP2 (hdc, R2_XORPEN); - MoveToEx (hdc, x, rect.top, NULL); - LineTo (hdc, x, rect.bottom); - SetROP2 (hdc, oldRop); - SelectObject (hdc, hOldPen); + PatBlt( hdc, x, rect.top, 1, rect.bottom - rect.top, DSTINVERT ); } /*** @@ -1241,6 +1233,14 @@ HEADER_SetOrderArray(HEADER_INFO *infoPtr, INT size, const INT *order) if ((UINT)size != infoPtr->uNumItem) return FALSE; + if (TRACE_ON(header)) + { + TRACE("count=%d, order array={", size); + for (i = 0; i < size; i++) + TRACE("%d%c", order[i], i != size-1 ? ',' : '}'); + TRACE("\n"); + } + for (i=0; i= size || order[i] < 0) diff --git a/reactos/dll/win32/comctl32/idb_hist_large.bmp b/reactos/dll/win32/comctl32/idb_hist_large.bmp index c6aee0bb37a..b7818fbafb2 100644 Binary files a/reactos/dll/win32/comctl32/idb_hist_large.bmp and b/reactos/dll/win32/comctl32/idb_hist_large.bmp differ diff --git a/reactos/dll/win32/comctl32/idb_hist_small.bmp b/reactos/dll/win32/comctl32/idb_hist_small.bmp index 2ae50010edb..c735f54377f 100644 Binary files a/reactos/dll/win32/comctl32/idb_hist_small.bmp and b/reactos/dll/win32/comctl32/idb_hist_small.bmp differ diff --git a/reactos/dll/win32/comctl32/idb_std_large.bmp b/reactos/dll/win32/comctl32/idb_std_large.bmp index c10dc72da1b..7e19185c929 100644 Binary files a/reactos/dll/win32/comctl32/idb_std_large.bmp and b/reactos/dll/win32/comctl32/idb_std_large.bmp differ diff --git a/reactos/dll/win32/comctl32/idb_std_small.bmp b/reactos/dll/win32/comctl32/idb_std_small.bmp index aedd4a861cf..7db2f3ca805 100644 Binary files a/reactos/dll/win32/comctl32/idb_std_small.bmp and b/reactos/dll/win32/comctl32/idb_std_small.bmp differ diff --git a/reactos/dll/win32/comctl32/idb_view_large.bmp b/reactos/dll/win32/comctl32/idb_view_large.bmp index ce4ea4f4c1b..22e4d1d8b8b 100644 Binary files a/reactos/dll/win32/comctl32/idb_view_large.bmp and b/reactos/dll/win32/comctl32/idb_view_large.bmp differ diff --git a/reactos/dll/win32/comctl32/idb_view_small.bmp b/reactos/dll/win32/comctl32/idb_view_small.bmp index abee9b8063d..6ba3d831637 100644 Binary files a/reactos/dll/win32/comctl32/idb_view_small.bmp and b/reactos/dll/win32/comctl32/idb_view_small.bmp differ diff --git a/reactos/dll/win32/comctl32/imagelist.c b/reactos/dll/win32/comctl32/imagelist.c index 28e2968774e..6142ba7c016 100644 --- a/reactos/dll/win32/comctl32/imagelist.c +++ b/reactos/dll/win32/comctl32/imagelist.c @@ -1186,7 +1186,7 @@ ImageList_Draw (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, UINT fStyle) /************************************************************************* * ImageList_DrawEx [COMCTL32.@] * - * Draws an image and allows to use extended drawing features. + * Draws an image and allows using extended drawing features. * * PARAMS * himl [I] handle to image list @@ -3366,7 +3366,7 @@ static HRESULT WINAPI ImageListImpl_Copy(IImageList *iface, int iDst, return E_FAIL; /* TODO: Add test for IID_ImageList2 too */ - if (FAILED(IImageList_QueryInterface(punkSrc, &IID_IImageList, + if (FAILED(IUnknown_QueryInterface(punkSrc, &IID_IImageList, (void **) &src))) return E_FAIL; @@ -3390,7 +3390,7 @@ static HRESULT WINAPI ImageListImpl_Merge(IImageList *iface, int i1, TRACE("(%p)->(%d %p %d %d %d %s %p)\n", iface, i1, punk2, i2, dx, dy, debugstr_guid(riid), ppv); /* TODO: Add test for IID_ImageList2 too */ - if (FAILED(IImageList_QueryInterface(punk2, &IID_IImageList, + if (FAILED(IUnknown_QueryInterface(punk2, &IID_IImageList, (void **) &iml2))) return E_FAIL; @@ -3523,7 +3523,7 @@ static HRESULT WINAPI ImageListImpl_SetDragCursorImage(IImageList *iface, return E_FAIL; /* TODO: Add test for IID_ImageList2 too */ - if (FAILED(IImageList_QueryInterface(punk, &IID_IImageList, + if (FAILED(IUnknown_QueryInterface(punk, &IID_IImageList, (void **) &iml2))) return E_FAIL; diff --git a/reactos/dll/win32/comctl32/listview.c b/reactos/dll/win32/comctl32/listview.c index ecb24446d4d..33084ae2cd8 100644 --- a/reactos/dll/win32/comctl32/listview.c +++ b/reactos/dll/win32/comctl32/listview.c @@ -6,7 +6,7 @@ * Copyright 2000 Jason Mawdsley * Copyright 2001 CodeWeavers Inc. * Copyright 2002 Dimitrie O. Paun - * Copyright 2009-2011 Nikolay Sivov + * Copyright 2009-2012 Nikolay Sivov * Copyright 2009 Owen Rudge for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -560,11 +560,8 @@ static inline int textcmpWT(LPCWSTR aw, LPCWSTR bt, BOOL isW) static inline int lstrncmpiW(LPCWSTR s1, LPCWSTR s2, int n) { - int res; - n = min(min(n, lstrlenW(s1)), lstrlenW(s2)); - res = CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, s1, n, s2, n); - return res ? res - sizeof(WCHAR) : res; + return CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, s1, n, s2, n) - CSTR_EQUAL; } /******** Debugging functions *****************************************/ @@ -3901,7 +3898,7 @@ static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, const POINT *coord } iterator_destroy(&new_elems); - LISTVIEW_InvalidateRect(infoPtr, &rect); + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); } /*** @@ -4288,6 +4285,10 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL { if (lpLVItem->state & LVIS_FOCUSED) { + /* update selection mark */ + if (infoPtr->nFocusedItem == -1 && infoPtr->nSelectionMark == -1) + infoPtr->nSelectionMark = lpLVItem->iItem; + if (infoPtr->nFocusedItem != -1) { /* remove current focus */ @@ -4957,10 +4958,7 @@ static void LISTVIEW_RefreshReportGrid(LISTVIEW_INFO *infoPtr, HDC hdc) itemheight = LISTVIEW_CalculateItemHeight(infoPtr); rcItem.left = infoPtr->rcList.left; rcItem.right = infoPtr->rcList.right; - rcItem.bottom = rcItem.top = Origin.y - 1; - MoveToEx(hdc, rcItem.left, rcItem.top, NULL); - LineTo(hdc, rcItem.right, rcItem.top); - for(y=itemheight-1+Origin.y; y<=infoPtr->rcList.bottom; y+=itemheight) + for(y = Origin.y > 1 ? Origin.y - 1 : itemheight - 1 + Origin.y % itemheight; y<=infoPtr->rcList.bottom; y+=itemheight) { rcItem.bottom = rcItem.top = y; TRACE("horz rcItem=%s\n", wine_dbgstr_rect(&rcItem)); @@ -8584,10 +8582,12 @@ static DWORD LISTVIEW_SetIconSpacing(LISTVIEW_INFO *infoPtr, INT cx, INT cy) if (cy == -1) cy = GetSystemMetrics(SM_CYICONSPACING); /* if 0 then compute width - * FIXME: Should scan each item and determine max width of - * icon or label, then make that the width */ - if (cx == 0) - cx = infoPtr->iconSpacing.cx; + * FIXME: computed cx and cy is not matching native behaviour */ + if (cx == 0) { + cx = GetSystemMetrics(SM_CXICONSPACING); + if (infoPtr->iconSize.cx + ICON_LR_PADDING > cx) + cx = infoPtr->iconSize.cx + ICON_LR_PADDING; + } /* if 0 then compute height */ if (cy == 0) @@ -8829,26 +8829,31 @@ static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, const PO * PARAMETER(S): * [I] infoPtr : valid pointer to the listview structure * [I] nItem : item index - * [I] lpLVItem : item or subitem info + * [I] item : item or subitem info * * RETURN: * SUCCESS : TRUE * FAILURE : FALSE */ -static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITEMW *lpLVItem) +static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITEMW *item) { - BOOL bResult = TRUE; + BOOL ret = TRUE; LVITEMW lvItem; + if (!item) return FALSE; + lvItem.iItem = nItem; lvItem.iSubItem = 0; lvItem.mask = LVIF_STATE; - lvItem.state = lpLVItem->state; - lvItem.stateMask = lpLVItem->stateMask; - TRACE("lvItem=%s\n", debuglvitem_t(&lvItem, TRUE)); + lvItem.state = item->state; + lvItem.stateMask = item->stateMask; + TRACE("item=%s\n", debuglvitem_t(&lvItem, TRUE)); if (nItem == -1) { + UINT oldstate = 0; + BOOL notify; + /* select all isn't allowed in LVS_SINGLESEL */ if ((lvItem.state & lvItem.stateMask & LVIS_SELECTED) && (infoPtr->dwStyle & LVS_SINGLESEL)) return FALSE; @@ -8856,14 +8861,40 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE /* focus all isn't allowed */ if (lvItem.state & lvItem.stateMask & LVIS_FOCUSED) return FALSE; + notify = infoPtr->bDoChangeNotify; + if (infoPtr->dwStyle & LVS_OWNERDATA) + { + infoPtr->bDoChangeNotify = FALSE; + if (!(lvItem.state & LVIS_SELECTED) && LISTVIEW_GetSelectedCount(infoPtr)) + oldstate |= LVIS_SELECTED; + if (infoPtr->nFocusedItem != -1) oldstate |= LVIS_FOCUSED; + } + /* apply to all items */ for (lvItem.iItem = 0; lvItem.iItem < infoPtr->nItemCount; lvItem.iItem++) - if (!LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE)) bResult = FALSE; + if (!LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE)) ret = FALSE; + + if (infoPtr->dwStyle & LVS_OWNERDATA) + { + NMLISTVIEW nmlv; + + infoPtr->bDoChangeNotify = notify; + + nmlv.iItem = -1; + nmlv.iSubItem = 0; + nmlv.uNewState = lvItem.state & lvItem.stateMask; + nmlv.uOldState = oldstate & lvItem.stateMask; + nmlv.uChanged = LVIF_STATE; + nmlv.ptAction.x = nmlv.ptAction.y = 0; + nmlv.lParam = 0; + + notify_listview(infoPtr, LVN_ITEMCHANGED, &nmlv); + } } else - bResult = LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE); + ret = LISTVIEW_SetItemT(infoPtr, &lvItem, TRUE); - return bResult; + return ret; } /*** @@ -8885,6 +8916,7 @@ static BOOL LISTVIEW_SetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE LVITEMW lvItem; if (!lpLVItem || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE; + if (infoPtr->dwStyle & LVS_OWNERDATA) return FALSE; lvItem.iItem = nItem; lvItem.iSubItem = lpLVItem->iSubItem; @@ -9252,21 +9284,15 @@ static BOOL LISTVIEW_Update(LISTVIEW_INFO *infoPtr, INT nItem) */ static BOOL LISTVIEW_DrawTrackLine(const LISTVIEW_INFO *infoPtr) { - HPEN hOldPen; HDC hdc; - INT oldROP; if (infoPtr->xTrackLine == -1) return FALSE; if (!(hdc = GetDC(infoPtr->hwndSelf))) return FALSE; - hOldPen = SelectObject(hdc, GetStockObject(BLACK_PEN)); - oldROP = SetROP2(hdc, R2_XORPEN); - MoveToEx(hdc, infoPtr->xTrackLine, infoPtr->rcList.top, NULL); - LineTo(hdc, infoPtr->xTrackLine, infoPtr->rcList.bottom); - SetROP2(hdc, oldROP); - SelectObject(hdc, hOldPen); + PatBlt( hdc, infoPtr->xTrackLine, infoPtr->rcList.top, + 1, infoPtr->rcList.bottom - infoPtr->rcList.top, DSTINVERT ); ReleaseDC(infoPtr->hwndSelf, hdc); return TRUE; } @@ -9418,6 +9444,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) /* init item size to avoid division by 0 */ LISTVIEW_UpdateItemSize (infoPtr); + LISTVIEW_UpdateSize (infoPtr); if (infoPtr->uView == LV_VIEW_DETAILS) { @@ -10873,7 +10900,7 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr) * The "2" is there to mimic the native control. I think it may be * related to either padding or edges. (GLA 7/2002) */ - if (!(infoPtr->dwStyle & WS_HSCROLL)) + if (!(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_HSCROLL)) infoPtr->rcList.bottom -= GetSystemMetrics(SM_CYHSCROLL); infoPtr->rcList.bottom = max (infoPtr->rcList.bottom - 2, 0); } @@ -11431,7 +11458,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, (POINT*)lParam); case LVM_SETITEMSTATE: - if (lParam == 0) return FALSE; return LISTVIEW_SetItemState(infoPtr, (INT)wParam, (LPLVITEMW)lParam); case LVM_SETITEMTEXTA: @@ -11580,9 +11606,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SHOWWINDOW: return LISTVIEW_ShowWindow(infoPtr, wParam, lParam); - case WM_SIZE: - return LISTVIEW_Size(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam)); - case WM_STYLECHANGED: return LISTVIEW_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam); @@ -11614,16 +11637,14 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_WINDOWPOSCHANGED: if (!(((WINDOWPOS *)lParam)->flags & SWP_NOSIZE)) { - SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | - SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | + SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE); - if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (infoPtr->uView == LV_VIEW_DETAILS)) - { - if (notify_measureitem(infoPtr)) LISTVIEW_InvalidateList(infoPtr); - } - - LISTVIEW_UpdateSize(infoPtr); - LISTVIEW_UpdateScroll(infoPtr); + if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (infoPtr->uView == LV_VIEW_DETAILS)) + { + if (notify_measureitem(infoPtr)) LISTVIEW_InvalidateList(infoPtr); + } + LISTVIEW_Size(infoPtr, ((WINDOWPOS *)lParam)->cx, ((WINDOWPOS *)lParam)->cy); } return DefWindowProcW(hwnd, uMsg, wParam, lParam); diff --git a/reactos/dll/win32/comctl32/monthcal.c b/reactos/dll/win32/comctl32/monthcal.c index e148a62aa80..f27eee3de3e 100644 --- a/reactos/dll/win32/comctl32/monthcal.c +++ b/reactos/dll/win32/comctl32/monthcal.c @@ -185,7 +185,14 @@ static inline void MONTHCAL_NotifySelectionChange(const MONTHCAL_INFO *infoPtr) nmsc.nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID); nmsc.nmhdr.code = MCN_SELCHANGE; nmsc.stSelStart = infoPtr->minSel; - nmsc.stSelEnd = infoPtr->maxSel; + nmsc.stSelStart.wDayOfWeek = 0; + if(infoPtr->dwStyle & MCS_MULTISELECT){ + nmsc.stSelEnd = infoPtr->maxSel; + nmsc.stSelEnd.wDayOfWeek = 0; + } + else + nmsc.stSelEnd = st_null; + SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmsc.nmhdr.idFrom, (LPARAM)&nmsc); } @@ -198,7 +205,13 @@ static inline void MONTHCAL_NotifySelect(const MONTHCAL_INFO *infoPtr) nmsc.nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID); nmsc.nmhdr.code = MCN_SELECT; nmsc.stSelStart = infoPtr->minSel; - nmsc.stSelEnd = infoPtr->maxSel; + nmsc.stSelStart.wDayOfWeek = 0; + if(infoPtr->dwStyle & MCS_MULTISELECT){ + nmsc.stSelEnd = infoPtr->maxSel; + nmsc.stSelEnd.wDayOfWeek = 0; + } + else + nmsc.stSelEnd = st_null; SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmsc.nmhdr.idFrom, (LPARAM)&nmsc); } @@ -296,7 +309,7 @@ static void MONTHCAL_CopyDate(const SYSTEMTIME *from, SYSTEMTIME *to) * * Note that no date validation performed, already validated values expected. */ -static LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) +LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) { FILETIME ft_first, ft_second; @@ -353,14 +366,17 @@ static BOOL MONTHCAL_IsDateInValidRange(const MONTHCAL_INFO *infoPtr, else if(MONTHCAL_CompareSystemTime(date, &min_allowed_date) == -1) { fix_st = &min_allowed_date; } - else if(infoPtr->rangeValid & GDTR_MAX) { - if((MONTHCAL_CompareSystemTime(date, &infoPtr->maxDate) == 1)) { - fix_st = &infoPtr->maxDate; + else { + if(infoPtr->rangeValid & GDTR_MAX) { + if((MONTHCAL_CompareSystemTime(date, &infoPtr->maxDate) == 1)) { + fix_st = &infoPtr->maxDate; + } } - } - else if(infoPtr->rangeValid & GDTR_MIN) { - if((MONTHCAL_CompareSystemTime(date, &infoPtr->minDate) == -1)) { - fix_st = &infoPtr->minDate; + + if(infoPtr->rangeValid & GDTR_MIN) { + if((MONTHCAL_CompareSystemTime(date, &infoPtr->minDate) == -1)) { + fix_st = &infoPtr->minDate; + } } } @@ -369,7 +385,7 @@ static BOOL MONTHCAL_IsDateInValidRange(const MONTHCAL_INFO *infoPtr, date->wMonth = fix_st->wMonth; } - return fix_st ? FALSE : TRUE; + return !fix_st; } /* Checks passed range width with configured maximum selection count @@ -1273,7 +1289,7 @@ MONTHCAL_SetColor(MONTHCAL_INFO *infoPtr, UINT index, COLORREF color) infoPtr->pens[PenText] = CreatePen(PS_SOLID, 1, infoPtr->colors[index]); } - InvalidateRect(infoPtr->hwndSelf, NULL, index == MCSC_BACKGROUND ? TRUE : FALSE); + InvalidateRect(infoPtr->hwndSelf, NULL, index == MCSC_BACKGROUND); return prev; } diff --git a/reactos/dll/win32/comctl32/pager.c b/reactos/dll/win32/comctl32/pager.c index e1420e06ab5..3b2c11c2c2d 100644 --- a/reactos/dll/win32/comctl32/pager.c +++ b/reactos/dll/win32/comctl32/pager.c @@ -84,9 +84,6 @@ typedef struct INT direction; /* direction of the scroll, (e.g. PGF_SCROLLUP) */ } PAGER_INFO; -#define MIN_ARROW_WIDTH 8 -#define MIN_ARROW_HEIGHT 5 - #define TIMERID1 1 #define TIMERID2 2 #define INITIAL_DELAY 500 @@ -116,115 +113,13 @@ PAGER_GetButtonRects(const PAGER_INFO* infoPtr, RECT* prcTopLeft, RECT* prcBotto } } -/* the horizontal arrows are: - * - * 01234 01234 - * 1 * * - * 2 ** ** - * 3*** *** - * 4*** *** - * 5 ** ** - * 6 * * - * 7 - * - */ static void -PAGER_DrawHorzArrow (HDC hdc, RECT r, INT colorRef, BOOL left) -{ - INT x, y, w, h; - HPEN hPen, hOldPen; - - w = r.right - r.left + 1; - h = r.bottom - r.top + 1; - if ((h < MIN_ARROW_WIDTH) || (w < MIN_ARROW_HEIGHT)) - return; /* refuse to draw partial arrow */ - - if (!(hPen = CreatePen( PS_SOLID, 1, GetSysColor( colorRef )))) return; - hOldPen = SelectObject ( hdc, hPen ); - if (left) - { - x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 3; - y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 1; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x--, y+5); y++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x--, y+3); y++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x, y+1); - } - else - { - x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 1; - y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 1; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x++, y+5); y++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x++, y+3); y++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x, y+1); - } - - SelectObject( hdc, hOldPen ); - DeleteObject( hPen ); -} - -/* the vertical arrows are: - * - * 01234567 01234567 - * 1****** ** - * 2 **** **** - * 3 ** ****** - * 4 - * - */ -static void -PAGER_DrawVertArrow (HDC hdc, RECT r, INT colorRef, BOOL up) -{ - INT x, y, w, h; - HPEN hPen, hOldPen; - - w = r.right - r.left + 1; - h = r.bottom - r.top + 1; - if ((h < MIN_ARROW_WIDTH) || (w < MIN_ARROW_HEIGHT)) - return; /* refuse to draw partial arrow */ - - if (!(hPen = CreatePen( PS_SOLID, 1, GetSysColor( colorRef )))) return; - hOldPen = SelectObject ( hdc, hPen ); - if (up) - { - x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 1; - y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 3; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x+5, y--); x++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x+3, y--); x++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x+1, y); - } - else - { - x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 1; - y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 1; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x+5, y++); x++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x+3, y++); x++; - MoveToEx (hdc, x, y, NULL); - LineTo (hdc, x+1, y); - } - - SelectObject( hdc, hOldPen ); - DeleteObject( hPen ); -} - -static void -PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT arrowRect, +PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT rc, BOOL horz, BOOL topLeft, INT btnState) { - HBRUSH hBrush, hOldBrush; - RECT rc = arrowRect; + UINT flags; - TRACE("arrowRect = %s, btnState = %d\n", wine_dbgstr_rect(&arrowRect), btnState); + TRACE("rc = %s, btnState = %d\n", wine_dbgstr_rect(&rc), btnState); if (btnState == PGF_INVISIBLE) return; @@ -232,54 +127,26 @@ PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT arrowRect, if ((rc.right - rc.left <= 0) || (rc.bottom - rc.top <= 0)) return; - hBrush = CreateSolidBrush(clrBk); - hOldBrush = SelectObject(hdc, hBrush); + if (horz) + flags = topLeft ? DFCS_SCROLLLEFT : DFCS_SCROLLRIGHT; + else + flags = topLeft ? DFCS_SCROLLUP : DFCS_SCROLLDOWN; - FillRect(hdc, &rc, hBrush); - - if (btnState == PGF_HOT) + switch (btnState) { - DrawEdge( hdc, &rc, BDR_RAISEDINNER, BF_RECT); - if (horz) - PAGER_DrawHorzArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft); - else - PAGER_DrawVertArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft); + case PGF_HOT: + break; + case PGF_NORMAL: + flags |= DFCS_FLAT; + break; + case PGF_DEPRESSED: + flags |= DFCS_PUSHED; + break; + case PGF_GRAYED: + flags |= DFCS_INACTIVE | DFCS_FLAT; + break; } - else if (btnState == PGF_NORMAL) - { - DrawEdge (hdc, &rc, BDR_OUTER, BF_FLAT); - if (horz) - PAGER_DrawHorzArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft); - else - PAGER_DrawVertArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft); - } - else if (btnState == PGF_DEPRESSED) - { - DrawEdge( hdc, &rc, BDR_SUNKENOUTER, BF_RECT); - if (horz) - PAGER_DrawHorzArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft); - else - PAGER_DrawVertArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft); - } - else if (btnState == PGF_GRAYED) - { - DrawEdge (hdc, &rc, BDR_OUTER, BF_FLAT); - if (horz) - { - PAGER_DrawHorzArrow(hdc, rc, COLOR_3DHIGHLIGHT, topLeft); - rc.left++, rc.top++; rc.right++, rc.bottom++; - PAGER_DrawHorzArrow(hdc, rc, COLOR_3DSHADOW, topLeft); - } - else - { - PAGER_DrawVertArrow(hdc, rc, COLOR_3DHIGHLIGHT, topLeft); - rc.left++, rc.top++; rc.right++, rc.bottom++; - PAGER_DrawVertArrow(hdc, rc, COLOR_3DSHADOW, topLeft); - } - } - - SelectObject( hdc, hOldBrush ); - DeleteObject(hBrush); + DrawFrameControl( hdc, &rc, DFC_SCROLL, flags ); } /* << PAGER_GetDropTarget >> */ @@ -338,22 +205,24 @@ PAGER_GetBkColor(const PAGER_INFO *infoPtr) } static void -PAGER_CalcSize (const PAGER_INFO *infoPtr, INT* size, BOOL getWidth) +PAGER_CalcSize( PAGER_INFO *infoPtr ) { NMPGCALCSIZE nmpgcs; ZeroMemory (&nmpgcs, sizeof (NMPGCALCSIZE)); nmpgcs.hdr.hwndFrom = infoPtr->hwndSelf; nmpgcs.hdr.idFrom = GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_ID); nmpgcs.hdr.code = PGN_CALCSIZE; - nmpgcs.dwFlag = getWidth ? PGF_CALCWIDTH : PGF_CALCHEIGHT; - nmpgcs.iWidth = getWidth ? *size : 0; - nmpgcs.iHeight = getWidth ? 0 : *size; + nmpgcs.dwFlag = (infoPtr->dwStyle & PGS_HORZ) ? PGF_CALCWIDTH : PGF_CALCHEIGHT; + nmpgcs.iWidth = infoPtr->nWidth; + nmpgcs.iHeight = infoPtr->nHeight; SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, nmpgcs.hdr.idFrom, (LPARAM)&nmpgcs); - *size = getWidth ? nmpgcs.iWidth : nmpgcs.iHeight; + if (infoPtr->dwStyle & PGS_HORZ) + infoPtr->nWidth = nmpgcs.iWidth; + else + infoPtr->nHeight = nmpgcs.iHeight; - TRACE("[%p] PGN_CALCSIZE returns %s=%d\n", infoPtr->hwndSelf, - getWidth ? "width" : "height", *size); + TRACE("[%p] PGN_CALCSIZE returns %dx%d\n", infoPtr->hwndSelf, nmpgcs.iWidth, nmpgcs.iHeight ); } static void @@ -414,16 +283,15 @@ PAGER_GetScrollRange(PAGER_INFO* infoPtr) RECT wndRect; GetWindowRect(infoPtr->hwndSelf, &wndRect); + PAGER_CalcSize(infoPtr); if (infoPtr->dwStyle & PGS_HORZ) { wndSize = wndRect.right - wndRect.left; - PAGER_CalcSize(infoPtr, &infoPtr->nWidth, TRUE); childSize = infoPtr->nWidth; } else { wndSize = wndRect.bottom - wndRect.top; - PAGER_CalcSize(infoPtr, &infoPtr->nHeight, FALSE); childSize = infoPtr->nHeight; } @@ -447,9 +315,10 @@ PAGER_UpdateBtns(PAGER_INFO *infoPtr, INT scrollRange, BOOL hideGrayBtns) RECT rcTopLeft, rcBottomRight; /* get button rects */ - PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, FALSE); + PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, TRUE); GetCursorPos(&pt); + ScreenToClient( infoPtr->hwndSelf, &pt ); /* update states based on scroll position */ if (infoPtr->nPos > 0) @@ -457,7 +326,7 @@ PAGER_UpdateBtns(PAGER_INFO *infoPtr, INT scrollRange, BOOL hideGrayBtns) if (infoPtr->TLbtnState == PGF_INVISIBLE || infoPtr->TLbtnState == PGF_GRAYED) infoPtr->TLbtnState = PGF_NORMAL; } - else if (PtInRect(&rcTopLeft, pt)) + else if (!hideGrayBtns && PtInRect(&rcTopLeft, pt)) infoPtr->TLbtnState = PGF_GRAYED; else infoPtr->TLbtnState = PGF_INVISIBLE; @@ -472,7 +341,7 @@ PAGER_UpdateBtns(PAGER_INFO *infoPtr, INT scrollRange, BOOL hideGrayBtns) if (infoPtr->BRbtnState == PGF_INVISIBLE || infoPtr->BRbtnState == PGF_GRAYED) infoPtr->BRbtnState = PGF_NORMAL; } - else if (PtInRect(&rcBottomRight, pt)) + else if (!hideGrayBtns && PtInRect(&rcBottomRight, pt)) infoPtr->BRbtnState = PGF_GRAYED; else infoPtr->BRbtnState = PGF_INVISIBLE; @@ -547,68 +416,6 @@ PAGER_WindowPosChanging(PAGER_INFO* infoPtr, WINDOWPOS *winpos) return DefWindowProcW (infoPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos); } -static INT -PAGER_SetFixedWidth(PAGER_INFO* infoPtr) -{ - /* Must set the non-scrollable dimension to be less than the full height/width - * so that NCCalcSize is called. The Microsoft docs mention 3/4 factor for button - * size, and experimentation shows that the effect is almost right. */ - - RECT wndRect; - INT delta, h; - GetWindowRect(infoPtr->hwndSelf, &wndRect); - - /* see what the app says for btn width */ - PAGER_CalcSize(infoPtr, &infoPtr->nWidth, TRUE); - - if (infoPtr->dwStyle & CCS_NORESIZE) - { - delta = wndRect.right - wndRect.left - infoPtr->nWidth; - if (delta > infoPtr->nButtonSize) - infoPtr->nWidth += 4 * infoPtr->nButtonSize / 3; - else if (delta > 0) - infoPtr->nWidth += infoPtr->nButtonSize / 3; - } - - h = wndRect.bottom - wndRect.top + infoPtr->nButtonSize; - - TRACE("[%p] infoPtr->nWidth set to %d\n", - infoPtr->hwndSelf, infoPtr->nWidth); - - return h; -} - -static INT -PAGER_SetFixedHeight(PAGER_INFO* infoPtr) -{ - /* Must set the non-scrollable dimension to be less than the full height/width - * so that NCCalcSize is called. The Microsoft docs mention 3/4 factor for button - * size, and experimentation shows that the effect is almost right. */ - - RECT wndRect; - INT delta, w; - GetWindowRect(infoPtr->hwndSelf, &wndRect); - - /* see what the app says for btn height */ - PAGER_CalcSize(infoPtr, &infoPtr->nHeight, FALSE); - - if (infoPtr->dwStyle & CCS_NORESIZE) - { - delta = wndRect.bottom - wndRect.top - infoPtr->nHeight; - if (delta > infoPtr->nButtonSize) - infoPtr->nHeight += infoPtr->nButtonSize; - else if (delta > 0) - infoPtr->nHeight += infoPtr->nButtonSize / 3; - } - - w = wndRect.right - wndRect.left + infoPtr->nButtonSize; - - TRACE("[%p] infoPtr->nHeight set to %d\n", - infoPtr->hwndSelf, infoPtr->nHeight); - - return w; -} - /****************************************************************** * For the PGM_RECALCSIZE message (but not the other uses in * * this module), the native control does only the following: * @@ -693,28 +500,14 @@ PAGER_SetButtonSize (PAGER_INFO* infoPtr, INT iButtonSize) static LRESULT PAGER_SetChild (PAGER_INFO* infoPtr, HWND hwndChild) { - INT hw; - infoPtr->hwndChild = IsWindow (hwndChild) ? hwndChild : 0; if (infoPtr->hwndChild) { TRACE("[%p] hwndChild=%p\n", infoPtr->hwndSelf, infoPtr->hwndChild); - if (infoPtr->dwStyle & PGS_HORZ) { - hw = PAGER_SetFixedHeight(infoPtr); - /* adjust non-scrollable dimension to fit the child */ - SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, hw, infoPtr->nHeight, - SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | - SWP_NOSIZE | SWP_NOACTIVATE); - } - else { - hw = PAGER_SetFixedWidth(infoPtr); - /* adjust non-scrollable dimension to fit the child */ - SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, infoPtr->nWidth, hw, - SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | - SWP_NOSIZE | SWP_NOACTIVATE); - } + SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); /* position child within the page scroller */ SetWindowPos(infoPtr->hwndChild, HWND_TOP, @@ -853,11 +646,12 @@ PAGER_NCCalcSize(PAGER_INFO* infoPtr, WPARAM wParam, LPRECT lpRect) MapWindowPoints (0, infoPtr->hwndSelf, (LPPOINT)&rcChild, 2); /* FIXME: RECT != 2 POINTS */ GetWindowRect (infoPtr->hwndSelf, &rcWindow); + infoPtr->nWidth = lpRect->right - lpRect->left; + infoPtr->nHeight = lpRect->bottom - lpRect->top; + PAGER_CalcSize( infoPtr ); + if (infoPtr->dwStyle & PGS_HORZ) { - infoPtr->nWidth = lpRect->right - lpRect->left; - PAGER_CalcSize (infoPtr, &infoPtr->nWidth, TRUE); - if (infoPtr->TLbtnState && (lpRect->left + infoPtr->nButtonSize < lpRect->right)) lpRect->left += infoPtr->nButtonSize; if (infoPtr->BRbtnState && (lpRect->right - infoPtr->nButtonSize > lpRect->left)) @@ -865,9 +659,6 @@ PAGER_NCCalcSize(PAGER_INFO* infoPtr, WPARAM wParam, LPRECT lpRect) } else { - infoPtr->nHeight = lpRect->bottom - lpRect->top; - PAGER_CalcSize (infoPtr, &infoPtr->nHeight, FALSE); - if (infoPtr->TLbtnState && (lpRect->top + infoPtr->nButtonSize < lpRect->bottom)) lpRect->top += infoPtr->nButtonSize; if (infoPtr->BRbtnState && (lpRect->bottom - infoPtr->nButtonSize > lpRect->top)) diff --git a/reactos/dll/win32/comctl32/progress.c b/reactos/dll/win32/comctl32/progress.c index d331d19a591..aba53027873 100644 --- a/reactos/dll/win32/comctl32/progress.c +++ b/reactos/dll/win32/comctl32/progress.c @@ -745,7 +745,7 @@ void PROGRESS_Register (void) ZeroMemory (&wndClass, sizeof(wndClass)); wndClass.style = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; - wndClass.lpfnWndProc = (WNDPROC)ProgressWindowProc; + wndClass.lpfnWndProc = ProgressWindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof (PROGRESS_INFO *); wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW); diff --git a/reactos/dll/win32/comctl32/propsheet.c b/reactos/dll/win32/comctl32/propsheet.c index 465c825167e..6547e3f1217 100644 --- a/reactos/dll/win32/comctl32/propsheet.c +++ b/reactos/dll/win32/comctl32/propsheet.c @@ -171,6 +171,7 @@ static BOOL PROPSHEET_SetCurSel(HWND hwndDlg, static int PROPSHEET_GetPageIndex(HPROPSHEETPAGE hpage, const PropSheetInfo* psInfo); static PADDING_INFO PROPSHEET_GetPaddingInfoWizard(HWND hwndDlg, const PropSheetInfo* psInfo); static BOOL PROPSHEET_DoCommand(HWND hwnd, WORD wID); +static BOOL PROPSHEET_RemovePage(HWND hwndDlg, int index, HPROPSHEETPAGE hpage); static INT_PTR CALLBACK PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -554,13 +555,12 @@ static BOOL PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEW lppsp, if (IS_INTRESOURCE( lppsp->pszTitle )) { - if (!LoadStringW( lppsp->hInstance, (DWORD_PTR)lppsp->pszTitle,szTitle,sizeof(szTitle)/sizeof(szTitle[0]) )) - { - pTitle = pszNull; - FIXME("Could not load resource #%04x?\n",LOWORD(lppsp->pszTitle)); - } - else + if (LoadStringW( lppsp->hInstance, (DWORD_PTR)lppsp->pszTitle, szTitle, sizeof(szTitle)/sizeof(szTitle[0]) )) pTitle = szTitle; + else if (*p) + pTitle = p; + else + pTitle = pszNull; } else pTitle = lppsp->pszTitle; @@ -1173,7 +1173,7 @@ static BOOL PROPSHEET_CreateTabControl(HWND hwndParent, SendMessageW(hwndTabCtrl, TCM_SETIMAGELIST, 0, (LPARAM)psInfo->hImageList); } - SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 0, 0); + SendMessageW(hwndTabCtrl, WM_SETREDRAW, 0, 0); for (i = 0; i < nTabs; i++) { if ( psInfo->proppage[i].hasIcon ) @@ -1189,7 +1189,7 @@ static BOOL PROPSHEET_CreateTabControl(HWND hwndParent, item.pszText = (LPWSTR) psInfo->proppage[i].pszText; SendMessageW(hwndTabCtrl, TCM_INSERTITEMW, i, (LPARAM)&item); } - SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 1, 0); + SendMessageW(hwndTabCtrl, WM_SETREDRAW, 1, 0); return TRUE; } @@ -1474,6 +1474,9 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent, /* Free a no more needed copy */ Free(pTemplateCopy); + if(!hwndPage) + return FALSE; + psInfo->proppage[index].hwndPage = hwndPage; /* Subclass exterior wizard pages */ @@ -2025,7 +2028,14 @@ static BOOL PROPSHEET_SetCurSel(HWND hwndDlg, psn.lParam = 0; if (!psInfo->proppage[index].hwndPage) { - PROPSHEET_CreatePage(hwndDlg, index, psInfo, ppshpage); + if(!PROPSHEET_CreatePage(hwndDlg, index, psInfo, ppshpage)) { + PROPSHEET_RemovePage(hwndDlg, index, NULL); + if(index >= psInfo->nPages) + index--; + if(index < 0) + return FALSE; + continue; + } } /* Resize the property sheet page to the fit in the Tab control @@ -2273,7 +2283,8 @@ static BOOL PROPSHEET_AddPage(HWND hwndDlg, if (ppsp->dwFlags & PSP_PREMATURE) { /* Create the page but don't show it */ - PROPSHEET_CreatePage(hwndDlg, psInfo->nPages, psInfo, ppsp); + if(!PROPSHEET_CreatePage(hwndDlg, psInfo->nPages, psInfo, ppsp)) + return FALSE; } /* diff --git a/reactos/dll/win32/comctl32/rebar.c b/reactos/dll/win32/comctl32/rebar.c index 1b86631f337..d15c7361fa4 100644 --- a/reactos/dll/win32/comctl32/rebar.c +++ b/reactos/dll/win32/comctl32/rebar.c @@ -2135,8 +2135,10 @@ REBAR_HandleUDDrag (REBAR_INFO *infoPtr, const POINT *ptsmove) if(yOff < 0) { /* Place the band above the current top row */ + if(iHitBand==0 && (infoPtr->uNumBands==1 || REBAR_GetBand(infoPtr, 1)->fStyle&RBBS_BREAK)) + return; DPA_DeletePtr(infoPtr->bands, iHitBand); - hitBand->fStyle &= RBBS_BREAK; + hitBand->fStyle &= ~RBBS_BREAK; REBAR_GetBand(infoPtr, 0)->fStyle |= RBBS_BREAK; infoPtr->iGrabbedBand = DPA_InsertPtr( infoPtr->bands, 0, hitBand); @@ -2144,6 +2146,8 @@ REBAR_HandleUDDrag (REBAR_INFO *infoPtr, const POINT *ptsmove) else if(yOff > REBAR_GetBand(infoPtr, infoPtr->uNumBands - 1)->rcBand.bottom) { /* Place the band below the current bottom row */ + if(iHitBand == infoPtr->uNumBands-1 && hitBand->fStyle&RBBS_BREAK) + return; DPA_DeletePtr(infoPtr->bands, iHitBand); hitBand->fStyle |= RBBS_BREAK; infoPtr->iGrabbedBand = DPA_InsertPtr( diff --git a/reactos/dll/win32/comctl32/status.c b/reactos/dll/win32/comctl32/status.c index 43b65aa814c..19d671d8324 100644 --- a/reactos/dll/win32/comctl32/status.c +++ b/reactos/dll/win32/comctl32/status.c @@ -1284,7 +1284,7 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return STATUSBAR_WMGetText (infoPtr, (INT)wParam, (LPWSTR)lParam); case WM_GETTEXTLENGTH: - return STATUSBAR_GetTextLength (infoPtr, 0); + return LOWORD(STATUSBAR_GetTextLength (infoPtr, 0)); case WM_LBUTTONDBLCLK: return STATUSBAR_SendMouseNotify(infoPtr, NM_DBLCLK, msg, wParam, lParam); diff --git a/reactos/dll/win32/comctl32/string.c b/reactos/dll/win32/comctl32/string.c index 7fead7ccc81..a9544fa8d23 100644 --- a/reactos/dll/win32/comctl32/string.c +++ b/reactos/dll/win32/comctl32/string.c @@ -77,7 +77,7 @@ static BOOL COMCTL32_ChrCmpHelperA(WORD ch1, WORD ch2, DWORD dwFlags) else str2[1] = '\0'; - return CompareStringA(GetThreadLocale(), dwFlags, str1, -1, str2, -1) - 2; + return CompareStringA(GetThreadLocale(), dwFlags, str1, -1, str2, -1) - CSTR_EQUAL; } /************************************************************************* @@ -117,7 +117,7 @@ static BOOL COMCTL32_ChrCmpIA(WORD ch1, WORD ch2) */ static inline BOOL COMCTL32_ChrCmpIW(WCHAR ch1, WCHAR ch2) { - return CompareStringW(GetThreadLocale(), NORM_IGNORECASE, &ch1, 1, &ch2, 1) - 2; + return CompareStringW(GetThreadLocale(), NORM_IGNORECASE, &ch1, 1, &ch2, 1) - CSTR_EQUAL; } /************************************************************************** @@ -299,12 +299,8 @@ LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch) */ INT WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen) { - INT iRet; - TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen); - - iRet = CompareStringA(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen); - return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0; + return CompareStringA(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL; } /************************************************************************* @@ -314,12 +310,8 @@ INT WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen) */ INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen) { - INT iRet; - TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen); - - iRet = CompareStringW(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen); - return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0; + return CompareStringW(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL; } /************************************************************************* @@ -496,12 +488,8 @@ LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch) */ INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen) { - INT iRet; - TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen); - - iRet = CompareStringA(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen); - return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0; + return CompareStringA(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL; } /************************************************************************** @@ -511,12 +499,8 @@ INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen) */ INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen) { - INT iRet; - TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen); - - iRet = CompareStringW(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen); - return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0; + return CompareStringW(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen) - CSTR_EQUAL; } /************************************************************************** @@ -877,10 +861,11 @@ BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp, TRACE("(%d,%s,%s,%d)\n", bCase, debugstr_a(lpszStr), debugstr_a(lpszComp), iLen); - /* FIXME: These flags are undocumented and unknown by our CompareString. - * We need defines for them. + /* FIXME: This flag is undocumented and unknown by our CompareString. + * We need a define for it. */ - dwFlags |= bCase ? 0x10000000 : 0x10000001; + dwFlags = 0x10000000; + if (!bCase) dwFlags |= NORM_IGNORECASE; iRet = CompareStringA(GetThreadLocale(), dwFlags, lpszStr, iLen, lpszComp, iLen); @@ -888,7 +873,7 @@ BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp, if (!iRet) iRet = CompareStringA(2048, dwFlags, lpszStr, iLen, lpszComp, iLen); - return iRet == 2 ? TRUE : FALSE; + return iRet == CSTR_EQUAL; } /************************************************************************* @@ -905,10 +890,11 @@ BOOL WINAPI IntlStrEqWorkerW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp, TRACE("(%d,%s,%s,%d)\n", bCase, debugstr_w(lpszStr),debugstr_w(lpszComp), iLen); - /* FIXME: These flags are undocumented and unknown by our CompareString. - * We need defines for them. + /* FIXME: This flag is undocumented and unknown by our CompareString. + * We need a define for it. */ - dwFlags = bCase ? 0x10000000 : 0x10000001; + dwFlags = 0x10000000; + if (!bCase) dwFlags |= NORM_IGNORECASE; iRet = CompareStringW(GetThreadLocale(), dwFlags, lpszStr, iLen, lpszComp, iLen); @@ -916,5 +902,5 @@ BOOL WINAPI IntlStrEqWorkerW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp, if (!iRet) iRet = CompareStringW(2048, dwFlags, lpszStr, iLen, lpszComp, iLen); - return iRet == 2 ? TRUE : FALSE; + return iRet == CSTR_EQUAL; } diff --git a/reactos/dll/win32/comctl32/tab.c b/reactos/dll/win32/comctl32/tab.c index ad27b8a18d5..43d8cdf353c 100644 --- a/reactos/dll/win32/comctl32/tab.c +++ b/reactos/dll/win32/comctl32/tab.c @@ -2879,14 +2879,13 @@ static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem) if (iItem < 0 || iItem >= infoPtr->uNumItem) return FALSE; + TAB_InvalidateTabArea(infoPtr); item = TAB_GetItem(infoPtr, iItem); Free(item->pszText); Free(item); infoPtr->uNumItem--; DPA_DeletePtr(infoPtr->items, iItem); - TAB_InvalidateTabArea(infoPtr); - if (infoPtr->uNumItem == 0) { if (infoPtr->iHotTracked >= 0) @@ -3021,7 +3020,7 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam) TEXTMETRICW fontMetrics; HDC hdc; HFONT hOldFont; - DWORD dwStyle; + DWORD style; infoPtr = Alloc (sizeof(TAB_INFO)); @@ -3055,11 +3054,13 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam) /* The tab control always has the WS_CLIPSIBLINGS style. Even if you don't specify it in CreateWindow. This is necessary in order for paint to work correctly. This follows windows behaviour. */ - dwStyle = GetWindowLongW(hwnd, GWL_STYLE); - SetWindowLongW(hwnd, GWL_STYLE, dwStyle|WS_CLIPSIBLINGS); + style = GetWindowLongW(hwnd, GWL_STYLE); + if (style & TCS_VERTICAL) style |= TCS_MULTILINE; + style |= WS_CLIPSIBLINGS; + SetWindowLongW(hwnd, GWL_STYLE, style); - infoPtr->dwStyle = dwStyle | WS_CLIPSIBLINGS; - infoPtr->exStyle = (dwStyle & TCS_FLATBUTTONS) ? TCS_EX_FLATSEPARATORS : 0; + infoPtr->dwStyle = style; + infoPtr->exStyle = (style & TCS_FLATBUTTONS) ? TCS_EX_FLATSEPARATORS : 0; if (infoPtr->dwStyle & TCS_TOOLTIPS) { /* Create tooltip control */ diff --git a/reactos/dll/win32/comctl32/toolbar.c b/reactos/dll/win32/comctl32/toolbar.c index bd35533c425..c26d70e6063 100644 --- a/reactos/dll/win32/comctl32/toolbar.c +++ b/reactos/dll/win32/comctl32/toolbar.c @@ -217,9 +217,6 @@ typedef enum #define TOOLBAR_NOWHERE (-1) -#define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE) -#define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE) - /* Used to find undocumented extended styles */ #define TBSTYLE_EX_ALL (TBSTYLE_EX_DRAWDDARROWS | \ TBSTYLE_EX_UNDOC1 | \ @@ -258,6 +255,11 @@ static inline int default_top_margin(const TOOLBAR_INFO *infoPtr) return (infoPtr->dwStyle & TBSTYLE_FLAT ? 0 : TOP_BORDER); } +static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle) +{ + return (exStyle & TBSTYLE_EX_DRAWDDARROWS) != 0; +} + static LPWSTR TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr) { @@ -428,7 +430,7 @@ TOOLBAR_GetImageListForDrawing (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPt if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) { if (btnPtr->iBitmap == I_IMAGENONE) return NULL; - ERR("bitmap for ID %d, index %d is not valid, number of bitmaps in imagelist: %d\n", + WARN("bitmap for ID %d, index %d is not valid, number of bitmaps in imagelist: %d\n", HIWORD(btnPtr->iBitmap), LOWORD(btnPtr->iBitmap), infoPtr->nNumBitmaps); return NULL; } @@ -1247,7 +1249,7 @@ TOOLBAR_CalcStrings (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize) btnPtr = infoPtr->buttons; for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) { - if(TOOLBAR_HasText(infoPtr, btnPtr)) + if(TOOLBAR_GetText(infoPtr, btnPtr)) { TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz); if (sz.cx > lpSize->cx) @@ -1775,11 +1777,14 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr) static INT -TOOLBAR_InternalHitTest (const TOOLBAR_INFO *infoPtr, const POINT *lpPt) +TOOLBAR_InternalHitTest (const TOOLBAR_INFO *infoPtr, const POINT *lpPt, BOOL *button) { TBUTTON_INFO *btnPtr; INT i; + if (button) + *button = FALSE; + btnPtr = infoPtr->buttons; for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) { if (btnPtr->fsState & TBSTATE_HIDDEN) @@ -1794,6 +1799,8 @@ TOOLBAR_InternalHitTest (const TOOLBAR_INFO *infoPtr, const POINT *lpPt) else { if (PtInRect (&btnPtr->rect, *lpPt)) { TRACE(" ON BUTTON %d!\n", i); + if (button) + *button = TRUE; return i; } } @@ -2399,7 +2406,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) nmtb.tbButton.iString >= 0 ? debugstr_w(infoPtr->strings[nmtb.tbButton.iString]) : ""); - /* insert button into the apropriate list */ + /* insert button into the appropriate list */ index = TOOLBAR_GetButtonIndex (custInfo->tbInfo, nmtb.tbButton.idCommand, FALSE); if (index == -1) { @@ -3133,7 +3140,7 @@ TOOLBAR_CheckButton (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam) btnPtr = &infoPtr->buttons[nIndex]; - bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE; + bChecked = (btnPtr->fsState & TBSTATE_CHECKED) != 0; if (LOWORD(lParam) == FALSE) btnPtr->fsState &= ~TBSTATE_CHECKED; @@ -3664,7 +3671,7 @@ TOOLBAR_HideButton (TOOLBAR_INFO *infoPtr, INT Id, BOOL fHide) static inline LRESULT TOOLBAR_HitTest (const TOOLBAR_INFO *infoPtr, const POINT* lpPt) { - return TOOLBAR_InternalHitTest (infoPtr, lpPt); + return TOOLBAR_InternalHitTest (infoPtr, lpPt, NULL); } @@ -4481,20 +4488,22 @@ TOOLBAR_SetDrawTextFlags (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) * (MSDN says that this parameter is reserved) */ static LRESULT -TOOLBAR_SetExtendedStyle (TOOLBAR_INFO *infoPtr, LPARAM lParam) +TOOLBAR_SetExtendedStyle (TOOLBAR_INFO *infoPtr, DWORD mask, DWORD style) { - DWORD dwOldStyle; + DWORD old_style = infoPtr->dwExStyle; - dwOldStyle = infoPtr->dwExStyle; - infoPtr->dwExStyle = (DWORD)lParam; + TRACE("mask=0x%08x, style=0x%08x\n", mask, style); - TRACE("new style 0x%08x\n", infoPtr->dwExStyle); + if (mask) + infoPtr->dwExStyle = (old_style & ~mask) | (style & mask); + else + infoPtr->dwExStyle = style; if (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL) FIXME("Unknown Toolbar Extended Style 0x%08x. Please report.\n", (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL)); - if ((dwOldStyle ^ infoPtr->dwExStyle) & TBSTYLE_EX_MIXEDBUTTONS) + if ((old_style ^ infoPtr->dwExStyle) & TBSTYLE_EX_MIXEDBUTTONS) TOOLBAR_CalcToolbar(infoPtr); else TOOLBAR_LayoutToolbar(infoPtr); @@ -4502,7 +4511,7 @@ TOOLBAR_SetExtendedStyle (TOOLBAR_INFO *infoPtr, LPARAM lParam) TOOLBAR_AutoSize(infoPtr); InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); - return (LRESULT)dwOldStyle; + return old_style; } @@ -5155,7 +5164,7 @@ TOOLBAR_Create (HWND hwnd, const CREATESTRUCTW *lpcs) TRACE("hwnd = %p, style=0x%08x\n", hwnd, lpcs->style); - infoPtr->dwStyle = lpcs->style; + infoPtr->dwStyle = GetWindowLongW(hwnd, GWL_STYLE); GetClientRect(hwnd, &infoPtr->client_rect); infoPtr->bUnicode = infoPtr->hwndNotify && (NFR_UNICODE == SendMessageW(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_REQUERY)); @@ -5374,13 +5383,13 @@ static LRESULT TOOLBAR_LButtonDblClk (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { POINT pt; - INT nHit; + BOOL button; pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - nHit = TOOLBAR_InternalHitTest (infoPtr, &pt); + TOOLBAR_InternalHitTest (infoPtr, &pt, &button); - if (nHit >= 0) + if (button) TOOLBAR_LButtonDown (infoPtr, wParam, lParam); else if (infoPtr->dwStyle & CCS_ADJUSTABLE) TOOLBAR_Customize (infoPtr); @@ -5398,6 +5407,7 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) NMTOOLBARA nmtb; NMMOUSE nmmouse; BOOL bDragKeyPressed; + BOOL button; TRACE("\n"); @@ -5412,11 +5422,12 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - nHit = TOOLBAR_InternalHitTest (infoPtr, &pt); + nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button); - btnPtr = &infoPtr->buttons[nHit]; + if (button) + btnPtr = &infoPtr->buttons[nHit]; - if ((nHit >= 0) && bDragKeyPressed && (infoPtr->dwStyle & CCS_ADJUSTABLE)) + if (button && bDragKeyPressed && (infoPtr->dwStyle & CCS_ADJUSTABLE)) { infoPtr->nButtonDrag = nHit; SetCapture (infoPtr->hwndSelf); @@ -5427,7 +5438,7 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) hCursorDrag = LoadCursorW(COMCTL32_hModule, (LPCWSTR)IDC_MOVEBUTTON); SetCursor(hCursorDrag); } - else if (nHit >= 0) + else if (button) { RECT arrowRect; infoPtr->nOldHit = nHit; @@ -5474,9 +5485,9 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) * NOTE: native doesn't do this, but that is a bug */ GetCursorPos(&pt); ScreenToClient(infoPtr->hwndSelf, &pt); - nHit = TOOLBAR_InternalHitTest(infoPtr, &pt); - if (!infoPtr->bAnchor || (nHit >= 0)) - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE); + nHit = TOOLBAR_InternalHitTest(infoPtr, &pt, &button); + if (!infoPtr->bAnchor || button) + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE); /* remove any left mouse button down or double-click messages * so that we can get a toggle effect on the button */ @@ -5494,7 +5505,7 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) btnPtr->fsState |= TBSTATE_PRESSED; - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE); + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE); if (btnPtr->fsState & TBSTATE_ENABLED) InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE); @@ -5502,7 +5513,7 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) SetCapture (infoPtr->hwndSelf); } - if (nHit >=0) + if (button) { memset(&nmtb, 0, sizeof(nmtb)); nmtb.iItem = btnPtr->idCommand; @@ -5512,7 +5523,7 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) nmmouse.dwHitInfo = nHit; /* !!! Undocumented - sends NM_LDOWN with the NMMOUSE structure. */ - if (nHit < 0) + if (!button) nmmouse.dwItemSpec = -1; else { @@ -5539,6 +5550,7 @@ TOOLBAR_LButtonUp (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) NMHDR hdr; NMMOUSE nmmouse; NMTOOLBARA nmtb; + BOOL button; if (infoPtr->hwndToolTip) TOOLBAR_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwndSelf, @@ -5546,10 +5558,10 @@ TOOLBAR_LButtonUp (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - nHit = TOOLBAR_InternalHitTest (infoPtr, &pt); + nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button); - if (!infoPtr->bAnchor || (nHit >= 0)) - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE); + if (!infoPtr->bAnchor || button) + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE); if (infoPtr->nButtonDrag >= 0) { RECT rcClient; @@ -5609,7 +5621,7 @@ TOOLBAR_LButtonUp (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) } /* button under cursor changed so need to re-set hot item */ - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE); + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE); infoPtr->nButtonDrag = -1; TOOLBAR_SendNotify(&hdr, infoPtr, TBN_TOOLBARCHANGE); @@ -5674,7 +5686,7 @@ TOOLBAR_LButtonUp (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) * NM_CLICK with the NMMOUSE structure. */ nmmouse.dwHitInfo = nHit; - if (nHit < 0) + if (!button) nmmouse.dwItemSpec = -1; else { @@ -5697,14 +5709,15 @@ TOOLBAR_RButtonUp(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) INT nHit; NMMOUSE nmmouse; POINT pt; + BOOL button; pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - nHit = TOOLBAR_InternalHitTest(infoPtr, &pt); + nHit = TOOLBAR_InternalHitTest(infoPtr, &pt, &button); nmmouse.dwHitInfo = nHit; - if (nHit < 0) { + if (!button) { nmmouse.dwItemSpec = -1; } else { nmmouse.dwItemSpec = infoPtr->buttons[nmmouse.dwHitInfo].idCommand; @@ -5803,6 +5816,7 @@ TOOLBAR_MouseMove (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) TRACKMOUSEEVENT trackinfo; INT nHit; TBUTTON_INFO *btnPtr; + BOOL button; if ((infoPtr->dwStyle & TBSTYLE_TOOLTIPS) && (infoPtr->hwndToolTip == NULL)) TOOLBAR_TooltipCreateControl(infoPtr); @@ -5833,11 +5847,11 @@ TOOLBAR_MouseMove (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - nHit = TOOLBAR_InternalHitTest (infoPtr, &pt); + nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button); if (((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf)) - && (!infoPtr->bAnchor || (nHit >= 0))) - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE); + && (!infoPtr->bAnchor || button)) + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE); if (infoPtr->nOldHit != nHit) { @@ -6629,7 +6643,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TOOLBAR_SetDrawTextFlags (infoPtr, wParam, lParam); case TB_SETEXTENDEDSTYLE: - return TOOLBAR_SetExtendedStyle (infoPtr, lParam); + return TOOLBAR_SetExtendedStyle (infoPtr, wParam, lParam); case TB_SETHOTIMAGELIST: return TOOLBAR_SetHotImageList (infoPtr, wParam, (HIMAGELIST)lParam); diff --git a/reactos/dll/win32/comctl32/tooltips.c b/reactos/dll/win32/comctl32/tooltips.c index 6dcc126c1d0..c09b9b8cbe5 100644 --- a/reactos/dll/win32/comctl32/tooltips.c +++ b/reactos/dll/win32/comctl32/tooltips.c @@ -171,6 +171,8 @@ typedef struct #define ICON_HEIGHT 16 #define ICON_WIDTH 16 +#define MAX_TEXT_SIZE_A 80 /* maximum retrieving text size by ANSI message */ + static LRESULT CALLBACK TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uId, DWORD_PTR dwRef); @@ -943,6 +945,22 @@ TOOLTIPS_GetToolFromPoint (const TOOLTIPS_INFO *infoPtr, HWND hwnd, const POINT return -1; } +static inline void +TOOLTIPS_CopyInfoT (const TTTOOL_INFO *toolPtr, TTTOOLINFOW *ti, BOOL isW) +{ + if (ti->lpszText) { + if (toolPtr->lpszText == NULL || + IS_INTRESOURCE(toolPtr->lpszText) || + toolPtr->lpszText == LPSTR_TEXTCALLBACKW) + ti->lpszText = toolPtr->lpszText; + else if (isW) + strcpyW (ti->lpszText, toolPtr->lpszText); + else + /* ANSI version, the buffer is maximum 80 bytes without null. */ + WideCharToMultiByte(CP_ACP, 0, toolPtr->lpszText, -1, + (LPSTR)ti->lpszText, MAX_TEXT_SIZE_A, NULL, NULL); + } +} static BOOL TOOLTIPS_IsWindowActive (HWND hwnd) @@ -1199,8 +1217,7 @@ TOOLTIPS_EnumToolsT (const TOOLTIPS_INFO *infoPtr, UINT uIndex, TTTOOLINFOW *ti, ti->uId = toolPtr->uId; ti->rect = toolPtr->rect; ti->hinst = toolPtr->hinst; -/* ti->lpszText = toolPtr->lpszText; */ - ti->lpszText = NULL; /* FIXME */ + TOOLTIPS_CopyInfoT (toolPtr, ti, isW); if (ti->cbSize >= TTTOOLINFOA_V2_SIZE) ti->lParam = toolPtr->lParam; @@ -1246,8 +1263,7 @@ TOOLTIPS_GetCurrentToolT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL is ti->uFlags = toolPtr->uFlags; ti->rect = toolPtr->rect; ti->hinst = toolPtr->hinst; -/* ti->lpszText = toolPtr->lpszText; */ - ti->lpszText = NULL; /* FIXME */ + TOOLTIPS_CopyInfoT (toolPtr, ti, isW); if (ti->cbSize >= TTTOOLINFOW_V2_SIZE) ti->lParam = toolPtr->lParam; @@ -1328,12 +1344,13 @@ TOOLTIPS_GetTextT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW) /* NB this API is broken, there is no way for the app to determine what size buffer it requires nor a way to specify how long the - one it supplies is. We'll assume it's up to INFOTIPSIZE */ + one it supplies is. According to the test result, it's up to + 80 bytes by the ANSI version. */ buffer[0] = '\0'; TOOLTIPS_GetTipText(infoPtr, nTool, buffer); WideCharToMultiByte(CP_ACP, 0, buffer, -1, (LPSTR)ti->lpszText, - INFOTIPSIZE, NULL, NULL); + MAX_TEXT_SIZE_A, NULL, NULL); } return 0; @@ -1385,8 +1402,7 @@ TOOLTIPS_GetToolInfoT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW) ti->uFlags = toolPtr->uFlags; ti->rect = toolPtr->rect; ti->hinst = toolPtr->hinst; -/* lpToolInfo->lpszText = toolPtr->lpszText; */ - ti->lpszText = NULL; /* FIXME */ + TOOLTIPS_CopyInfoT (toolPtr, ti, isW); if (ti->cbSize >= TTTOOLINFOW_V2_SIZE) ti->lParam = toolPtr->lParam; @@ -1420,8 +1436,7 @@ TOOLTIPS_HitTestT (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit, lptthit->ti.uId = toolPtr->uId; lptthit->ti.rect = toolPtr->rect; lptthit->ti.hinst = toolPtr->hinst; -/* lptthit->ti.lpszText = toolPtr->lpszText; */ - lptthit->ti.lpszText = NULL; /* FIXME */ + TOOLTIPS_CopyInfoT (toolPtr, &lptthit->ti, isW); if (lptthit->ti.cbSize >= TTTOOLINFOW_V2_SIZE) lptthit->ti.lParam = toolPtr->lParam; } diff --git a/reactos/dll/win32/comctl32/trackbar.c b/reactos/dll/win32/comctl32/trackbar.c index 788e21f75c9..99fde1b16b4 100644 --- a/reactos/dll/win32/comctl32/trackbar.c +++ b/reactos/dll/win32/comctl32/trackbar.c @@ -457,7 +457,7 @@ TRACKBAR_AutoPage (TRACKBAR_INFO *infoPtr, POINT clickPoint) TRACKBAR_PageUp(infoPtr); else return FALSE; - infoPtr->flags |= TB_THUMBPOSCHANGED; + TRACKBAR_UpdateThumb (infoPtr); TRACKBAR_InvalidateThumbMove (infoPtr, prevPos, infoPtr->lPos); return TRUE; @@ -1151,10 +1151,13 @@ TRACKBAR_SetPos (TRACKBAR_INFO *infoPtr, BOOL fPosition, LONG lPosition) static inline LRESULT -TRACKBAR_SetRange (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lRange) +TRACKBAR_SetRange (TRACKBAR_INFO *infoPtr, BOOL redraw, LONG range) { - infoPtr->lRangeMin = (SHORT)LOWORD(lRange); - infoPtr->lRangeMax = (SHORT)HIWORD(lRange); + BOOL changed = infoPtr->lRangeMin != (SHORT)LOWORD(range) || + infoPtr->lRangeMax != (SHORT)HIWORD(range); + + infoPtr->lRangeMin = (SHORT)LOWORD(range); + infoPtr->lRangeMax = (SHORT)HIWORD(range); if (infoPtr->lPos < infoPtr->lRangeMin) { infoPtr->lPos = infoPtr->lRangeMin; @@ -1169,15 +1172,20 @@ TRACKBAR_SetRange (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lRange) infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5; if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1; - if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); + if (changed && (infoPtr->dwStyle & TBS_AUTOTICKS)) + TRACKBAR_RecalculateTics (infoPtr); + + if (redraw) TRACKBAR_InvalidateAll(infoPtr); return 0; } static inline LRESULT -TRACKBAR_SetRangeMax (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lMax) +TRACKBAR_SetRangeMax (TRACKBAR_INFO *infoPtr, BOOL redraw, LONG lMax) { + BOOL changed = infoPtr->lRangeMax != lMax; + infoPtr->lRangeMax = lMax; if (infoPtr->lPos > infoPtr->lRangeMax) { infoPtr->lPos = infoPtr->lRangeMax; @@ -1187,15 +1195,20 @@ TRACKBAR_SetRangeMax (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lMax) infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5; if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1; - if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); + if (changed && (infoPtr->dwStyle & TBS_AUTOTICKS)) + TRACKBAR_RecalculateTics (infoPtr); + + if (redraw) TRACKBAR_InvalidateAll(infoPtr); return 0; } static inline LRESULT -TRACKBAR_SetRangeMin (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lMin) +TRACKBAR_SetRangeMin (TRACKBAR_INFO *infoPtr, BOOL redraw, LONG lMin) { + BOOL changed = infoPtr->lRangeMin != lMin; + infoPtr->lRangeMin = lMin; if (infoPtr->lPos < infoPtr->lRangeMin) { infoPtr->lPos = infoPtr->lRangeMin; @@ -1205,7 +1218,10 @@ TRACKBAR_SetRangeMin (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lMin) infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5; if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1; - if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); + if (changed && (infoPtr->dwStyle & TBS_AUTOTICKS)) + TRACKBAR_RecalculateTics (infoPtr); + + if (redraw) TRACKBAR_InvalidateAll(infoPtr); return 0; } @@ -1648,11 +1664,10 @@ TRACKBAR_MouseMove (TRACKBAR_INFO *infoPtr, INT x, INT y) if (dragPos == oldPos) return TRUE; infoPtr->lPos = dragPos; + TRACKBAR_UpdateThumb (infoPtr); - infoPtr->flags |= TB_THUMBPOSCHANGED; notify_with_scroll (infoPtr, TB_THUMBTRACK | (infoPtr->lPos<<16)); - TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, dragPos); UpdateWindow (infoPtr->hwndSelf); diff --git a/reactos/dll/win32/comctl32/treeview.c b/reactos/dll/win32/comctl32/treeview.c index d1ace57bf86..a4800d06229 100644 --- a/reactos/dll/win32/comctl32/treeview.c +++ b/reactos/dll/win32/comctl32/treeview.c @@ -66,44 +66,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(treeview); -enum StateListType -{ - OriginInternal, - OriginUser -}; - /* internal structures */ - -typedef struct _TREEITEM /* HTREEITEM is a _TREEINFO *. */ -{ - HTREEITEM parent; /* handle to parent or 0 if at root */ - HTREEITEM nextSibling; /* handle to next item in list, 0 if last */ - HTREEITEM firstChild; /* handle to first child or 0 if no child */ - - UINT callbackMask; - UINT state; - UINT stateMask; - LPWSTR pszText; - int cchTextMax; - int iImage; - int iSelectedImage; - int iExpandedImage; - int cChildren; - LPARAM lParam; - int iIntegral; /* item height multiplier (1 is normal) */ - int iLevel; /* indentation level:0=root level */ - HTREEITEM lastChild; - HTREEITEM prevSibling; /* handle to prev item in list, 0 if first */ - RECT rect; - LONG linesOffset; - LONG stateOffset; - LONG imageOffset; - LONG textOffset; - LONG textWidth; /* horizontal text extent for pszText */ - LONG visibleOrder; /* visible ordering, 0 is first visible item */ -} TREEVIEW_ITEM; - - typedef struct tagTREEVIEW_INFO { HWND hwnd; @@ -162,7 +125,6 @@ typedef struct tagTREEVIEW_INFO HIMAGELIST himlState; int stateImageHeight; int stateImageWidth; - enum StateListType statehimlType; HDPA items; DWORD lastKeyPressTimestamp; @@ -171,6 +133,35 @@ typedef struct tagTREEVIEW_INFO WCHAR szSearchParam[ MAX_PATH ]; } TREEVIEW_INFO; +typedef struct _TREEITEM /* HTREEITEM is a _TREEINFO *. */ +{ + HTREEITEM parent; /* handle to parent or 0 if at root */ + HTREEITEM nextSibling; /* handle to next item in list, 0 if last */ + HTREEITEM firstChild; /* handle to first child or 0 if no child */ + + UINT callbackMask; + UINT state; + UINT stateMask; + LPWSTR pszText; + int cchTextMax; + int iImage; + int iSelectedImage; + int iExpandedImage; + int cChildren; + LPARAM lParam; + int iIntegral; /* item height multiplier (1 is normal) */ + int iLevel; /* indentation level:0=root level */ + HTREEITEM lastChild; + HTREEITEM prevSibling; /* handle to prev item in list, 0 if first */ + RECT rect; + LONG linesOffset; + LONG stateOffset; + LONG imageOffset; + LONG textOffset; + LONG textWidth; /* horizontal text extent for pszText */ + LONG visibleOrder; /* visible ordering, 0 is first visible item */ + const TREEVIEW_INFO *infoPtr; /* tree data this item belongs to */ +} TREEVIEW_ITEM; /******** Defines that TREEVIEW_ProcessLetterKeys uses ****************/ #define KEY_DELAY 450 @@ -217,7 +208,6 @@ static VOID TREEVIEW_Invalidate(const TREEVIEW_INFO *, const TREEVIEW_ITEM *); static LRESULT TREEVIEW_DoSelectItem(TREEVIEW_INFO *, INT, HTREEITEM, INT); static VOID TREEVIEW_SetFirstVisible(TREEVIEW_INFO *, TREEVIEW_ITEM *, BOOL); static LRESULT TREEVIEW_EnsureVisible(TREEVIEW_INFO *, HTREEITEM, BOOL); -static LRESULT TREEVIEW_RButtonUp(const TREEVIEW_INFO *, const POINT *); static LRESULT TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel); static VOID TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr); static LRESULT TREEVIEW_HScroll(TREEVIEW_INFO *, WPARAM); @@ -858,7 +848,9 @@ static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nC format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY); TRACE("format=%d\n", format); - if (format != NFR_ANSI && format != NFR_UNICODE) return 0; + /* Invalid format returned by NF_QUERY defaults to ANSI*/ + if (format != NFR_ANSI && format != NFR_UNICODE) + format = NFR_ANSI; infoPtr->bNtfUnicode = (format == NFR_UNICODE); @@ -1020,6 +1012,7 @@ TREEVIEW_AllocateItem(const TREEVIEW_INFO *infoPtr) newItem->iImage = 0; newItem->iSelectedImage = 0; newItem->iExpandedImage = (WORD)I_IMAGENONE; + newItem->infoPtr = infoPtr; if (DPA_InsertPtr(infoPtr->items, INT_MAX, newItem) == -1) { @@ -1621,7 +1614,7 @@ TREEVIEW_DeleteItem(TREEVIEW_INFO *infoPtr, HTREEITEM item) static LRESULT TREEVIEW_SetRedraw(TREEVIEW_INFO* infoPtr, WPARAM wParam) { - infoPtr->bRedraw = wParam ? TRUE : FALSE; + infoPtr->bRedraw = wParam != 0; if (infoPtr->bRedraw) { @@ -1793,11 +1786,8 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, UINT type, HIMAGELIST himlNew) infoPtr->himlState = himlNew; if (himlNew) - { ImageList_GetIconSize(himlNew, &infoPtr->stateImageWidth, &infoPtr->stateImageHeight); - infoPtr->statehimlType = OriginUser; - } else { infoPtr->stateImageWidth = 0; @@ -2093,7 +2083,13 @@ TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW) TREEVIEW_ITEM *item = tvItem->hItem; if (!TREEVIEW_ValidItem(infoPtr, item)) - return FALSE; + { + if (!item) return FALSE; + + TRACE("got item from different tree %p, called from %p\n", item->infoPtr, infoPtr); + infoPtr = item->infoPtr; + if (!TREEVIEW_ValidItem(infoPtr, item)) return FALSE; + } TREEVIEW_UpdateDispInfo(infoPtr, item, tvItem->mask); @@ -3243,21 +3239,23 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, RECT scrollRect; LONG scrollDist = 0; TREEVIEW_ITEM *nextItem = NULL, *tmpItem; + BOOL wasExpanded; TRACE("TVE_COLLAPSE %p %s\n", item, TREEVIEW_ItemName(item)); - if (!(item->state & TVIS_EXPANDED)) + if (!TREEVIEW_HasChildren(infoPtr, item)) return FALSE; - if (bUser || !(item->state & TVIS_EXPANDEDONCE)) + if (bUser) TREEVIEW_SendExpanding(infoPtr, item, action); if (item->firstChild == NULL) return FALSE; + wasExpanded = (item->state & TVIS_EXPANDED) != 0; item->state &= ~TVIS_EXPANDED; - if (bUser || !(item->state & TVIS_EXPANDEDONCE)) + if (wasExpanded && bUser) TREEVIEW_SendExpanded(infoPtr, item, action); bSetSelection = (infoPtr->selectedItem != NULL @@ -3338,7 +3336,7 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, bSetFirstVisible ? item : infoPtr->firstVisible, TRUE); - return TRUE; + return wasExpanded; } static BOOL @@ -3353,8 +3351,8 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, TRACE("(%p, %p, partial=%d, %d\n", infoPtr, item, partial, user); - if (item->state & TVIS_EXPANDED) - return TRUE; + if (!TREEVIEW_HasChildren(infoPtr, item)) + return FALSE; tmpItem = item; nextItem = NULL; while (tmpItem) @@ -3820,6 +3818,9 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem) TEXTMETRICW textMetric; TRACE("%p %p\n", hwnd, hItem); + if (!(infoPtr->dwStyle & TVS_EDITLABELS)) + return NULL; + if (!TREEVIEW_ValidItem(infoPtr, hItem)) return NULL; @@ -4050,8 +4051,6 @@ TREEVIEW_TrackMouse(const TREEVIEW_INFO *infoPtr, POINT pt) else if (msg.message >= WM_LBUTTONDOWN && msg.message <= WM_RBUTTONDBLCLK) { - if (msg.message == WM_RBUTTONUP) - TREEVIEW_RButtonUp(infoPtr, &pt); break; } @@ -4267,34 +4266,17 @@ TREEVIEW_RButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) else { SetFocus(infoPtr->hwnd); - TREEVIEW_SendSimpleNotify(infoPtr, NM_RCLICK); + if(!TREEVIEW_SendSimpleNotify(infoPtr, NM_RCLICK)) + { + /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */ + SendMessageW(infoPtr->hwndNotify, WM_CONTEXTMENU, + (WPARAM)infoPtr->hwnd, (LPARAM)GetMessagePos()); + } } return 0; } -static LRESULT -TREEVIEW_RButtonUp(const TREEVIEW_INFO *infoPtr, const POINT *pPt) -{ - TVHITTESTINFO ht; - - ht.pt = *pPt; - - TREEVIEW_HitTest(infoPtr, &ht); - - if (ht.hItem) - { - /* Change to screen coordinate for WM_CONTEXTMENU */ - ClientToScreen(infoPtr->hwnd, &ht.pt); - - /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */ - SendMessageW(infoPtr->hwnd, WM_CONTEXTMENU, - (WPARAM)infoPtr->hwnd, MAKELPARAM(ht.pt.x, ht.pt.y)); - } - return 0; -} - - static LRESULT TREEVIEW_CreateDragImage(TREEVIEW_INFO *infoPtr, LPARAM lParam) { @@ -4975,7 +4957,6 @@ TREEVIEW_InitCheckboxes(TREEVIEW_INFO *infoPtr) int nIndex; infoPtr->himlState = ImageList_Create(16, 16, ILC_COLOR | ILC_MASK, 3, 0); - infoPtr->statehimlType = OriginInternal; hdcScreen = GetDC(0); @@ -5095,10 +5076,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->hwndNotify = lpcs->hwndParent; infoPtr->hwndToolTip = 0; - infoPtr->bNtfUnicode = IsWindowUnicode (hwnd); - - /* Determine what type of notify should be issued */ - /* sets infoPtr->bNtfUnicode */ + /* Determine what type of notify should be issued (sets infoPtr->bNtfUnicode) */ TREEVIEW_NotifyFormat(infoPtr, infoPtr->hwndNotify, NF_REQUERY); if (!(infoPtr->dwStyle & TVS_NOTOOLTIPS)) @@ -5139,8 +5117,6 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr) CloseThemeData (GetWindowTheme (infoPtr->hwnd)); - if (infoPtr->statehimlType == OriginInternal) - ImageList_Destroy(infoPtr->himlState); /* Deassociate treeview from the window before doing anything drastic. */ SetWindowLongPtrW(infoPtr->hwnd, 0, 0); @@ -5269,13 +5245,11 @@ TREEVIEW_KeyDown(TREEVIEW_INFO *infoPtr, WPARAM wParam) break; case VK_ADD: - if (!(prevItem->state & TVIS_EXPANDED)) - TREEVIEW_Expand(infoPtr, prevItem, FALSE, TRUE); + TREEVIEW_Expand(infoPtr, prevItem, FALSE, TRUE); break; case VK_SUBTRACT: - if (prevItem->state & TVIS_EXPANDED) - TREEVIEW_Collapse(infoPtr, prevItem, FALSE, TRUE); + TREEVIEW_Collapse(infoPtr, prevItem, FALSE, TRUE); break; case VK_PRIOR: diff --git a/reactos/include/psdk/commctrl.h b/reactos/include/psdk/commctrl.h index 591b8374248..64326f99065 100644 --- a/reactos/include/psdk/commctrl.h +++ b/reactos/include/psdk/commctrl.h @@ -3037,6 +3037,8 @@ extern "C" { #define TVIS_STATEIMAGEMASK 0xF000 #define TVIS_USERMASK 0xF000 +#define TVIS_FOCUSED 0x0001 + #define I_CHILDRENCALLBACK (-1) #define LPTV_ITEMW LPTVITEMW diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index c113517baa6..8f9393c601a 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -48,7 +48,7 @@ reactos/dll/win32/browseui # Out of sync reactos/dll/win32/cabinet # Synced to Wine-1.5.19 reactos/dll/win32/clusapi # Synced to Wine-1.5.19 reactos/dll/win32/comcat # Synced to Wine-1.5.4 -reactos/dll/win32/comctl32 # Synced to Wine 1.3.37 +reactos/dll/win32/comctl32 # Synced to Wine 1.5.19 reactos/dll/win32/comdlg32 # Synced to Wine 1.3.37 reactos/dll/win32/compstui # Synced to Wine-1.5.19 reactos/dll/win32/credui # Synced to Wine-1.5.4