Nikolay Sivov : comctl32: Properly handle repainting for HDF_OWNERDRAW items.

Alexandre Julliard julliard at winehq.org
Mon Jul 22 14:22:45 CDT 2013


Module: wine
Branch: master
Commit: b130ca1c5fb48c06a1e9f59ba52b00a2dbe90082
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b130ca1c5fb48c06a1e9f59ba52b00a2dbe90082

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Jun 13 13:43:35 2013 +0400

comctl32: Properly handle repainting for HDF_OWNERDRAW items.

---

 dlls/comctl32/header.c |  102 ++++++++++++++++++++++++++++++------------------
 1 files changed, 64 insertions(+), 38 deletions(-)

diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index d1386e3..ec7d844 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -289,6 +289,41 @@ static void HEADER_GetHotDividerRect(const HEADER_INFO *infoPtr, RECT *r)
     }
 }
 
+static void
+HEADER_FillItemFrame(HEADER_INFO *infoPtr, HDC hdc, RECT *r, const HEADER_ITEM *item, BOOL hottrack)
+{
+    HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
+
+    if (theme) {
+        int state = (item->bDown) ? HIS_PRESSED : (hottrack ? HIS_HOT : HIS_NORMAL);
+        DrawThemeBackground (theme, hdc, HP_HEADERITEM, state, r, NULL);
+        GetThemeBackgroundContentRect (theme, hdc, HP_HEADERITEM, state, r, r);
+    }
+    else
+    {
+        HBRUSH hbr = CreateSolidBrush(GetBkColor(hdc));
+        FillRect(hdc, r, hbr);
+        DeleteObject(hbr);
+    }
+}
+
+static void
+HEADER_DrawItemFrame(HEADER_INFO *infoPtr, HDC hdc, RECT *r, const HEADER_ITEM *item)
+{
+    if (GetWindowTheme(infoPtr->hwndSelf)) return;
+
+    if (!(infoPtr->dwStyle & HDS_FLAT))
+    {
+        if (infoPtr->dwStyle & HDS_BUTTONS) {
+            if (item->bDown)
+                DrawEdge (hdc, r, BDR_RAISEDOUTER, BF_RECT | BF_FLAT | BF_ADJUST);
+            else
+                DrawEdge (hdc, r, EDGE_RAISED, BF_RECT | BF_SOFT | BF_ADJUST);
+        }
+        else
+            DrawEdge (hdc, r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
+    }
+}
 
 static INT
 HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESULT lCDFlags)
@@ -325,43 +360,13 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
             return phdi->rect.right;
     }
 
-    if (theme != NULL) {
-        int state = (phdi->bDown) ? HIS_PRESSED :
-            (bHotTrack ? HIS_HOT : HIS_NORMAL);
-        DrawThemeBackground (theme, hdc, HP_HEADERITEM, state,
-            &r, NULL);
-        GetThemeBackgroundContentRect (theme, hdc, HP_HEADERITEM, state,
-            &r, &r);
-    }
-    else {
-        HBRUSH hbr;
+    /* Fill background, owner could draw over it. */
+    HEADER_FillItemFrame(infoPtr, hdc, &r, phdi, bHotTrack);
 
-        if (!(infoPtr->dwStyle & HDS_FLAT))
-        {
-            if (infoPtr->dwStyle & HDS_BUTTONS) {
-                if (phdi->bDown) {
-                    DrawEdge (hdc, &r, BDR_RAISEDOUTER,
-                                BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
-                }
-                else
-                    DrawEdge (hdc, &r, EDGE_RAISED,
-                                BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
-            }
-            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;
-    }
-
-    if (phdi->fmt & HDF_OWNERDRAW) {
+    if (phdi->fmt & HDF_OWNERDRAW)
+    {
 	DRAWITEMSTRUCT dis;
+        BOOL ret;
 
 	dis.CtlType    = ODT_HEADER;
 	dis.CtlID      = GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_ID);
@@ -373,11 +378,32 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
 	dis.rcItem     = phdi->rect;
 	dis.itemData   = phdi->lParam;
         oldBkMode = SetBkMode(hdc, TRANSPARENT);
-        SendMessageW (infoPtr->hwndNotify, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
+        ret = SendMessageW (infoPtr->hwndNotify, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
         if (oldBkMode != TRANSPARENT)
             SetBkMode(hdc, oldBkMode);
+
+        if (!ret)
+            HEADER_FillItemFrame(infoPtr, hdc, &r, phdi, bHotTrack);
+
+        /* Edges are always drawn if we don't have attached theme. */
+        HEADER_DrawItemFrame(infoPtr, hdc, &r, phdi);
+        /* If application processed WM_DRAWITEM we should skip label painting,
+           edges are drawn no matter what. */
+        if (ret) return phdi->rect.right;
     }
-    else {
+    else
+    {
+        HEADER_FillItemFrame(infoPtr, hdc, &r, phdi, bHotTrack);
+        HEADER_DrawItemFrame(infoPtr, hdc, &r, phdi);
+    }
+
+    if (phdi->bDown) {
+        r.left += 2;
+        r.top  += 2;
+    }
+
+    /* Now text and image */
+    {
 	UINT rw, rh, /* width and height of r */
 	     *x = NULL, *w = NULL; /* x and width of the pic (bmp or img) which is part of cnt */
 	  /* cnt,txt,img,bmp */
@@ -495,7 +521,7 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
 	        SetBkMode(hdc, oldBkMode);
         }
         HEADER_FreeCallbackItems(phdi);
-    }/*Ownerdrawn*/
+    }
 
     return phdi->rect.right;
 }




More information about the wine-cvs mailing list