⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 header.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
	else /* HDF_RIGHT */
	    cx = r.right - cw;
        
	/* clip cx & cw */
	if (cx < r.left)
	    cx = r.left;
	if (cx + cw > r.right)
	    cw = r.right - cx;
	
	tx = cx + infoPtr->iMargin;
	/* since cw might have changed we have to recalculate tw */
	tw = cw - infoPtr->iMargin * 2;
			
	if (iw || bw) {
	    tw -= *w;
	    if (phdi->fmt & HDF_BITMAP_ON_RIGHT) {
		/* put pic behind text */
		*x = cx + tw + infoPtr->iMargin * 3;
	    } else {
		*x = cx + infoPtr->iMargin;
		/* move text behind pic */
		tx += *w;
	    }
	}

	if (iw && bw) {
	    /* since we're done with the layout we can
	       now calculate the position of bmp which
	       has no influence on alignment and layout
	       because of img */
	    if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
	        bx = cx - bw + infoPtr->iMargin;
	    else
	        bx = cx + cw + infoPtr->iMargin;
	}

	if (iw || bw) {
	    HDC hClipDC = GetDC(hwnd);
	    HRGN hClipRgn = CreateRectRgn(r.left, r.top, r.right, r.bottom);
	    SelectClipRgn(hClipDC, hClipRgn);
	    
	    if (bw) {
	        HDC hdcBitmap = CreateCompatibleDC (hClipDC);
	        SelectObject (hdcBitmap, phdi->hbm);
	        BitBlt (hClipDC, bx, r.top + ((INT)rh - bmp.bmHeight) / 2, 
		        bmp.bmWidth, bmp.bmHeight, hdcBitmap, 0, 0, SRCCOPY);
	        DeleteDC (hdcBitmap);
	    }

	    if (iw) {
	        ImageList_DrawEx (infoPtr->himl, phdi->iImage, hClipDC, 
	                          ix, r.top + ((INT)rh - infoPtr->himl->cy) / 2,
	                          infoPtr->himl->cx, infoPtr->himl->cy, CLR_DEFAULT, CLR_DEFAULT, 0);
	    }

	    DeleteObject(hClipRgn);
	    ReleaseDC(hwnd, hClipDC);
	}
        
	if (((phdi->fmt & HDF_STRING)
		|| (!(phdi->fmt & (HDF_OWNERDRAW|HDF_STRING|HDF_BITMAP|
				   HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */
	    && (phdi->pszText)) {
	    oldBkMode = SetBkMode(hdc, TRANSPARENT);
	    r.left  = tx;
	    r.right = tx + tw;
	    DrawTextW (hdc, phdi->pszText, -1,
	               &r, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE);
	    if (oldBkMode != TRANSPARENT)
	        SetBkMode(hdc, oldBkMode);
        }
        HEADER_FreeCallbackItems(phdi);
    }/*Ownerdrawn*/

    return phdi->rect.right;
}

static void
HEADER_DrawHotDivider(HWND hwnd, HDC hdc)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HBRUSH brush;
    RECT r;
    
    HEADER_GetHotDividerRect(hwnd, infoPtr, &r);
    brush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
    FillRect(hdc, &r, brush);
    DeleteObject(brush);
}

static void
HEADER_Refresh (HWND hwnd, HDC hdc)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HFONT hFont, hOldFont;
    RECT rect, rcRest;
    HBRUSH hbrBk;
    UINT i;
    INT x;
    LRESULT lCDFlags;
    HTHEME theme = GetWindowTheme (hwnd);

    if (!infoPtr->bRectsValid)
        HEADER_SetItemBounds(hwnd);

    /* 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);

    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
    hOldFont = SelectObject (hdc, hFont);

    /* draw Background */
    if (infoPtr->uNumItem == 0 && theme == NULL) {
        hbrBk = GetSysColorBrush(COLOR_3DFACE);
        FillRect(hdc, &rect, hbrBk);
    }

    x = rect.left;
    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, lCDFlags);
        x = infoPtr->items[idx].rect.right;
    }

    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, &rcRest, NULL);
        }
        else {
            if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS)
                DrawEdge (hdc, &rcRest, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT|BF_MIDDLE);
            else
                DrawEdge (hdc, &rcRest, EDGE_ETCHED, BF_BOTTOM|BF_MIDDLE);
        }
    }
    
    if (infoPtr->iHotDivider != -1)
        HEADER_DrawHotDivider(hwnd, hdc);

    if (infoPtr->bDragging)
	ImageList_DragShowNolock(TRUE);
    SelectObject (hdc, hOldFont);
    
    if (lCDFlags & CDRF_NOTIFYPOSTPAINT)
        HEADER_SendCtrlCustomDraw(hwnd, CDDS_POSTPAINT, hdc, &rect);
}


static void
HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);

    if (!infoPtr->bRectsValid)
        HEADER_SetItemBounds(hwnd);

    InvalidateRect(hwnd, &infoPtr->items[iItem].rect, FALSE);
}


static void
HEADER_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pItem)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    RECT rect, rcTest;
    UINT iCount;
    INT width;
    BOOL bNoWidth;

    GetClientRect (hwnd, &rect);

    *pFlags = 0;
    bNoWidth = FALSE;
    if (PtInRect (&rect, *lpPt))
    {
	if (infoPtr->uNumItem == 0) {
	    *pFlags |= HHT_NOWHERE;
	    *pItem = 1;
	    TRACE("NOWHERE\n");
	    return;
	}
	else {
	    /* somewhere inside */
	    for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
		rect = infoPtr->items[iCount].rect;
		width = rect.right - rect.left;
		if (width == 0) {
		    bNoWidth = TRUE;
		    continue;
		}
		if (PtInRect (&rect, *lpPt)) {
		    if (width <= 2 * DIVIDER_WIDTH) {
			*pFlags |= HHT_ONHEADER;
			*pItem = iCount;
			TRACE("ON HEADER %d\n", iCount);
			return;
		    }
                    if (HEADER_IndexToOrder(hwnd, iCount) > 0) {
			rcTest = rect;
			rcTest.right = rcTest.left + DIVIDER_WIDTH;
			if (PtInRect (&rcTest, *lpPt)) {
			    if (bNoWidth) {
				*pFlags |= HHT_ONDIVOPEN;
                                *pItem = HEADER_PrevItem(hwnd, iCount);
				TRACE("ON DIVOPEN %d\n", *pItem);
				return;
			    }
			    else {
				*pFlags |= HHT_ONDIVIDER;
                                *pItem = HEADER_PrevItem(hwnd, iCount);
				TRACE("ON DIVIDER %d\n", *pItem);
				return;
			    }
			}
		    }
		    rcTest = rect;
		    rcTest.left = rcTest.right - DIVIDER_WIDTH;
		    if (PtInRect (&rcTest, *lpPt)) {
			*pFlags |= HHT_ONDIVIDER;
			*pItem = iCount;
			TRACE("ON DIVIDER %d\n", *pItem);
			return;
		    }

		    *pFlags |= HHT_ONHEADER;
		    *pItem = iCount;
		    TRACE("ON HEADER %d\n", iCount);
		    return;
		}
	    }

	    /* check for last divider part (on nowhere) */
	    rect = infoPtr->items[infoPtr->uNumItem-1].rect;
	    rect.left = rect.right;
	    rect.right += DIVIDER_WIDTH;
	    if (PtInRect (&rect, *lpPt)) {
		if (bNoWidth) {
		    *pFlags |= HHT_ONDIVOPEN;
		    *pItem = infoPtr->uNumItem - 1;
		    TRACE("ON DIVOPEN %d\n", *pItem);
		    return;
		}
		else {
		    *pFlags |= HHT_ONDIVIDER;
		    *pItem = infoPtr->uNumItem-1;
		    TRACE("ON DIVIDER %d\n", *pItem);
		    return;
		}
	    }

	    *pFlags |= HHT_NOWHERE;
	    *pItem = 1;
	    TRACE("NOWHERE\n");
	    return;
	}
    }
    else {
	if (lpPt->x < rect.left) {
	   TRACE("TO LEFT\n");
	   *pFlags |= HHT_TOLEFT;
	}
	else if (lpPt->x > rect.right) {
	    TRACE("TO RIGHT\n");
	    *pFlags |= HHT_TORIGHT;
	}

	if (lpPt->y < rect.top) {
	    TRACE("ABOVE\n");
	    *pFlags |= HHT_ABOVE;
	}
	else if (lpPt->y > rect.bottom) {
	    TRACE("BELOW\n");
	    *pFlags |= HHT_BELOW;
	}
    }

    *pItem = 1;
    TRACE("flags=0x%X\n", *pFlags);
    return;
}


static void
HEADER_DrawTrackLine (HWND hwnd, HDC hdc, INT x)
{
    RECT rect;
    HPEN hOldPen;
    INT  oldRop;

    GetClientRect (hwnd, &rect);

    hOldPen = SelectObject (hdc, GetStockObject (BLACK_PEN));
    oldRop = SetROP2 (hdc, R2_XORPEN);
    MoveToEx (hdc, x, rect.top, NULL);
    LineTo (hdc, x, rect.bottom);
    SetROP2 (hdc, oldRop);
    SelectObject (hdc, hOldPen);
}

/***
 * DESCRIPTION:
 * Convert a HDITEM into the correct format (ANSI/Unicode) to send it in a notify
 *
 * PARAMETER(S):
 * [I] infoPtr : the header that wants to send the notify
 * [O] dest : The buffer to store the HDITEM for notify. It may be set to a HDITEMA of HDITEMW
 * [I] src  : The source HDITEM. It may be a HDITEMA or HDITEMW
 * [I] fSourceUnicode : is src a HDITEMW or HDITEMA
 * [O] ppvScratch : a pointer to a scratch buffer that needs to be freed after
 *                  the HDITEM is no longer in use or NULL if none was needed
 * 
 * NOTE: We depend on HDITEMA and HDITEMW having the same structure
 */
static void HEADER_CopyHDItemForNotify(HEADER_INFO *infoPtr, HDITEMW *dest,
    HDITEMW *src, BOOL fSourceUnicode, LPVOID *ppvScratch)
{
    *ppvScratch = NULL;
    *dest = *src;
    
    if (src->mask & HDI_TEXT && src->pszText != LPSTR_TEXTCALLBACKW) /* covers TEXTCALLBACKA as well */
    {
        if (fSourceUnicode && infoPtr->nNotifyFormat != NFR_UNICODE)
        {
            dest->pszText = NULL;
            Str_SetPtrWtoA((LPSTR *)&dest->pszText, src->pszText);
            *ppvScratch = dest->pszText;
        }
        
        if (!fSourceUnicode && infoPtr->nNotifyFormat == NFR_UNICODE)
        {
            dest->pszText = NULL;
            Str_SetPtrAtoW(&dest->pszText, (LPSTR)src->pszText);
            *ppvScratch = dest->pszText;
        }
    }
}

static UINT HEADER_NotifyCodeWtoA(UINT code)
{
    /* we use the fact that all the unicode messages are in HDN_FIRST_UNICODE..HDN_LAST*/
    if (code >= HDN_LAST && code <= HDN_FIRST_UNICODE)
        return code + HDN_UNICODE_OFFSET;
    else
        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)
{
    NMHDR nmhdr;
    return (BOOL)HEADER_SendNotify(hwnd, code, &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
HEADER_SendNotifyWithHDItemT(HWND hwnd, UINT code, INT iItem, HDITEMW *lpItem)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    NMHEADERW nmhdr;
    
    if (infoPtr->nNotifyFormat != NFR_UNICODE)
        code = HEADER_NotifyCodeWtoA(code);
    nmhdr.iItem = iItem;
    nmhdr.iButton = 0;
    nmhdr.pitem = lpItem;

    return (BOOL)HEADER_SendNotify(hwnd, code, (NMHDR *)&nmhdr);
}

static BOOL
HEADER_SendNotifyWithIntFieldT(HWND hwnd, UINT code, INT iItem, INT mask, INT iValue)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HDITEMW nmitem;

    /* copying only the iValue should be ok but to make the code more robust we copy everything */
    nmitem.cxy = infoPtr->items[iItem].cxy;
    nmitem.hbm = infoPtr->items[iItem].hbm;
    nmitem.pszText = NULL;
    nmitem.cchTextMax = 0;
    nmitem.fmt = infoPtr->items[iItem].fmt;
    nmitem.lParam = infoPtr->items[iItem].lParam;
    nmitem.iOrder = infoPtr->items[iItem].iOrder;
    nmitem.iImage = infoPtr->items[iItem].iImage;

    nmitem.mask = mask;
    switch (mask)
    {
	case HDI_WIDTH:
	    nmitem.cxy = iValue;
	    break;
	case HDI_ORDER:
	    nmitem.iOrder = iValue;
	    break;
	default:
	    ERR("invalid mask value 0x%x\n", iValue);
    }

    return HEADER_SendNotifyWithHDItemT(hwnd, code, iItem, &nmitem);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -