Merge 16747 from trunk: Don't use DeleteDC on DC handles returned by GetDC. Modified: branches/ros-branch-0_2_7/reactos/lib/comctl32/header.c _____
Modified: branches/ros-branch-0_2_7/reactos/lib/comctl32/header.c --- branches/ros-branch-0_2_7/reactos/lib/comctl32/header.c 2005-08-03 17:15:48 UTC (rev 17017) +++ branches/ros-branch-0_2_7/reactos/lib/comctl32/header.c 2005-08-03 17:16:24 UTC (rev 17018) @@ -1,1849 +1,1849 @@
-/* - * Header control - * - * Copyright 1998 Eric Kohl - * Copyright 2000 Eric Kohl for CodeWeavers - * Copyright 2003 Maxime Bellenge - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * TODO: - * - Imagelist support (partially). - * - Callback items (under construction). - * - Hottrack support (partially). - * - Custom draw support (including Notifications). - * - Drag and Drop support (including Notifications). - * - New messages. - * - Use notification format - * - Correct the order maintenance code to preserve valid order - * - */ - -#include <stdarg.h> -#include <string.h> - -#include "windef.h" -#include "winbase.h" -#include "wine/unicode.h" -#include "wingdi.h" -#include "winuser.h" -#include "winnls.h" -#include "commctrl.h" -#include "comctl32.h" -#include "imagelist.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(header); - -typedef struct -{ - INT cxy; - HBITMAP hbm; - LPWSTR pszText; - INT fmt; - LPARAM lParam; - INT iImage; - INT iOrder; /* see documentation of HD_ITEM */ - - BOOL bDown; /* is item pressed? (used for drawing) */ - RECT rect; /* bounding rectangle of the item */ -} HEADER_ITEM; - - -typedef struct -{ - HWND hwndNotify; /* Owner window to send notifications to */ - INT nNotifyFormat; /* format used for WM_NOTIFY messages */ - UINT uNumItem; /* number of items (columns) */ - INT nHeight; /* height of the header (pixels) */ - HFONT hFont; /* handle to the current font */ - HCURSOR hcurArrow; /* handle to the arrow cursor */ - HCURSOR hcurDivider; /* handle to a cursor (used over dividers) <-|-> */ - HCURSOR hcurDivopen; /* handle to a cursor (used over dividers) <-||-> */ - BOOL bCaptured; /* Is the mouse captured? */ - BOOL bPressed; /* Is a header item pressed (down)? */ - BOOL bTracking; /* Is in tracking mode? */ - BOOL bUnicode; /* Unicode flag */ - INT iMoveItem; /* index of tracked item. (Tracking mode) */ - INT xTrackOffset; /* distance between the right side of the tracked item and the cursor */ - INT xOldTrack; /* track offset (see above) after the last WM_MOUSEMOVE */ - INT nOldWidth; /* width of a sizing item after the last WM_MOUSEMOVE */ - INT iHotItem; /* index of hot item (cursor is over this item) */ - INT iMargin; /* width of the margin that surrounds a bitmap */ - - HIMAGELIST himl; /* handle to an image list (may be 0) */ - HEADER_ITEM *items; /* pointer to array of HEADER_ITEM's */ - BOOL bRectsValid; /* validity flag for bounding rectangles */ -} HEADER_INFO; - - -#define VERT_BORDER 3 -#define DIVIDER_WIDTH 10 - -#define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongPtrW(hwnd,0)) - - -inline static LRESULT -HEADER_IndexToOrder (HWND hwnd, INT iItem) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HEADER_ITEM *lpItem = &infoPtr->items[iItem]; - return lpItem->iOrder; -} - - -static INT -HEADER_OrderToIndex(HWND hwnd, WPARAM wParam) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - INT iorder = (INT)wParam; - UINT i; - - if ((iorder <0) || iorder >infoPtr->uNumItem) - return iorder; - for (i=0; i<infoPtr->uNumItem; i++) - if (HEADER_IndexToOrder(hwnd,i) == iorder) - return i; - return iorder; -} - -static void -HEADER_SetItemBounds (HWND hwnd) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HEADER_ITEM *phdi; - RECT rect; - unsigned int i; - int x; - - infoPtr->bRectsValid = TRUE; - - if (infoPtr->uNumItem == 0) - return; - - GetClientRect (hwnd, &rect); - - x = rect.left; - for (i = 0; i < infoPtr->uNumItem; i++) { - phdi = &infoPtr->items[HEADER_OrderToIndex(hwnd,i)]; - phdi->rect.top = rect.top; - phdi->rect.bottom = rect.bottom; - phdi->rect.left = x; - phdi->rect.right = phdi->rect.left + ((phdi->cxy>0)?phdi->cxy:0); - x = phdi->rect.right; - } -} - -static LRESULT -HEADER_Size (HWND hwnd, WPARAM wParam) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - - infoPtr->bRectsValid = FALSE; - - return 0; -} - - -static INT -HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HEADER_ITEM *phdi = &infoPtr->items[iItem]; - RECT r; - INT oldBkMode, cxEdge = GetSystemMetrics(SM_CXEDGE); - - TRACE("DrawItem(iItem %d bHotTrack %d unicode flag %d)\n", iItem, bHotTrack, infoPtr->bUnicode); - - if (!infoPtr->bRectsValid) - HEADER_SetItemBounds(hwnd); - - r = phdi->rect; - if (r.right - r.left == 0) - return phdi->rect.right; - - if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) { - if (phdi->bDown) { - DrawEdge (hdc, &r, BDR_RAISEDOUTER, - BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST); - r.left += 2; - r.top += 2; - } - else - DrawEdge (hdc, &r, EDGE_RAISED, - BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST); - } - else - DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST); - - r.left -= cxEdge; - r.right += cxEdge; - - if (phdi->fmt & HDF_OWNERDRAW) { - DRAWITEMSTRUCT dis; - dis.CtlType = ODT_HEADER; - dis.CtlID = GetWindowLongPtrW (hwnd, GWLP_ID); - dis.itemID = iItem; - dis.itemAction = ODA_DRAWENTIRE; - dis.itemState = phdi->bDown ? ODS_SELECTED : 0; - dis.hwndItem = hwnd; - dis.hDC = hdc; - dis.rcItem = r; - dis.itemData = phdi->lParam; - oldBkMode = SetBkMode(hdc, TRANSPARENT); - SendMessageW (infoPtr->hwndNotify, WM_DRAWITEM, - (WPARAM)dis.CtlID, (LPARAM)&dis); - if (oldBkMode != TRANSPARENT) - SetBkMode(hdc, oldBkMode); - } - else { - UINT rw, rh, /* width and height of r */ - *x = NULL, *w = NULL; /* x and width of the pic (bmp or img) which is part of cnt */ - /* cnt,txt,img,bmp */ - UINT cx, tx, ix, bx, - cw, tw, iw, bw; - BITMAP bmp; - - cw = tw = iw = bw = 0; - rw = r.right - r.left; - rh = r.bottom - r.top; - - if (phdi->fmt & HDF_STRING) { - RECT textRect; - - DrawTextW (hdc, phdi->pszText, -1, - &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT); - cw = textRect.right - textRect.left + 2 * infoPtr->iMargin; - } - - if ((phdi->fmt & HDF_IMAGE) && (infoPtr->himl)) { - iw = infoPtr->himl->cx + 2 * infoPtr->iMargin; - x = &ix; - w = &iw; - } - - if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) { - GetObjectW (phdi->hbm, sizeof(BITMAP), (LPVOID)&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) - cx = r.left; - else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER) - cx = r.left + rw / 2 - cw / 2; - 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); - DeleteDC(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); - SetTextColor (hdc, (bHotTrack) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT); - 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); - } - }/*Ownerdrawn*/ - - return phdi->rect.right; -} - - -static void -HEADER_Refresh (HWND hwnd, HDC hdc) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HFONT hFont, hOldFont; - RECT rect; - HBRUSH hbrBk; - UINT i; - INT x; - - /* get rect for the bar, adjusted for the border */ - GetClientRect (hwnd, &rect); - - hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT); - hOldFont = SelectObject (hdc, hFont); - - /* draw Background */ - hbrBk = GetSysColorBrush(COLOR_3DFACE); - FillRect(hdc, &rect, hbrBk); - - x = rect.left; - for (i = 0; i < infoPtr->uNumItem; i++) { - x = HEADER_DrawItem (hwnd, hdc, HEADER_OrderToIndex(hwnd,i), FALSE); - } - - if ((x <= rect.right) && (infoPtr->uNumItem > 0)) { - rect.left = x; - if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) - DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT); - else - DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM); - } - - SelectObject (hdc, hOldFont); -} - - -static void -HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HFONT hFont, hOldFont; - - hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT); - hOldFont = SelectObject (hdc, hFont); - HEADER_DrawItem (hwnd, hdc, iItem, FALSE); - SelectObject (hdc, hOldFont); -} - - -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 (iCount > 0) { - rcTest = rect; - rcTest.right = rcTest.left + DIVIDER_WIDTH; - if (PtInRect (&rcTest, *lpPt)) { - if (bNoWidth) { - *pFlags |= HHT_ONDIVOPEN; - *pItem = iCount - 1; - TRACE("ON DIVOPEN %d\n", *pItem); - return; - } - else { - *pFlags |= HHT_ONDIVIDER; - *pItem = iCount - 1; - 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); -} - - -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); -} - - -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); - infoPtr->items = 0; - infoPtr->uNumItem = 0; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - HEADER_ITEM *pItem; - INT i; - INT iOrder; - TRACE("Complex delete! [iItem=%d]\n", iItem); - - 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 */ - for (i=infoPtr->uNumItem, pItem = infoPtr->items; i; i--, pItem++) - { - if (pItem->iOrder > iOrder) - pItem->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_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HDITEMA *phdi = (HDITEMA*)lParam; - INT nItem = (INT)wParam; - 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)) { - lpItem = NULL; - } - else { - 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_TEXT) { - if (lpItem == NULL) { - *phdi->pszText = 0; - } - else if (lpItem->pszText != LPSTR_TEXTCALLBACKW) { - if (lpItem->pszText) - WideCharToMultiByte (CP_ACP, 0, lpItem->pszText, -1, - phdi->pszText, phdi->cchTextMax, NULL, NULL); - else - *phdi->pszText = 0; - } - else - phdi->pszText = LPSTR_TEXTCALLBACKA; - } - - if (phdi->mask & HDI_IMAGE) - phdi->iImage = (lpItem != NULL) ? lpItem->iImage : 0; - - if (phdi->mask & HDI_ORDER) - phdi->iOrder = (lpItem != NULL) ? lpItem->iOrder : 0; - - return TRUE; -} - - -static LRESULT -HEADER_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HDITEMW *phdi = (HDITEMW*)lParam; - INT nItem = (INT)wParam; - 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)) { - lpItem = NULL; - } - else { - 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_TEXT) { - if (lpItem == NULL) { - *phdi->pszText = 0; - } - else if (lpItem->pszText != LPSTR_TEXTCALLBACKW) { - if (lpItem->pszText) - lstrcpynW (phdi->pszText, lpItem->pszText, phdi->cchTextMax); - else - *phdi->pszText = 0; - } - else - phdi->pszText = LPSTR_TEXTCALLBACKW; - } - - if (phdi->mask & HDI_IMAGE) - phdi->iImage = (lpItem != NULL) ? lpItem->iImage : 0; - - if (phdi->mask & HDI_ORDER) - phdi->iOrder = (lpItem != NULL) ? lpItem->iOrder : 0; - - 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) -{ - int i; - LPINT order = (LPINT) lParam; - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - - if ((unsigned int)wParam <infoPtr->uNumItem) - return FALSE; - for (i=0; i<(int)wParam; i++) - *order++=HEADER_OrderToIndex(hwnd,i); - 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; - 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; -} - - -static LRESULT -HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HDITEMA *phdi = (HDITEMA*)lParam; - INT nItem = (INT)wParam; - HEADER_ITEM *lpItem; - INT len, 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 (infoPtr->uNumItem == 0) { - infoPtr->items = Alloc (sizeof (HEADER_ITEM)); - infoPtr->uNumItem++; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - - 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)); - } - } - - Free (oldItems); - } - - for (i=0; i < infoPtr->uNumItem; i++) - { - if (infoPtr->items[i].iOrder >= iOrder) - infoPtr->items[i].iOrder++; - } - - lpItem = &infoPtr->items[nItem]; - lpItem->bDown = FALSE; - - if (phdi->mask & HDI_WIDTH) - lpItem->cxy = phdi->cxy; - - if (phdi->mask & HDI_TEXT) { - if (!phdi->pszText) /* null pointer check */ - phdi->pszText = ""; - if (phdi->pszText != LPSTR_TEXTCALLBACKA) { - len = MultiByteToWideChar(CP_ACP, 0, phdi->pszText, -1, NULL, 0); - lpItem->pszText = Alloc( len*sizeof(WCHAR) ); - MultiByteToWideChar(CP_ACP, 0, phdi->pszText, -1, lpItem->pszText, len); - } - else - lpItem->pszText = LPSTR_TEXTCALLBACKW; - } - - if (phdi->mask & HDI_FORMAT) - lpItem->fmt = phdi->fmt; - - if (lpItem->fmt == 0) - lpItem->fmt = HDF_LEFT; - - if (!(lpItem->fmt & HDF_STRING) && (phdi->mask & HDI_TEXT)) - { - lpItem->fmt |= HDF_STRING; - } - if (phdi->mask & HDI_BITMAP) - lpItem->hbm = phdi->hbm; - - if (phdi->mask & HDI_LPARAM) - lpItem->lParam = phdi->lParam; - - if (phdi->mask & HDI_IMAGE) - lpItem->iImage = phdi->iImage; - - lpItem->iOrder = iOrder; - - HEADER_SetItemBounds (hwnd); - - InvalidateRect(hwnd, NULL, FALSE); - - return nItem; -} - - -static LRESULT -HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - HDITEMW *phdi = (HDITEMW*)lParam; - INT nItem = (INT)wParam; - HEADER_ITEM *lpItem; - INT len, 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 (infoPtr->uNumItem == 0) { - infoPtr->items = Alloc (sizeof (HEADER_ITEM)); - infoPtr->uNumItem++; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - - 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)); [truncated at 1000 lines; 2703 more skipped]