Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
dbd997c3
Commit
dbd997c3
authored
Jan 12, 2013
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jan 14, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
comctl32/listview: Update focus index when new item data is already there.
parent
bd72767e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
8 deletions
+87
-8
listview.c
dlls/comctl32/listview.c
+24
-8
listview.c
dlls/comctl32/tests/listview.c
+63
-0
No files found.
dlls/comctl32/listview.c
View file @
dbd997c3
...
@@ -4164,7 +4164,7 @@ static inline BOOL is_assignable_item(const LVITEMW *lpLVItem, LONG lStyle)
...
@@ -4164,7 +4164,7 @@ static inline BOOL is_assignable_item(const LVITEMW *lpLVItem, LONG lStyle)
/***
/***
* DESCRIPTION:
* DESCRIPTION:
* Helper for LISTVIEW_SetItemT
*only*
: sets item attributes.
* Helper for LISTVIEW_SetItemT
and LISTVIEW_InsertItemT
: sets item attributes.
*
*
* PARAMETER(S):
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
* [I] infoPtr : valid pointer to the listview structure
...
@@ -4256,6 +4256,15 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
...
@@ -4256,6 +4256,15 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
return
FALSE
;
return
FALSE
;
}
}
/* When item is inserted we need to shift existing focus index if new item has lower index. */
if
(
isNew
&&
(
stateMask
&
~
infoPtr
->
uCallbackMask
&
LVIS_FOCUSED
)
&&
/* this means we won't hit a focus change path later */
((
uChanged
&
LVIF_STATE
)
==
0
||
(
!
(
lpLVItem
->
state
&
LVIS_FOCUSED
)
&&
(
infoPtr
->
nFocusedItem
!=
lpLVItem
->
iItem
))))
{
if
(
infoPtr
->
nFocusedItem
!=
-
1
&&
(
lpLVItem
->
iItem
<=
infoPtr
->
nFocusedItem
))
infoPtr
->
nFocusedItem
++
;
}
if
(
!
uChanged
)
return
TRUE
;
if
(
!
uChanged
)
return
TRUE
;
*
bChanged
=
TRUE
;
*
bChanged
=
TRUE
;
...
@@ -4288,7 +4297,14 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
...
@@ -4288,7 +4297,14 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
{
{
ranges_delitem
(
infoPtr
->
selectionRanges
,
lpLVItem
->
iItem
);
ranges_delitem
(
infoPtr
->
selectionRanges
,
lpLVItem
->
iItem
);
}
}
/* if we are asked to change focus, and we manage it, do it */
/* If we are asked to change focus, and we manage it, do it.
It's important to have all new item data stored at this point,
cause changing existing focus could result in redrawing operation,
which in turn could ask for disp data, application should see all data
for inserted item when processing LVN_GETDISPINFO.
The way this works application will see nested item change notifications -
changed item notifications interrupted by ones from item loosing focus. */
if
(
stateMask
&
~
infoPtr
->
uCallbackMask
&
LVIS_FOCUSED
)
if
(
stateMask
&
~
infoPtr
->
uCallbackMask
&
LVIS_FOCUSED
)
{
{
if
(
lpLVItem
->
state
&
LVIS_FOCUSED
)
if
(
lpLVItem
->
state
&
LVIS_FOCUSED
)
...
@@ -4320,7 +4336,7 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
...
@@ -4320,7 +4336,7 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
/* if we're inserting the item, we're done */
/* if we're inserting the item, we're done */
if
(
isNew
)
return
TRUE
;
if
(
isNew
)
return
TRUE
;
/* 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
->
bDoChangeNotify
)
notify_listview
(
infoPtr
,
LVN_ITEMCHANGED
,
&
nmlv
);
...
@@ -7680,7 +7696,7 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
...
@@ -7680,7 +7696,7 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
LVITEMW
item
;
LVITEMW
item
;
HWND
hwndSelf
=
infoPtr
->
hwndSelf
;
HWND
hwndSelf
=
infoPtr
->
hwndSelf
;
TRACE
(
"(
lpLVI
tem=%s, isW=%d)
\n
"
,
debuglvitem_t
(
lpLVItem
,
isW
),
isW
);
TRACE
(
"(
i
tem=%s, isW=%d)
\n
"
,
debuglvitem_t
(
lpLVItem
,
isW
),
isW
);
if
(
infoPtr
->
dwStyle
&
LVS_OWNERDATA
)
return
infoPtr
->
nItemCount
++
;
if
(
infoPtr
->
dwStyle
&
LVS_OWNERDATA
)
return
infoPtr
->
nItemCount
++
;
...
@@ -7730,14 +7746,13 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
...
@@ -7730,14 +7746,13 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
else
else
nItem
=
min
(
lpLVItem
->
iItem
,
infoPtr
->
nItemCount
);
nItem
=
min
(
lpLVItem
->
iItem
,
infoPtr
->
nItemCount
);
TRACE
(
"
inserting at %d, sorted=%d, count=%d, iItem=%d
\n
"
,
nItem
,
is_sorted
,
infoPtr
->
nItemCount
,
lpLVItem
->
iItem
);
TRACE
(
"inserting at %d, sorted=%d, count=%d, iItem=%d
\n
"
,
nItem
,
is_sorted
,
infoPtr
->
nItemCount
,
lpLVItem
->
iItem
);
nItem
=
DPA_InsertPtr
(
infoPtr
->
hdpaItems
,
nItem
,
hdpaSubItems
);
nItem
=
DPA_InsertPtr
(
infoPtr
->
hdpaItems
,
nItem
,
hdpaSubItems
);
if
(
nItem
==
-
1
)
goto
fail
;
if
(
nItem
==
-
1
)
goto
fail
;
infoPtr
->
nItemCount
++
;
infoPtr
->
nItemCount
++
;
/* shift indices first so they don't get tangled */
/* shift indices first so they don't get tangled */
LISTVIEW_ShiftIndices
(
infoPtr
,
nItem
,
1
);
LISTVIEW_ShiftIndices
(
infoPtr
,
nItem
,
1
);
LISTVIEW_ShiftFocus
(
infoPtr
,
infoPtr
->
nFocusedItem
,
nItem
,
1
);
/* set the item attributes */
/* set the item attributes */
if
(
lpLVItem
->
mask
&
(
LVIF_GROUPID
|
LVIF_COLUMNS
))
if
(
lpLVItem
->
mask
&
(
LVIF_GROUPID
|
LVIF_COLUMNS
))
...
@@ -7763,6 +7778,7 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
...
@@ -7763,6 +7778,7 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
item
.
state
&=
~
LVIS_STATEIMAGEMASK
;
item
.
state
&=
~
LVIS_STATEIMAGEMASK
;
item
.
state
|=
INDEXTOSTATEIMAGEMASK
(
1
);
item
.
state
|=
INDEXTOSTATEIMAGEMASK
(
1
);
}
}
if
(
!
set_main_item
(
infoPtr
,
&
item
,
TRUE
,
isW
,
&
has_changed
))
goto
undo
;
if
(
!
set_main_item
(
infoPtr
,
&
item
,
TRUE
,
isW
,
&
has_changed
))
goto
undo
;
/* make room for the position, if we are in the right mode */
/* make room for the position, if we are in the right mode */
...
@@ -7776,9 +7792,9 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
...
@@ -7776,9 +7792,9 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
goto
undo
;
goto
undo
;
}
}
}
}
/* send LVN_INSERTITEM notification */
/* send LVN_INSERTITEM notification */
ZeroMemory
(
&
nmlv
,
sizeof
(
NMLISTVIEW
));
memset
(
&
nmlv
,
0
,
sizeof
(
NMLISTVIEW
));
nmlv
.
iItem
=
nItem
;
nmlv
.
iItem
=
nItem
;
nmlv
.
lParam
=
lpItem
->
lParam
;
nmlv
.
lParam
=
lpItem
->
lParam
;
notify_listview
(
infoPtr
,
LVN_INSERTITEM
,
&
nmlv
);
notify_listview
(
infoPtr
,
LVN_INSERTITEM
,
&
nmlv
);
...
...
dlls/comctl32/tests/listview.c
View file @
dbd997c3
...
@@ -363,6 +363,15 @@ static const struct message listview_header_set_imagelist[] = {
...
@@ -363,6 +363,15 @@ static const struct message listview_header_set_imagelist[] = {
{
0
}
{
0
}
};
};
static
const
struct
message
parent_insert_focused_seq
[]
=
{
{
WM_NOTIFY
,
sent
|
id
,
0
,
0
,
LVN_ITEMCHANGING
},
{
WM_NOTIFY
,
sent
|
id
,
0
,
0
,
LVN_ITEMCHANGING
},
{
WM_NOTIFY
,
sent
|
id
,
0
,
0
,
LVN_ITEMCHANGED
},
{
WM_NOTIFY
,
sent
|
id
,
0
,
0
,
LVN_ITEMCHANGED
},
{
WM_NOTIFY
,
sent
|
id
,
0
,
0
,
LVN_INSERTITEM
},
{
0
}
};
static
LRESULT
WINAPI
parent_wnd_proc
(
HWND
hwnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
static
LRESULT
WINAPI
parent_wnd_proc
(
HWND
hwnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
{
static
LONG
defwndproc_counter
=
0
;
static
LONG
defwndproc_counter
=
0
;
...
@@ -5434,6 +5443,58 @@ static void test_deleteitem(void)
...
@@ -5434,6 +5443,58 @@ static void test_deleteitem(void)
DestroyWindow
(
hwnd
);
DestroyWindow
(
hwnd
);
}
}
static
void
test_insertitem
(
void
)
{
LVITEMA
item
;
UINT
state
;
HWND
hwnd
;
INT
ret
;
hwnd
=
create_listview_control
(
LVS_REPORT
);
/* insert item 0 focused */
item
.
mask
=
LVIF_STATE
;
item
.
state
=
LVIS_FOCUSED
;
item
.
stateMask
=
LVIS_FOCUSED
;
item
.
iItem
=
0
;
item
.
iSubItem
=
0
;
ret
=
SendMessageA
(
hwnd
,
LVM_INSERTITEMA
,
0
,
(
LPARAM
)
&
item
);
ok
(
ret
==
0
,
"got %d
\n
"
,
ret
);
state
=
SendMessageA
(
hwnd
,
LVM_GETITEMSTATE
,
0
,
LVIS_FOCUSED
);
ok
(
state
==
LVIS_FOCUSED
,
"got %x
\n
"
,
state
);
flush_sequences
(
sequences
,
NUM_MSG_SEQUENCES
);
/* insert item 1, focus shift */
item
.
mask
=
LVIF_STATE
;
item
.
state
=
LVIS_FOCUSED
;
item
.
stateMask
=
LVIS_FOCUSED
;
item
.
iItem
=
1
;
item
.
iSubItem
=
0
;
ret
=
SendMessageA
(
hwnd
,
LVM_INSERTITEMA
,
0
,
(
LPARAM
)
&
item
);
ok
(
ret
==
1
,
"got %d
\n
"
,
ret
);
ok_sequence
(
sequences
,
PARENT_SEQ_INDEX
,
parent_insert_focused_seq
,
"insert focused"
,
TRUE
);
state
=
SendMessageA
(
hwnd
,
LVM_GETITEMSTATE
,
1
,
LVIS_FOCUSED
);
ok
(
state
==
LVIS_FOCUSED
,
"got %x
\n
"
,
state
);
/* insert item 2, no focus shift */
item
.
mask
=
LVIF_STATE
;
item
.
state
=
0
;
item
.
stateMask
=
LVIS_FOCUSED
;
item
.
iItem
=
2
;
item
.
iSubItem
=
0
;
ret
=
SendMessageA
(
hwnd
,
LVM_INSERTITEMA
,
0
,
(
LPARAM
)
&
item
);
ok
(
ret
==
2
,
"got %d
\n
"
,
ret
);
state
=
SendMessageA
(
hwnd
,
LVM_GETITEMSTATE
,
1
,
LVIS_FOCUSED
);
ok
(
state
==
LVIS_FOCUSED
,
"got %x
\n
"
,
state
);
DestroyWindow
(
hwnd
);
}
START_TEST
(
listview
)
START_TEST
(
listview
)
{
{
HMODULE
hComctl32
;
HMODULE
hComctl32
;
...
@@ -5502,6 +5563,7 @@ START_TEST(listview)
...
@@ -5502,6 +5563,7 @@ START_TEST(listview)
test_LVM_SETITEMTEXT
();
test_LVM_SETITEMTEXT
();
test_imagelists
();
test_imagelists
();
test_deleteitem
();
test_deleteitem
();
test_insertitem
();
if
(
!
load_v6_module
(
&
ctx_cookie
,
&
hCtx
))
if
(
!
load_v6_module
(
&
ctx_cookie
,
&
hCtx
))
{
{
...
@@ -5533,6 +5595,7 @@ START_TEST(listview)
...
@@ -5533,6 +5595,7 @@ START_TEST(listview)
test_LVS_EX_HEADERINALLVIEWS
();
test_LVS_EX_HEADERINALLVIEWS
();
test_deleteitem
();
test_deleteitem
();
test_multiselect
();
test_multiselect
();
test_insertitem
();
unload_v6_module
(
ctx_cookie
,
hCtx
);
unload_v6_module
(
ctx_cookie
,
hCtx
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment