header.c
来自「一个类似windows」· C语言 代码 · 共 1,885 行 · 第 1/4 页
C
1,885 行
}
}
}
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);
}
static BOOL
HEADER_SendSimpleNotify (HWND hwnd, UINT code)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
NMHDR nmhdr;
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
nmhdr.code = code;
return (BOOL)SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
static BOOL
HEADER_SendHeaderNotify (HWND hwnd, UINT code, INT iItem, INT mask)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
NMHEADERA nmhdr;
HDITEMA nmitem;
nmhdr.hdr.hwndFrom = hwnd;
nmhdr.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
nmhdr.hdr.code = code;
nmhdr.iItem = iItem;
nmhdr.iButton = 0;
nmhdr.pitem = &nmitem;
nmitem.mask = mask;
nmitem.cxy = infoPtr->items[iItem].cxy;
nmitem.hbm = infoPtr->items[iItem].hbm;
nmitem.pszText = NULL;
nmitem.cchTextMax = 0;
/* nmitem.pszText = infoPtr->items[iItem].pszText; */
/* nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
nmitem.fmt = infoPtr->items[iItem].fmt;
nmitem.lParam = infoPtr->items[iItem].lParam;
nmitem.iOrder = infoPtr->items[iItem].iOrder;
nmitem.iImage = infoPtr->items[iItem].iImage;
return (BOOL)SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
}
/**
* Send Disp Info notification.
* depends on NMHDDISPINFOW having same structure as NMHDDISPINFOA
* (so we handle the two cases only doing a specific cast for pszText).
*
* @param hwnd : hwnd header container handler
* @param mask : notification mask (usually HDI_TEXT or HDI_IMAGE)
* @param pDispInfo : NMHDDISPINFO structure (can be unicode or ansi)
* @param isW : TRUE if dispinfo is Unicode
*/
static BOOL
HEADER_SendHeaderDispInfoNotify(HWND hwnd, INT iItem, INT mask, LPHDITEMW phdi, HEADER_ITEM* lpItem, BOOL isW)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
BOOL ret;
BOOL convertToAnsi = FALSE;
BOOL convertToUnicode = FALSE;
BOOL isUnicodeNotify = FALSE;
NMHDDISPINFOW dispInfo;
if (mask & HDI_TEXT)
{
convertToAnsi = (isW && infoPtr->nNotifyFormat == NFR_ANSI);
convertToUnicode = (!isW && infoPtr->nNotifyFormat == NFR_UNICODE);
}
isUnicodeNotify = (isW && !convertToAnsi);
memset(&dispInfo, 0, sizeof(NMHDDISPINFOW));
dispInfo.hdr.hwndFrom = hwnd;
dispInfo.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
if (isUnicodeNotify || convertToUnicode)
{
dispInfo.hdr.code = HDN_GETDISPINFOW;
}
else
{
dispInfo.hdr.code = HDN_GETDISPINFOA;
}
dispInfo.iItem = iItem;
dispInfo.mask = mask;
/*
dispInfo.pszText = Alloc(sizeof(WCHAR) * 260);
dispInfo.cchTextMax = 260;
*/
ret = (BOOL) SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM) dispInfo.hdr.idFrom,
(LPARAM) &dispInfo);
TRACE("SendMessage returns(mask:0x%x,str:%s,lParam:%p)\n",
dispInfo.mask,
(isUnicodeNotify ? debugstr_w(dispInfo.pszText) : (LPSTR) dispInfo.pszText),
(void*) dispInfo.lParam);
if (dispInfo.mask & HDI_DI_SETITEM)
{
if (dispInfo.mask & HDI_IMAGE)
{
lpItem->iImage = dispInfo.iImage;
}
if (dispInfo.mask & HDI_TEXT)
{
if (isUnicodeNotify || convertToUnicode)
Str_SetPtrW(&lpItem->pszText, (LPCWSTR)dispInfo.pszText);
else /*if (convertToAnsi || !isW)*/
Str_SetPtrAtoW(&lpItem->pszText, (LPCSTR)dispInfo.pszText);
}
FIXME("NMHDDISPINFO returns with flags HDI_DI_SETITEM\n");
}
if (NULL != phdi)
{
if ((phdi->mask & mask) & HDI_IMAGE)
{
phdi->iImage = dispInfo.iImage;
}
if ((phdi->mask & mask) & HDI_TEXT)
{
if (isUnicodeNotify)
Str_GetPtrW ((LPCWSTR)dispInfo.pszText, phdi->pszText, phdi->cchTextMax);
else if (convertToUnicode)
Str_GetPtrWtoA ((LPCWSTR)dispInfo.pszText, (LPSTR)phdi->pszText, phdi->cchTextMax);
else /*if (!isW) */
Str_GetPtrA ((LPCSTR)dispInfo.pszText, (LPSTR)phdi->pszText, phdi->cchTextMax);
}
}
return ret;
}
static BOOL
HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
NMHEADERA nmhdr;
nmhdr.hdr.hwndFrom = hwnd;
nmhdr.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
nmhdr.hdr.code = code;
nmhdr.iItem = iItem;
nmhdr.iButton = 0;
nmhdr.pitem = NULL;
return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
}
static LRESULT
HEADER_CreateDragImage (HWND hwnd, WPARAM wParam)
{
FIXME("empty stub!\n");
return 0;
}
static LRESULT
HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
INT iItem = (INT)wParam;
TRACE("[iItem=%d]\n", iItem);
if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
return FALSE;
if (infoPtr->uNumItem == 1) {
TRACE("Simple delete!\n");
if (infoPtr->items[0].pszText)
Free (infoPtr->items[0].pszText);
Free (infoPtr->items);
Free(infoPtr->order);
infoPtr->items = 0;
infoPtr->order = 0;
infoPtr->uNumItem = 0;
}
else {
HEADER_ITEM *oldItems = infoPtr->items;
INT i;
INT iOrder;
TRACE("Complex delete! [iItem=%d]\n", iItem);
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);
if (infoPtr->items[iItem].pszText)
Free (infoPtr->items[iItem].pszText);
iOrder = infoPtr->items[iItem].iOrder;
infoPtr->uNumItem--;
infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
/* pre delete copy */
if (iItem > 0) {
memcpy (&infoPtr->items[0], &oldItems[0],
iItem * sizeof(HEADER_ITEM));
}
/* post delete copy */
if (iItem < infoPtr->uNumItem) {
memcpy (&infoPtr->items[iItem], &oldItems[iItem+1],
(infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
}
/* Correct the orders */
if (iOrder < infoPtr->uNumItem)
{
memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1],
(infoPtr->uNumItem - iOrder) * sizeof(INT));
for (i = 0; i < infoPtr->uNumItem; i++)
{
if (infoPtr->order[i] > iItem)
infoPtr->order[i]--;
if (i >= iOrder)
infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[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);
Free (oldItems);
}
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;
if (!phdi)
return FALSE;
TRACE("[nItem=%d]\n", nItem);
if (phdi->mask == 0)
return TRUE;
if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
return FALSE;
lpItem = &infoPtr->items[nItem];
if (phdi->mask & HDI_BITMAP)
phdi->hbm = (lpItem != NULL) ? lpItem->hbm : 0;
if (phdi->mask & HDI_FORMAT)
phdi->fmt = (lpItem != NULL) ? lpItem->fmt : 0;
if (phdi->mask & HDI_WIDTH)
phdi->cxy = (lpItem != NULL) ? lpItem->cxy : 0;
if (phdi->mask & HDI_LPARAM)
phdi->lParam = (lpItem != NULL) ? lpItem->lParam : 0;
if (phdi->mask & HDI_IMAGE)
{
phdi->iImage = (lpItem != NULL) ? lpItem->iImage : 0;
if (lpItem->iImage == I_IMAGECALLBACK)
{
HEADER_SendHeaderDispInfoNotify(hwnd, nItem, HDI_IMAGE, phdi, lpItem, bUnicode);
}
}
if (phdi->mask & HDI_ORDER)
phdi->iOrder = (lpItem != NULL) ? lpItem->iOrder : 0;
if (phdi->mask & HDI_TEXT)
{
if (lpItem == NULL) *phdi->pszText = 0; /* null pointer check */
else if (lpItem->pszText == LPSTR_TEXTCALLBACKW) /* covers == TEXTCALLBACKA too */
{
HEADER_SendHeaderDispInfoNotify(hwnd, nItem, HDI_TEXT, phdi, lpItem, bUnicode);
}
else
{
if (bUnicode)
Str_GetPtrW (lpItem->pszText, phdi->pszText, phdi->cchTextMax);
else
Str_GetPtrWtoA (lpItem->pszText, (LPSTR)phdi->pszText, phdi->cchTextMax);
}
}
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->bUnicode;
}
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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?