4 * Copyright 1998 Eric Kohl
7 * - Imagelist support (partially).
8 * - Callback items (under construction).
9 * - Order list support.
10 * - Control specific cursors (over dividers).
11 * - Hottrack support (partially).
12 * - Custom draw support (including Notifications).
13 * - Drag and Drop support (including Notifications).
17 * - Replace DrawText32A by DrawTextEx32A(...|DT_ENDELLIPSIS) in
19 * - Little flaw when drawing a bitmap on the right side of the text.
25 #include "wine/unicode.h"
26 #include "wine/winestring.h"
28 #include "debugtools.h"
30 DEFAULT_DEBUG_CHANNEL(header);
40 INT iOrder; /* see documentation of HD_ITEM */
42 BOOL bDown; /* is item pressed? (used for drawing) */
43 RECT rect; /* bounding rectangle of the item */
49 UINT uNumItem; /* number of items (columns) */
50 INT nHeight; /* height of the header (pixels) */
51 HFONT hFont; /* handle to the current font */
52 HCURSOR hcurArrow; /* handle to the arrow cursor */
53 HCURSOR hcurDivider; /* handle to a cursor (used over dividers) <-|-> */
54 HCURSOR hcurDivopen; /* handle to a cursor (used over dividers) <-||-> */
55 BOOL bCaptured; /* Is the mouse captured? */
56 BOOL bPressed; /* Is a header item pressed (down)? */
57 BOOL bTracking; /* Is in tracking mode? */
58 BOOL bUnicode; /* Unicode flag */
59 INT iMoveItem; /* index of tracked item. (Tracking mode) */
60 INT xTrackOffset; /* distance between the right side of the tracked item and the cursor */
61 INT xOldTrack; /* track offset (see above) after the last WM_MOUSEMOVE */
62 INT nOldWidth; /* width of a sizing item after the last WM_MOUSEMOVE */
63 INT iHotItem; /* index of hot item (cursor is over this item) */
65 HIMAGELIST himl; /* handle to a image list (may be 0) */
66 HEADER_ITEM *items; /* pointer to array of HEADER_ITEM's */
67 BOOL bRectsValid; /* validity flag for bounding rectangles */
68 LPINT pOrder; /* pointer to order array */
73 #define DIVIDER_WIDTH 10
75 #define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
79 HEADER_SetItemBounds (HWND hwnd)
81 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
86 infoPtr->bRectsValid = TRUE;
88 if (infoPtr->uNumItem == 0)
91 GetClientRect (hwnd, &rect);
94 for (i = 0; i < infoPtr->uNumItem; i++) {
95 phdi = &infoPtr->items[i];
96 phdi->rect.top = rect.top;
97 phdi->rect.bottom = rect.bottom;
99 phdi->rect.right = phdi->rect.left + phdi->cxy;
100 x = phdi->rect.right;
105 HEADER_Size (HWND hwnd, WPARAM wParam)
107 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
109 infoPtr->bRectsValid = FALSE;
116 HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
118 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
119 HEADER_ITEM *phdi = &infoPtr->items[iItem];
123 if (!infoPtr->bRectsValid)
124 HEADER_SetItemBounds(hwnd);
127 if (r.right - r.left == 0)
128 return phdi->rect.right;
130 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) {
132 DrawEdge (hdc, &r, BDR_RAISEDOUTER,
133 BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
138 DrawEdge (hdc, &r, EDGE_RAISED,
139 BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
142 DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
144 if (phdi->fmt & HDF_OWNERDRAW) {
146 dis.CtlType = ODT_HEADER;
147 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
149 dis.itemAction = ODA_DRAWENTIRE;
150 dis.itemState = phdi->bDown ? ODS_SELECTED : 0;
154 dis.itemData = phdi->lParam;
155 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
156 (WPARAM)dis.CtlID, (LPARAM)&dis);
159 UINT uTextJustify = DT_LEFT;
161 if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER)
162 uTextJustify = DT_CENTER;
163 else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
164 uTextJustify = DT_RIGHT;
166 if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
169 INT yD, yS, cx, cy, rx, ry;
171 GetObjectA (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp);
173 ry = r.bottom - r.top;
174 rx = r.right - r.left;
176 if (ry >= bmp.bmHeight) {
178 yD = r.top + (ry - bmp.bmHeight) / 2;
184 yS = (bmp.bmHeight - ry) / 2;
188 if (rx >= bmp.bmWidth + 6) {
195 hdcBitmap = CreateCompatibleDC (hdc);
196 SelectObject (hdcBitmap, phdi->hbm);
197 BitBlt (hdc, r.left + 3, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
198 DeleteDC (hdcBitmap);
200 r.left += (bmp.bmWidth + 3);
204 if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
207 INT xD, yD, yS, cx, cy, rx, ry, tx;
210 GetObjectA (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp);
213 DrawTextW (hdc, phdi->pszText, -1,
214 &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
215 tx = textRect.right - textRect.left;
216 ry = r.bottom - r.top;
217 rx = r.right - r.left;
219 if (ry >= bmp.bmHeight) {
221 yD = r.top + (ry - bmp.bmHeight) / 2;
227 yS = (bmp.bmHeight - ry) / 2;
231 if (r.left + tx + bmp.bmWidth + 9 <= r.right) {
233 xD = r.left + tx + 6;
236 if (rx >= bmp.bmWidth + 6) {
238 xD = r.right - bmp.bmWidth - 3;
248 hdcBitmap = CreateCompatibleDC (hdc);
249 SelectObject (hdcBitmap, phdi->hbm);
250 BitBlt (hdc, xD, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
251 DeleteDC (hdcBitmap);
254 if (phdi->fmt & HDF_IMAGE) {
257 /* ImageList_Draw (infoPtr->himl, phdi->iImage,...); */
260 if (((phdi->fmt & HDF_STRING)
261 || (!(phdi->fmt & (HDF_OWNERDRAW|HDF_STRING|HDF_BITMAP|
262 HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */
263 && (phdi->pszText)) {
264 oldBkMode = SetBkMode(hdc, TRANSPARENT);
267 SetTextColor (hdc, bHotTrack ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
268 DrawTextW (hdc, phdi->pszText, -1,
269 &r, uTextJustify|DT_VCENTER|DT_SINGLELINE);
270 if (oldBkMode != TRANSPARENT)
271 SetBkMode(hdc, oldBkMode);
275 return phdi->rect.right;
280 HEADER_Refresh (HWND hwnd, HDC hdc)
282 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
283 HFONT hFont, hOldFont;
288 /* get rect for the bar, adjusted for the border */
289 GetClientRect (hwnd, &rect);
291 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
292 hOldFont = SelectObject (hdc, hFont);
294 /* draw Background */
295 hbrBk = GetSysColorBrush(COLOR_3DFACE);
296 FillRect(hdc, &rect, hbrBk);
299 for (i = 0; i < infoPtr->uNumItem; i++) {
300 x = HEADER_DrawItem (hwnd, hdc, i, FALSE);
303 if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
305 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS)
306 DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
308 DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
311 SelectObject (hdc, hOldFont);
316 HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem)
318 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
319 HFONT hFont, hOldFont;
321 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
322 hOldFont = SelectObject (hdc, hFont);
323 HEADER_DrawItem (hwnd, hdc, iItem, FALSE);
324 SelectObject (hdc, hOldFont);
329 HEADER_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pItem)
331 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
336 GetClientRect (hwnd, &rect);
340 if (PtInRect (&rect, *lpPt))
342 if (infoPtr->uNumItem == 0) {
343 *pFlags |= HHT_NOWHERE;
349 /* somewhere inside */
350 for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
351 rect = infoPtr->items[iCount].rect;
352 width = rect.right - rect.left;
357 if (PtInRect (&rect, *lpPt)) {
358 if (width <= 2 * DIVIDER_WIDTH) {
359 *pFlags |= HHT_ONHEADER;
361 TRACE("ON HEADER %d\n", iCount);
366 rcTest.right = rcTest.left + DIVIDER_WIDTH;
367 if (PtInRect (&rcTest, *lpPt)) {
369 *pFlags |= HHT_ONDIVOPEN;
371 TRACE("ON DIVOPEN %d\n", *pItem);
375 *pFlags |= HHT_ONDIVIDER;
377 TRACE("ON DIVIDER %d\n", *pItem);
383 rcTest.left = rcTest.right - DIVIDER_WIDTH;
384 if (PtInRect (&rcTest, *lpPt)) {
385 *pFlags |= HHT_ONDIVIDER;
387 TRACE("ON DIVIDER %d\n", *pItem);
391 *pFlags |= HHT_ONHEADER;
393 TRACE("ON HEADER %d\n", iCount);
398 /* check for last divider part (on nowhere) */
399 rect = infoPtr->items[infoPtr->uNumItem-1].rect;
400 rect.left = rect.right;
401 rect.right += DIVIDER_WIDTH;
402 if (PtInRect (&rect, *lpPt)) {
404 *pFlags |= HHT_ONDIVOPEN;
405 *pItem = infoPtr->uNumItem - 1;
406 TRACE("ON DIVOPEN %d\n", *pItem);
410 *pFlags |= HHT_ONDIVIDER;
411 *pItem = infoPtr->uNumItem-1;
412 TRACE("ON DIVIDER %d\n", *pItem);
417 *pFlags |= HHT_NOWHERE;
424 if (lpPt->x < rect.left) {
426 *pFlags |= HHT_TOLEFT;
428 else if (lpPt->x > rect.right) {
430 *pFlags |= HHT_TORIGHT;
433 if (lpPt->y < rect.top) {
435 *pFlags |= HHT_ABOVE;
437 else if (lpPt->y > rect.bottom) {
439 *pFlags |= HHT_BELOW;
444 TRACE("flags=0x%X\n", *pFlags);
450 HEADER_DrawTrackLine (HWND hwnd, HDC hdc, INT x)
456 GetClientRect (hwnd, &rect);
458 hOldPen = SelectObject (hdc, GetStockObject (BLACK_PEN));
459 oldRop = SetROP2 (hdc, R2_XORPEN);
460 MoveToEx (hdc, x, rect.top, NULL);
461 LineTo (hdc, x, rect.bottom);
462 SetROP2 (hdc, oldRop);
463 SelectObject (hdc, hOldPen);
468 HEADER_SendSimpleNotify (HWND hwnd, UINT code)
472 nmhdr.hwndFrom = hwnd;
473 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
476 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
477 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
481 HEADER_SendItemChange(HWND hwnd, INT iItem, UINT mask, UINT msg)
483 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
487 nmhdr.hdr.hwndFrom = hwnd;
488 nmhdr.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
489 nmhdr.hdr.code = msg;
492 nmhdr.pitem = &nmitem;
494 nmitem.cxy = infoPtr->items[iItem].cxy;
495 nmitem.hbm = infoPtr->items[iItem].hbm;
496 nmitem.pszText = NULL;
497 nmitem.cchTextMax = 0;
498 nmitem.fmt = infoPtr->items[iItem].fmt;
499 nmitem.lParam = infoPtr->items[iItem].lParam;
500 nmitem.iOrder = infoPtr->items[iItem].iOrder;
501 nmitem.iImage = infoPtr->items[iItem].iImage;
503 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
504 (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
508 HEADER_SendHeaderNotify (HWND hwnd, UINT code, INT iItem)
510 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
514 nmhdr.hdr.hwndFrom = hwnd;
515 nmhdr.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
516 nmhdr.hdr.code = code;
519 nmhdr.pitem = &nmitem;
521 nmitem.cxy = infoPtr->items[iItem].cxy;
522 nmitem.hbm = infoPtr->items[iItem].hbm;
523 nmitem.pszText = NULL;
524 nmitem.cchTextMax = 0;
525 /* nmitem.pszText = infoPtr->items[iItem].pszText; */
526 /* nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
527 nmitem.fmt = infoPtr->items[iItem].fmt;
528 nmitem.lParam = infoPtr->items[iItem].lParam;
529 nmitem.iOrder = infoPtr->items[iItem].iOrder;
530 nmitem.iImage = infoPtr->items[iItem].iImage;
532 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
533 (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
538 HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem)
542 nmhdr.hdr.hwndFrom = hwnd;
543 nmhdr.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
544 nmhdr.hdr.code = code;
549 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
550 (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
555 HEADER_CreateDragImage (HWND hwnd, WPARAM wParam)
557 FIXME("empty stub!\n");
563 HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
565 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
566 INT iItem = (INT)wParam;
568 TRACE("[iItem=%d]\n", iItem);
570 if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
573 if (infoPtr->uNumItem == 1) {
574 TRACE("Simple delete!\n");
575 if (infoPtr->items[0].pszText)
576 COMCTL32_Free (infoPtr->items[0].pszText);
577 COMCTL32_Free (infoPtr->items);
579 infoPtr->uNumItem = 0;
582 HEADER_ITEM *oldItems = infoPtr->items;
583 TRACE("Complex delete! [iItem=%d]\n", iItem);
585 if (infoPtr->items[iItem].pszText)
586 COMCTL32_Free (infoPtr->items[iItem].pszText);
589 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
590 /* pre delete copy */
592 memcpy (&infoPtr->items[0], &oldItems[0],
593 iItem * sizeof(HEADER_ITEM));
596 /* post delete copy */
597 if (iItem < infoPtr->uNumItem) {
598 memcpy (&infoPtr->items[iItem], &oldItems[iItem+1],
599 (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
602 COMCTL32_Free (oldItems);
605 HEADER_SetItemBounds (hwnd);
607 InvalidateRect(hwnd, NULL, FALSE);
614 HEADER_GetImageList (HWND hwnd)
616 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
618 return (LRESULT)infoPtr->himl;
623 HEADER_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
625 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
626 HDITEMA *phdi = (HDITEMA*)lParam;
627 INT nItem = (INT)wParam;
632 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
635 TRACE("[nItem=%d]\n", nItem);
640 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
641 if (phdi->mask & HDI_BITMAP)
642 phdi->hbm = lpItem->hbm;
644 if (phdi->mask & HDI_FORMAT)
645 phdi->fmt = lpItem->fmt;
647 if (phdi->mask & HDI_WIDTH)
648 phdi->cxy = lpItem->cxy;
650 if (phdi->mask & HDI_LPARAM)
651 phdi->lParam = lpItem->lParam;
653 if (phdi->mask & HDI_TEXT) {
654 if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
655 lstrcpynWtoA (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
657 phdi->pszText = LPSTR_TEXTCALLBACKA;
660 if (phdi->mask & HDI_IMAGE)
661 phdi->iImage = lpItem->iImage;
663 if (phdi->mask & HDI_ORDER)
664 phdi->iOrder = lpItem->iOrder;
671 HEADER_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
673 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
674 HDITEMW *phdi = (HDITEMW*)lParam;
675 INT nItem = (INT)wParam;
680 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
683 TRACE("[nItem=%d]\n", nItem);
688 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
689 if (phdi->mask & HDI_BITMAP)
690 phdi->hbm = lpItem->hbm;
692 if (phdi->mask & HDI_FORMAT)
693 phdi->fmt = lpItem->fmt;
695 if (phdi->mask & HDI_WIDTH)
696 phdi->cxy = lpItem->cxy;
698 if (phdi->mask & HDI_LPARAM)
699 phdi->lParam = lpItem->lParam;
701 if (phdi->mask & HDI_TEXT) {
702 if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
703 lstrcpynW (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
705 phdi->pszText = LPSTR_TEXTCALLBACKW;
708 if (phdi->mask & HDI_IMAGE)
709 phdi->iImage = lpItem->iImage;
711 if (phdi->mask & HDI_ORDER)
712 phdi->iOrder = lpItem->iOrder;
718 inline static LRESULT
719 HEADER_GetItemCount (HWND hwnd)
721 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
722 return infoPtr->uNumItem;
727 HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
729 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
730 INT iItem = (INT)wParam;
731 LPRECT lpRect = (LPRECT)lParam;
733 if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
736 lpRect->left = infoPtr->items[iItem].rect.left;
737 lpRect->right = infoPtr->items[iItem].rect.right;
738 lpRect->top = infoPtr->items[iItem].rect.top;
739 lpRect->bottom = infoPtr->items[iItem].rect.bottom;
745 /* << HEADER_GetOrderArray >> */
748 inline static LRESULT
749 HEADER_GetUnicodeFormat (HWND hwnd)
751 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
752 return infoPtr->bUnicode;
757 HEADER_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
759 LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;
761 HEADER_InternalHitTest (hwnd, &phti->pt, &phti->flags, &phti->iItem);
763 if (phti->flags == HHT_ONHEADER)
771 HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
773 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
774 HDITEMA *phdi = (HDITEMA*)lParam;
775 INT nItem = (INT)wParam;
779 if ((phdi == NULL) || (nItem < 0))
782 if (nItem > infoPtr->uNumItem)
783 nItem = infoPtr->uNumItem;
785 if (infoPtr->uNumItem == 0) {
786 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
790 HEADER_ITEM *oldItems = infoPtr->items;
793 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
795 memcpy (&infoPtr->items[1], &oldItems[0],
796 (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM));
800 /* pre insert copy */
802 memcpy (&infoPtr->items[0], &oldItems[0],
803 nItem * sizeof(HEADER_ITEM));
806 /* post insert copy */
807 if (nItem < infoPtr->uNumItem - 1) {
808 memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
809 (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM));
813 COMCTL32_Free (oldItems);
816 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
817 lpItem->bDown = FALSE;
819 if (phdi->mask & HDI_WIDTH)
820 lpItem->cxy = phdi->cxy;
822 if (phdi->mask & HDI_TEXT) {
823 if (!phdi->pszText) /* null pointer check */
825 if (phdi->pszText != LPSTR_TEXTCALLBACKA) {
826 len = strlen (phdi->pszText);
827 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
828 lstrcpyAtoW (lpItem->pszText, phdi->pszText);
831 lpItem->pszText = LPSTR_TEXTCALLBACKW;
834 if (phdi->mask & HDI_FORMAT)
835 lpItem->fmt = phdi->fmt;
837 if (lpItem->fmt == 0)
838 lpItem->fmt = HDF_LEFT;
840 if (phdi->mask & HDI_BITMAP)
841 lpItem->hbm = phdi->hbm;
843 if (phdi->mask & HDI_LPARAM)
844 lpItem->lParam = phdi->lParam;
846 if (phdi->mask & HDI_IMAGE)
847 lpItem->iImage = phdi->iImage;
849 if (phdi->mask & HDI_ORDER)
850 lpItem->iOrder = phdi->iOrder;
852 HEADER_SetItemBounds (hwnd);
854 InvalidateRect(hwnd, NULL, FALSE);
861 HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
863 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
864 HDITEMW *phdi = (HDITEMW*)lParam;
865 INT nItem = (INT)wParam;
869 if ((phdi == NULL) || (nItem < 0))
872 if (nItem > infoPtr->uNumItem)
873 nItem = infoPtr->uNumItem;
875 if (infoPtr->uNumItem == 0) {
876 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
880 HEADER_ITEM *oldItems = infoPtr->items;
883 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
884 /* pre insert copy */
886 memcpy (&infoPtr->items[0], &oldItems[0],
887 nItem * sizeof(HEADER_ITEM));
890 /* post insert copy */
891 if (nItem < infoPtr->uNumItem - 1) {
892 memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
893 (infoPtr->uNumItem - nItem) * sizeof(HEADER_ITEM));
896 COMCTL32_Free (oldItems);
899 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
900 lpItem->bDown = FALSE;
902 if (phdi->mask & HDI_WIDTH)
903 lpItem->cxy = phdi->cxy;
905 if (phdi->mask & HDI_TEXT) {
906 WCHAR wide_null_char = 0;
907 if (!phdi->pszText) /* null pointer check */
908 phdi->pszText = &wide_null_char;
909 if (phdi->pszText != LPSTR_TEXTCALLBACKW) {
910 len = strlenW (phdi->pszText);
911 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
912 strcpyW (lpItem->pszText, phdi->pszText);
915 lpItem->pszText = LPSTR_TEXTCALLBACKW;
918 if (phdi->mask & HDI_FORMAT)
919 lpItem->fmt = phdi->fmt;
921 if (lpItem->fmt == 0)
922 lpItem->fmt = HDF_LEFT;
924 if (phdi->mask & HDI_BITMAP)
925 lpItem->hbm = phdi->hbm;
927 if (phdi->mask & HDI_LPARAM)
928 lpItem->lParam = phdi->lParam;
930 if (phdi->mask & HDI_IMAGE)
931 lpItem->iImage = phdi->iImage;
933 if (phdi->mask & HDI_ORDER)
934 lpItem->iOrder = phdi->iOrder;
936 HEADER_SetItemBounds (hwnd);
938 InvalidateRect(hwnd, NULL, FALSE);
945 HEADER_Layout (HWND hwnd, WPARAM wParam, LPARAM lParam)
947 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
948 LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;
950 lpLayout->pwpos->hwnd = hwnd;
951 lpLayout->pwpos->hwndInsertAfter = 0;
952 lpLayout->pwpos->x = lpLayout->prc->left;
953 lpLayout->pwpos->y = lpLayout->prc->top;
954 lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
955 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_HIDDEN)
956 lpLayout->pwpos->cy = 0;
958 lpLayout->pwpos->cy = infoPtr->nHeight;
959 lpLayout->prc->top += infoPtr->nHeight;
961 lpLayout->pwpos->flags = SWP_NOZORDER;
963 TRACE("Layout x=%d y=%d cx=%d cy=%d\n",
964 lpLayout->pwpos->x, lpLayout->pwpos->y,
965 lpLayout->pwpos->cx, lpLayout->pwpos->cy);
967 infoPtr->bRectsValid = FALSE;
974 HEADER_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
976 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
979 himlOld = infoPtr->himl;
980 infoPtr->himl = (HIMAGELIST)lParam;
982 /* FIXME: Refresh needed??? */
984 return (LRESULT)himlOld;
989 HEADER_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
991 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
992 HDITEMA *phdi = (HDITEMA*)lParam;
993 INT nItem = (INT)wParam;
998 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
1001 TRACE("[nItem=%d]\n", nItem);
1003 if (HEADER_SendItemChange(hwnd, nItem, phdi->mask,HDN_ITEMCHANGINGA))
1006 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1007 if (phdi->mask & HDI_BITMAP)
1008 lpItem->hbm = phdi->hbm;
1010 if (phdi->mask & HDI_FORMAT)
1011 lpItem->fmt = phdi->fmt;
1013 if (phdi->mask & HDI_LPARAM)
1014 lpItem->lParam = phdi->lParam;
1016 if (phdi->mask & HDI_TEXT) {
1017 if (phdi->pszText != LPSTR_TEXTCALLBACKA) {
1018 if (lpItem->pszText) {
1019 COMCTL32_Free (lpItem->pszText);
1020 lpItem->pszText = NULL;
1022 if (phdi->pszText) {
1023 INT len = strlen (phdi->pszText);
1024 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1025 lstrcpyAtoW (lpItem->pszText, phdi->pszText);
1029 lpItem->pszText = LPSTR_TEXTCALLBACKW;
1032 if (phdi->mask & HDI_WIDTH)
1033 lpItem->cxy = phdi->cxy;
1035 if (phdi->mask & HDI_IMAGE)
1036 lpItem->iImage = phdi->iImage;
1038 if (phdi->mask & HDI_ORDER)
1039 lpItem->iOrder = phdi->iOrder;
1041 HEADER_SendItemChange(hwnd,nItem,phdi->mask,HDN_ITEMCHANGEDA);
1043 HEADER_SetItemBounds (hwnd);
1045 InvalidateRect(hwnd, NULL, FALSE);
1052 HEADER_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1054 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1055 HDITEMW *phdi = (HDITEMW*)lParam;
1056 INT nItem = (INT)wParam;
1057 HEADER_ITEM *lpItem;
1061 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
1064 TRACE("[nItem=%d]\n", nItem);
1066 if (HEADER_SendItemChange(hwnd,nItem,phdi->mask,HDN_ITEMCHANGINGW))
1069 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1070 if (phdi->mask & HDI_BITMAP)
1071 lpItem->hbm = phdi->hbm;
1073 if (phdi->mask & HDI_FORMAT)
1074 lpItem->fmt = phdi->fmt;
1076 if (phdi->mask & HDI_LPARAM)
1077 lpItem->lParam = phdi->lParam;
1079 if (phdi->mask & HDI_TEXT) {
1080 if (phdi->pszText != LPSTR_TEXTCALLBACKW) {
1081 if (lpItem->pszText) {
1082 COMCTL32_Free (lpItem->pszText);
1083 lpItem->pszText = NULL;
1085 if (phdi->pszText) {
1086 INT len = strlenW (phdi->pszText);
1087 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1088 strcpyW (lpItem->pszText, phdi->pszText);
1092 lpItem->pszText = LPSTR_TEXTCALLBACKW;
1095 if (phdi->mask & HDI_WIDTH)
1096 lpItem->cxy = phdi->cxy;
1098 if (phdi->mask & HDI_IMAGE)
1099 lpItem->iImage = phdi->iImage;
1101 if (phdi->mask & HDI_ORDER)
1102 lpItem->iOrder = phdi->iOrder;
1104 HEADER_SendItemChange(hwnd, nItem, phdi->mask,HDN_ITEMCHANGEDW);
1106 HEADER_SetItemBounds (hwnd);
1108 InvalidateRect(hwnd, NULL, FALSE);
1114 /* << HEADER_SetOrderArray >> */
1117 inline static LRESULT
1118 HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
1120 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1121 BOOL bTemp = infoPtr->bUnicode;
1123 infoPtr->bUnicode = (BOOL)wParam;
1130 HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1132 HEADER_INFO *infoPtr;
1137 infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
1138 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1140 infoPtr->uNumItem = 0;
1141 infoPtr->nHeight = 20;
1144 infoPtr->bRectsValid = FALSE;
1145 infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
1146 infoPtr->hcurDivider = LoadCursorA (0, IDC_SIZEWEA);
1147 infoPtr->hcurDivopen = LoadCursorA (0, IDC_SIZENSA);
1148 infoPtr->bPressed = FALSE;
1149 infoPtr->bTracking = FALSE;
1150 infoPtr->iMoveItem = 0;
1152 infoPtr->iHotItem = -1;
1153 infoPtr->bUnicode = IsWindowUnicode (hwnd);
1156 hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT));
1157 GetTextMetricsA (hdc, &tm);
1158 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1159 SelectObject (hdc, hOldFont);
1167 HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1169 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1170 HEADER_ITEM *lpItem;
1173 if (infoPtr->items) {
1174 lpItem = (HEADER_ITEM*)infoPtr->items;
1175 for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
1176 if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACKW))
1177 COMCTL32_Free (lpItem->pszText);
1179 COMCTL32_Free (infoPtr->items);
1183 ImageList_Destroy (infoPtr->himl);
1185 COMCTL32_Free (infoPtr);
1186 SetWindowLongA (hwnd, 0, 0);
1191 static inline LRESULT
1192 HEADER_GetFont (HWND hwnd)
1194 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1196 return (LRESULT)infoPtr->hFont;
1201 HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
1207 pt.x = (INT)LOWORD(lParam);
1208 pt.y = (INT)HIWORD(lParam);
1209 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1211 if ((GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER))
1212 HEADER_SendHeaderNotify (hwnd, HDN_ITEMDBLCLICKA, nItem);
1213 else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
1214 HEADER_SendHeaderNotify (hwnd, HDN_DIVIDERDBLCLICKA, nItem);
1221 HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1223 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1224 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1230 pt.x = (INT)LOWORD(lParam);
1231 pt.y = (INT)HIWORD(lParam);
1232 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1234 if ((dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
1236 infoPtr->bCaptured = TRUE;
1237 infoPtr->bPressed = TRUE;
1238 infoPtr->iMoveItem = nItem;
1240 infoPtr->items[nItem].bDown = TRUE;
1242 /* Send WM_CUSTOMDRAW */
1244 HEADER_RefreshItem (hwnd, hdc, nItem);
1245 ReleaseDC (hwnd, hdc);
1247 TRACE("Pressed item %d!\n", nItem);
1249 else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
1250 if (!(HEADER_SendHeaderNotify (hwnd, HDN_BEGINTRACKA, nItem))) {
1252 infoPtr->bCaptured = TRUE;
1253 infoPtr->bTracking = TRUE;
1254 infoPtr->iMoveItem = nItem;
1255 infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
1256 infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;
1258 if (!(dwStyle & HDS_FULLDRAG)) {
1259 infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
1261 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1262 ReleaseDC (hwnd, hdc);
1265 TRACE("Begin tracking item %d!\n", nItem);
1274 HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1276 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1278 *DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1285 pt.x = (INT)SLOWORD(lParam);
1286 pt.y = (INT)SHIWORD(lParam);
1287 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1289 if (infoPtr->bPressed) {
1290 if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
1291 infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
1293 HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
1294 ReleaseDC (hwnd, hdc);
1296 HEADER_SendClickNotify (hwnd, HDN_ITEMCLICKA, infoPtr->iMoveItem);
1298 TRACE("Released item %d!\n", infoPtr->iMoveItem);
1299 infoPtr->bPressed = FALSE;
1301 else if (infoPtr->bTracking) {
1302 TRACE("End tracking item %d!\n", infoPtr->iMoveItem);
1303 infoPtr->bTracking = FALSE;
1305 HEADER_SendHeaderNotify (hwnd, HDN_ENDTRACKA, infoPtr->iMoveItem);
1308 * we want to do this even for HDS_FULLDRAG because this is where
1309 * we send the HDN_ITEMCHANGING and HDN_ITEMCHANGED notifications
1311 * if (!(dwStyle & HDS_FULLDRAG)) {
1315 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1316 ReleaseDC (hwnd, hdc);
1317 if (HEADER_SendItemChange(hwnd, infoPtr->iMoveItem,HDI_WIDTH,
1319 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1321 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
1324 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
1327 HEADER_SendItemChange(hwnd,infoPtr->iMoveItem,HDI_WIDTH,
1329 HEADER_SetItemBounds (hwnd);
1330 InvalidateRect(hwnd, NULL, FALSE);
1336 if (infoPtr->bCaptured) {
1337 infoPtr->bCaptured = FALSE;
1339 HEADER_SendSimpleNotify (hwnd, NM_RELEASEDCAPTURE);
1347 HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1349 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1350 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1356 pt.x = (INT)SLOWORD(lParam);
1357 pt.y = (INT)SHIWORD(lParam);
1358 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1360 if ((dwStyle & HDS_BUTTONS) && (dwStyle & HDS_HOTTRACK)) {
1361 if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
1362 infoPtr->iHotItem = nItem;
1364 infoPtr->iHotItem = -1;
1365 InvalidateRect(hwnd, NULL, FALSE);
1368 if (infoPtr->bCaptured) {
1369 if (infoPtr->bPressed) {
1370 if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
1371 infoPtr->items[infoPtr->iMoveItem].bDown = TRUE;
1373 infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
1375 HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
1376 ReleaseDC (hwnd, hdc);
1378 TRACE("Moving pressed item %d!\n", infoPtr->iMoveItem);
1380 else if (infoPtr->bTracking) {
1381 if (dwStyle & HDS_FULLDRAG) {
1383 * Investigation shows that the changing message occure only
1384 * after tracking is done
1386 *if (HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGINGA, infoPtr->iMoveItem))
1387 * infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1391 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
1394 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
1396 * Invistigation shows that the item changed only occures
1397 * after the tracking is done
1399 * HEADER_SendItemChanged(FALSE,hwnd,infoPtr->iMoveItem,HDI_WIDTH);
1403 HEADER_SetItemBounds (hwnd);
1404 InvalidateRect(hwnd, NULL, FALSE);
1408 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1409 infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset;
1410 if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left)
1411 infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left;
1412 infoPtr->items[infoPtr->iMoveItem].cxy =
1413 infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left;
1414 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1415 ReleaseDC (hwnd, hdc);
1418 HEADER_SendHeaderNotify (hwnd, HDN_TRACKA, infoPtr->iMoveItem);
1419 TRACE("Tracking item %d!\n", infoPtr->iMoveItem);
1423 if ((dwStyle & HDS_BUTTONS) && (dwStyle & HDS_HOTTRACK)) {
1424 FIXME("hot track support!\n");
1432 HEADER_Paint (HWND hwnd, WPARAM wParam)
1437 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1438 HEADER_Refresh (hwnd, hdc);
1440 EndPaint (hwnd, &ps);
1446 HEADER_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1451 pt.x = LOWORD(lParam);
1452 pt.y = HIWORD(lParam);
1454 /* Send a Notify message */
1455 bRet = HEADER_SendSimpleNotify (hwnd, NM_RCLICK);
1457 /* Change to screen coordinate for WM_CONTEXTMENU */
1458 ClientToScreen(hwnd, &pt);
1460 /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
1461 SendMessageA( hwnd, WM_CONTEXTMENU, (WPARAM) hwnd, MAKELPARAM(pt.x, pt.y));
1468 HEADER_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1470 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1475 TRACE("code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
1478 ScreenToClient (hwnd, &pt);
1480 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1482 if (flags == HHT_ONDIVIDER)
1483 SetCursor (infoPtr->hcurDivider);
1484 else if (flags == HHT_ONDIVOPEN)
1485 SetCursor (infoPtr->hcurDivopen);
1487 SetCursor (infoPtr->hcurArrow);
1494 HEADER_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1496 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1498 HFONT hFont, hOldFont;
1501 infoPtr->hFont = (HFONT)wParam;
1503 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
1506 hOldFont = SelectObject (hdc, hFont);
1507 GetTextMetricsA (hdc, &tm);
1508 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1509 SelectObject (hdc, hOldFont);
1512 infoPtr->bRectsValid = FALSE;
1515 InvalidateRect(hwnd, NULL, FALSE);
1522 static LRESULT WINAPI
1523 HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1525 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, msg, wParam, lParam);
1526 if (!HEADER_GetInfoPtr (hwnd) && (msg != WM_CREATE))
1527 return DefWindowProcA (hwnd, msg, wParam, lParam);
1529 case HDM_CREATEDRAGIMAGE:
1530 return HEADER_CreateDragImage (hwnd, wParam);
1532 case HDM_DELETEITEM:
1533 return HEADER_DeleteItem (hwnd, wParam);
1535 case HDM_GETIMAGELIST:
1536 return HEADER_GetImageList (hwnd);
1539 return HEADER_GetItemA (hwnd, wParam, lParam);
1542 return HEADER_GetItemW (hwnd, wParam, lParam);
1544 case HDM_GETITEMCOUNT:
1545 return HEADER_GetItemCount (hwnd);
1547 case HDM_GETITEMRECT:
1548 return HEADER_GetItemRect (hwnd, wParam, lParam);
1550 /* case HDM_GETORDERARRAY: */
1552 case HDM_GETUNICODEFORMAT:
1553 return HEADER_GetUnicodeFormat (hwnd);
1556 return HEADER_HitTest (hwnd, wParam, lParam);
1558 case HDM_INSERTITEMA:
1559 return HEADER_InsertItemA (hwnd, wParam, lParam);
1561 case HDM_INSERTITEMW:
1562 return HEADER_InsertItemW (hwnd, wParam, lParam);
1565 return HEADER_Layout (hwnd, wParam, lParam);
1567 case HDM_SETIMAGELIST:
1568 return HEADER_SetImageList (hwnd, wParam, lParam);
1571 return HEADER_SetItemA (hwnd, wParam, lParam);
1574 return HEADER_SetItemW (hwnd, wParam, lParam);
1576 /* case HDM_SETORDERARRAY: */
1578 case HDM_SETUNICODEFORMAT:
1579 return HEADER_SetUnicodeFormat (hwnd, wParam);
1582 return HEADER_Create (hwnd, wParam, lParam);
1585 return HEADER_Destroy (hwnd, wParam, lParam);
1591 return DLGC_WANTTAB | DLGC_WANTARROWS;
1594 return HEADER_GetFont (hwnd);
1596 case WM_LBUTTONDBLCLK:
1597 return HEADER_LButtonDblClk (hwnd, wParam, lParam);
1599 case WM_LBUTTONDOWN:
1600 return HEADER_LButtonDown (hwnd, wParam, lParam);
1603 return HEADER_LButtonUp (hwnd, wParam, lParam);
1606 return HEADER_MouseMove (hwnd, wParam, lParam);
1608 /* case WM_NOTIFYFORMAT: */
1611 return HEADER_Size (hwnd, wParam);
1614 return HEADER_Paint (hwnd, wParam);
1617 return HEADER_RButtonUp (hwnd, wParam, lParam);
1620 return HEADER_SetCursor (hwnd, wParam, lParam);
1623 return HEADER_SetFont (hwnd, wParam, lParam);
1627 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1628 msg, wParam, lParam );
1629 return DefWindowProcA (hwnd, msg, wParam, lParam);
1636 HEADER_Register (void)
1640 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1641 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
1642 wndClass.lpfnWndProc = (WNDPROC)HEADER_WindowProc;
1643 wndClass.cbClsExtra = 0;
1644 wndClass.cbWndExtra = sizeof(HEADER_INFO *);
1645 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1646 wndClass.lpszClassName = WC_HEADERA;
1648 RegisterClassA (&wndClass);
1653 HEADER_Unregister (void)
1655 UnregisterClassA (WC_HEADERA, (HINSTANCE)NULL);