Nikolay Sivov : comctl32/listview: Handle mouse selections more accurately.
Alexandre Julliard
julliard at winehq.org
Tue May 19 09:23:09 CDT 2009
Module: wine
Branch: master
Commit: d769368f66ae648dce519264c748fe670e79aab5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d769368f66ae648dce519264c748fe670e79aab5
Author: Nikolay Sivov <bunglehead at gmail.com>
Date: Mon May 18 20:50:43 2009 +0400
comctl32/listview: Handle mouse selections more accurately.
---
dlls/comctl32/listview.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index e94d389..ce78224 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -293,6 +293,7 @@ typedef struct tagLISTVIEW_INFO
HWND hwndEdit;
WNDPROC EditWndProc;
INT nEditLabelItem;
+ INT nLButtonDownItem; /* tracks item to reset multiselection on WM_LBUTTONUP */
DWORD dwHoverTime;
HWND hwndToolTip;
@@ -3388,6 +3389,7 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
{
POINT tmp;
RECT rect;
+ LVHITTESTINFO lvHitTestInfo;
WORD wDragWidth = GetSystemMetrics(SM_CXDRAG);
WORD wDragHeight= GetSystemMetrics(SM_CYDRAG);
@@ -3399,11 +3401,33 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
tmp.x = x;
tmp.y = y;
+ lvHitTestInfo.pt = tmp;
+ LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
+
+ /* reset item marker */
+ if (infoPtr->nLButtonDownItem != lvHitTestInfo.iItem)
+ infoPtr->nLButtonDownItem = -1;
+
if (!PtInRect(&rect, tmp))
{
- LVHITTESTINFO lvHitTestInfo;
NMLISTVIEW nmlv;
+ /* this path covers the following:
+ 1. WM_LBUTTONDOWN over selected item (sets focus on it)
+ 2. change focus with keys
+ 3. move mouse over item from step 1 selects it and moves focus on it */
+ if (infoPtr->nLButtonDownItem != -1 &&
+ !LISTVIEW_GetItemState(infoPtr, infoPtr->nLButtonDownItem, LVIS_SELECTED))
+ {
+ LVITEMW lvItem;
+
+ lvItem.state = LVIS_FOCUSED | LVIS_SELECTED;
+ lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
+
+ LISTVIEW_SetItemState(infoPtr, infoPtr->nLButtonDownItem, &lvItem);
+ infoPtr->nLButtonDownItem = -1;
+ }
+
lvHitTestInfo.pt = infoPtr->ptClickPos;
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
@@ -3420,8 +3444,6 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
return 0;
}
}
- else
- infoPtr->bLButtonDown = FALSE;
/* see if we are supposed to be tracking mouse hovering */
if (LISTVIEW_isHotTracking(infoPtr)) {
@@ -8144,6 +8166,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING);
infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING);
infoPtr->nEditLabelItem = -1;
+ infoPtr->nLButtonDownItem = -1;
infoPtr->dwHoverTime = -1; /* default system hover time */
infoPtr->nMeasureItemHeight = 0;
infoPtr->xTrackLine = -1; /* no track line */
@@ -8835,10 +8858,15 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN
else
{
if (LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED))
+ {
infoPtr->nEditLabelItem = nItem;
+ infoPtr->nLButtonDownItem = nItem;
- /* set selection (clears other pre-existing selections) */
- LISTVIEW_SetSelection(infoPtr, nItem);
+ LISTVIEW_SetItemFocus(infoPtr, nItem);
+ }
+ else
+ /* set selection (clears other pre-existing selections) */
+ LISTVIEW_SetSelection(infoPtr, nItem);
}
}
@@ -8848,7 +8876,8 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN
else
{
/* remove all selections */
- LISTVIEW_DeselectAll(infoPtr);
+ if (!(wKey & MK_CONTROL) && !(wKey & MK_SHIFT))
+ LISTVIEW_DeselectAll(infoPtr);
ReleaseCapture();
}
@@ -8885,6 +8914,11 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT
/* set left button flag */
infoPtr->bLButtonDown = FALSE;
+ /* set a single selection, reset others */
+ if(lvHitTestInfo.iItem == infoPtr->nLButtonDownItem && lvHitTestInfo.iItem != -1)
+ LISTVIEW_SetSelection(infoPtr, infoPtr->nLButtonDownItem);
+ infoPtr->nLButtonDownItem = -1;
+
if (infoPtr->bDragging)
{
infoPtr->bDragging = FALSE;
More information about the wine-cvs
mailing list