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

📄 header.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:

/**
 * Prepare callback items
 *   depends on NMHDDISPINFOW having same structure as NMHDDISPINFOA 
 *   (so we handle the two cases only doing a specific cast for pszText).
 * Checks if any of the required field are callback. If there are sends a 
 * NMHDISPINFO notify to retrieve these items. The items are stored in the
 * HEADER_ITEM pszText and iImage fields. They should be freed with
 * HEADER_FreeCallbackItems.
 *
 * @param hwnd : hwnd header container handler
 * @param iItem : the header item id
 * @param reqMask : required fields. If any of them is callback this function will fetch it
 *
 * @return TRUE on success, else FALSE
 */
static BOOL
HEADER_PrepareCallbackItems(HWND hwnd, INT iItem, INT reqMask)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HEADER_ITEM *lpItem = &infoPtr->items[iItem];
    DWORD mask = reqMask & lpItem->callbackMask;
    NMHDDISPINFOW dispInfo;
    void *pvBuffer = NULL;

    if (mask == 0)
        return TRUE;
    if (mask&HDI_TEXT && lpItem->pszText != NULL)
    {
        ERR("(): function called without a call to FreeCallbackItems\n");
        Free(lpItem->pszText);
        lpItem->pszText = NULL;
    }
    
    memset(&dispInfo, 0, sizeof(NMHDDISPINFOW));
    dispInfo.hdr.hwndFrom = hwnd;
    dispInfo.hdr.idFrom   = GetWindowLongPtrW (hwnd, GWLP_ID);
    if (infoPtr->nNotifyFormat == NFR_UNICODE)
    {
        dispInfo.hdr.code = HDN_GETDISPINFOW;
        if (mask & HDI_TEXT)
            pvBuffer = Alloc(MAX_HEADER_TEXT_LEN * sizeof(WCHAR));
    }
    else
    {
        dispInfo.hdr.code = HDN_GETDISPINFOA;
        if (mask & HDI_TEXT)
            pvBuffer = Alloc(MAX_HEADER_TEXT_LEN * sizeof(CHAR));
    }
    dispInfo.pszText      = (LPWSTR)pvBuffer;
    dispInfo.cchTextMax   = (pvBuffer!=NULL?MAX_HEADER_TEXT_LEN:0);
    dispInfo.iItem        = iItem;
    dispInfo.mask         = mask;
    dispInfo.lParam       = lpItem->lParam;
    
    TRACE("Sending HDN_GETDISPINFO%c\n", infoPtr->nNotifyFormat == NFR_UNICODE?'W':'A');
    SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, 
                 (WPARAM) dispInfo.hdr.idFrom, 
                 (LPARAM) &dispInfo);

    TRACE("SendMessage returns(mask:0x%x,str:%s,lParam:%p)\n", 
          dispInfo.mask,
          (infoPtr->nNotifyFormat == NFR_UNICODE ? debugstr_w(dispInfo.pszText) : (LPSTR) dispInfo.pszText),
          (void*) dispInfo.lParam);
          
    if (mask & HDI_IMAGE)
        lpItem->iImage = dispInfo.iImage;
    if (mask & HDI_TEXT)
    {
        if (infoPtr->nNotifyFormat == NFR_UNICODE)
        {
            lpItem->pszText = (LPWSTR)pvBuffer;

            /* the user might have used his own buffer */
            if (dispInfo.pszText != lpItem->pszText)
                Str_GetPtrW(dispInfo.pszText, lpItem->pszText, MAX_HEADER_TEXT_LEN);
        }
        else
        {
            Str_SetPtrAtoW(&lpItem->pszText, (LPSTR)dispInfo.pszText);
            Free(pvBuffer);
        }
    }
        
    if (dispInfo.mask & HDI_DI_SETITEM) 
    {
        /* make the items permanent */
        lpItem->callbackMask &= ~dispInfo.mask;
    }
    
    return TRUE;
}

/***
 * DESCRIPTION:
 * Free the items that might be allocated with HEADER_PrepareCallbackItems
 *
 * PARAMETER(S):
 * [I] lpItem : the item to free the data
 *
 */
static void
HEADER_FreeCallbackItems(HEADER_ITEM *lpItem)
{
    if (lpItem->callbackMask&HDI_TEXT && lpItem->pszText != NULL)
    {
        Free(lpItem->pszText);
        lpItem->pszText = NULL;
    }
    
    if (lpItem->callbackMask&HDI_IMAGE)
        lpItem->iImage = I_IMAGECALLBACK;
}

static LRESULT
HEADER_CreateDragImage (HWND hwnd, WPARAM wParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
    HEADER_ITEM *lpItem;
    HIMAGELIST himl;
    HBITMAP hMemory, hOldBitmap;
    LRESULT lCDFlags;
    RECT rc;
    HDC hMemoryDC;
    HDC hDeviceDC;
    int height, width;
    
    if (wParam < 0 || wParam >= infoPtr->uNumItem)
        return FALSE;

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

    lpItem = &infoPtr->items[wParam];
    width = lpItem->rect.right - lpItem->rect.left;
    height = lpItem->rect.bottom - lpItem->rect.top;
    
    hDeviceDC = GetDC(NULL);
    hMemoryDC = CreateCompatibleDC(hDeviceDC);
    hMemory = CreateCompatibleBitmap(hDeviceDC, width, height);
    ReleaseDC(NULL, hDeviceDC);
    hOldBitmap = SelectObject(hMemoryDC, hMemory);
    SetViewportOrgEx(hMemoryDC, -lpItem->rect.left, -lpItem->rect.top, NULL);

    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);
    
    if (hMemory == NULL)    /* if anything failed */
        return FALSE;
    
    himl = ImageList_Create(width, height, ILC_COLORDDB, 1, 1);
    ImageList_Add(himl, hMemory, NULL);
    DeleteObject(hMemory);
    return (LRESULT)himl;
}

static LRESULT
HEADER_SetHotDivider(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
    INT iDivider;
    RECT r;
    
    if (wParam)
    {
        POINT pt;
        UINT flags;
        pt.x = (INT)(SHORT)LOWORD(lParam);
        pt.y = 0;
        HEADER_InternalHitTest (hwnd, &pt, &flags, &iDivider);
        
        if (flags & HHT_TOLEFT)
            iDivider = 0;
        else if (flags & HHT_NOWHERE || flags & HHT_TORIGHT)
            iDivider = infoPtr->uNumItem;
        else
        {
            HEADER_ITEM *lpItem = &infoPtr->items[iDivider];
            if (pt.x > (lpItem->rect.left+lpItem->rect.right)/2)
                iDivider = HEADER_NextItem(hwnd, iDivider);
        }
    }
    else
        iDivider = (INT)lParam;
        
    /* Note; wParam==FALSE, lParam==-1 is valid and is used to clear the hot divider */
    if (iDivider<-1 || iDivider>(int)infoPtr->uNumItem)
        return iDivider;

    if (iDivider != infoPtr->iHotDivider)
    {
        if (infoPtr->iHotDivider != -1)
        {
            HEADER_GetHotDividerRect(hwnd, infoPtr, &r);
            InvalidateRect(hwnd, &r, FALSE);
        }
        infoPtr->iHotDivider = iDivider;
        if (iDivider != -1)
        {
            HEADER_GetHotDividerRect(hwnd, infoPtr, &r);
            InvalidateRect(hwnd, &r, FALSE);
        }
    }
    return iDivider;
}

static LRESULT
HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
    INT iItem = (INT)wParam;
    INT iOrder;
    INT i;

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

    if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
        return FALSE;

    for (i = 0; i < infoPtr->uNumItem; i++)
       TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder);

    iOrder = infoPtr->items[iItem].iOrder;
    HEADER_DisposeItem(&infoPtr->items[iItem]);

    infoPtr->uNumItem--;
    memmove(&infoPtr->items[iItem], &infoPtr->items[iItem + 1],
            (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
    memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1],
            (infoPtr->uNumItem - iOrder) * sizeof(INT));
    infoPtr->items = ReAlloc(infoPtr->items, sizeof(HEADER_ITEM) * infoPtr->uNumItem);
    infoPtr->order = ReAlloc(infoPtr->order, sizeof(INT) * infoPtr->uNumItem);
        
    /* Correct the orders */
    for (i = 0; i < infoPtr->uNumItem; i++)
    {
        if (infoPtr->order[i] > iItem)
            infoPtr->order[i]--;
        if (i >= iOrder)
            infoPtr->items[infoPtr->order[i]].iOrder = i;
    }
    for (i = 0; i < infoPtr->uNumItem; i++)
       TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder);

    HEADER_SetItemBounds (hwnd);
    InvalidateRect(hwnd, NULL, FALSE);

    return TRUE;
}


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

    return (LRESULT)infoPtr->himl;
}


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

    if (!phdi)
	return FALSE;

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

    mask = phdi->mask;
    if (mask == 0)
	return TRUE;

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

    if (mask & HDI_UNKNOWN_FIELDS)
    {
        TRACE("mask %x contains unknown fields. Using only comctl32 4.0 fields\n", mask);
        mask &= HDI_COMCTL32_4_0_FIELDS;
    }
    
    lpItem = &infoPtr->items[nItem];
    HEADER_PrepareCallbackItems(hwnd, nItem, mask);

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

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

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

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

    if (mask & HDI_IMAGE) 
        phdi->iImage = lpItem->iImage;

    if (mask & HDI_ORDER)
        phdi->iOrder = lpItem->iOrder;

    if (mask & HDI_TEXT)
    {
        if (bUnicode)
            Str_GetPtrW (lpItem->pszText, phdi->pszText, phdi->cchTextMax);
        else
            Str_GetPtrWtoA (lpItem->pszText, (LPSTR)phdi->pszText, phdi->cchTextMax);
    }

    HEADER_FreeCallbackItems(lpItem);
    return TRUE;
}


inline static LRESULT
HEADER_GetItemCount (HWND hwnd)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    return infoPtr->uNumItem;
}


static LRESULT
HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    INT iItem = (INT)wParam;
    LPRECT lpRect = (LPRECT)lParam;

    if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
        return FALSE;

    lpRect->left   = infoPtr->items[iItem].rect.left;
    lpRect->right  = infoPtr->items[iItem].rect.right;
    lpRect->top    = infoPtr->items[iItem].rect.top;
    lpRect->bottom = infoPtr->items[iItem].rect.bottom;

    return TRUE;
}


static LRESULT
HEADER_GetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    LPINT order = (LPINT) lParam;
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);

    if ((unsigned int)wParam <infoPtr->uNumItem)
      return FALSE;

    memcpy(order, infoPtr->order, infoPtr->uNumItem * sizeof(INT));
    return TRUE;
}

static LRESULT
HEADER_SetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    int i;
    LPINT order = (LPINT) lParam;
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    HEADER_ITEM *lpItem;

    if ((unsigned int)wParam <infoPtr->uNumItem)
      return FALSE;
    memcpy(infoPtr->order, order, infoPtr->uNumItem * sizeof(INT));
    for (i=0; i<(int)wParam; i++)
      {
        lpItem = &infoPtr->items[*order++];
	lpItem->iOrder=i;
      }
    infoPtr->bRectsValid=0;
    InvalidateRect(hwnd, NULL, FALSE);
    return TRUE;
}

inline static LRESULT
HEADER_GetUnicodeFormat (HWND hwnd)
{
    HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
    return (infoPtr->nNotifyFormat == NFR_UNICODE);
}


static LRESULT
HEADER_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;

    HEADER_InternalHitTest (hwnd, &phti->pt, &phti->flags, &phti->iItem);

    if (phti->flags == HHT_NOWHERE)
        return -1;
    else
        return phti->iItem;
}


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;
    UINT      copyMask;

    if ((phdi == NULL) || (nItem < 0) || (phdi->mask == 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;

    infoPtr->uNumItem++;
    infoPtr->items = ReAlloc(infoPtr->items, sizeof(HEADER_ITEM) * infoPtr->uNumItem);
    infoPtr->order = ReAlloc(infoPtr->order, sizeof(INT) * infoPtr->uNumItem);
    

⌨️ 快捷键说明

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