[COMCTL32] Sync listview.c and progress.c with Wine Staging 4.18. CORE-16441

This commit is contained in:
Amine Khaldi 2019-10-26 22:51:10 +01:00
parent 22c0673bd9
commit 00f14ee1f2
2 changed files with 112 additions and 73 deletions

View file

@ -124,9 +124,6 @@
* -- LVGroupComparE * -- LVGroupComparE
*/ */
#include "config.h"
#include "wine/port.h"
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
@ -145,7 +142,6 @@
#include "uxtheme.h" #include "uxtheme.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(listview); WINE_DEFAULT_DEBUG_CHANNEL(listview);
@ -211,6 +207,13 @@ typedef struct tagDELAYED_ITEM_EDIT
INT iItem; INT iItem;
} DELAYED_ITEM_EDIT; } DELAYED_ITEM_EDIT;
enum notification_mask
{
NOTIFY_MASK_ITEM_CHANGE = 0x1,
NOTIFY_MASK_END_LABEL_EDIT = 0x2,
NOTIFY_MASK_UNMASK_ALL = 0xffffffff
};
typedef struct tagLISTVIEW_INFO typedef struct tagLISTVIEW_INFO
{ {
/* control window */ /* control window */
@ -225,7 +228,7 @@ typedef struct tagLISTVIEW_INFO
/* notification window */ /* notification window */
SHORT notifyFormat; SHORT notifyFormat;
HWND hwndNotify; HWND hwndNotify;
BOOL bDoChangeNotify; /* send change notification messages? */ DWORD notify_mask;
UINT uCallbackMask; UINT uCallbackMask;
/* tooltips */ /* tooltips */
@ -993,7 +996,7 @@ static BOOL notify_dispinfoT(const LISTVIEW_INFO *infoPtr, UINT code, LPNMLVDISP
} }
else if (return_unicode && (pdi->hdr.code == LVN_GETDISPINFOW)) else if (return_unicode && (pdi->hdr.code == LVN_GETDISPINFOW))
{ {
strcpyW(ret_text, pdi->item.pszText); lstrcpyW(ret_text, pdi->item.pszText);
} }
else if (return_ansi) /* note : pointer can be changed by app ! */ else if (return_ansi) /* note : pointer can be changed by app ! */
{ {
@ -1311,21 +1314,19 @@ static inline void iterator_destroy(const ITERATOR *i)
/*** /***
* Create an empty iterator. * Create an empty iterator.
*/ */
static inline BOOL iterator_empty(ITERATOR* i) static inline void iterator_empty(ITERATOR* i)
{ {
ZeroMemory(i, sizeof(*i)); ZeroMemory(i, sizeof(*i));
i->nItem = i->nSpecial = i->range.lower = i->range.upper = -1; i->nItem = i->nSpecial = i->range.lower = i->range.upper = -1;
return TRUE;
} }
/*** /***
* Create an iterator over a range. * Create an iterator over a range.
*/ */
static inline BOOL iterator_rangeitems(ITERATOR* i, RANGE range) static inline void iterator_rangeitems(ITERATOR* i, RANGE range)
{ {
iterator_empty(i); iterator_empty(i);
i->range = range; i->range = range;
return TRUE;
} }
/*** /***
@ -1333,11 +1334,10 @@ static inline BOOL iterator_rangeitems(ITERATOR* i, RANGE range)
* Please note that the iterator will take ownership of the ranges, * Please note that the iterator will take ownership of the ranges,
* and will free them upon destruction. * and will free them upon destruction.
*/ */
static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges) static inline void iterator_rangesitems(ITERATOR* i, RANGES ranges)
{ {
iterator_empty(i); iterator_empty(i);
i->ranges = ranges; i->ranges = ranges;
return TRUE;
} }
/*** /***
@ -1347,12 +1347,16 @@ static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges)
static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *frame) static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *frame)
{ {
RECT rcItem, rcTemp; RECT rcItem, rcTemp;
RANGES ranges;
/* in case we fail, we want to return an empty iterator */
if (!iterator_empty(i)) return FALSE;
TRACE("(frame=%s)\n", wine_dbgstr_rect(frame)); TRACE("(frame=%s)\n", wine_dbgstr_rect(frame));
/* in case we fail, we want to return an empty iterator */
iterator_empty(i);
if (infoPtr->nItemCount == 0)
return TRUE;
if (infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON) if (infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON)
{ {
INT nItem; INT nItem;
@ -1363,7 +1367,8 @@ static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* info
if (IntersectRect(&rcTemp, &rcItem, frame)) if (IntersectRect(&rcTemp, &rcItem, frame))
i->nSpecial = infoPtr->nFocusedItem; i->nSpecial = infoPtr->nFocusedItem;
} }
if (!(iterator_rangesitems(i, ranges_create(50)))) return FALSE; if (!(ranges = ranges_create(50))) return FALSE;
iterator_rangesitems(i, ranges);
/* to do better here, we need to have PosX, and PosY sorted */ /* to do better here, we need to have PosX, and PosY sorted */
TRACE("building icon ranges:\n"); TRACE("building icon ranges:\n");
for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) for (nItem = 0; nItem < infoPtr->nItemCount; nItem++)
@ -1387,7 +1392,7 @@ static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* info
range.lower = max(frame->top / infoPtr->nItemHeight, 0); range.lower = max(frame->top / infoPtr->nItemHeight, 0);
range.upper = min((frame->bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1; range.upper = min((frame->bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1;
if (range.upper <= range.lower) return TRUE; if (range.upper <= range.lower) return TRUE;
if (!iterator_rangeitems(i, range)) return FALSE; iterator_rangeitems(i, range);
TRACE(" report=%s\n", debugrange(&i->range)); TRACE(" report=%s\n", debugrange(&i->range));
} }
else else
@ -1419,7 +1424,8 @@ static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* info
if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE; if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;
if (!(iterator_rangesitems(i, ranges_create(nLastCol - nFirstCol + 1)))) return FALSE; if (!(ranges = ranges_create(nLastCol - nFirstCol + 1))) return FALSE;
iterator_rangesitems(i, ranges);
TRACE("building list ranges:\n"); TRACE("building list ranges:\n");
for (nCol = nFirstCol; nCol <= nLastCol; nCol++) for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
{ {
@ -1460,7 +1466,11 @@ static BOOL iterator_visibleitems(ITERATOR *i, const LISTVIEW_INFO *infoPtr, HDC
INT rgntype; INT rgntype;
rgntype = GetClipBox(hdc, &rcClip); rgntype = GetClipBox(hdc, &rcClip);
if (rgntype == NULLREGION) return iterator_empty(i); if (rgntype == NULLREGION)
{
iterator_empty(i);
return TRUE;
}
if (!iterator_frameditems(i, infoPtr, &rcClip)) return FALSE; if (!iterator_frameditems(i, infoPtr, &rcClip)) return FALSE;
if (rgntype == SIMPLEREGION) return TRUE; if (rgntype == SIMPLEREGION) return TRUE;
@ -1746,7 +1756,9 @@ static inline void LISTVIEW_InvalidateItem(const LISTVIEW_INFO *infoPtr, INT nIt
{ {
RECT rcBox; RECT rcBox;
if(!is_redrawing(infoPtr)) return; if (!is_redrawing(infoPtr) || nItem < 0 || nItem >= infoPtr->nItemCount)
return;
LISTVIEW_GetItemBox(infoPtr, nItem, &rcBox); LISTVIEW_GetItemBox(infoPtr, nItem, &rcBox);
LISTVIEW_InvalidateRect(infoPtr, &rcBox); LISTVIEW_InvalidateRect(infoPtr, &rcBox);
} }
@ -1763,7 +1775,7 @@ static inline void LISTVIEW_InvalidateSubItem(const LISTVIEW_INFO *infoPtr, INT
LISTVIEW_GetHeaderRect(infoPtr, nSubItem, &rcBox); LISTVIEW_GetHeaderRect(infoPtr, nSubItem, &rcBox);
rcBox.top = 0; rcBox.top = 0;
rcBox.bottom = infoPtr->nItemHeight; rcBox.bottom = infoPtr->nItemHeight;
OffsetRect(&rcBox, Origin.x + Position.x, Origin.y + Position.y); OffsetRect(&rcBox, Origin.x, Origin.y + Position.y);
LISTVIEW_InvalidateRect(infoPtr, &rcBox); LISTVIEW_InvalidateRect(infoPtr, &rcBox);
} }
@ -1815,7 +1827,7 @@ static inline INT LISTVIEW_GetCountPerColumn(const LISTVIEW_INFO *infoPtr)
{ {
INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top; INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
return max(nListHeight / infoPtr->nItemHeight, 1); return infoPtr->nItemHeight ? max(nListHeight / infoPtr->nItemHeight, 1) : 0;
} }
@ -1873,7 +1885,7 @@ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, L
if (!charCode || !keyData || infoPtr->nItemCount == 0) return 0; if (!charCode || !keyData || infoPtr->nItemCount == 0) return 0;
/* only allow the valid WM_CHARs through */ /* only allow the valid WM_CHARs through */
if (!isalnumW(charCode) && if (!iswalnum(charCode) &&
charCode != '.' && charCode != '`' && charCode != '!' && charCode != '.' && charCode != '`' && charCode != '!' &&
charCode != '@' && charCode != '#' && charCode != '$' && charCode != '@' && charCode != '#' && charCode != '$' &&
charCode != '%' && charCode != '^' && charCode != '&' && charCode != '%' && charCode != '^' && charCode != '&' &&
@ -3524,13 +3536,13 @@ Parameters:
*/ */
static void LISTVIEW_ShiftFocus(LISTVIEW_INFO *infoPtr, INT focus, INT item, INT direction) static void LISTVIEW_ShiftFocus(LISTVIEW_INFO *infoPtr, INT focus, INT item, INT direction)
{ {
BOOL old_change = infoPtr->bDoChangeNotify; DWORD old_mask = infoPtr->notify_mask & NOTIFY_MASK_ITEM_CHANGE;
infoPtr->bDoChangeNotify = FALSE; infoPtr->notify_mask &= ~NOTIFY_MASK_ITEM_CHANGE;
focus = shift_item(infoPtr, focus, item, direction); focus = shift_item(infoPtr, focus, item, direction);
if (focus != infoPtr->nFocusedItem) if (focus != infoPtr->nFocusedItem)
LISTVIEW_SetItemFocus(infoPtr, focus); LISTVIEW_SetItemFocus(infoPtr, focus);
infoPtr->bDoChangeNotify = old_change; infoPtr->notify_mask |= old_mask;
} }
/** /**
@ -3573,8 +3585,8 @@ static BOOL LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
INT nLast = max(infoPtr->nSelectionMark, nItem); INT nLast = max(infoPtr->nSelectionMark, nItem);
HWND hwndSelf = infoPtr->hwndSelf; HWND hwndSelf = infoPtr->hwndSelf;
NMLVODSTATECHANGE nmlv; NMLVODSTATECHANGE nmlv;
DWORD old_mask;
LVITEMW item; LVITEMW item;
BOOL bOldChange;
INT i; INT i;
/* Temporarily disable change notification /* Temporarily disable change notification
@ -3582,8 +3594,9 @@ static BOOL LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
* only one LVN_ODSTATECHANGED notification. * only one LVN_ODSTATECHANGED notification.
* See MSDN documentation for LVN_ITEMCHANGED. * See MSDN documentation for LVN_ITEMCHANGED.
*/ */
bOldChange = infoPtr->bDoChangeNotify; old_mask = infoPtr->notify_mask & NOTIFY_MASK_ITEM_CHANGE;
if (infoPtr->dwStyle & LVS_OWNERDATA) infoPtr->bDoChangeNotify = FALSE; if (infoPtr->dwStyle & LVS_OWNERDATA)
infoPtr->notify_mask &= ~NOTIFY_MASK_ITEM_CHANGE;
if (nFirst == -1) nFirst = nItem; if (nFirst == -1) nFirst = nItem;
@ -3602,7 +3615,7 @@ static BOOL LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
notify_hdr(infoPtr, LVN_ODSTATECHANGED, (LPNMHDR)&nmlv); notify_hdr(infoPtr, LVN_ODSTATECHANGED, (LPNMHDR)&nmlv);
if (!IsWindow(hwndSelf)) if (!IsWindow(hwndSelf))
return FALSE; return FALSE;
infoPtr->bDoChangeNotify = bOldChange; infoPtr->notify_mask |= old_mask;
return TRUE; return TRUE;
} }
@ -3621,9 +3634,9 @@ static BOOL LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem) static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
{ {
RANGES selection; RANGES selection;
DWORD old_mask;
LVITEMW item; LVITEMW item;
ITERATOR i; ITERATOR i;
BOOL bOldChange;
if (!(selection = ranges_create(100))) return; if (!(selection = ranges_create(100))) return;
@ -3673,8 +3686,9 @@ static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
/* disable per item notifications on LVS_OWNERDATA style /* disable per item notifications on LVS_OWNERDATA style
FIXME: single LVN_ODSTATECHANGED should be used */ FIXME: single LVN_ODSTATECHANGED should be used */
bOldChange = infoPtr->bDoChangeNotify; old_mask = infoPtr->notify_mask & NOTIFY_MASK_ITEM_CHANGE;
if (infoPtr->dwStyle & LVS_OWNERDATA) infoPtr->bDoChangeNotify = FALSE; if (infoPtr->dwStyle & LVS_OWNERDATA)
infoPtr->notify_mask &= ~NOTIFY_MASK_ITEM_CHANGE;
LISTVIEW_DeselectAllSkipItems(infoPtr, selection); LISTVIEW_DeselectAllSkipItems(infoPtr, selection);
@ -3685,8 +3699,7 @@ static void LISTVIEW_SetGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
/* this will also destroy the selection */ /* this will also destroy the selection */
iterator_destroy(&i); iterator_destroy(&i);
infoPtr->bDoChangeNotify = bOldChange; infoPtr->notify_mask |= old_mask;
LISTVIEW_SetItemFocus(infoPtr, nItem); LISTVIEW_SetItemFocus(infoPtr, nItem);
} }
@ -4265,8 +4278,11 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
memset(&nmlv, 0, sizeof(NMLISTVIEW)); memset(&nmlv, 0, sizeof(NMLISTVIEW));
nmlv.iItem = lpLVItem->iItem; nmlv.iItem = lpLVItem->iItem;
nmlv.uNewState = (item.state & ~stateMask) | (lpLVItem->state & stateMask); if (lpLVItem->mask & LVIF_STATE)
nmlv.uOldState = item.state; {
nmlv.uNewState = (item.state & ~stateMask) | (lpLVItem->state & stateMask);
nmlv.uOldState = item.state;
}
nmlv.uChanged = uChanged ? uChanged : lpLVItem->mask; nmlv.uChanged = uChanged ? uChanged : lpLVItem->mask;
nmlv.lParam = item.lParam; nmlv.lParam = item.lParam;
@ -4274,7 +4290,7 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
and we are _NOT_ virtual (LVS_OWNERDATA), and change notifications and we are _NOT_ virtual (LVS_OWNERDATA), and change notifications
are enabled. Even nothing really changed we still need to send this, are enabled. Even nothing really changed we still need to send this,
in this case uChanged mask is just set to passed item mask. */ in this case uChanged mask is just set to passed item mask. */
if(lpItem && !isNew && infoPtr->bDoChangeNotify) if (lpItem && !isNew && (infoPtr->notify_mask & NOTIFY_MASK_ITEM_CHANGE))
{ {
HWND hwndSelf = infoPtr->hwndSelf; HWND hwndSelf = infoPtr->hwndSelf;
@ -4367,7 +4383,8 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
/* send LVN_ITEMCHANGED notification */ /* send LVN_ITEMCHANGED notification */
if (lpLVItem->mask & LVIF_PARAM) nmlv.lParam = lpLVItem->lParam; if (lpLVItem->mask & LVIF_PARAM) nmlv.lParam = lpLVItem->lParam;
if (infoPtr->bDoChangeNotify) notify_listview(infoPtr, LVN_ITEMCHANGED, &nmlv); if (infoPtr->notify_mask & NOTIFY_MASK_ITEM_CHANGE)
notify_listview(infoPtr, LVN_ITEMCHANGED, &nmlv);
return TRUE; return TRUE;
} }
@ -5265,11 +5282,15 @@ enddraw:
/* Draw marquee rectangle if appropriate */ /* Draw marquee rectangle if appropriate */
if (infoPtr->bMarqueeSelect) if (infoPtr->bMarqueeSelect)
#ifdef __REACTOS__
{ {
SetBkColor(hdc, RGB(255, 255, 255)); SetBkColor(hdc, RGB(255, 255, 255));
SetTextColor(hdc, RGB(0, 0, 0)); SetTextColor(hdc, RGB(0, 0, 0));
DrawFocusRect(hdc, &infoPtr->marqueeDrawRect); DrawFocusRect(hdc, &infoPtr->marqueeDrawRect);
} }
#else
DrawFocusRect(hdc, &infoPtr->marqueeDrawRect);
#endif
if (cdmode & CDRF_NOTIFYPOSTPAINT) if (cdmode & CDRF_NOTIFYPOSTPAINT)
notify_postpaint(infoPtr, &nmlvcd); notify_postpaint(infoPtr, &nmlvcd);
@ -5938,9 +5959,13 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
dispInfo.item.pszText = same ? NULL : pszText; dispInfo.item.pszText = same ? NULL : pszText;
dispInfo.item.cchTextMax = textlenT(dispInfo.item.pszText, isW); dispInfo.item.cchTextMax = textlenT(dispInfo.item.pszText, isW);
infoPtr->notify_mask &= ~NOTIFY_MASK_END_LABEL_EDIT;
/* Do we need to update the Item Text */ /* Do we need to update the Item Text */
res = notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW); res = notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW);
infoPtr->notify_mask |= NOTIFY_MASK_END_LABEL_EDIT;
infoPtr->nEditLabelItem = -1; infoPtr->nEditLabelItem = -1;
infoPtr->hwndEdit = 0; infoPtr->hwndEdit = 0;
@ -6409,7 +6434,7 @@ again:
{ {
if (lpFindInfo->flags & (LVFI_PARTIAL | LVFI_SUBSTRING)) if (lpFindInfo->flags & (LVFI_PARTIAL | LVFI_SUBSTRING))
{ {
WCHAR *p = strstrW(lvItem.pszText, lpFindInfo->psz); WCHAR *p = wcsstr(lvItem.pszText, lpFindInfo->psz);
if (!p || p != lvItem.pszText) continue; if (!p || p != lvItem.pszText) continue;
} }
else else
@ -9000,7 +9025,7 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE
if (nItem == -1) if (nItem == -1)
{ {
UINT oldstate = 0; UINT oldstate = 0;
BOOL notify; DWORD old_mask;
/* special case optimization for recurring attempt to deselect all */ /* special case optimization for recurring attempt to deselect all */
if (lvItem.state == 0 && lvItem.stateMask == LVIS_SELECTED && !LISTVIEW_GetSelectedCount(infoPtr)) if (lvItem.state == 0 && lvItem.stateMask == LVIS_SELECTED && !LISTVIEW_GetSelectedCount(infoPtr))
@ -9013,10 +9038,10 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE
/* focus all isn't allowed */ /* focus all isn't allowed */
if (lvItem.state & lvItem.stateMask & LVIS_FOCUSED) return FALSE; if (lvItem.state & lvItem.stateMask & LVIS_FOCUSED) return FALSE;
notify = infoPtr->bDoChangeNotify; old_mask = infoPtr->notify_mask & NOTIFY_MASK_ITEM_CHANGE;
if (infoPtr->dwStyle & LVS_OWNERDATA) if (infoPtr->dwStyle & LVS_OWNERDATA)
{ {
infoPtr->bDoChangeNotify = FALSE; infoPtr->notify_mask &= ~NOTIFY_MASK_ITEM_CHANGE;
if (!(lvItem.state & LVIS_SELECTED) && LISTVIEW_GetSelectedCount(infoPtr)) if (!(lvItem.state & LVIS_SELECTED) && LISTVIEW_GetSelectedCount(infoPtr))
oldstate |= LVIS_SELECTED; oldstate |= LVIS_SELECTED;
if (infoPtr->nFocusedItem != -1) oldstate |= LVIS_FOCUSED; if (infoPtr->nFocusedItem != -1) oldstate |= LVIS_FOCUSED;
@ -9030,7 +9055,7 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE
{ {
NMLISTVIEW nmlv; NMLISTVIEW nmlv;
infoPtr->bDoChangeNotify = notify; infoPtr->notify_mask |= old_mask;
nmlv.iItem = -1; nmlv.iItem = -1;
nmlv.iSubItem = 0; nmlv.iSubItem = 0;
@ -9514,7 +9539,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
infoPtr->nHotItem = -1; infoPtr->nHotItem = -1;
infoPtr->redraw = TRUE; infoPtr->redraw = TRUE;
infoPtr->bNoItemMetrics = TRUE; infoPtr->bNoItemMetrics = TRUE;
infoPtr->bDoChangeNotify = TRUE; infoPtr->notify_mask = NOTIFY_MASK_UNMASK_ALL;
infoPtr->autoSpacing = TRUE; infoPtr->autoSpacing = TRUE;
infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON); infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON);
infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON); infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
@ -9909,7 +9934,7 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
/* carry on only if it really changed */ /* carry on only if it really changed */
if (nNewScrollPos == nOldScrollPos) return 0; if (nNewScrollPos == nOldScrollPos) return 0;
if (infoPtr->hwndHeader) LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos); LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos);
/* now adjust to client coordinates */ /* now adjust to client coordinates */
nScrollDiff = nOldScrollPos - nNewScrollPos; nScrollDiff = nOldScrollPos - nNewScrollPos;
@ -9923,7 +9948,7 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta) static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta)
{ {
UINT pulScrollLines = 3; INT pulScrollLines = 3;
TRACE("(wheelDelta=%d)\n", wheelDelta); TRACE("(wheelDelta=%d)\n", wheelDelta);
@ -9952,8 +9977,8 @@ static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta)
{ {
int cLineScroll; int cLineScroll;
pulScrollLines = min((UINT)LISTVIEW_GetCountPerColumn(infoPtr), pulScrollLines); pulScrollLines = min((UINT)LISTVIEW_GetCountPerColumn(infoPtr), pulScrollLines);
cLineScroll = pulScrollLines * (float)infoPtr->cWheelRemainder / WHEEL_DELTA; cLineScroll = pulScrollLines * infoPtr->cWheelRemainder / WHEEL_DELTA;
infoPtr->cWheelRemainder -= WHEEL_DELTA * cLineScroll / (int)pulScrollLines; infoPtr->cWheelRemainder -= WHEEL_DELTA * cLineScroll / pulScrollLines;
LISTVIEW_VScroll(infoPtr, SB_INTERNAL, -cLineScroll); LISTVIEW_VScroll(infoPtr, SB_INTERNAL, -cLineScroll);
} }
break; break;
@ -10248,7 +10273,9 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN
{ {
if ((infoPtr->dwLvExStyle & LVS_EX_CHECKBOXES) && (lvHitTestInfo.flags & LVHT_ONITEMSTATEICON)) if ((infoPtr->dwLvExStyle & LVS_EX_CHECKBOXES) && (lvHitTestInfo.flags & LVHT_ONITEMSTATEICON))
{ {
notify_click(infoPtr, NM_CLICK, &lvHitTestInfo);
toggle_checkbox_state(infoPtr, nItem); toggle_checkbox_state(infoPtr, nItem);
infoPtr->bLButtonDown = FALSE;
return 0; return 0;
} }
@ -11099,13 +11126,21 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr)
infoPtr->rcList.bottom = max (infoPtr->rcList.bottom - 2, 0); infoPtr->rcList.bottom = max (infoPtr->rcList.bottom - 2, 0);
} }
/* if control created invisible header isn't created */ /* When ListView control is created invisible, header isn't created right away. */
if (infoPtr->hwndHeader) if (infoPtr->hwndHeader)
{ {
HDLAYOUT hl; POINT origin;
WINDOWPOS wp; WINDOWPOS wp;
HDLAYOUT hl;
RECT rect;
hl.prc = &infoPtr->rcList; LISTVIEW_GetOrigin(infoPtr, &origin);
rect = infoPtr->rcList;
rect.left += origin.x;
rect.top += origin.y;
hl.prc = &rect;
hl.pwpos = &wp; hl.pwpos = &wp;
SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl ); SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl );
TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy); TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy);
@ -11145,14 +11180,13 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr)
static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
const STYLESTRUCT *lpss) const STYLESTRUCT *lpss)
{ {
UINT uNewView = lpss->styleNew & LVS_TYPEMASK; UINT uNewView, uOldView;
UINT uOldView = lpss->styleOld & LVS_TYPEMASK;
UINT style; UINT style;
TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n", TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
wStyleType, lpss->styleOld, lpss->styleNew); wStyleType, lpss->styleOld, lpss->styleNew);
if (wStyleType != GWL_STYLE) return 0; if (wStyleType != GWL_STYLE || lpss->styleNew == infoPtr->dwStyle) return 0;
infoPtr->dwStyle = lpss->styleNew; infoPtr->dwStyle = lpss->styleNew;
@ -11164,6 +11198,9 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
((lpss->styleNew & WS_VSCROLL) == 0)) ((lpss->styleNew & WS_VSCROLL) == 0))
ShowScrollBar(infoPtr->hwndSelf, SB_VERT, FALSE); ShowScrollBar(infoPtr->hwndSelf, SB_VERT, FALSE);
uNewView = lpss->styleNew & LVS_TYPEMASK;
uOldView = lpss->styleOld & LVS_TYPEMASK;
if (uNewView != uOldView) if (uNewView != uOldView)
{ {
HIMAGELIST himl; HIMAGELIST himl;
@ -11949,8 +11986,9 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP
} }
case EN_KILLFOCUS: case EN_KILLFOCUS:
{ {
LISTVIEW_CancelEditLabel(infoPtr); if (infoPtr->notify_mask & NOTIFY_MASK_END_LABEL_EDIT)
break; LISTVIEW_CancelEditLabel(infoPtr);
break;
} }
default: default:

View file

@ -652,23 +652,24 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
case PBM_STEPIT: case PBM_STEPIT:
{ {
INT oldVal; int oldVal = infoPtr->CurVal;
oldVal = infoPtr->CurVal;
infoPtr->CurVal += infoPtr->Step; if (infoPtr->MinVal != infoPtr->MaxVal)
if (infoPtr->CurVal > infoPtr->MaxVal)
{ {
infoPtr->CurVal = (infoPtr->CurVal - infoPtr->MinVal) % (infoPtr->MaxVal - infoPtr->MinVal) + infoPtr->MinVal; infoPtr->CurVal += infoPtr->Step;
if (infoPtr->CurVal > infoPtr->MaxVal)
infoPtr->CurVal = (infoPtr->CurVal - infoPtr->MinVal) % (infoPtr->MaxVal - infoPtr->MinVal) + infoPtr->MinVal;
if (infoPtr->CurVal < infoPtr->MinVal)
infoPtr->CurVal = (infoPtr->CurVal - infoPtr->MinVal) % (infoPtr->MaxVal - infoPtr->MinVal) + infoPtr->MaxVal;
if (oldVal != infoPtr->CurVal)
{
TRACE("PBM_STEPIT: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
UpdateWindow( infoPtr->Self );
}
} }
if (infoPtr->CurVal < infoPtr->MinVal)
{
infoPtr->CurVal = (infoPtr->CurVal - infoPtr->MinVal) % (infoPtr->MaxVal - infoPtr->MinVal) + infoPtr->MaxVal;
}
if(oldVal != infoPtr->CurVal)
{
TRACE("PBM_STEPIT: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
UpdateWindow( infoPtr->Self );
}
return oldVal; return oldVal;
} }