header.c

来自「一个类似windows」· C语言 代码 · 共 1,885 行 · 第 1/4 页

C
1,885
字号
}


static LRESULT
HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HEADER_ITEM *lpItem;
    INT       iOrder;
    UINT      i;

    if ((phdi == NULL) || (nItem < 0))
	return -1;

    if (nItem > infoPtr->uNumItem)
        nItem = infoPtr->uNumItem;

    iOrder = (phdi->mask & HDI_ORDER) ? phdi->iOrder : nItem;
    if (iOrder < 0)
        iOrder = 0;
    else if (infoPtr->uNumItem < iOrder)
        iOrder = infoPtr->uNumItem;

    if (infoPtr->uNumItem == 0) {
        infoPtr->items = Alloc (sizeof (HEADER_ITEM));
        infoPtr->order = Alloc(sizeof(INT));
        infoPtr->uNumItem++;
    }
    else {
        HEADER_ITEM *oldItems = infoPtr->items;
        INT *oldOrder = infoPtr->order;

        infoPtr->uNumItem++;
        infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
        if (nItem == 0) {
            memcpy (&infoPtr->items[1], &oldItems[0],
                    (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM));
        }
        else
        {
              /* pre insert copy */
            if (nItem > 0) {
                 memcpy (&infoPtr->items[0], &oldItems[0],
                         nItem * sizeof(HEADER_ITEM));
            }

            /* post insert copy */
            if (nItem < infoPtr->uNumItem - 1) {
                memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
                        (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM));
            }
        }

        infoPtr->order = Alloc(sizeof(INT) * infoPtr->uNumItem);
        memcpy(infoPtr->order, oldOrder, iOrder * sizeof(INT));
        infoPtr->order[iOrder] = nItem;
        memcpy(&infoPtr->order[iOrder + 1], &oldOrder[iOrder],
               (infoPtr->uNumItem - iOrder - 1) * sizeof(INT));

        Free (oldItems);
        Free(oldOrder);
    }

    for (i = 0; i < infoPtr->uNumItem; i++)
    {
        if (i != iOrder && infoPtr->order[i] >= nItem)
            infoPtr->order[i]++;
        infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
    }

    lpItem = &infoPtr->items[nItem];
    lpItem->bDown = FALSE;

    if (phdi->mask & HDI_WIDTH)
	lpItem->cxy = phdi->cxy;

    if (phdi->mask & HDI_FORMAT)
	lpItem->fmt = phdi->fmt;

    if (lpItem->fmt == 0)
	lpItem->fmt = HDF_LEFT;

    if (phdi->mask & HDI_BITMAP)
        lpItem->hbm = phdi->hbm;

    if (phdi->mask & HDI_LPARAM)
        lpItem->lParam = phdi->lParam;

    if (phdi->mask & HDI_IMAGE) 
    {
        if (phdi->iImage != I_IMAGECALLBACK) 
        {
            lpItem->iImage = phdi->iImage;
        } 
        else 
        {
            lpItem->iImage = phdi->iImage;
            HEADER_SendHeaderDispInfoNotify(hwnd, nItem, HDI_IMAGE, NULL, lpItem, bUnicode);
        }
    }

    if (phdi->mask & HDI_TEXT)
    {
	if (!phdi->pszText) phdi->pszText = '\0'; /* null pointer check */
        if (phdi->pszText != LPSTR_TEXTCALLBACKW) /* covers != TEXTCALLBACKA too */
        {
            if (bUnicode)
                Str_SetPtrW(&lpItem->pszText, phdi->pszText);
            else
                Str_SetPtrAtoW(&lpItem->pszText, (LPSTR)phdi->pszText);
        }
        else 
        {
            lpItem->pszText = phdi->pszText;
            HEADER_SendHeaderDispInfoNotify(hwnd, nItem, HDI_TEXT, NULL, lpItem, bUnicode);
        }
        lpItem->fmt |= HDF_STRING;
    }

    lpItem->iOrder = iOrder;

    HEADER_SetItemBounds (hwnd);

    InvalidateRect(hwnd, NULL, FALSE);

    return nItem;
}


static LRESULT
HEADER_Layout (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;

    lpLayout->pwpos->hwnd = hwnd;
    lpLayout->pwpos->hwndInsertAfter = 0;
    lpLayout->pwpos->x = lpLayout->prc->left;
    lpLayout->pwpos->y = lpLayout->prc->top;
    lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
    if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_HIDDEN)
        lpLayout->pwpos->cy = 0;
    else {
        lpLayout->pwpos->cy = infoPtr->nHeight;
        lpLayout->prc->top += infoPtr->nHeight;
    }
    lpLayout->pwpos->flags = SWP_NOZORDER;

    TRACE("Layout x=%d y=%d cx=%d cy=%d\n",
           lpLayout->pwpos->x, lpLayout->pwpos->y,
           lpLayout->pwpos->cx, lpLayout->pwpos->cy);

    infoPtr->bRectsValid = FALSE;

    return TRUE;
}


static LRESULT
HEADER_SetImageList (HWND hwnd, HIMAGELIST himl)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HIMAGELIST himlOld;

    TRACE("(himl %p)\n", himl);
    himlOld = infoPtr->himl;
    infoPtr->himl = himl;

    /* FIXME: Refresh needed??? */

    return (LRESULT)himlOld;
}


static LRESULT
HEADER_GetBitmapMargin(HWND hwnd)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
    
    return infoPtr->iMargin;
}

static LRESULT
HEADER_SetBitmapMargin(HWND hwnd, WPARAM wParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    INT oldMargin = infoPtr->iMargin;

    infoPtr->iMargin = (INT)wParam;

    return oldMargin;
}

static LRESULT
HEADER_SetItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HEADER_ITEM *lpItem;

    if (phdi == NULL)
	return FALSE;
    if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
        return FALSE;

    TRACE("[nItem=%d]\n", nItem);

    if (HEADER_SendHeaderNotify (hwnd, bUnicode ? HDN_ITEMCHANGINGW : HDN_ITEMCHANGINGA,
                                 nItem, phdi->mask))
	return FALSE;

    lpItem = &infoPtr->items[nItem];
    if (phdi->mask & HDI_BITMAP)
	lpItem->hbm = phdi->hbm;

    if (phdi->mask & HDI_FORMAT)
	lpItem->fmt = phdi->fmt;

    if (phdi->mask & HDI_LPARAM)
	lpItem->lParam = phdi->lParam;

    if (phdi->mask & HDI_WIDTH)
	lpItem->cxy = phdi->cxy;

    if (phdi->mask & HDI_IMAGE) 
    {
        if (phdi->iImage != I_IMAGECALLBACK) 
        {
            lpItem->iImage = phdi->iImage;
        } 
        else 
        {
            lpItem->iImage = phdi->iImage;
            HEADER_SendHeaderDispInfoNotify(hwnd, nItem, HDI_IMAGE, NULL, lpItem, bUnicode);
        }
    }

    if (phdi->mask & HDI_TEXT)
    {
        if (phdi->pszText != LPSTR_TEXTCALLBACKW) /* covers != TEXTCALLBACKA too */
        {
            if (lpItem->pszText)
            {
                Free(lpItem->pszText);
                lpItem->pszText = NULL;
            }
            if (phdi->pszText)
            {
                if (bUnicode)
                    Str_SetPtrW(&lpItem->pszText, phdi->pszText);
                else
                    Str_SetPtrAtoW(&lpItem->pszText, (LPSTR)phdi->pszText);
            }
	}
	else 
	{
            lpItem->pszText = phdi->pszText;
            HEADER_SendHeaderDispInfoNotify(hwnd, nItem, HDI_TEXT, NULL, lpItem, bUnicode);
        }  
    }

    if (phdi->mask & HDI_ORDER)
      {
        INT i, nMin, nMax;
        
        if (lpItem->iOrder < phdi->iOrder)
        {
            memmove(&infoPtr->order[lpItem->iOrder],
                   &infoPtr->order[lpItem->iOrder + 1],
                   (phdi->iOrder - lpItem->iOrder) * sizeof(INT));
        }
        if (phdi->iOrder < lpItem->iOrder)
        {
            memmove(&infoPtr->order[phdi->iOrder + 1],
                    &infoPtr->order[phdi->iOrder],
                    (lpItem->iOrder - phdi->iOrder) * sizeof(INT));
        }
        infoPtr->order[phdi->iOrder] = nItem;
        nMin = min(lpItem->iOrder, phdi->iOrder);
        nMax = max(lpItem->iOrder, phdi->iOrder);
        for (i = nMin; i <= nMax; i++)
        {
            infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i];
        }
      }

    HEADER_SendHeaderNotify (hwnd, bUnicode ? HDN_ITEMCHANGEDW : HDN_ITEMCHANGEDA,
                             nItem, phdi->mask);

    HEADER_SetItemBounds (hwnd);

    InvalidateRect(hwnd, NULL, FALSE);

    return TRUE;
}

inline static LRESULT
HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    BOOL bTemp = infoPtr->bUnicode;

    infoPtr->bUnicode = (BOOL)wParam;

    return bTemp;
}


static LRESULT
HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr;
    TEXTMETRICW tm;
    HFONT hOldFont;
    HDC   hdc;

    infoPtr = (HEADER_INFO *)Alloc (sizeof(HEADER_INFO));
    SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

    infoPtr->hwndNotify = ((LPCREATESTRUCTA)lParam)->hwndParent;
    infoPtr->uNumItem = 0;
    infoPtr->hFont = 0;
    infoPtr->items = 0;
    infoPtr->order = 0;
    infoPtr->bRectsValid = FALSE;
    infoPtr->hcurArrow = LoadCursorW (0, (LPWSTR)IDC_ARROW);
    infoPtr->hcurDivider = LoadCursorW (COMCTL32_hModule, MAKEINTRESOURCEW(IDC_DIVIDER));
    infoPtr->hcurDivopen = LoadCursorW (COMCTL32_hModule, MAKEINTRESOURCEW(IDC_DIVIDEROPEN));
    infoPtr->bPressed  = FALSE;
    infoPtr->bTracking = FALSE;
    infoPtr->iMoveItem = 0;
    infoPtr->himl = 0;
    infoPtr->iHotItem = -1;
    infoPtr->bUnicode = IsWindowUnicode (hwnd);
    infoPtr->iMargin = 3*GetSystemMetrics(SM_CXEDGE);
    infoPtr->nNotifyFormat =
	SendMessageW (infoPtr->hwndNotify, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);

    hdc = GetDC (0);
    hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT));
    GetTextMetricsW (hdc, &tm);
    infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
    SelectObject (hdc, hOldFont);
    ReleaseDC (0, hdc);

    OpenThemeData(hwnd, themeClass);

    return 0;
}


static LRESULT
HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HEADER_ITEM *lpItem;
    INT nItem;
    HTHEME theme;

    if (infoPtr->items) {
        lpItem = infoPtr->items;
        for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
	    if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACKW))
		Free (lpItem->pszText);
        }
        Free (infoPtr->items);
    }

    if (infoPtr->order)
        Free(infoPtr->order);

    if (infoPtr->himl)
	ImageList_Destroy (infoPtr->himl);

    SetWindowLongPtrW (hwnd, 0, 0);
    Free (infoPtr);

    theme = GetWindowTheme(hwnd);
    CloseThemeData(theme);
    return 0;
}


static inline LRESULT
HEADER_GetFont (HWND hwnd)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);

    return (LRESULT)infoPtr->hFont;
}


static LRESULT
HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    POINT pt;
    UINT  flags;
    INT   nItem;

    pt.x = (INT)LOWORD(lParam);
    pt.y = (INT)HIWORD(lParam);
    HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);

    if ((GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER))
	HEADER_SendHeaderNotify (hwnd, HDN_ITEMDBLCLICKA, nItem,0);
    else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
	HEADER_SendHeaderNotify (hwnd, HDN_DIVIDERDBLCLICKA, nItem,0);

    return 0;
}


static LRESULT
HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
    POINT pt;
    UINT  flags;
    INT   nItem;
    HDC   hdc;

    pt.x = (INT)LOWORD(lParam);
    pt.y = (INT)HIWORD(lParam);
    HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);

    if ((dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
	SetCapture (hwnd);
	infoPtr->bCaptured = TRUE;
	infoPtr->bPressed  = TRUE;
	infoPtr->iMoveItem = nItem;

	infoPtr->items[nItem].bDown = TRUE;

	/* Send WM_CUSTOMDRAW */
	hdc = GetDC (hwnd);
	HEADER_RefreshItem (hwnd, hdc, nItem);
	ReleaseDC (hwnd, hdc);

	TRACE("Pressed item %d!\n", nItem);
    }
    else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
	if (!(HEADER_SendHeaderNotify (hwnd, HDN_BEGINTRACKA, nItem,0))) {
	    SetCapture (hwnd);
	    infoPtr->bCaptured = TRUE;
	    infoPtr->bTracking = TRUE;
	    infoPtr->iMoveItem = nItem;
	    infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
	    infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;

	    if (!(dwStyle & HDS_FULLDRAG)) {
		infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
		hdc = GetDC (hwnd);
		HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
		ReleaseDC (hwnd, hdc);
	    }

	    TRACE("Begin tracking item %d!\n", nItem);
	}
    }

    return 0;
}


static LRESULT
HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    /*
     *DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
     */
    POINT pt;

⌨️ 快捷键说明

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