Huw Davies : comctl32: Add support for the sort arrows.

Alexandre Julliard julliard at winehq.org
Wed Oct 19 20:47:57 CDT 2016


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Wed Oct 19 16:08:27 2016 +0100

comctl32: Add support for the sort arrows.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/comctl32/header.c | 98 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 79 insertions(+), 19 deletions(-)

diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index 224ff9e..705c6c4 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -326,6 +326,48 @@ HEADER_DrawItemFrame(HEADER_INFO *infoPtr, HDC hdc, RECT *r, const HEADER_ITEM *
     }
 }
 
+/* Create a region for the sort arrow with its bounding rect's top-left
+   co-ord x,y and its height h. */
+static HRGN create_sort_arrow( INT x, INT y, INT h, BOOL is_up )
+{
+    char buffer[256];
+    RGNDATA *data = (RGNDATA *)buffer;
+    DWORD size = FIELD_OFFSET(RGNDATA, Buffer[h * sizeof(RECT)]);
+    INT i, yinc = 1;
+    HRGN rgn;
+
+    if (size > sizeof(buffer))
+    {
+        data = HeapAlloc( GetProcessHeap(), 0, size );
+        if (!data) return NULL;
+    }
+    data->rdh.dwSize = sizeof(data->rdh);
+    data->rdh.iType = RDH_RECTANGLES;
+    data->rdh.nCount = 0;
+    data->rdh.nRgnSize = h * sizeof(RECT);
+
+    if (!is_up)
+    {
+        y += h - 1;
+        yinc = -1;
+    }
+
+    x += h - 1; /* set x to the centre */
+
+    for (i = 0; i < h; i++, y += yinc)
+    {
+        RECT *rect = (RECT *)data->Buffer + data->rdh.nCount;
+        rect->left   = x - i;
+        rect->top    = y;
+        rect->right  = x + i + 1;
+        rect->bottom = y + 1;
+        data->rdh.nCount++;
+    }
+    rgn = ExtCreateRegion( NULL, size, data );
+    if (data != (RGNDATA *)buffer) HeapFree( GetProcessHeap(), 0, data );
+    return rgn;
+}
+
 static INT
 HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESULT lCDFlags)
 {
@@ -413,10 +455,11 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
         INT  cx, tx, ix, bx;
 	UINT cw, tw, iw, bw;
         INT img_cx, img_cy;
+        INT sort_w, sort_x, sort_h;
 	BITMAP bmp;
 
         HEADER_PrepareCallbackItems(infoPtr, iItem, HDI_TEXT|HDI_IMAGE);
-        cw = iw = bw = 0;
+        cw = iw = bw = sort_w = sort_h = 0;
 	rw = r.right - r.left;
 	rh = r.bottom - r.top;
 
@@ -435,23 +478,28 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
 	    cw = textRect.right - textRect.left + 2 * infoPtr->iMargin;
 	}
 
-	if ((phdi->fmt & HDF_IMAGE) && ImageList_GetIconSize( infoPtr->himl, &img_cx, &img_cy )) {
-	    iw = img_cx + 2 * infoPtr->iMargin;
-	    x = &ix;
-	    w = &iw;
-	}
-
-	if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
-            GetObjectW (phdi->hbm, sizeof(BITMAP), &bmp);
-	    bw = bmp.bmWidth + 2 * infoPtr->iMargin;
-	    if (!iw) {
-		x = &bx;
-		w = &bw;
-	    }
-	}
+        if (phdi->fmt & (HDF_SORTUP | HDF_SORTDOWN)) {
+            sort_h = MulDiv( infoPtr->nHeight - VERT_BORDER, 4, 13 );
+            sort_w = 2 * sort_h - 1 + infoPtr->iMargin * 2;
+            cw += sort_w;
+        } else { /* sort arrows take precedent over images/bitmaps */
+            if ((phdi->fmt & HDF_IMAGE) && ImageList_GetIconSize( infoPtr->himl, &img_cx, &img_cy )) {
+                iw = img_cx + 2 * infoPtr->iMargin;
+                x = &ix;
+                w = &iw;
+            }
 
-	if (bw || iw)
-	    cw += *w; 
+            if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
+                GetObjectW (phdi->hbm, sizeof(BITMAP), &bmp);
+                bw = bmp.bmWidth + 2 * infoPtr->iMargin;
+                if (!iw) {
+                    x = &bx;
+                    w = &bw;
+                }
+            }
+            if (bw || iw)
+                cw += *w;
+        }
 
 	/* align cx using the unclipped cw */
 	if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_LEFT)
@@ -470,7 +518,10 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
 	tx = cx + infoPtr->iMargin;
 	/* since cw might have changed we have to recalculate tw */
 	tw = cw - infoPtr->iMargin * 2;
-			
+
+        tw -= sort_w;
+        sort_x = cx + tw + infoPtr->iMargin * 3;
+
 	if (iw || bw) {
 	    tw -= *w;
 	    if (phdi->fmt & HDF_BITMAP_ON_RIGHT) {
@@ -494,11 +545,20 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
 	        bx = cx + cw + infoPtr->iMargin;
 	}
 
-	if (iw || bw) {
+	if (sort_w || iw || bw) {
 	    HDC hClipDC = GetDC(infoPtr->hwndSelf);
 	    HRGN hClipRgn = CreateRectRgn(r.left, r.top, r.right, r.bottom);
 	    SelectClipRgn(hClipDC, hClipRgn);
 	    
+            if (sort_w) {
+                HRGN arrow = create_sort_arrow( sort_x, r.top + (rh - sort_h) / 2,
+                                                sort_h, phdi->fmt & HDF_SORTUP );
+                if (arrow) {
+                    FillRgn( hClipDC, arrow, GetSysColorBrush( COLOR_GRAYTEXT ) );
+                    DeleteObject( arrow );
+                }
+            }
+
 	    if (bw) {
 	        HDC hdcBitmap = CreateCompatibleDC (hClipDC);
 	        SelectObject (hdcBitmap, phdi->hbm);




More information about the wine-cvs mailing list