Mikołaj Zalewski : comctl32: header: Fix INSERTITEM on a zero mask and GETITEM on a mask with unknown fields.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue May 16 13:54:29 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 36a8e5fba340cc15a2e76bbd5608772b8bce4dff
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=36a8e5fba340cc15a2e76bbd5608772b8bce4dff
Author: Mikołaj Zalewski <mikolaj at zalewski.pl>
Date: Tue May 16 00:10:08 2006 +0200
comctl32: header: Fix INSERTITEM on a zero mask and GETITEM on a mask with unknown fields.
INSERTITEM should fail on a zero mask. If in GETITEM the mask has an
unknown field it should store only the comctl32 4.0 fields (with test
case).
---
dlls/comctl32/header.c | 37 +++++++++++++++++++---------
dlls/comctl32/tests/header.c | 56 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index dc533e1..4dec2d7 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -98,6 +98,11 @@ #define MAX_HEADER_TEXT_LEN 260
#define HDN_UNICODE_OFFSET 20
#define HDN_FIRST_UNICODE (HDN_FIRST-HDN_UNICODE_OFFSET)
+#define HDI_SUPPORTED_FIELDS (HDI_WIDTH|HDI_TEXT|HDI_FORMAT|HDI_LPARAM|HDI_BITMAP|HDI_IMAGE|HDI_ORDER)
+#define HDI_UNSUPPORTED_FIELDS (HDI_FILTER)
+#define HDI_UNKNOWN_FIELDS (~(HDI_SUPPORTED_FIELDS|HDI_UNSUPPORTED_FIELDS|HDI_DI_SETITEM))
+#define HDI_COMCTL32_4_0_FIELDS (HDI_WIDTH|HDI_TEXT|HDI_FORMAT|HDI_LPARAM|HDI_BITMAP)
+
#define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongPtrW(hwnd,0))
static BOOL HEADER_PrepareCallbackItems(HWND hwnd, INT iItem, INT reqMask);
@@ -116,6 +121,9 @@ static void HEADER_DisposeItem(HEADER_IT
static void HEADER_StoreHDItemInHeader(HEADER_ITEM *lpItem, UINT mask, HDITEMW *phdi, BOOL fUnicode)
{
+ if (mask & HDI_UNSUPPORTED_FIELDS)
+ FIXME("unsupported header fields %x\n", (mask & HDI_UNSUPPORTED_FIELDS));
+
if (mask & HDI_BITMAP)
lpItem->hbm = phdi->hbm;
@@ -955,41 +963,46 @@ HEADER_GetItemT (HWND hwnd, INT nItem, L
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
HEADER_ITEM *lpItem;
+ UINT mask = phdi->mask;
if (!phdi)
return FALSE;
TRACE("[nItem=%d]\n", nItem);
- if (phdi->mask == 0)
+ if (mask == 0)
return TRUE;
if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
return FALSE;
+ if (mask & HDI_UNKNOWN_FIELDS)
+ {
+ TRACE("mask %x contains unknown fields. Using only comctl32 4.0 fields\n", mask);
+ mask &= HDI_COMCTL32_4_0_FIELDS;
+ }
+
lpItem = &infoPtr->items[nItem];
- HEADER_PrepareCallbackItems(hwnd, nItem, phdi->mask);
+ HEADER_PrepareCallbackItems(hwnd, nItem, mask);
- if (phdi->mask & HDI_BITMAP)
+ if (mask & HDI_BITMAP)
phdi->hbm = lpItem->hbm;
- if (phdi->mask & HDI_FORMAT)
+ if (mask & HDI_FORMAT)
phdi->fmt = lpItem->fmt;
- if (phdi->mask & HDI_WIDTH)
+ if (mask & HDI_WIDTH)
phdi->cxy = lpItem->cxy;
- if (phdi->mask & HDI_LPARAM)
+ if (mask & HDI_LPARAM)
phdi->lParam = lpItem->lParam;
- if (phdi->mask & HDI_IMAGE)
- {
+ if (mask & HDI_IMAGE)
phdi->iImage = lpItem->iImage;
- }
- if (phdi->mask & HDI_ORDER)
+ if (mask & HDI_ORDER)
phdi->iOrder = lpItem->iOrder;
- if (phdi->mask & HDI_TEXT)
+ if (mask & HDI_TEXT)
{
if (bUnicode)
Str_GetPtrW (lpItem->pszText, phdi->pszText, phdi->cchTextMax);
@@ -1094,7 +1107,7 @@ HEADER_InsertItemT (HWND hwnd, INT nItem
UINT i;
UINT copyMask;
- if ((phdi == NULL) || (nItem < 0))
+ if ((phdi == NULL) || (nItem < 0) || (phdi->mask == 0))
return -1;
if (nItem > infoPtr->uNumItem)
diff --git a/dlls/comctl32/tests/header.c b/dlls/comctl32/tests/header.c
index 856bfc6..eb06bb0 100644
--- a/dlls/comctl32/tests/header.c
+++ b/dlls/comctl32/tests/header.c
@@ -321,6 +321,60 @@ static void check_auto_fields(void)
/* field from comctl >4.0 not tested as the system probably won't touch them */
}
+static void check_mask()
+{
+ HDITEMA hdi;
+ LRESULT ret;
+
+ /* don't create items if the mask is zero */
+ ZeroMemory(&hdi, sizeof(hdi));
+ hdi.mask = 0;
+ hdi.cxy = 200;
+ hdi.pszText = "ABC";
+ hdi.fmt = 0;
+ hdi.iOrder = 0;
+ hdi.lParam = 17;
+ hdi.cchTextMax = 260;
+ ret = SendMessage(hWndHeader, HDM_INSERTITEM, (WPARAM)0, (LPARAM)&hdi);
+ ok(ret == -1, "Creating an item with a zero mask should have failed\n");
+ if (ret != -1) SendMessage(hWndHeader, HDM_DELETEITEM, (WPARAM)0, (LPARAM)0);
+
+ /* with a non-zero mask creation will succeed */
+ ZeroMemory(&hdi, sizeof(hdi));
+ hdi.mask = HDI_LPARAM;
+ ret = SendMessage(hWndHeader, HDM_INSERTITEM, (WPARAM)0, (LPARAM)&hdi);
+ ok(ret != -1, "Adding item with non-zero mask failed\n");
+ if (ret != -1)
+ SendMessage(hWndHeader, HDM_DELETEITEM, (WPARAM)0, (LPARAM)0);
+
+ /* in SETITEM if the mask contains a unknown bit, it is ignored */
+ ZeroMemory(&hdi, sizeof(hdi));
+ hdi.mask = 0x08000000 | HDI_LPARAM | HDI_IMAGE;
+ hdi.lParam = 133;
+ hdi.iImage = 17;
+ ret = SendMessage(hWndHeader, HDM_INSERTITEM, (WPARAM)0, (LPARAM)&hdi);
+ ok(ret != -1, "Adding item failed\n");
+
+ if (ret != -1)
+ {
+ /* check result */
+ ZeroMemory(&hdi, sizeof(hdi));
+ hdi.mask = HDI_LPARAM | HDI_IMAGE;
+ SendMessage(hWndHeader, HDM_GETITEM, (WPARAM)0, (LPARAM)&hdi);
+ ok(hdi.lParam == 133, "comctl32 4.0 field not set\n");
+ ok(hdi.iImage == 17, "comctl32 >4.0 field not set\n");
+
+ /* but in GETITEM if an unknown bit is set, comctl32 uses only version 4.0 fields */
+ ZeroMemory(&hdi, sizeof(hdi));
+ hdi.mask = 0x08000000 | HDI_LPARAM | HDI_IMAGE;
+ SendMessage(hWndHeader, HDM_GETITEM, (WPARAM)0, (LPARAM)&hdi);
+ ok(hdi.lParam == 133, "comctl32 4.0 field not read\n");
+ ok(hdi.iImage == 0, "comctl32 >4.0 field shouldn't be read\n");
+
+ SendMessage(hWndHeader, HDM_DELETEITEM, (WPARAM)0, (LPARAM)0);
+ }
+}
+
static void test_header_control (void)
{
LONG res;
@@ -396,6 +450,8 @@ static void test_header_control (void)
TEST_GET_ITEMCOUNT(6);
check_auto_fields();
TEST_GET_ITEMCOUNT(6);
+ check_mask();
+ TEST_GET_ITEMCOUNT(6);
res = delItem(hWndHeader, 5);
ok(res == 1, "Deleting Out of Range item should fail with 1 (%ld)\n", res);
More information about the wine-cvs
mailing list