/* Unit test suite for header control.
 *
 * Copyright 2005 Vijay Kiran Kamuju
 * Copyright 2007 Shanren Zhou
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */


#include <windows.h>
#include <commctrl.h>
#include <assert.h>

#include "wine/test.h"
#include "v6util.h"
#include "msg.h"

typedef struct tagEXPECTEDNOTIFY
{
    INT iCode;
    BOOL fUnicode;
    HDITEMA hdItem;
} EXPECTEDNOTIFY;

typedef LRESULT (*CUSTOMDRAWPROC)(int n, NMCUSTOMDRAW *nm);

static CUSTOMDRAWPROC g_CustomDrawProc;
static int g_CustomDrawCount;
static DRAWITEMSTRUCT g_DrawItem;
static BOOL g_DrawItemReceived;
static DWORD g_customheight;

static EXPECTEDNOTIFY expectedNotify[10];
static INT nExpectedNotify = 0;
static INT nReceivedNotify = 0;
static INT unexpectedNotify[10];
static INT nUnexpectedNotify = 0;

static HWND hHeaderParentWnd;
static HWND hWndHeader;
#define MAX_CHARS 100

#define compare(val, exp, fmt)  ok((val) == (exp), #val " value: " fmt ", expected: " fmt "\n", (val), (exp))

#define expect(expected, got) ok(expected == got, "expected %d, got %d\n", expected,got)

#define NUM_MSG_SEQUENCES    2
#define PARENT_SEQ_INDEX     0
#define HEADER_SEQ_INDEX     1

static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];

static const struct message create_parent_wnd_seq[] = {
    { WM_GETMINMAXINFO, sent },
    { WM_NCCREATE, sent },
    { WM_NCCALCSIZE, sent|wparam, 0 },
    { WM_CREATE, sent },
    { 0 }
};

static const struct message add_header_to_parent_seq_interactive[] = {
    { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY },
    { WM_QUERYUISTATE, sent },
    { WM_PARENTNOTIFY, sent|wparam, 1 },
    { WM_SHOWWINDOW, sent|wparam, 1 },
    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
    { WM_ACTIVATEAPP, sent|wparam, 1 },
    { WM_NCACTIVATE, sent|wparam, 1 },
    { WM_ACTIVATE, sent|wparam, 1 },
    { WM_IME_SETCONTEXT, sent|defwinproc|wparam, 1 },
    { WM_IME_NOTIFY, sent|defwinproc|wparam, 2 },
    { WM_SETFOCUS, sent|defwinproc|wparam, 0 },
    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
    { WM_SIZE, sent|wparam, 0 },
    { WM_MOVE, sent|wparam, 0 },
    { 0 }
};

static const struct message add_header_to_parent_seq[] = {
    { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY },
    { WM_QUERYUISTATE, sent|optional },
    { WM_PARENTNOTIFY, sent },
    { 0 }
};

static const struct message insertItem_seq[] = {
    { HDM_INSERTITEM, sent|wparam, 0 },
    { HDM_INSERTITEM, sent|wparam, 1 },
    { HDM_INSERTITEM, sent|wparam, 2 },
    { HDM_INSERTITEM, sent|wparam, 3 },
    { 0 }
};

static const struct message getItem_seq[] = {
    { HDM_GETITEM, sent|wparam, 3 },
    { HDM_GETITEM, sent|wparam, 0 },
    { 0 }
};


static const struct message deleteItem_getItemCount_seq[] = {
    { HDM_DELETEITEM, sent|wparam, 3 },
    { HDM_GETITEMCOUNT, sent },
    { HDM_DELETEITEM, sent|wparam, 3 },
    { HDM_GETITEMCOUNT, sent },
    { HDM_DELETEITEM, sent|wparam, 2 },
    { HDM_GETITEMCOUNT, sent },
    { 0 }
};

static const struct message orderArray_seq[] = {
    { HDM_SETORDERARRAY, sent|wparam, 2 },
    { HDM_GETORDERARRAY, sent|wparam, 2 },
    { 0 }
};

static const struct message setItem_seq[] = {
    { HDM_SETITEM, sent|wparam, 0 },
    { HDM_SETITEM, sent|wparam, 1 },
    { 0 }
};

static const struct message getItemRect_seq[] = {
    { HDM_GETITEMRECT, sent|wparam, 1 },
    { HDM_GETITEMRECT, sent|wparam, 0 },
    { HDM_GETITEMRECT, sent|wparam, 10 },
    { 0 }
};

static const struct message layout_seq[] = {
    { HDM_LAYOUT, sent },
    { 0 }
};

static const struct message orderToIndex_seq[] = {
    { HDM_ORDERTOINDEX, sent|wparam, 1 },
    { 0 }
};

static const struct message hittest_seq[] = {
    { HDM_HITTEST, sent },
    { HDM_HITTEST, sent },
    { HDM_HITTEST, sent },
    { 0 }
};

static const struct message setHotDivider_seq_interactive[] = {
    { HDM_SETHOTDIVIDER, sent|wparam, TRUE },
    { WM_PAINT, sent|defwinproc},
    { WM_NCPAINT, sent|defwinproc},
    { WM_ERASEBKGND, sent|defwinproc},
    { HDM_SETHOTDIVIDER, sent|wparam|lparam, FALSE, 100 },
    { WM_PAINT, sent|defwinproc},
    { HDM_SETHOTDIVIDER, sent|wparam|lparam, FALSE, 1},
    { WM_PAINT, sent|defwinproc},
    { 0 }
};

static const struct message setHotDivider_seq_noninteractive[] = {
    { HDM_SETHOTDIVIDER, sent|wparam, TRUE },
    { HDM_SETHOTDIVIDER, sent|wparam|lparam, FALSE, 100 },
    { HDM_SETHOTDIVIDER, sent|wparam|lparam, FALSE, 1},
    { 0 }
};

static const struct message imageMessages_seq[] = {
    { HDM_SETIMAGELIST, sent },
    { HDM_GETIMAGELIST, sent },
    { HDM_CREATEDRAGIMAGE, sent },
    { 0 }
};

static const struct message filterMessages_seq_interactive[] = {
    { HDM_SETFILTERCHANGETIMEOUT, sent|wparam|lparam, 1, 100 },
    { HDM_CLEARFILTER, sent|wparam|lparam, 0, 1 },
    { HDM_EDITFILTER,  sent|wparam|lparam, 1, 0 },
    { WM_PARENTNOTIFY, sent|wparam|defwinproc, WM_CREATE },
    { WM_CTLCOLOREDIT, sent|defwinproc },
    { WM_COMMAND, sent|defwinproc },
    { 0 }
};

static const struct message filterMessages_seq_noninteractive[] = {
    { HDM_SETFILTERCHANGETIMEOUT, sent|wparam|lparam, 1, 100 },
    { HDM_CLEARFILTER, sent|wparam|lparam, 0, 1 },
    { HDM_EDITFILTER,  sent|wparam|lparam, 1, 0 },
    { WM_PARENTNOTIFY, sent|wparam|defwinproc|optional, WM_CREATE },
    { WM_COMMAND, sent|defwinproc|optional },
    { 0 }
};

static const struct message unicodeformatMessages_seq[] = {
    { HDM_SETUNICODEFORMAT, sent|wparam, TRUE },
    { HDM_GETUNICODEFORMAT, sent },
    { 0 }
};

static const struct message bitmapmarginMessages_seq[] = {
    { HDM_GETBITMAPMARGIN, sent },
    { 0 }
};


static void expect_notify(INT iCode, BOOL fUnicode, HDITEMA *lpItem)
{
    assert(nExpectedNotify < 10);
    expectedNotify[nExpectedNotify].iCode = iCode;
    expectedNotify[nExpectedNotify].fUnicode = fUnicode;
    expectedNotify[nExpectedNotify].hdItem = *lpItem;
    nExpectedNotify++;
}

static void dont_expect_notify(INT iCode)
{
    assert(nUnexpectedNotify < 10);
    unexpectedNotify[nUnexpectedNotify++] = iCode;
}

static BOOL notifies_received(void)
{
    BOOL fRet = (nExpectedNotify == nReceivedNotify);
    nExpectedNotify = nReceivedNotify = 0;
    nUnexpectedNotify = 0;
    return fRet;
}

static LONG addItem(HWND hdex, int idx, LPSTR text)
{
    HDITEMA hdItem;
    hdItem.mask       = HDI_TEXT | HDI_WIDTH;
    hdItem.cxy        = 100;
    hdItem.pszText    = text;
    hdItem.cchTextMax = 0;
    return SendMessage(hdex, HDM_INSERTITEMA, idx, (LPARAM)&hdItem);
}

static LONG setItem(HWND hdex, int idx, LPSTR text, BOOL fCheckNotifies)
{
    LONG ret;
    HDITEMA hdexItem;
    hdexItem.mask       = HDI_TEXT;
    hdexItem.pszText    = text;
    hdexItem.cchTextMax = 0;
    if (fCheckNotifies)
    {
        expect_notify(HDN_ITEMCHANGINGA, FALSE, &hdexItem);
        expect_notify(HDN_ITEMCHANGEDA, FALSE, &hdexItem);
    }
    ret = SendMessage(hdex, HDM_SETITEMA, idx, (LPARAM)&hdexItem);
    if (fCheckNotifies)
        ok(notifies_received(), "setItem(): not all expected notifies were received\n");
    return ret;
}

static LONG setItemUnicodeNotify(HWND hdex, int idx, LPSTR text, LPWSTR wText)
{
    LONG ret;
    HDITEMA hdexItem;
    HDITEMW hdexNotify;
    hdexItem.mask       = HDI_TEXT;
    hdexItem.pszText    = text;
    hdexItem.cchTextMax = 0;
    
    hdexNotify.mask    = HDI_TEXT;
    hdexNotify.pszText = wText;
    
    expect_notify(HDN_ITEMCHANGINGW, TRUE, (HDITEMA*)&hdexNotify);
    expect_notify(HDN_ITEMCHANGEDW, TRUE, (HDITEMA*)&hdexNotify);
    ret = SendMessage(hdex, HDM_SETITEMA, idx, (LPARAM)&hdexItem);
    ok(notifies_received(), "setItemUnicodeNotify(): not all expected notifies were received\n");
    return ret;
}

static LONG delItem(HWND hdex, int idx)
{
    return SendMessage(hdex, HDM_DELETEITEM, idx, 0);
}

static LONG getItemCount(HWND hdex)
{
    return SendMessage(hdex, HDM_GETITEMCOUNT, 0, 0);
}

static LONG getItem(HWND hdex, int idx, LPSTR textBuffer)
{
    HDITEMA hdItem;
    hdItem.mask         = HDI_TEXT;
    hdItem.pszText      = textBuffer;
    hdItem.cchTextMax   = MAX_CHARS;
    return SendMessage(hdex, HDM_GETITEMA, idx, (LPARAM)&hdItem);
}

static void addReadDelItem(HWND hdex, HDITEMA *phdiCreate, int maskRead, HDITEMA *phdiRead)
{
    ok(SendMessage(hdex, HDM_INSERTITEMA, 0, (LPARAM)phdiCreate)!=-1, "Adding item failed\n");
    ZeroMemory(phdiRead, sizeof(HDITEMA));
    phdiRead->mask = maskRead;
    ok(SendMessage(hdex, HDM_GETITEMA, 0, (LPARAM)phdiRead)!=0, "Getting item data failed\n");
    ok(SendMessage(hdex, HDM_DELETEITEM, 0, 0)!=0, "Deleting item failed\n");
}

static HWND create_header_control (void)
{
    HWND handle;
    HDLAYOUT hlayout;
    RECT rectwin;
    WINDOWPOS winpos;

    handle = CreateWindowEx(0, WC_HEADER, NULL,
			    WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ,
			    0, 0, 0, 0,
			    hHeaderParentWnd, NULL, NULL, NULL);
    assert(handle);

    if (winetest_interactive)
	ShowWindow (hHeaderParentWnd, SW_SHOW);

    GetClientRect(hHeaderParentWnd,&rectwin);
    hlayout.prc = &rectwin;
    hlayout.pwpos = &winpos;
    SendMessageA(handle,HDM_LAYOUT,0,(LPARAM) &hlayout);
    SetWindowPos(handle, winpos.hwndInsertAfter, winpos.x, winpos.y, 
                 winpos.cx, winpos.cy, 0);

    return handle;
}

static void compare_items(INT iCode, HDITEMA *hdi1, HDITEMA *hdi2, BOOL fUnicode)
{
    ok(hdi1->mask == hdi2->mask, "Notify %d mask mismatch (%08x != %08x)\n", iCode, hdi1->mask, hdi2->mask);
    if (hdi1->mask & HDI_WIDTH)
    {
        ok(hdi1->cxy == hdi2->cxy, "Notify %d cxy mismatch (%08x != %08x)\n", iCode, hdi1->cxy, hdi2->cxy);
    }
    if (hdi1->mask & HDI_TEXT)
    {
        if (hdi1->pszText == LPSTR_TEXTCALLBACKA)
        {
            ok(hdi1->pszText == LPSTR_TEXTCALLBACKA, "Notify %d - only one item is LPSTR_TEXTCALLBACK\n", iCode);
        }
        else
        if (fUnicode)
        {
            char buf1[260];
            char buf2[260];
            WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)hdi1->pszText, -1, buf1, 260, NULL, NULL);
            WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)hdi2->pszText, -1, buf2, 260, NULL, NULL);
            ok(lstrcmpW((LPWSTR)hdi1->pszText, (LPWSTR)hdi2->pszText)==0,
                "Notify %d text mismatch (L\"%s\" vs L\"%s\")\n",
                    iCode, buf1, buf2);
        }
        else
        {
            ok(strcmp(hdi1->pszText, hdi2->pszText)==0,
                "Notify %d text mismatch (\"%s\" vs \"%s\")\n",
                    iCode, hdi1->pszText, hdi2->pszText);
            }
    }
}

static char pszFirstItem[]      = "First Item";
static char pszSecondItem[]     = "Second Item";
static char pszThirdItem[]      = "Third Item";
static char pszFourthItem[]     = "Fourth Item";
static char pszReplaceItem[]    = "Replace Item";
static char pszOutOfRangeItem[] = "Out Of Range Item";

static char *str_items[] =
    {pszFirstItem, pszSecondItem, pszThirdItem, pszFourthItem, pszReplaceItem, pszOutOfRangeItem};
    
static char pszUniTestA[]  = "TST";
static WCHAR pszUniTestW[] = {'T','S','T',0};


#define TEST_GET_ITEM(i,c)\
{   res = getItem(hWndHeader, i, buffer);\
    ok(res != 0, "Getting item[%d] using valid index failed unexpectedly (%d)\n", i, res);\
    ok(strcmp(str_items[c], buffer) == 0, "Getting item[%d] returned \"%s\" expecting \"%s\"\n", i, buffer, str_items[c]);\
}

#define TEST_GET_ITEMCOUNT(i)\
{   res = getItemCount(hWndHeader);\
    ok(res == i, "Got Item Count as %d\n", res);\
}

static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
    static LONG defwndproc_counter = 0;
    LRESULT ret;
    struct message msg;

    trace("header: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
    msg.message = message;
    msg.flags = sent|wparam|lparam;
    if (defwndproc_counter) msg.flags |= defwinproc;
    msg.wParam = wParam;
    msg.lParam = lParam;
    add_message(sequences, HEADER_SEQ_INDEX, &msg);

    defwndproc_counter++;
    ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
    defwndproc_counter--;

    return ret;
}

static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static LONG defwndproc_counter = 0;
    LRESULT ret;
    struct message msg;

    /* do not log painting messages */
    if (message != WM_PAINT &&
        message != WM_ERASEBKGND &&
        message != WM_NCPAINT &&
        message != WM_NCHITTEST &&
        message != WM_GETTEXT &&
        message != WM_GETICON &&
        message != WM_DEVICECHANGE)

    {
        trace("parent: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);

        msg.message = message;
        msg.flags = sent|wparam|lparam;
        if (defwndproc_counter) msg.flags |= defwinproc;
        msg.wParam = wParam;
        msg.lParam = lParam;
        add_message(sequences, PARENT_SEQ_INDEX, &msg);
   }

    defwndproc_counter++;
    ret = DefWindowProcA(hwnd, message, wParam, lParam);
    defwndproc_counter--;

    return ret;
}

static BOOL register_parent_wnd_class(void)
{
    WNDCLASSA cls;

    cls.style = 0;
    cls.lpfnWndProc = parent_wnd_proc;
    cls.cbClsExtra = 0;
    cls.cbWndExtra = 0;
    cls.hInstance = GetModuleHandleA(NULL);
    cls.hIcon = 0;
    cls.hCursor = LoadCursorA(0, IDC_ARROW);
    cls.hbrBackground = GetStockObject(WHITE_BRUSH);
    cls.lpszMenuName = NULL;
    cls.lpszClassName = "Header test parent class";
    return RegisterClassA(&cls);
}

static HWND create_custom_parent_window(void)
{
    if (!register_parent_wnd_class())
        return NULL;

    return CreateWindowExA(0, "Header test parent class", "Header Message Sequence Testing",
                           WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                           672+2*GetSystemMetrics(SM_CXSIZEFRAME),
                           226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
                           NULL, NULL, GetModuleHandleA(NULL), 0);
}

static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems)
{
    WNDPROC oldproc;
    HWND childHandle;
    HDLAYOUT hlayout;
    RECT rectwin;
    WINDOWPOS winpos;
    int retVal;
    int loopcnt;
    static char firstHeaderItem[] = "Name";
    static char secondHeaderItem[] = "Size";
    static char *items[] = {secondHeaderItem, firstHeaderItem};
    HDITEM hdItem;
    hdItem.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
    hdItem.fmt = HDF_LEFT;
    hdItem.cxy = 80;
    hdItem.cchTextMax = 260;


    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    childHandle = CreateWindowEx(0, WC_HEADER, NULL,
                           WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ,
                           0, 0, 0, 0,
                           hParent, NULL, NULL, NULL);
    assert(childHandle);
    if (preloadHeaderItems)
    {
         for ( loopcnt = 0 ; loopcnt < 2 ; loopcnt++ )
         {
             hdItem.pszText = items[loopcnt];
             retVal = SendMessage(childHandle, HDM_INSERTITEM, loopcnt, (LPARAM) &hdItem);
             ok(retVal == loopcnt, "Adding item %d failed with return value %d\n", ( loopcnt + 1 ), retVal);
          }
    }

    if (winetest_interactive)
       ShowWindow (hParent, SW_SHOW);

    GetClientRect(hParent,&rectwin);
    hlayout.prc = &rectwin;
    hlayout.pwpos = &winpos;
    SendMessageA(childHandle,HDM_LAYOUT,0,(LPARAM) &hlayout);
    SetWindowPos(childHandle, winpos.hwndInsertAfter, winpos.x, winpos.y,
                 winpos.cx, winpos.cy, 0);

    oldproc = (WNDPROC)SetWindowLongPtrA(childHandle, GWLP_WNDPROC,
                                         (LONG_PTR)header_subclass_proc);
    SetWindowLongPtrA(childHandle, GWLP_USERDATA, (LONG_PTR)oldproc);
    return childHandle;
}

static void check_auto_format(void)
{
    HDITEMA hdiCreate;
    HDITEMA hdiRead;
    static CHAR text[] = "Test";
    ZeroMemory(&hdiCreate, sizeof(HDITEMA));

    /* Windows implicitly sets some format bits in INSERTITEM */

    /* HDF_STRING is automatically set and cleared for no text */
    hdiCreate.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT;
    hdiCreate.pszText = text;
    hdiCreate.cxy = 100;
    hdiCreate.fmt=HDF_CENTER;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == (HDF_STRING|HDF_CENTER), "HDF_STRING not set automatically (fmt=%x)\n", hdiRead.fmt);

    hdiCreate.mask = HDI_WIDTH|HDI_FORMAT;
    hdiCreate.pszText = text;
    hdiCreate.fmt = HDF_CENTER|HDF_STRING;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == (HDF_CENTER), "HDF_STRING should be automatically cleared (fmt=%x)\n", hdiRead.fmt);

    /* HDF_BITMAP is automatically set and cleared for a NULL bitmap or no bitmap */
    hdiCreate.mask = HDI_BITMAP|HDI_WIDTH|HDI_FORMAT;
    hdiCreate.hbm = CreateBitmap(16, 16, 1, 8, NULL);
    hdiCreate.fmt = HDF_CENTER;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == (HDF_BITMAP|HDF_CENTER), "HDF_BITMAP not set automatically (fmt=%x)\n", hdiRead.fmt);
    DeleteObject(hdiCreate.hbm);

    hdiCreate.hbm = NULL;
    hdiCreate.fmt = HDF_CENTER|HDF_BITMAP;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == HDF_CENTER, "HDF_BITMAP not cleared automatically for NULL bitmap (fmt=%x)\n", hdiRead.fmt);

    hdiCreate.mask = HDI_WIDTH|HDI_FORMAT;
    hdiCreate.fmt = HDF_CENTER|HDF_BITMAP;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == HDF_CENTER, "HDF_BITMAP not cleared automatically for no bitmap (fmt=%x)\n", hdiRead.fmt);

    /* HDF_IMAGE is automatically set but not cleared */
    hdiCreate.mask = HDI_IMAGE|HDI_WIDTH|HDI_FORMAT;
    hdiCreate.iImage = 17;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == (HDF_IMAGE|HDF_CENTER), "HDF_IMAGE not set automatically (fmt=%x)\n", hdiRead.fmt);

    hdiCreate.mask = HDI_WIDTH|HDI_FORMAT;
    hdiCreate.fmt = HDF_CENTER|HDF_IMAGE;
    hdiCreate.iImage = 0;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    ok(hdiRead.fmt == (HDF_CENTER|HDF_IMAGE), "HDF_IMAGE shouldn't be cleared automatically (fmt=%x)\n", hdiRead.fmt);
}

static void check_auto_fields(void)
{
    HDITEMA hdiCreate;
    HDITEMA hdiRead;
    static CHAR text[] = "Test";
    LONG res;

    /* Windows stores the format, width, lparam even if they are not in the item's mask */
    ZeroMemory(&hdiCreate, sizeof(HDITEMA));
    hdiCreate.mask = HDI_TEXT;
    hdiCreate.cxy = 100;
    hdiCreate.pszText = text;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_WIDTH, &hdiRead);
    TEST_GET_ITEMCOUNT(6);
    ok(hdiRead.cxy == hdiCreate.cxy, "cxy should be automatically set\n");

    ZeroMemory(&hdiCreate, sizeof(HDITEMA));
    hdiCreate.mask = HDI_TEXT;
    hdiCreate.pszText = text;
    hdiCreate.lParam = 0x12345678;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_LPARAM, &hdiRead);
    TEST_GET_ITEMCOUNT(6);
    ok(hdiRead.lParam == hdiCreate.lParam, "lParam should be automatically set\n");

    ZeroMemory(&hdiCreate, sizeof(HDITEMA));
    hdiCreate.mask = HDI_TEXT;
    hdiCreate.pszText = text;
    hdiCreate.fmt = HDF_STRING|HDF_CENTER;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_FORMAT, &hdiRead);
    TEST_GET_ITEMCOUNT(6);
    ok(hdiRead.fmt == hdiCreate.fmt, "fmt should be automatically set\n");

    /* others fields are not set */
    ZeroMemory(&hdiCreate, sizeof(HDITEMA));
    hdiCreate.mask = HDI_TEXT;
    hdiCreate.pszText = text;
    hdiCreate.hbm = CreateBitmap(16, 16, 1, 8, NULL);
    addReadDelItem(hWndHeader, &hdiCreate, HDI_BITMAP, &hdiRead);
    TEST_GET_ITEMCOUNT(6);
    ok(hdiRead.hbm == NULL, "hbm should not be automatically set\n");
    DeleteObject(hdiCreate.hbm);

    ZeroMemory(&hdiCreate, sizeof(HDITEMA));
    hdiCreate.mask = HDI_IMAGE;
    hdiCreate.iImage = 17;
    hdiCreate.pszText = text;
    addReadDelItem(hWndHeader, &hdiCreate, HDI_TEXT, &hdiRead);
    TEST_GET_ITEMCOUNT(6);
    ok(hdiRead.pszText==NULL, "pszText shouldn't be automatically set\n");

    /* field from comctl >4.0 not tested as the system probably won't touch them */
}

static void check_mask(void)
{
    HDITEMA hdi;
    static CHAR text[] = "ABC";
    LRESULT ret;

    /* don't create items if the mask is zero */
    ZeroMemory(&hdi, sizeof(hdi));
    hdi.mask = 0;
    hdi.cxy = 200;
    hdi.pszText = text;
    hdi.fmt = 0;
    hdi.iOrder = 0;
    hdi.lParam = 17;
    hdi.cchTextMax = 260;
    ret = SendMessage(hWndHeader, HDM_INSERTITEM, 0, (LPARAM)&hdi);
    ok(ret == -1, "Creating an item with a zero mask should have failed\n");
    if (ret != -1) SendMessage(hWndHeader, HDM_DELETEITEM, 0, 0);

    /* with a non-zero mask creation will succeed */
    ZeroMemory(&hdi, sizeof(hdi));
    hdi.mask = HDI_LPARAM;
    ret = SendMessage(hWndHeader, HDM_INSERTITEM, 0, (LPARAM)&hdi);
    ok(ret != -1, "Adding item with non-zero mask failed\n");
    if (ret != -1)
        SendMessage(hWndHeader, HDM_DELETEITEM, 0, 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, 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, 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, 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, 0, 0);
    }
}

static void test_header_control (void)
{
    LONG res;
    static char buffer[MAX_CHARS];
    int i;

    hWndHeader = create_header_control ();

    for (i = 3; i >= 0; i--)
    {
        TEST_GET_ITEMCOUNT(3-i);
        res = addItem(hWndHeader, 0, str_items[i]);
        ok(res == 0, "Adding simple item failed (%d)\n", res);
    }

    TEST_GET_ITEMCOUNT(4);
    res = addItem(hWndHeader, 99, str_items[i+1]);
    ok(res != -1, "Adding Out of Range item should fail with -1 got (%d)\n", res);
    TEST_GET_ITEMCOUNT(5);
    res = addItem(hWndHeader, 5, str_items[i+1]);
    ok(res != -1, "Adding Out of Range item should fail with -1 got (%d)\n", res);
    TEST_GET_ITEMCOUNT(6);

    for (i = 0; i < 4; i++) { TEST_GET_ITEM(i,i); TEST_GET_ITEMCOUNT(6); }

    res=getItem(hWndHeader, 99, buffer);
    ok(res == 0, "Getting Out of Range item should fail with 0 (%d), got %s\n", res,buffer);
    res=getItem(hWndHeader, 5, buffer);
    ok(res == 1, "Getting Out of Range item should fail with 1 (%d), got %s\n", res,buffer);
    res=getItem(hWndHeader, -2, buffer);
    ok(res == 0, "Getting Out of Range item should fail with 0 (%d), got %s\n", res,buffer);

    if (winetest_interactive)
    {
        UpdateWindow(hHeaderParentWnd);
        UpdateWindow(hWndHeader);
    }

    TEST_GET_ITEMCOUNT(6);
    res=setItem(hWndHeader, 99, str_items[5], FALSE);
    ok(res == 0, "Setting Out of Range item should fail with 0 (%d)\n", res);
    res=setItem(hWndHeader, 5, str_items[5], TRUE);
    ok(res == 1, "Setting Out of Range item should fail with 1 (%d)\n", res);
    res=setItem(hWndHeader, -2, str_items[5], FALSE);
    ok(res == 0, "Setting Out of Range item should fail with 0 (%d)\n", res);
    TEST_GET_ITEMCOUNT(6);

    for (i = 0; i < 4; i++)
    {
        res = setItem(hWndHeader, i, str_items[4], TRUE);
        ok(res != 0, "Setting %d item failed (%d)\n", i+1, res);
        TEST_GET_ITEM(i, 4);
        TEST_GET_ITEMCOUNT(6);
    }

    SendMessageA(hWndHeader, HDM_SETUNICODEFORMAT, TRUE, 0);
    setItemUnicodeNotify(hWndHeader, 3, pszUniTestA, pszUniTestW);
    SendMessageA(hWndHeader, WM_NOTIFYFORMAT, (WPARAM)hHeaderParentWnd, NF_REQUERY);
    setItem(hWndHeader, 3, str_items[4], TRUE);
    
    dont_expect_notify(HDN_GETDISPINFOA);
    dont_expect_notify(HDN_GETDISPINFOW);
    addItem(hWndHeader, 0, LPSTR_TEXTCALLBACKA);
    setItem(hWndHeader, 0, str_items[4], TRUE);
    /* unexpected notifies cleared by notifies_received in setItem */
    dont_expect_notify(HDN_GETDISPINFOA);
    dont_expect_notify(HDN_GETDISPINFOW);
    setItem(hWndHeader, 0, LPSTR_TEXTCALLBACKA, TRUE);
    /* unexpected notifies cleared by notifies_received in setItem */
    delItem(hWndHeader, 0);

    check_auto_format();
    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 (%d)\n", res);
    res = delItem(hWndHeader, -2);
    ok(res == 0, "Deleting Out of Range item should fail with 0 (%d)\n", res);
    TEST_GET_ITEMCOUNT(5);

    res = delItem(hWndHeader, 3);
    ok(res != 0, "Deleting using out of range index failed (%d)\n", res);
    TEST_GET_ITEMCOUNT(4);
    res = delItem(hWndHeader, 0);
    ok(res != 0, "Deleting using out of range index failed (%d)\n", res);
    TEST_GET_ITEMCOUNT(3);
    res = delItem(hWndHeader, 0);
    ok(res != 0, "Deleting using out of range index failed (%d)\n", res);
    TEST_GET_ITEMCOUNT(2);
    res = delItem(hWndHeader, 0);
    ok(res != 0, "Deleting using out of range index failed (%d)\n", res);
    TEST_GET_ITEMCOUNT(1);

    DestroyWindow(hWndHeader);
}

static void test_hdm_getitemrect(HWND hParent)
{

    HWND hChild;
    RECT rect;
    int retVal;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    retVal = SendMessage(hChild, HDM_GETITEMRECT, 1, (LPARAM) &rect);
    ok(retVal == TRUE, "Getting item rect should TRUE, got %d\n", retVal);
    /* check bounding rectangle information of 2nd header item */
    expect(80, rect.left);
    expect(0, rect.top);
    expect(160, rect.right);
    expect(g_customheight, rect.bottom);

    retVal = SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM) &rect);

    ok(retVal == TRUE, "Getting item rect should TRUE, got %d\n", retVal);
    /* check bounding rectangle information of 1st header item */
    expect(0, rect.left);
    expect(0, rect.top);

    expect(80, rect.right);
    expect(g_customheight, rect.bottom);

    retVal = SendMessage(hChild, HDM_GETITEMRECT, 10, (LPARAM) &rect);
    ok(retVal == 0, "Getting rect of nonexistent item should return 0, got %d\n", retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, getItemRect_seq, "getItemRect sequence testing", FALSE);
    DestroyWindow(hChild);
}

static void test_hdm_layout(HWND hParent)
{
    HWND hChild;
    int retVal;
    RECT rect;
    HDLAYOUT hdLayout;
    WINDOWPOS windowPos;
    hdLayout.prc = &rect;
    hdLayout.pwpos = &windowPos;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    retVal = SendMessage(hChild, HDM_LAYOUT, 0, (LPARAM) &hdLayout);
    expect(TRUE, retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, layout_seq, "layout sequence testing", FALSE);

    DestroyWindow(hChild);
}

static void test_hdm_ordertoindex(HWND hParent)
{
    HWND hChild;
    int retVal;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    retVal = SendMessage(hChild, HDM_ORDERTOINDEX, 1, 0);
    expect(1, retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, orderToIndex_seq, "orderToIndex sequence testing", FALSE);
    DestroyWindow(hChild);
}

static void test_hdm_hittest(HWND hParent)
{
    HWND hChild;
    int retVal;
    POINT pt;
    HDHITTESTINFO hdHitTestInfo;
    const int firstItemRightBoundary = 80;
    const int secondItemRightBoundary = 160;
    const int bottomBoundary = g_customheight;

    pt.x = firstItemRightBoundary - 1;
    pt.y = bottomBoundary - 1;
    hdHitTestInfo.pt = pt;


    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
    expect(0, retVal);
    expect(0, hdHitTestInfo.iItem);
    expect(HHT_ONDIVIDER, hdHitTestInfo.flags);

    pt.x = secondItemRightBoundary - 1;
    pt.y = bottomBoundary - 1;
    hdHitTestInfo.pt = pt;
    retVal = SendMessage(hChild, HDM_HITTEST, 1, (LPARAM) &hdHitTestInfo);
    expect(1, retVal);
    expect(1, hdHitTestInfo.iItem);
    expect(HHT_ONDIVIDER, hdHitTestInfo.flags);

    pt.x = secondItemRightBoundary;
    pt.y = bottomBoundary + 1;
    hdHitTestInfo.pt = pt;
    retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
    expect(-1, retVal);
    expect(-1, hdHitTestInfo.iItem);
    expect(HHT_BELOW, hdHitTestInfo.flags);

    ok_sequence(sequences, HEADER_SEQ_INDEX, hittest_seq, "hittest sequence testing", FALSE);

    DestroyWindow(hChild);
}

static void test_hdm_sethotdivider(HWND hParent)
{
    HWND hChild;
    int retVal;
    /*  low word: x coordinate = 5
     *  high word:  y coordinate = 5
     */

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, TRUE, MAKELPARAM(5, 5));
    expect(0, retVal);

    retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, FALSE, 100);
    expect(100, retVal);
    retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, FALSE, 1);
    expect(1, retVal);
    if (winetest_interactive)
       ok_sequence(sequences, HEADER_SEQ_INDEX, setHotDivider_seq_interactive,
                   "setHotDivider sequence testing", TRUE);
    else
       ok_sequence(sequences, HEADER_SEQ_INDEX, setHotDivider_seq_noninteractive,
                   "setHotDivider sequence testing", FALSE);

    DestroyWindow(hChild);
}

static void test_hdm_imageMessages(HWND hParent)
{
    HIMAGELIST hImageList = ImageList_Create (4, 4, 0, 1, 0);
    HIMAGELIST hIml;
    BOOL wasValid;
    HWND hChild;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    hIml = (HIMAGELIST) SendMessage(hChild, HDM_SETIMAGELIST, 0, (LPARAM) hImageList);
    ok(hIml == NULL, "Expected NULL, got %p\n", hIml);

    hIml = (HIMAGELIST) SendMessage(hChild, HDM_GETIMAGELIST, 0, 0);
    ok(hIml != NULL, "Expected non-NULL handle, got %p\n", hIml);

    hIml = (HIMAGELIST) SendMessage(hChild, HDM_CREATEDRAGIMAGE, 0, 0);
    ok(hIml != NULL, "Expected non-NULL handle, got %p\n", hIml);
    ImageList_Destroy(hIml);

    ok_sequence(sequences, HEADER_SEQ_INDEX, imageMessages_seq, "imageMessages sequence testing", FALSE);

    DestroyWindow(hChild);

    wasValid = ImageList_Destroy(hImageList);
    ok(wasValid, "Header must not free image list at destruction!\n");
}

static void test_hdm_filterMessages(HWND hParent)
{
    HWND hChild;
    int retVal, timeout;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    assert(hChild);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    timeout = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100);
    SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, timeout);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    /* msdn incorrectly states that return value
     * is the index of the filter control being
     * modified. The sendMessage here should
     * return previous filter timeout value
     */

    retVal = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100);
    expect(timeout, retVal);

    todo_wine
    {
        retVal = SendMessage(hChild, HDM_CLEARFILTER, 0, 1);
        if (retVal == 0)
            win_skip("HDM_CLEARFILTER needs 5.80\n");
        else
            expect(1, retVal);

        retVal = SendMessage(hChild, HDM_EDITFILTER, 1, 0);
        if (retVal == 0)
            win_skip("HDM_EDITFILTER needs 5.80\n");
        else
            expect(1, retVal);
    }
    if (winetest_interactive)
         ok_sequence(sequences, HEADER_SEQ_INDEX, filterMessages_seq_interactive,
                     "filterMessages sequence testing", TRUE);
    else
         ok_sequence(sequences, HEADER_SEQ_INDEX, filterMessages_seq_noninteractive,
                     "filterMessages sequence testing", FALSE);
    DestroyWindow(hChild);

}

static void test_hdm_unicodeformatMessages(HWND hParent)
{
    HWND hChild;
    int retVal;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    retVal = SendMessage(hChild, HDM_SETUNICODEFORMAT, TRUE, 0);
    expect(0, retVal);
    retVal = SendMessage(hChild, HDM_GETUNICODEFORMAT, 0, 0);
    expect(1, retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, unicodeformatMessages_seq,
                     "unicodeformatMessages sequence testing", FALSE);
    DestroyWindow(hChild);
}

static void test_hdm_bitmapmarginMessages(HWND hParent)
{
    HWND hChild;
    int retVal;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, TRUE);
    ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                    "adder header control to parent", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    retVal = SendMessage(hChild, HDM_GETBITMAPMARGIN, 0, 0);
    if (retVal == 0)
        win_skip("HDM_GETBITMAPMARGIN needs 5.80\n");
    else
        expect(6, retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, bitmapmarginMessages_seq,
                      "bitmapmarginMessages sequence testing", FALSE);
    DestroyWindow(hChild);
}

static void test_hdm_index_messages(HWND hParent)
{
    HWND hChild;
    int retVal;
    int loopcnt;
    int strcmpResult;
    int iSize;
    static const int lpiarray[2] = {1, 0};
    static int lpiarrayReceived[2];
    static char firstHeaderItem[] = "Name";
    static char secondHeaderItem[] = "Size";
    static char thirdHeaderItem[] = "Type";
    static char fourthHeaderItem[] = "Date Modified";
    static char *items[] = {firstHeaderItem, secondHeaderItem, thirdHeaderItem, fourthHeaderItem};
    RECT rect;
    HDITEM hdItem;
    hdItem.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
    hdItem.fmt = HDF_LEFT;
    hdItem.cxy = 80;
    hdItem.cchTextMax = 260;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    hChild = create_custom_header_control(hParent, FALSE);
    if (winetest_interactive)
         ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq_interactive,
                                              "adder header control to parent", TRUE);
    else
         ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
                                     "adder header control to parent", FALSE);
    flush_sequences(sequences, NUM_MSG_SEQUENCES);
    for ( loopcnt = 0 ; loopcnt < 4 ; loopcnt++ )
    {
      hdItem.pszText = items[loopcnt];
      retVal = SendMessage(hChild, HDM_INSERTITEM, loopcnt, (LPARAM) &hdItem);
      ok(retVal == loopcnt, "Adding item %d failed with return value %d\n", ( loopcnt + 1 ), retVal);
    }
    ok_sequence(sequences, HEADER_SEQ_INDEX, insertItem_seq, "insertItem sequence testing", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    retVal = SendMessage(hChild, HDM_DELETEITEM, 3, (LPARAM) &hdItem);
    ok(retVal == TRUE, "Deleting item 3 should return TRUE, got %d\n", retVal);
    retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
    ok(retVal == 3, "Getting item count should return 3, got %d\n", retVal);

    retVal = SendMessage(hChild, HDM_DELETEITEM, 3, (LPARAM) &hdItem);
    ok(retVal == FALSE, "Deleting already-deleted item should return FALSE, got %d\n", retVal);
    retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
    ok(retVal == 3, "Getting item count should return 3, got %d\n", retVal);

    retVal = SendMessage(hChild, HDM_DELETEITEM, 2, (LPARAM) &hdItem);
    ok(retVal == TRUE, "Deleting item 2 should return TRUE, got %d\n", retVal);
    retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
    ok(retVal == 2, "Getting item count should return 2, got %d\n", retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, deleteItem_getItemCount_seq,
                         "deleteItem_getItemCount sequence testing", FALSE);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    retVal = SendMessage(hChild, HDM_GETITEM, 3, (LPARAM) &hdItem);
    ok(retVal == FALSE, "Getting already-deleted item should return FALSE, got %d\n", retVal);

    retVal = SendMessage(hChild, HDM_GETITEM, 0, (LPARAM) &hdItem);
    ok(retVal == TRUE, "Getting the 1st header item should return TRUE, got %d\n", retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, getItem_seq, "getItem sequence testing", FALSE);

    /* check if the item is the right one */
    strcmpResult =  strcmp(hdItem.pszText, firstHeaderItem);
    expect(0, strcmpResult);
    expect(80, hdItem.cxy);

    iSize = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);

    /* item should be updated just after accepting new array */
    ShowWindow(hChild, SW_HIDE);
    retVal = SendMessage(hChild, HDM_SETORDERARRAY, iSize, (LPARAM) lpiarray);
    expect(TRUE, retVal);
    rect.left = 0;
    retVal = SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM) &rect);
    expect(TRUE, retVal);
    ok(rect.left != 0, "Expected updated rectangle\n");

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    retVal = SendMessage(hChild, HDM_SETORDERARRAY, iSize, (LPARAM) lpiarray);
    ok(retVal == TRUE, "Setting header items order should return TRUE, got %d\n", retVal);

    retVal = SendMessage(hChild, HDM_GETORDERARRAY, iSize, (LPARAM) lpiarrayReceived);
    ok(retVal == TRUE, "Getting header items order should return TRUE, got %d\n", retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, orderArray_seq, "set_get_orderArray sequence testing", FALSE);

    /* check if the array order is set correctly and the size of the array is correct. */
    expect(2, iSize);
    expect(lpiarray[0], lpiarrayReceived[0]);
    expect(lpiarray[1], lpiarrayReceived[1]);

    hdItem.mask = HDI_FORMAT;
    hdItem.fmt = HDF_CENTER | HDF_STRING;

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    retVal = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM) &hdItem);
    ok(retVal == TRUE, "Aligning 1st header item to center should return TRUE, got %d\n", retVal);
    hdItem.fmt = HDF_RIGHT | HDF_STRING;
    retVal = SendMessage(hChild, HDM_SETITEM, 1, (LPARAM) &hdItem);
    ok(retVal == TRUE, "Aligning 2nd header item to right should return TRUE, got %d\n", retVal);

    ok_sequence(sequences, HEADER_SEQ_INDEX, setItem_seq, "setItem sequence testing", FALSE);
    DestroyWindow(hChild);
}

static void test_hdf_fixedwidth(HWND hParent)
{
    HWND hChild;
    HDITEM hdItem;
    DWORD ret;
    RECT rect;
    HDHITTESTINFO ht;

    hChild = create_custom_header_control(hParent, FALSE);

    hdItem.mask = HDI_WIDTH | HDI_FORMAT;
    hdItem.fmt = HDF_FIXEDWIDTH;
    hdItem.cxy = 80;

    ret = SendMessage(hChild, HDM_INSERTITEM, 0, (LPARAM)&hdItem);
    expect(0, ret);

    /* try to change width */
    rect.right = rect.bottom = 0;
    SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
    ok(rect.right  != 0, "Expected not zero width\n");
    ok(rect.bottom != 0, "Expected not zero height\n");

    SendMessage(hChild, WM_LBUTTONDOWN, 0, MAKELPARAM(rect.right, rect.bottom / 2));
    SendMessage(hChild, WM_MOUSEMOVE, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));
    SendMessage(hChild, WM_LBUTTONUP, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));

    SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);

    if (hdItem.cxy != rect.right)
    {
        win_skip("HDF_FIXEDWIDTH format not supported\n");
        DestroyWindow(hChild);
        return;
    }

    /* try to adjust with message */
    hdItem.mask = HDI_WIDTH;
    hdItem.cxy = 90;

    ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem);
    expect(TRUE, ret);

    rect.right = 0;
    SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
    expect(90, rect.right);

    /* hittesting doesn't report ondivider flag for HDF_FIXEDWIDTH */
    ht.pt.x = rect.right - 1;
    ht.pt.y = rect.bottom / 2;
    SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
    expect(HHT_ONHEADER, ht.flags);

    /* try to adjust with message */
    hdItem.mask = HDI_FORMAT;
    hdItem.fmt  = 0;

    ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem);
    expect(TRUE, ret);

    ht.pt.x = 90;
    ht.pt.y = rect.bottom / 2;
    SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
    expect(HHT_ONDIVIDER, ht.flags);

    DestroyWindow(hChild);
}

static void test_hds_nosizing(HWND hParent)
{
    HWND hChild;
    HDITEM hdItem;
    DWORD ret;
    RECT rect;
    HDHITTESTINFO ht;

    hChild = create_custom_header_control(hParent, FALSE);

    memset(&hdItem, 0, sizeof(hdItem));
    hdItem.mask = HDI_WIDTH;
    hdItem.cxy = 80;

    ret = SendMessage(hChild, HDM_INSERTITEM, 0, (LPARAM)&hdItem);
    expect(0, ret);

    /* HDS_NOSIZING only blocks hittesting */
    ret = GetWindowLong(hChild, GWL_STYLE);
    SetWindowLong(hChild, GWL_STYLE, ret | HDS_NOSIZING);

    /* try to change width with mouse gestures */
    rect.right = rect.bottom = 0;
    SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
    ok(rect.right  != 0, "Expected not zero width\n");
    ok(rect.bottom != 0, "Expected not zero height\n");

    SendMessage(hChild, WM_LBUTTONDOWN, 0, MAKELPARAM(rect.right, rect.bottom / 2));
    SendMessage(hChild, WM_MOUSEMOVE, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));
    SendMessage(hChild, WM_LBUTTONUP, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));

    SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);

    if (hdItem.cxy != rect.right)
    {
        win_skip("HDS_NOSIZING style not supported\n");
        DestroyWindow(hChild);
        return;
    }

    /* this style doesn't set HDF_FIXEDWIDTH for items */
    hdItem.mask = HDI_FORMAT;
    ret = SendMessage(hChild, HDM_GETITEM, 0, (LPARAM)&hdItem);
    expect(TRUE, ret);
    ok(!(hdItem.fmt & HDF_FIXEDWIDTH), "Unexpected HDF_FIXEDWIDTH\n");

    /* try to adjust with message */
    hdItem.mask = HDI_WIDTH;
    hdItem.cxy = 90;

    ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem);
    expect(TRUE, ret);

    rect.right = 0;
    SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
    expect(90, rect.right);

    /* hittesting doesn't report ondivider flags for HDS_NOSIZING */
    ht.pt.x = rect.right - 1;
    ht.pt.y = rect.bottom / 2;
    SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
    expect(HHT_ONHEADER, ht.flags);

    /* try to adjust with message */
    ret = GetWindowLong(hChild, GWL_STYLE);
    SetWindowLong(hChild, GWL_STYLE, ret & ~HDS_NOSIZING);

    ht.pt.x = 90;
    ht.pt.y = rect.bottom / 2;
    SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
    expect(HHT_ONDIVIDER, ht.flags);

    DestroyWindow(hChild);
}

#define TEST_NMCUSTOMDRAW(draw_stage, item_spec, lparam, _left, _top, _right, _bottom) \
    ok(nm->dwDrawStage == draw_stage, "Invalid dwDrawStage %d vs %d\n", draw_stage, nm->dwDrawStage); \
    if (item_spec != -1) \
        ok(nm->dwItemSpec == item_spec, "Invalid dwItemSpec %d vs %ld\n", item_spec, nm->dwItemSpec); \
    ok(nm->lItemlParam == lparam, "Invalid lItemlParam %d vs %ld\n", lparam, nm->lItemlParam); \
    ok((nm->rc.top == _top && nm->rc.bottom == _bottom && nm->rc.left == _left && nm->rc.right == _right) || \
        broken(draw_stage != CDDS_ITEMPREPAINT), /* comctl32 < 5.80 */ \
        "Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", _left, _top, _right, _bottom, \
        nm->rc.left, nm->rc.top, nm->rc.right, nm->rc.bottom);

static LRESULT customdraw_1(int n, NMCUSTOMDRAW *nm)
{
    if (nm == NULL) {  /* test ended */
        ok(n==1, "NM_CUSTOMDRAW messages: %d, expected: 1\n", n);
        return 0;
    }

    switch (n)
    {
    case 0:
        /* don't test dwItemSpec - it's 0 no comctl5 but 1308756 on comctl6 */
        TEST_NMCUSTOMDRAW(CDDS_PREPAINT, -1, 0, 0, 0, 670, g_customheight);
        return 0;
    }

    ok(FALSE, "To many custom draw messages (n=%d, nm->dwDrawStage=%d)\n", n, nm->dwDrawStage);
    return -1;
}

static LRESULT customdraw_2(int n, NMCUSTOMDRAW *nm)
{
    if (nm == NULL) {  /* test ended */
        ok(n==4, "NM_CUSTOMDRAW messages: %d, expected: 4\n", n);
        return 0;
    }

    switch (n)
    {
    case 0:
        TEST_NMCUSTOMDRAW(CDDS_PREPAINT, -1, 0, 0, 0, 670, g_customheight);
        return CDRF_NOTIFYITEMDRAW;
    case 1:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 0, 0, 0, 0, 50, g_customheight);
        return 0;
    case 2:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 1, 5, 50, 0, 150, g_customheight);
        return 0;
    case 3:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 2, 10, 150, 0, 300, g_customheight);
        return 0;
    }

    ok(FALSE, "To many custom draw messages (n=%d, nm->dwDrawStage=%d)\n", n, nm->dwDrawStage);
    return 0;
}

static LRESULT customdraw_3(int n, NMCUSTOMDRAW *nm)
{
    if (nm == NULL) {  /* test ended */
        ok(n==5, "NM_CUSTOMDRAW messages: %d, expected: 5\n", n);
        return 0;
    }

    switch (n)
    {
    case 0:
        TEST_NMCUSTOMDRAW(CDDS_PREPAINT, -1, 0, 0, 0, 670, g_customheight);
        return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTERASE|CDRF_NOTIFYPOSTPAINT|CDRF_SKIPDEFAULT;
    case 1:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 0, 0, 0, 0, 50, g_customheight);
        return 0;
    case 2:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 1, 5, 50, 0, 150, g_customheight);
        return 0;
    case 3:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 2, 10, 150, 0, 300, g_customheight);
        return 0;
    case 4:
        TEST_NMCUSTOMDRAW(CDDS_POSTPAINT, -1, 0, 0, 0, 670, g_customheight);
        return 0;
    }

    ok(FALSE, "To many custom draw messages (n=%d, nm->dwDrawStage=%d)\n", n, nm->dwDrawStage);
    return 0;
}


static LRESULT customdraw_4(int n, NMCUSTOMDRAW *nm)
{
    if (nm == NULL) {  /* test ended */
        ok(n==4, "NM_CUSTOMDRAW messages: %d, expected: 4\n", n);
        return 0;
    }

    switch (n)
    {
    case 0:
        TEST_NMCUSTOMDRAW(CDDS_PREPAINT, -1, 0, 0, 0, 670, g_customheight);
        return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTPAINT;
    case 1:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 0, 0, 0, 0, 50, g_customheight);
        return 0;
    case 2:
        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 2, 10, 150, 0, 300, g_customheight);
        return 0;
    case 3:
        TEST_NMCUSTOMDRAW(CDDS_POSTPAINT, -1, 0, 0, 0, 670, g_customheight);
        return 0;
    }

    ok(FALSE, "To many custom draw messages (n=%d, nm->dwDrawStage=%d)\n", n, nm->dwDrawStage);
    return 0;
}

static void run_customdraw_scenario(CUSTOMDRAWPROC proc)
{
    g_CustomDrawProc = proc;
    g_CustomDrawCount = 0;
    InvalidateRect(hWndHeader, NULL, TRUE);
    UpdateWindow(hWndHeader);
    proc(g_CustomDrawCount, NULL);
    g_CustomDrawProc = NULL;
}

static void test_customdraw(void)
{
    int i;
    HDITEM item;
    RECT rect;
    CHAR name[] = "Test";
    hWndHeader = create_header_control();
    GetClientRect(hWndHeader, &rect);
    ok(rect.right - rect.left == 670 && rect.bottom - rect.top == g_customheight,
        "Tests will fail as header size is %dx%d instead of 670x%d\n",
        rect.right - rect.left, rect.bottom - rect.top, g_customheight);

    for (i = 0; i < 3; i++)
    {
        ZeroMemory(&item, sizeof(item));
        item.mask = HDI_TEXT|HDI_WIDTH;
        item.cxy = 50*(i+1);
        item.pszText = name;
        item.lParam = i*5;
        SendMessage(hWndHeader, HDM_INSERTITEM, i, (LPARAM)&item);
    }

    run_customdraw_scenario(customdraw_1);
    run_customdraw_scenario(customdraw_2);
    run_customdraw_scenario(customdraw_3);

    ZeroMemory(&item, sizeof(item));
    item.mask = HDI_FORMAT;
    item.fmt = HDF_OWNERDRAW;
    SendMessage(hWndHeader, HDM_SETITEM, 1, (LPARAM)&item);
    g_DrawItem.CtlID = 0;
    g_DrawItem.CtlType = ODT_HEADER;
    g_DrawItem.hwndItem = hWndHeader;
    g_DrawItem.itemID = 1;
    g_DrawItem.itemState = 0;
    SendMessage(hWndHeader, HDM_GETITEMRECT, 1, (LPARAM)&g_DrawItem.rcItem);
    run_customdraw_scenario(customdraw_4);
    ok(g_DrawItemReceived, "WM_DRAWITEM not received\n");
    DestroyWindow(hWndHeader);
    hWndHeader = NULL;
    g_DrawItem.CtlType = 0;
    g_DrawItemReceived = FALSE;
}

static void check_order(const int expected_id[], const int expected_order[],
                        int count, const char *type)
{
    int i;
    HDITEMA hdi;

    ok(getItemCount(hWndHeader) == count, "Invalid item count in order tests\n");
    for (i = 0; i < count; i++)
    {
        hdi.mask = HDI_LPARAM|HDI_ORDER;
        SendMessage(hWndHeader, HDM_GETITEMA, i, (LPARAM)&hdi);
        ok(hdi.lParam == expected_id[i],
            "Invalid item ids after '%s'- item %d has lParam %d\n", type, i, (int)hdi.lParam);
        ok(hdi.iOrder == expected_order[i],
            "Invalid item order after '%s'- item %d has iOrder %d\n", type, i, hdi.iOrder);
    }
}

static void test_header_order (void)
{
    const int rand1[] = {0, 1, 1, 0, 4};
    const int rand2[] = {4, 5, 6, 7, 4};
    const int rand3[] = {5, 5, 1, 6, 1};
    const int rand4[] = {1, 5, 2, 7, 6, 1, 4, 2, 3, 2};
    const int rand5[] = {7, 8, 5, 6, 7, 2, 1, 9, 10, 10};
    const int rand6[] = {2, 8, 3, 4, 0};

    const int ids1[] = {3, 0, 2, 1, 4};
    const int ord1[] = {0, 1, 2, 3, 4};
    const int ids2[] = {3, 9, 7, 0, 2, 1, 4, 8, 6, 5};
    const int ord2[] = {0, 4, 7, 1, 2, 3, 9, 8, 6, 5};
    const int ord3[] = {0, 3, 9, 2, 1, 8, 7, 6, 5, 4};
    const int ids4[] = {9, 0, 1, 8, 6};
    const int ord4[] = {1, 0, 4, 3, 2};

    char buffer[20];
    HDITEMA hdi;
    int i;

    hWndHeader = create_header_control();

    ZeroMemory(&hdi, sizeof(HDITEMA));
    hdi.mask = HDI_TEXT | HDI_LPARAM;
    hdi.pszText = buffer;
    strcpy(buffer, "test");

    for (i = 0; i < 5; i++)
    {
        hdi.lParam = i;
        SendMessage(hWndHeader, HDM_INSERTITEMA, rand1[i], (LPARAM)&hdi);
        rand();
    }
    check_order(ids1, ord1, 5, "insert without iOrder");

    hdi.mask |= HDI_ORDER;
    for (i = 0; i < 5; i++)
    {
        hdi.lParam = i + 5;
        hdi.iOrder = rand2[i];
        SendMessage(hWndHeader, HDM_INSERTITEMA, rand3[i], (LPARAM)&hdi);
        rand(); rand();
    }
    check_order(ids2, ord2, 10, "insert with order");

    hdi.mask = HDI_ORDER;
    for (i=0; i<10; i++)
    {
        hdi.iOrder = rand5[i];
        SendMessage(hWndHeader, HDM_SETITEMA, rand4[i], (LPARAM)&hdi);
        rand(); rand();
    }
    check_order(ids2, ord3, 10, "setitems changing order");

    for (i=0; i<5; i++)
        SendMessage(hWndHeader, HDM_DELETEITEM, rand6[i], 0);
    check_order(ids4, ord4, 5, "deleteitem");

    DestroyWindow(hWndHeader);
}

static LRESULT CALLBACK HeaderTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    DRAWITEMSTRUCT *di;
    switch(msg) {

    case WM_NOTIFY:
    {
        NMHEADERA *hdr = (NMHEADER *)lParam;
        EXPECTEDNOTIFY *expected;
        int i;

        if (hdr->hdr.code == NM_CUSTOMDRAW)
            if (g_CustomDrawProc)
                return g_CustomDrawProc(g_CustomDrawCount++, (NMCUSTOMDRAW*)hdr);

        for (i=0; i<nUnexpectedNotify; i++)
            ok(hdr->hdr.code != unexpectedNotify[i], "Received invalid notify %d\n", hdr->hdr.code);
        
        if (nReceivedNotify >= nExpectedNotify || hdr->hdr.hwndFrom != hWndHeader )
            break;

        expected = &expectedNotify[nReceivedNotify];
        if (hdr->hdr.code != expected->iCode)
            break;
        
        nReceivedNotify++;
        compare_items(hdr->hdr.code, &expected->hdItem, hdr->pitem, expected->fUnicode);
        break;
    }

    case WM_DRAWITEM:
        di = (DRAWITEMSTRUCT *)lParam;
        ok(g_DrawItem.CtlType != 0, "Unexpected WM_DRAWITEM\n");
        if (g_DrawItem.CtlType == 0) return 0;
        g_DrawItemReceived = TRUE;
        compare(di->CtlType,   g_DrawItem.CtlType, "%d");
        compare(di->CtlID,     g_DrawItem.CtlID, "%d");
        compare(di->hwndItem,  g_DrawItem.hwndItem, "%p");
        compare(di->itemID,    g_DrawItem.itemID, "%d");
        compare(di->itemState, g_DrawItem.itemState, "%d");
        compare(di->rcItem.left,   g_DrawItem.rcItem.left, "%d");
        compare(di->rcItem.top,    g_DrawItem.rcItem.top, "%d");
        compare(di->rcItem.right,  g_DrawItem.rcItem.right, "%d");
        compare(di->rcItem.bottom, g_DrawItem.rcItem.bottom, "%d");
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
  
    default:
        return DefWindowProcA(hWnd, msg, wParam, lParam);
    }
    
    return 0L;
}

static int init(void)
{
    HMODULE hComctl32;
    BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
    WNDCLASSA wc;
    INITCOMMONCONTROLSEX iccex;
    TEXTMETRICA tm;
    HFONT hOldFont;
    HDC hdc;

    hComctl32 = GetModuleHandleA("comctl32.dll");
    pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
    if (!pInitCommonControlsEx)
    {
        skip("InitCommonControlsEx() is missing. Skipping the tests\n");
        return 0;
    }

    iccex.dwSize = sizeof(iccex);
    iccex.dwICC  = ICC_USEREX_CLASSES;
    pInitCommonControlsEx(&iccex);

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = GetModuleHandleA(NULL);
    wc.hIcon = NULL;
    wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
    wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "HeaderTestClass";
    wc.lpfnWndProc = HeaderTestWndProc;
    RegisterClassA(&wc);

    /* The height of the header control depends on the height of the system font.
       The height of the system font is dpi dependent */
    hdc = GetDC(0);
    hOldFont = SelectObject(hdc, GetStockObject(SYSTEM_FONT));
    GetTextMetricsA(hdc, &tm);
    /* 2 dot extra space are needed for the border */
    g_customheight = tm.tmHeight + 2;
    trace("customdraw height: %d (dpi: %d)\n", g_customheight, GetDeviceCaps(hdc, LOGPIXELSY));
    SelectObject(hdc, hOldFont);
    ReleaseDC(0, hdc);

    hHeaderParentWnd = CreateWindowExA(0, "HeaderTestClass", "Header test", WS_OVERLAPPEDWINDOW, 
      CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
      226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
      NULL, NULL, GetModuleHandleA(NULL), 0);
    assert(hHeaderParentWnd != NULL);
    ShowWindow(hHeaderParentWnd, SW_SHOW);
    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, 0);
    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;
    ULONG_PTR ctx_cookie;
    HANDLE hCtx;
    HWND hwnd;

    if (!init())
        return;

    test_header_control();
    test_header_order();
    test_hdm_orderarray();
    test_customdraw();

    DestroyWindow(hHeaderParentWnd);

    init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
    parent_hwnd = create_custom_parent_window();
    ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create parent windows", FALSE);

    test_hdm_index_messages(parent_hwnd);
    test_hdm_getitemrect(parent_hwnd);
    test_hdm_hittest(parent_hwnd);
    test_hdm_layout(parent_hwnd);
    test_hdm_ordertoindex(parent_hwnd);
    test_hdm_sethotdivider(parent_hwnd);
    test_hdm_imageMessages(parent_hwnd);
    test_hdm_filterMessages(parent_hwnd);
    test_hdm_unicodeformatMessages(parent_hwnd);
    test_hdm_bitmapmarginMessages(parent_hwnd);

    if (!load_v6_module(&ctx_cookie, &hCtx))
    {
        DestroyWindow(parent_hwnd);
        return;
    }

    /* this is a XP SP3 failure workaround */
    hwnd = CreateWindowExA(0, WC_HEADER, NULL,
                           WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ,
                           0, 0, 100, 100,
                           parent_hwnd, NULL, GetModuleHandleA(NULL), NULL);

    if (!IsWindow(hwnd))
    {
        win_skip("FIXME: failed to create Header window.\n");
        unload_v6_module(ctx_cookie, hCtx);
        DestroyWindow(parent_hwnd);
        return;
    }
    else
        DestroyWindow(hwnd);

    /* comctl32 version 6 tests start here */
    test_hdf_fixedwidth(parent_hwnd);
    test_hds_nosizing(parent_hwnd);

    unload_v6_module(ctx_cookie, hCtx);

    DestroyWindow(parent_hwnd);
}
