Module: wine Branch: refs/heads/master Commit: 36a8e5fba340cc15a2e76bbd5608772b8bce4dff URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=36a8e5fba340cc15a2e76bbd...
Author: Mikołaj Zalewski mikolaj@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);