mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
comctl32/header: Process input order array more accurately.
This commit is contained in:
parent
76859b0f47
commit
5517209a24
@ -1214,20 +1214,64 @@ HEADER_GetOrderArray(const HEADER_INFO *infoPtr, INT size, LPINT order)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Returns index of first duplicate 'value' from [0,to) range,
|
||||
or -1 if there isn't any */
|
||||
static INT has_duplicate(INT *array, INT to, INT value)
|
||||
{
|
||||
INT i;
|
||||
for(i = 0; i < to; i++)
|
||||
if (array[i] == value) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns next available value from [0,max] not to duplicate in [0,to) */
|
||||
static INT get_nextvalue(INT *array, INT to, INT max)
|
||||
{
|
||||
INT i;
|
||||
for(i = 0; i < max; i++)
|
||||
if (has_duplicate(array, to, i) == -1) return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT
|
||||
HEADER_SetOrderArray(HEADER_INFO *infoPtr, INT size, const INT *order)
|
||||
{
|
||||
INT i;
|
||||
HEADER_ITEM *lpItem;
|
||||
INT i;
|
||||
|
||||
if ((UINT)size <infoPtr->uNumItem)
|
||||
if ((UINT)size != infoPtr->uNumItem)
|
||||
return FALSE;
|
||||
memcpy(infoPtr->order, order, infoPtr->uNumItem * sizeof(INT));
|
||||
|
||||
for (i=0; i<size; i++)
|
||||
{
|
||||
lpItem = &infoPtr->items[*order++];
|
||||
lpItem->iOrder=i;
|
||||
}
|
||||
{
|
||||
if (order[i] >= size || order[i] < 0)
|
||||
/* on invalid index get next available */
|
||||
/* FIXME: if i==0 array item is out of range behaviour is
|
||||
different, see tests */
|
||||
infoPtr->order[i] = get_nextvalue(infoPtr->order, i, size);
|
||||
else
|
||||
{
|
||||
INT j, dup;
|
||||
|
||||
infoPtr->order[i] = order[i];
|
||||
j = i;
|
||||
/* remove duplicates */
|
||||
while ((dup = has_duplicate(infoPtr->order, j, order[j])) != -1)
|
||||
{
|
||||
INT next;
|
||||
|
||||
next = get_nextvalue(infoPtr->order, j, size);
|
||||
infoPtr->order[dup] = next;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sync with item data */
|
||||
for (i=0; i<size; i++)
|
||||
{
|
||||
lpItem = &infoPtr->items[infoPtr->order[i]];
|
||||
lpItem->iOrder = i;
|
||||
}
|
||||
HEADER_SetItemBounds(infoPtr);
|
||||
InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
|
||||
return TRUE;
|
||||
|
@ -1689,6 +1689,126 @@ static int init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* maximum 8 items allowed */
|
||||
static void check_orderarray(HWND hwnd, DWORD start, DWORD set, DWORD expected,
|
||||
int todo, int line)
|
||||
{
|
||||
int count, i;
|
||||
INT order[8];
|
||||
DWORD ret, array = 0;
|
||||
|
||||
count = SendMessage(hwnd, HDM_GETITEMCOUNT, 0, 0);
|
||||
|
||||
/* initial order */
|
||||
for(i = 1; i<=count; i++)
|
||||
order[i-1] = start>>(4*(count-i)) & 0xf;
|
||||
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, count, (LPARAM)order);
|
||||
ok_(__FILE__, line)(ret, "Expected HDM_SETORDERARAY to succeed, got %d\n", ret);
|
||||
|
||||
/* new order */
|
||||
for(i = 1; i<=count; i++)
|
||||
order[i-1] = set>>(4*(count-i)) & 0xf;
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, count, (LPARAM)order);
|
||||
ok_(__FILE__, line)(ret, "Expected HDM_SETORDERARAY to succeed, got %d\n", ret);
|
||||
|
||||
/* check actual order */
|
||||
ret = SendMessage(hwnd, HDM_GETORDERARRAY, count, (LPARAM)order);
|
||||
ok_(__FILE__, line)(ret, "Expected HDM_GETORDERARAY to succeed, got %d\n", ret);
|
||||
for(i = 1; i<=count; i++)
|
||||
array |= order[i-1]<<(4*(count-i));
|
||||
|
||||
if (todo) {
|
||||
todo_wine
|
||||
ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array);
|
||||
}
|
||||
else
|
||||
ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array);
|
||||
}
|
||||
|
||||
static void test_hdm_orderarray(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
INT order[5];
|
||||
DWORD ret;
|
||||
|
||||
hwnd = create_header_control();
|
||||
|
||||
/* three items */
|
||||
addItem(hwnd, 0, NULL);
|
||||
addItem(hwnd, 1, NULL);
|
||||
addItem(hwnd, 2, NULL);
|
||||
|
||||
ret = SendMessage(hwnd, HDM_GETORDERARRAY, 3, (LPARAM)order);
|
||||
if (!ret)
|
||||
{
|
||||
win_skip("HDM_GETORDERARRAY not implemented.\n");
|
||||
DestroyWindow(hwnd);
|
||||
return;
|
||||
}
|
||||
|
||||
expect(0, order[0]);
|
||||
expect(1, order[1]);
|
||||
expect(2, order[2]);
|
||||
|
||||
if (0)
|
||||
{
|
||||
/* null pointer, crashes native */
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, 3, (LPARAM)NULL);
|
||||
expect(FALSE, ret);
|
||||
}
|
||||
/* count out of limits */
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, 5, (LPARAM)order);
|
||||
expect(FALSE, ret);
|
||||
/* count out of limits */
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, 2, (LPARAM)order);
|
||||
expect(FALSE, ret);
|
||||
|
||||
/* try with out of range item index */
|
||||
/* (0,1,2)->(1,0,3) => (1,0,2) */
|
||||
check_orderarray(hwnd, 0x120, 0x103, 0x102, FALSE, __LINE__);
|
||||
/* (1,0,2)->(3,0,1) => (0,2,1) */
|
||||
check_orderarray(hwnd, 0x102, 0x301, 0x021, TRUE, __LINE__);
|
||||
/* (0,2,1)->(2,3,1) => (2,0,1) */
|
||||
check_orderarray(hwnd, 0x021, 0x231, 0x201, FALSE, __LINE__);
|
||||
|
||||
/* (0,1,2)->(0,2,2) => (0,1,2) */
|
||||
check_orderarray(hwnd, 0x012, 0x022, 0x012, FALSE, __LINE__);
|
||||
|
||||
addItem(hwnd, 3, NULL);
|
||||
|
||||
/* (0,1,2,3)->(0,1,2,2) => (0,1,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0122, 0x0132, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(0,1,3,3) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0133, 0x0123, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(0,4,2,3) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0423, 0x0123, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,0,1,2) => (0,1,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4012, 0x0132, TRUE, __LINE__);
|
||||
/* (0,1,3,2)->(4,0,1,4) => (0,3,1,2) */
|
||||
check_orderarray(hwnd, 0x0132, 0x4014, 0x0312, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(4,1,0,2) => (1,0,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4102, 0x1032, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(0,1,4,2) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0142, 0x0132, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,4,4,4) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4444, 0x0123, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,4,1,2) => (0,1,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4412, 0x0132, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(4,4,4,1) => (0,2,3,1) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4441, 0x0231, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(1,4,4,4) => (1,0,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x1444, 0x1023, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,2,4,1) => (0,2,3,1) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4241, 0x0231, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,2,0,1) => (2,0,3,1) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4201, 0x2031, TRUE, __LINE__);
|
||||
/* (3,2,1,0)->(4,2,0,1) => (3,2,0,1) */
|
||||
check_orderarray(hwnd, 0x3210, 0x4201, 0x3201, FALSE, __LINE__);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(header)
|
||||
{
|
||||
HWND parent_hwnd;
|
||||
@ -1700,6 +1820,7 @@ START_TEST(header)
|
||||
|
||||
test_header_control();
|
||||
test_header_order();
|
||||
test_hdm_orderarray();
|
||||
test_customdraw();
|
||||
|
||||
DestroyWindow(hHeaderParentWnd);
|
||||
|
Loading…
Reference in New Issue
Block a user