[PATCH 2/5] Fix DRAWITEMSTRUCT filling when large enough extra item data is used
Nikolay Sivov
nsivov at codeweavers.com
Mon Sep 27 16:48:24 CDT 2010
---
dlls/comctl32/tab.c | 20 ++++++-------
dlls/comctl32/tests/tab.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 72 insertions(+), 12 deletions(-)
diff --git a/dlls/comctl32/tab.c b/dlls/comctl32/tab.c
index 0ecbb63..28c8bfd 100644
--- a/dlls/comctl32/tab.c
+++ b/dlls/comctl32/tab.c
@@ -1728,7 +1728,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 +1741,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 +1756,14 @@ 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
+ dis.itemData = *(ULONG_PTR*)TAB_GetItem(infoPtr, iItem)->extra;
+
+ /* draw notification */
SendMessageW( infoPtr->hwndNotify, WM_DRAWITEM, id, (LPARAM)&dis );
}
else
diff --git a/dlls/comctl32/tests/tab.c b/dlls/comctl32/tests/tab.c
index d74155d..0cddeba 100644
--- a/dlls/comctl32/tests/tab.c
+++ b/dlls/comctl32/tests/tab.c
@@ -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--;
@@ -1233,6 +1238,62 @@ static void test_TCM_SETITEMEXTRA(HWND parent_wnd)
DestroyWindow(hTab);
}
+static void test_TCS_OWNERDRAWFIXED(HWND parent_wnd)
+{
+ HWND hTab;
+ TCITEMA item;
+ 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 */
+ item.mask = TCIF_PARAM;
+ item.lParam = 0xdeadbeef;
+ 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);
+
+ ok(g_drawitem.itemData == 0xdeadbeef, "got %lx, expected 0xdeadbeef\n", g_drawitem.itemData);
+
+ 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 */
+ item.mask = TCIF_PARAM;
+ item.lParam = 0xdeadbeef;
+
+ 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 == 0xdeadbeef, "got %lx, expected 0xdeadbeef\n", g_drawitem.itemData);
+
+ DestroyWindow(hTab);
+}
+
START_TEST(tab)
{
HWND parent_wnd;
@@ -1278,6 +1339,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);
}
--
1.5.6.5
--------------050805020403070404020905--
More information about the wine-patches
mailing list