comctl32: header[2/2]: test and improve the custom draw and owner draw code

Mikołaj Zalewski mikolaj at zalewski.pl
Sat Oct 14 13:27:39 CDT 2006


-------------- next part --------------
diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index 5e5fca6..3b87da4 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -23,7 +23,6 @@
  *  TODO:
  *   - Imagelist support (completed?)
  *   - Hottrack support (completed?)
- *   - Custom draw support (completed?)
  *   - Filters support (HDS_FILTER, HDI_FILTER, HDM_*FILTER*, HDN_*FILTER*)
  *   - New Windows Vista features
  */
@@ -108,6 +107,8 @@ #define HEADER_GetInfoPtr(hwnd) ((HEADER
 
 static BOOL HEADER_PrepareCallbackItems(HWND hwnd, INT iItem, INT reqMask);
 static void HEADER_FreeCallbackItems(HEADER_ITEM *lpItem);
+static LRESULT HEADER_SendNotify(HWND hwnd, UINT code, NMHDR *hdr);
+static LRESULT HEADER_SendCtrlCustomDraw(HWND hwnd, DWORD dwDrawStage, HDC hdc, RECT *rect);
 
 static const WCHAR themeClass[] = {'H','e','a','d','e','r',0};
 static WCHAR emptyString[] = {0};
@@ -300,12 +301,12 @@ static void HEADER_GetHotDividerRect(HWN
 
 
 static INT
-HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
+HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack, LRESULT lCDFlags)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
     HEADER_ITEM *phdi = &infoPtr->items[iItem];
     RECT r;
-    INT  oldBkMode, cxEdge = GetSystemMetrics(SM_CXEDGE);
+    INT  oldBkMode;
     HTHEME theme = GetWindowTheme (hwnd);
     NMCUSTOMDRAW nmcd;
 
@@ -315,6 +316,26 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT
     if (r.right - r.left == 0)
 	return phdi->rect.right;
 
+    /* Set the colors before sending NM_CUSTOMDRAW so that it can change them */
+    SetTextColor(hdc, (bHotTrack && !theme) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
+    SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
+
+    if (lCDFlags & CDRF_NOTIFYITEMDRAW && !(phdi->fmt & HDF_OWNERDRAW))
+    {
+        LRESULT lCDItemFlags;
+
+        nmcd.dwDrawStage  = CDDS_PREPAINT | CDDS_ITEM;
+        nmcd.hdc          = hdc;
+        nmcd.dwItemSpec   = iItem;
+        nmcd.rc           = r;
+        nmcd.uItemState   = phdi->bDown ? CDIS_SELECTED : 0;
+        nmcd.lItemlParam  = phdi->lParam;
+
+        lCDItemFlags = HEADER_SendNotify(hwnd, NM_CUSTOMDRAW, (NMHDR *)&nmcd);
+        if (lCDItemFlags & CDRF_SKIPDEFAULT)
+            return phdi->rect.right;
+    }
+
     if (theme != NULL) {
         int state = (phdi->bDown) ? HIS_PRESSED :
             (bHotTrack ? HIS_HOT : HIS_NORMAL);
@@ -324,6 +345,8 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT
             &r, &r);
     }
     else {
+        HBRUSH hbr;
+    
         if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) {
             if (phdi->bDown) {
                 DrawEdge (hdc, &r, BDR_RAISEDOUTER,
@@ -335,31 +358,16 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT
         }
         else
             DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
+
+        hbr = CreateSolidBrush(GetBkColor(hdc));
+        FillRect(hdc, &r, hbr);
+        DeleteObject(hbr);
     }
     if (phdi->bDown) {
         r.left += 2;
         r.top  += 2;
     }
 
-    r.left  -= cxEdge;
-    r.right += cxEdge;
-
-    /* Set the colors before sending NM_CUSTOMDRAW so that it can change them */
-    SetTextColor (hdc, (bHotTrack && !theme) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
-    SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
-
-    nmcd.hdr.hwndFrom = hwnd;
-    nmcd.hdr.idFrom   = GetWindowLongPtrW (hwnd, GWLP_ID);
-    nmcd.hdr.code     = NM_CUSTOMDRAW;
-    nmcd.dwDrawStage  = CDDS_PREPAINT | CDDS_ITEM | CDDS_ITEMPOSTERASE;
-    nmcd.hdc          = hdc;
-    nmcd.dwItemSpec   = iItem;
-    nmcd.rc           = r;
-    nmcd.uItemState   = phdi->bDown ? CDIS_SELECTED : 0;
-    nmcd.lItemlParam  = phdi->lParam;
-
-    SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd);
-
     if (phdi->fmt & HDF_OWNERDRAW) {
 	DRAWITEMSTRUCT dis;
 
@@ -370,7 +378,7 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT
 	dis.itemState  = phdi->bDown ? ODS_SELECTED : 0;
 	dis.hwndItem   = hwnd;
 	dis.hDC        = hdc;
-	dis.rcItem     = r;
+	dis.rcItem     = phdi->rect;
 	dis.itemData   = phdi->lParam;
         oldBkMode = SetBkMode(hdc, TRANSPARENT);
 	SendMessageW (infoPtr->hwndNotify, WM_DRAWITEM,
@@ -391,15 +399,6 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT
 	rw = r.right - r.left;
 	rh = r.bottom - r.top;
 
-        if (theme == NULL) {
-            HBRUSH hbr = CreateSolidBrush(GetBkColor(hdc));
-            RECT rcBackground = r;
-
-            rcBackground.right -= cxEdge;
-            rcBackground.left += cxEdge;
-            FillRect(hdc, &rcBackground, hbr);
-            DeleteObject(hbr);
-        }
 	if (phdi->fmt & HDF_STRING) {
 	    RECT textRect;
 
@@ -526,10 +525,11 @@ HEADER_Refresh (HWND hwnd, HDC hdc)
 {
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
     HFONT hFont, hOldFont;
-    RECT rect;
+    RECT rect, rcRest;
     HBRUSH hbrBk;
     UINT i;
     INT x;
+    LRESULT lCDFlags;
     HTHEME theme = GetWindowTheme (hwnd);
 
     if (!infoPtr->bRectsValid)
@@ -537,6 +537,7 @@ HEADER_Refresh (HWND hwnd, HDC hdc)
 
     /* get rect for the bar, adjusted for the border */
     GetClientRect (hwnd, &rect);
+    lCDFlags = HEADER_SendCtrlCustomDraw(hwnd, CDDS_PREPAINT, hdc, &rect);
     
     if (infoPtr->bDragging)
 	ImageList_DragShowNolock(FALSE);
@@ -554,21 +555,21 @@ HEADER_Refresh (HWND hwnd, HDC hdc)
     for (i = 0; x <= rect.right && i < infoPtr->uNumItem; i++) {
         int idx = HEADER_OrderToIndex(hwnd,i);
         if (RectVisible(hdc, &infoPtr->items[idx].rect))
-            HEADER_DrawItem(hwnd, hdc, idx, infoPtr->iHotItem == idx);
+            HEADER_DrawItem(hwnd, hdc, idx, infoPtr->iHotItem == idx, lCDFlags);
         x = infoPtr->items[idx].rect.right;
     }
 
-    rect.left = x;
-    if ((x <= rect.right) && RectVisible(hdc, &rect) && (infoPtr->uNumItem > 0)) {
+    rcRest = rect;
+    rcRest.left = x;
+    if ((x <= rect.right) && RectVisible(hdc, &rcRest) && (infoPtr->uNumItem > 0)) {
         if (theme != NULL) {
-            DrawThemeBackground (theme, hdc, HP_HEADERITEM, HIS_NORMAL, &rect,
-                NULL);
+            DrawThemeBackground(theme, hdc, HP_HEADERITEM, HIS_NORMAL, &rcRest, NULL);
         }
         else {
             if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS)
-                DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT|BF_MIDDLE);
+                DrawEdge (hdc, &rcRest, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT|BF_MIDDLE);
             else
-                DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM|BF_MIDDLE);
+                DrawEdge (hdc, &rcRest, EDGE_ETCHED, BF_BOTTOM|BF_MIDDLE);
         }
     }
     
@@ -578,6 +579,9 @@ HEADER_Refresh (HWND hwnd, HDC hdc)
     if (infoPtr->bDragging)
 	ImageList_DragShowNolock(TRUE);
     SelectObject (hdc, hOldFont);
+    
+    if (lCDFlags & CDRF_NOTIFYPOSTPAINT)
+        HEADER_SendCtrlCustomDraw(hwnd, CDDS_POSTPAINT, hdc, &rect);
 }
 
 
@@ -779,18 +783,38 @@ static UINT HEADER_NotifyCodeWtoA(UINT c
         return code;
 }
 
+static LRESULT
+HEADER_SendNotify(HWND hwnd, UINT code, NMHDR *nmhdr)
+{
+    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
+
+    nmhdr->hwndFrom = hwnd;
+    nmhdr->idFrom   = GetWindowLongPtrW (hwnd, GWLP_ID);
+    nmhdr->code     = code;
+
+    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
+				   (WPARAM)nmhdr->idFrom, (LPARAM)nmhdr);
+}
+
 static BOOL
 HEADER_SendSimpleNotify (HWND hwnd, UINT code)
 {
-    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
     NMHDR nmhdr;
+    return (BOOL)HEADER_SendNotify(hwnd, code, &nmhdr);
+}
 
-    nmhdr.hwndFrom = hwnd;
-    nmhdr.idFrom   = GetWindowLongPtrW (hwnd, GWLP_ID);
-    nmhdr.code     = code;
-
-    return (BOOL)SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
-				   (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
+static LRESULT
+HEADER_SendCtrlCustomDraw(HWND hwnd, DWORD dwDrawStage, HDC hdc, RECT *rect)
+{
+    NMCUSTOMDRAW nm;
+    nm.dwDrawStage = dwDrawStage;
+    nm.hdc = hdc;
+    nm.rc = *rect;
+    nm.dwItemSpec = 0;
+    nm.uItemState = 0;
+    nm.lItemlParam = 0;
+
+    return HEADER_SendNotify(hwnd, NM_CUSTOMDRAW, (NMHDR *)&nm);
 }
 
 static BOOL
@@ -799,15 +823,13 @@ HEADER_SendNotifyWithHDItemT(HWND hwnd, 
     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
     NMHEADERW nmhdr;
     
-    nmhdr.hdr.hwndFrom = hwnd;
-    nmhdr.hdr.idFrom   = GetWindowLongPtrW (hwnd, GWLP_ID);
-    nmhdr.hdr.code = (infoPtr->nNotifyFormat == NFR_UNICODE ? code : HEADER_NotifyCodeWtoA(code));
+    if (infoPtr->nNotifyFormat != NFR_UNICODE)
+        code = HEADER_NotifyCodeWtoA(code);
     nmhdr.iItem = iItem;
     nmhdr.iButton = 0;
     nmhdr.pitem = lpItem;
 
-    return (BOOL)SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
-                               (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
+    return (BOOL)HEADER_SendNotify(hwnd, code, (NMHDR *)&nmhdr);
 }
 
 static BOOL
@@ -962,6 +984,8 @@ HEADER_CreateDragImage (HWND hwnd, WPARA
     HEADER_ITEM *lpItem;
     HIMAGELIST himl;
     HBITMAP hMemory, hOldBitmap;
+    LRESULT lCDFlags;
+    RECT rc;
     HDC hMemoryDC;
     HDC hDeviceDC;
     int height, width;
@@ -982,7 +1006,13 @@ HEADER_CreateDragImage (HWND hwnd, WPARA
     ReleaseDC(NULL, hDeviceDC);
     hOldBitmap = SelectObject(hMemoryDC, hMemory);
     SetViewportOrgEx(hMemoryDC, -lpItem->rect.left, -lpItem->rect.top, NULL);
-    HEADER_DrawItem(hwnd, hMemoryDC, wParam, FALSE);
+
+    GetClientRect(hwnd, &rc);
+    lCDFlags = HEADER_SendCtrlCustomDraw(hwnd, CDDS_PREPAINT, hMemoryDC, &rc);
+    HEADER_DrawItem(hwnd, hMemoryDC, wParam, FALSE, lCDFlags);
+    if (lCDFlags & CDRF_NOTIFYPOSTPAINT)
+        HEADER_SendCtrlCustomDraw(hwnd, CDDS_POSTPAINT, hMemoryDC, &rc);
+    
     hMemory = SelectObject(hMemoryDC, hOldBitmap);
     DeleteDC(hMemoryDC);
     
diff --git a/dlls/comctl32/tests/header.c b/dlls/comctl32/tests/header.c
index 4ef32d0..ad64c08 100644
--- a/dlls/comctl32/tests/header.c
+++ b/dlls/comctl32/tests/header.c
@@ -31,6 +31,13 @@ typedef struct tagEXPECTEDNOTIFY
     HDITEMA hdItem;
 } EXPECTEDNOTIFY;
 
+typedef LRESULT (*CUSTOMDRAWPROC)(int n, NMCUSTOMDRAW *nm);
+
+CUSTOMDRAWPROC g_CustomDrawProc;
+int g_CustomDrawCount;
+DRAWITEMSTRUCT g_DrawItem;
+BOOL g_DrawItemReceived;
+
 EXPECTEDNOTIFY expectedNotify[10];
 INT nExpectedNotify = 0;
 INT nReceivedNotify = 0;
@@ -41,6 +48,8 @@ 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))
+
 static void expect_notify(INT iCode, BOOL fUnicode, HDITEMA *lpItem)
 {
     assert(nExpectedNotify < 10);
@@ -479,6 +488,173 @@ static void test_header_control (void)
 }
 
 
+#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, \
+        "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, 18);
+        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, 18);
+        return CDRF_NOTIFYITEMDRAW;
+    case 1:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 0, 0, 0, 0, 50, 18);
+        return 0;
+    case 2:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 1, 5, 50, 0, 150, 18);
+        return 0;
+    case 3:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 2, 10, 150, 0, 300, 18);
+        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, 18);
+        return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTERASE|CDRF_NOTIFYPOSTPAINT|CDRF_SKIPDEFAULT;
+    case 1:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 0, 0, 0, 0, 50, 18);
+        return 0;
+    case 2:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 1, 5, 50, 0, 150, 18);
+        return 0;
+    case 3:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 2, 10, 150, 0, 300, 18);
+        return 0;
+    case 4:
+        TEST_NMCUSTOMDRAW(CDDS_POSTPAINT, -1, 0, 0, 0, 670, 18);
+        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, 18);
+        return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTPAINT;
+    case 1:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 0, 0, 0, 0, 50, 18);
+        return 0;
+    case 2:
+        TEST_NMCUSTOMDRAW(CDDS_ITEMPREPAINT, 2, 10, 150, 0, 300, 18);
+        return 0;
+    case 3:
+        TEST_NMCUSTOMDRAW(CDDS_POSTPAINT, -1, 0, 0, 0, 670, 18);
+        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;
+}
+
+void test_customdraw()
+{
+    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 == 18,
+        "Tests will fail as header size is %dx%d instead of 670x18\n",
+        rect.right - rect.left == 670, rect.bottom - rect.top == 18);
+
+    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)
 {
@@ -561,6 +737,7 @@ static void test_header_order (void)
 
 LRESULT CALLBACK HeaderTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
+    DRAWITEMSTRUCT *di;
     switch(msg) {
 
     case WM_NOTIFY:
@@ -568,7 +745,11 @@ LRESULT CALLBACK HeaderTestWndProc(HWND 
         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);
         
@@ -583,7 +764,23 @@ LRESULT CALLBACK HeaderTestWndProc(HWND 
         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;
@@ -618,6 +815,7 @@ static void init(void) {
     hHeaderParentWnd = CreateWindowExA(0, "HeaderTestClass", "Header test", WS_OVERLAPPEDWINDOW, 
       CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
     assert(hHeaderParentWnd != NULL);
+    ShowWindow(hHeaderParentWnd, SW_SHOW);
 }
 
 START_TEST(header)
@@ -626,6 +824,7 @@ START_TEST(header)
 
     test_header_control();
     test_header_order();
+    test_customdraw();
 
     DestroyWindow(hHeaderParentWnd);
 }
-- 
1.4.2.3


More information about the wine-patches mailing list