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
f08938c3
Commit
f08938c3
authored
Oct 03, 2010
by
Nikolay Sivov
Committed by
Alexandre Julliard
Oct 04, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
comctl32/tab: Fix DRAWITEMSTRUCT filling when extra item data of a custom size is used.
parent
66bad889
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
155 additions
and
18 deletions
+155
-18
tab.c
dlls/comctl32/tab.c
+20
-16
tab.c
dlls/comctl32/tests/tab.c
+135
-2
No files found.
dlls/comctl32/tab.c
View file @
f08938c3
...
...
@@ -83,8 +83,10 @@ typedef struct
BYTE
extra
[
1
];
/* Space for caller supplied info, variable size */
}
TAB_ITEM
;
/* The size of a tab item depends on how much extra data is requested */
#define TAB_ITEM_SIZE(infoPtr) (FIELD_OFFSET(TAB_ITEM, extra[(infoPtr)->cbInfo]))
/* The size of a tab item depends on how much extra data is requested.
TCM_INSERTITEM always stores at least LPARAM sized data. */
#define EXTRA_ITEM_SIZE(infoPtr) (max((infoPtr)->cbInfo, sizeof(LPARAM)))
#define TAB_ITEM_SIZE(infoPtr) FIELD_OFFSET(TAB_ITEM, extra[EXTRA_ITEM_SIZE(infoPtr)])
typedef
struct
{
...
...
@@ -1728,7 +1730,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
/*
* if owner draw, tell the owner to draw
*/
if
((
infoPtr
->
dwStyle
&
TCS_OWNERDRAWFIXED
)
&&
GetParent
(
infoPtr
->
hwnd
))
if
((
infoPtr
->
dwStyle
&
TCS_OWNERDRAWFIXED
)
&&
IsWindow
(
infoPtr
->
hwndNotify
))
{
DRAWITEMSTRUCT
dis
;
UINT
id
;
...
...
@@ -1741,14 +1743,9 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
drawRect
->
left
+=
1
;
}
/*
* get the control id
*/
id
=
(
UINT
)
GetWindowLongPtrW
(
infoPtr
->
hwnd
,
GWLP_ID
);
/*
* put together the DRAWITEMSTRUCT
*/
/* fill DRAWITEMSTRUCT */
dis
.
CtlType
=
ODT_TAB
;
dis
.
CtlID
=
id
;
dis
.
itemID
=
iItem
;
...
...
@@ -1761,11 +1758,18 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
dis
.
hwndItem
=
infoPtr
->
hwnd
;
dis
.
hDC
=
hdc
;
CopyRect
(
&
dis
.
rcItem
,
drawRect
);
dis
.
itemData
=
(
ULONG_PTR
)
TAB_GetItem
(
infoPtr
,
iItem
)
->
extra
;
/*
* send the draw message
*/
/* when extra data fits ULONG_PTR, store it directly */
if
(
infoPtr
->
cbInfo
>
sizeof
(
LPARAM
))
dis
.
itemData
=
(
ULONG_PTR
)
TAB_GetItem
(
infoPtr
,
iItem
)
->
extra
;
else
{
/* this could be considered broken on 64 bit, but that's how it works -
only first 4 bytes are copied */
memcpy
(
&
dis
.
itemData
,
(
ULONG_PTR
*
)
TAB_GetItem
(
infoPtr
,
iItem
)
->
extra
,
4
);
}
/* draw notification */
SendMessageW
(
infoPtr
->
hwndNotify
,
WM_DRAWITEM
,
id
,
(
LPARAM
)
&
dis
);
}
else
...
...
@@ -2686,10 +2690,10 @@ TAB_InsertItemT (TAB_INFO *infoPtr, INT iItem, const TCITEMW *pti, BOOL bUnicode
item
->
iImage
=
-
1
;
if
(
pti
->
mask
&
TCIF_PARAM
)
memcpy
(
item
->
extra
,
&
pti
->
lParam
,
infoPtr
->
cbInfo
);
memcpy
(
item
->
extra
,
&
pti
->
lParam
,
EXTRA_ITEM_SIZE
(
infoPtr
)
);
else
memset
(
item
->
extra
,
0
,
infoPtr
->
cbInfo
);
memset
(
item
->
extra
,
0
,
EXTRA_ITEM_SIZE
(
infoPtr
)
);
TAB_SetItemBounds
(
infoPtr
);
if
(
infoPtr
->
uNumItem
>
1
)
TAB_InvalidateTabArea
(
infoPtr
);
...
...
dlls/comctl32/tests/tab.c
View file @
f08938c3
...
...
@@ -61,7 +61,8 @@
"%s: Expected [%d,%d] got [%d,%d]\n", msg, (int)width, (int)height,\
rTab.right - rTab.left, rTab.bottom - rTab.top);
static
HFONT
hFont
=
0
;
static
HFONT
hFont
;
static
DRAWITEMSTRUCT
g_drawitem
;
static
struct
msg_sequence
*
sequences
[
NUM_MSG_SEQUENCES
];
...
...
@@ -337,6 +338,10 @@ static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam
add_message
(
sequences
,
PARENT_SEQ_INDEX
,
&
msg
);
}
/* dump sent structure data */
if
(
message
==
WM_DRAWITEM
)
g_drawitem
=
*
(
DRAWITEMSTRUCT
*
)
lParam
;
defwndproc_counter
++
;
ret
=
DefWindowProcA
(
hwnd
,
message
,
wParam
,
lParam
);
defwndproc_counter
--
;
...
...
@@ -790,11 +795,43 @@ static void test_unicodeformat(HWND parent_wnd, INT nTabs)
static
void
test_getset_item
(
HWND
parent_wnd
,
INT
nTabs
)
{
char
szText
[
32
]
=
"New Label"
;
TCITEM
tcItem
;
LPARAM
lparam
;
DWORD
ret
;
char
szText
[
32
]
=
"New Label"
;
HWND
hTab
;
hTab
=
CreateWindowA
(
WC_TABCONTROLA
,
"TestTab"
,
WS_CLIPSIBLINGS
|
WS_CLIPCHILDREN
|
TCS_FOCUSNEVER
|
TCS_FIXEDWIDTH
|
TCS_OWNERDRAWFIXED
,
10
,
10
,
300
,
100
,
parent_wnd
,
NULL
,
NULL
,
0
);
ok
(
GetParent
(
hTab
)
==
NULL
,
"got %p, expected null parent
\n
"
,
GetParent
(
hTab
));
ret
=
SendMessageA
(
hTab
,
TCM_SETITEMEXTRA
,
sizeof
(
LPARAM
)
-
1
,
0
);
ok
(
ret
==
TRUE
,
"got %d
\n
"
,
ret
);
/* set some item data */
tcItem
.
lParam
=
~
0
;
tcItem
.
mask
=
TCIF_PARAM
;
ret
=
SendMessageA
(
hTab
,
TCM_INSERTITEMA
,
0
,
(
LPARAM
)
&
tcItem
);
ok
(
ret
==
0
,
"got %d
\n
"
,
ret
);
/* all sizeof(LPARAM) returned anyway when using sizeof(LPARAM)-1 size */
memset
(
&
lparam
,
0xaa
,
sizeof
(
lparam
));
tcItem
.
lParam
=
lparam
;
tcItem
.
mask
=
TCIF_PARAM
;
ret
=
SendMessage
(
hTab
,
TCM_GETITEM
,
0
,
(
LPARAM
)
&
tcItem
);
expect
(
TRUE
,
ret
);
/* everything higher specified size is preserved */
memset
(
&
lparam
,
0xff
,
sizeof
(
lparam
)
-
1
);
ok
(
tcItem
.
lParam
==
lparam
,
"Expected 0x%lx, got 0x%lx
\n
"
,
lparam
,
tcItem
.
lParam
);
DestroyWindow
(
hTab
);
hTab
=
createFilledTabControl
(
parent_wnd
,
TCS_FIXEDWIDTH
,
TCIF_TEXT
|
TCIF_IMAGE
,
nTabs
);
ok
(
hTab
!=
NULL
,
"Failed to create tab control
\n
"
);
...
...
@@ -1233,6 +1270,101 @@ static void test_TCM_SETITEMEXTRA(HWND parent_wnd)
DestroyWindow
(
hTab
);
}
static
void
test_TCS_OWNERDRAWFIXED
(
HWND
parent_wnd
)
{
LPARAM
lparam
,
lparam2
;
TCITEMA
item
;
HWND
hTab
;
BOOL
ret
;
hTab
=
createFilledTabControl
(
parent_wnd
,
TCS_FIXEDWIDTH
|
TCS_OWNERDRAWFIXED
,
TCIF_TEXT
|
TCIF_IMAGE
,
4
);
ok
(
hTab
!=
NULL
,
"Failed to create tab control
\n
"
);
ok
(
GetParent
(
hTab
)
==
NULL
,
"got %p, expected null parent
\n
"
,
GetParent
(
hTab
));
/* set some item data */
memset
(
&
lparam
,
0xde
,
sizeof
(
LPARAM
));
item
.
mask
=
TCIF_PARAM
;
item
.
lParam
=
lparam
;
ret
=
SendMessageA
(
hTab
,
TCM_SETITEMA
,
0
,
(
LPARAM
)
&
item
);
ok
(
ret
==
TRUE
,
"got %d
\n
"
,
ret
);
memset
(
&
g_drawitem
,
0
,
sizeof
(
g_drawitem
));
ShowWindow
(
hTab
,
SW_SHOW
);
RedrawWindow
(
hTab
,
NULL
,
0
,
RDW_UPDATENOW
);
lparam
=
0
;
memset
(
&
lparam
,
0xde
,
4
);
ok
(
g_drawitem
.
itemData
==
lparam
,
"got %lx, expected %lx
\n
"
,
g_drawitem
.
itemData
,
lparam
);
DestroyWindow
(
hTab
);
/* now with custom extra data length */
hTab
=
CreateWindowA
(
WC_TABCONTROLA
,
"TestTab"
,
WS_CLIPSIBLINGS
|
WS_CLIPCHILDREN
|
TCS_FOCUSNEVER
|
TCS_FIXEDWIDTH
|
TCS_OWNERDRAWFIXED
,
10
,
10
,
300
,
100
,
parent_wnd
,
NULL
,
NULL
,
0
);
ok
(
GetParent
(
hTab
)
==
NULL
,
"got %p, expected null parent
\n
"
,
GetParent
(
hTab
));
ret
=
SendMessageA
(
hTab
,
TCM_SETITEMEXTRA
,
sizeof
(
LPARAM
)
+
1
,
0
);
ok
(
ret
==
TRUE
,
"got %d
\n
"
,
ret
);
/* set some item data */
memset
(
&
lparam
,
0xde
,
sizeof
(
LPARAM
));
item
.
mask
=
TCIF_PARAM
;
item
.
lParam
=
lparam
;
ret
=
SendMessageA
(
hTab
,
TCM_INSERTITEMA
,
0
,
(
LPARAM
)
&
item
);
ok
(
ret
==
0
,
"got %d
\n
"
,
ret
);
memset
(
&
g_drawitem
,
0
,
sizeof
(
g_drawitem
));
ShowWindow
(
hTab
,
SW_SHOW
);
RedrawWindow
(
hTab
,
NULL
,
0
,
RDW_UPDATENOW
);
ok
(
*
(
ULONG_PTR
*
)
g_drawitem
.
itemData
==
lparam
,
"got %lx, expected %lx
\n
"
,
g_drawitem
.
itemData
,
lparam
);
DestroyWindow
(
hTab
);
/* same thing, but size smaller than default */
hTab
=
CreateWindowA
(
WC_TABCONTROLA
,
"TestTab"
,
WS_CLIPSIBLINGS
|
WS_CLIPCHILDREN
|
TCS_FOCUSNEVER
|
TCS_FIXEDWIDTH
|
TCS_OWNERDRAWFIXED
,
10
,
10
,
300
,
100
,
parent_wnd
,
NULL
,
NULL
,
0
);
ok
(
GetParent
(
hTab
)
==
NULL
,
"got %p, expected null parent
\n
"
,
GetParent
(
hTab
));
ret
=
SendMessageA
(
hTab
,
TCM_SETITEMEXTRA
,
sizeof
(
LPARAM
)
-
1
,
0
);
ok
(
ret
==
TRUE
,
"got %d
\n
"
,
ret
);
memset
(
&
lparam
,
0xde
,
sizeof
(
lparam
));
item
.
mask
=
TCIF_PARAM
;
item
.
lParam
=
lparam
;
ret
=
SendMessageA
(
hTab
,
TCM_INSERTITEMA
,
0
,
(
LPARAM
)
&
item
);
ok
(
ret
==
0
,
"got %d
\n
"
,
ret
);
memset
(
&
g_drawitem
,
0
,
sizeof
(
g_drawitem
));
ShowWindow
(
hTab
,
SW_SHOW
);
RedrawWindow
(
hTab
,
NULL
,
0
,
RDW_UPDATENOW
);
lparam
=
0
;
memset
(
&
lparam
,
0xde
,
4
);
memset
(
&
lparam2
,
0xde
,
sizeof
(
LPARAM
)
-
1
);
ok
(
g_drawitem
.
itemData
==
lparam
||
broken
(
g_drawitem
.
itemData
==
lparam2
)
/* win98 */
,
"got 0x%lx, expected 0x%lx
\n
"
,
g_drawitem
.
itemData
,
lparam
);
DestroyWindow
(
hTab
);
}
START_TEST
(
tab
)
{
HWND
parent_wnd
;
...
...
@@ -1278,6 +1410,7 @@ START_TEST(tab)
test_delete_selection
(
parent_wnd
);
test_removeimage
(
parent_wnd
);
test_TCM_SETITEMEXTRA
(
parent_wnd
);
test_TCS_OWNERDRAWFIXED
(
parent_wnd
);
DestroyWindow
(
parent_wnd
);
}
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