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"
27 #include "debugtools.h"
29 DEFAULT_DEBUG_CHANNEL(header);
39 INT iOrder; /* see documentation of HD_ITEM */
41 BOOL bDown; /* is item pressed? (used for drawing) */
42 RECT rect; /* bounding rectangle of the item */
48 UINT uNumItem; /* number of items (columns) */
49 INT nHeight; /* height of the header (pixels) */
50 HFONT hFont; /* handle to the current font */
51 HCURSOR hcurArrow; /* handle to the arrow cursor */
52 HCURSOR hcurDivider; /* handle to a cursor (used over dividers) <-|-> */
53 HCURSOR hcurDivopen; /* handle to a cursor (used over dividers) <-||-> */
54 BOOL bCaptured; /* Is the mouse captured? */
55 BOOL bPressed; /* Is a header item pressed (down)? */
56 BOOL bTracking; /* Is in tracking mode? */
57 BOOL bUnicode; /* Unicode flag */
58 INT iMoveItem; /* index of tracked item. (Tracking mode) */
59 INT xTrackOffset; /* distance between the right side of the tracked item and the cursor */
60 INT xOldTrack; /* track offset (see above) after the last WM_MOUSEMOVE */
61 INT nOldWidth; /* width of a sizing item after the last WM_MOUSEMOVE */
62 INT iHotItem; /* index of hot item (cursor is over this item) */
64 HIMAGELIST himl; /* handle to a image list (may be 0) */
65 HEADER_ITEM *items; /* pointer to array of HEADER_ITEM's */
66 BOOL bRectsValid; /* validity flag for bounding rectangles */
67 LPINT pOrder; /* pointer to order array */
72 #define DIVIDER_WIDTH 10
74 #define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
78 HEADER_SetItemBounds (HWND hwnd)
80 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
85 infoPtr->bRectsValid = TRUE;
87 if (infoPtr->uNumItem == 0)
90 GetClientRect (hwnd, &rect);
93 for (i = 0; i < infoPtr->uNumItem; i++) {
94 phdi = &infoPtr->items[i];
95 phdi->rect.top = rect.top;
96 phdi->rect.bottom = rect.bottom;
98 phdi->rect.right = phdi->rect.left + phdi->cxy;
104 HEADER_Size (HWND hwnd, WPARAM wParam)
106 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
108 infoPtr->bRectsValid = FALSE;
115 HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
117 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
118 HEADER_ITEM *phdi = &infoPtr->items[iItem];
122 if (!infoPtr->bRectsValid)
123 HEADER_SetItemBounds(hwnd);
126 if (r.right - r.left == 0)
127 return phdi->rect.right;
129 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) {
131 DrawEdge (hdc, &r, BDR_RAISEDOUTER,
132 BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
137 DrawEdge (hdc, &r, EDGE_RAISED,
138 BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
141 DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
143 if (phdi->fmt & HDF_OWNERDRAW) {
145 dis.CtlType = ODT_HEADER;
146 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
148 dis.itemAction = ODA_DRAWENTIRE;
149 dis.itemState = phdi->bDown ? ODS_SELECTED : 0;
153 dis.itemData = phdi->lParam;
154 SendMessageA (GetParent (hwnd), WM_DRAWITEM,
155 (WPARAM)dis.CtlID, (LPARAM)&dis);
158 UINT uTextJustify = DT_LEFT;
160 if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER)
161 uTextJustify = DT_CENTER;
162 else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
163 uTextJustify = DT_RIGHT;
165 if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
168 INT yD, yS, cx, cy, rx, ry;
170 GetObjectA (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp);
172 ry = r.bottom - r.top;
173 rx = r.right - r.left;
175 if (ry >= bmp.bmHeight) {
177 yD = r.top + (ry - bmp.bmHeight) / 2;
183 yS = (bmp.bmHeight - ry) / 2;
187 if (rx >= bmp.bmWidth + 6) {
194 hdcBitmap = CreateCompatibleDC (hdc);
195 SelectObject (hdcBitmap, phdi->hbm);
196 BitBlt (hdc, r.left + 3, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
197 DeleteDC (hdcBitmap);
199 r.left += (bmp.bmWidth + 3);
203 if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
206 INT xD, yD, yS, cx, cy, rx, ry, tx;
209 GetObjectA (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp);
212 DrawTextW (hdc, phdi->pszText, -1,
213 &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
214 tx = textRect.right - textRect.left;
215 ry = r.bottom - r.top;
216 rx = r.right - r.left;
218 if (ry >= bmp.bmHeight) {
220 yD = r.top + (ry - bmp.bmHeight) / 2;
226 yS = (bmp.bmHeight - ry) / 2;
230 if (r.left + tx + bmp.bmWidth + 9 <= r.right) {
232 xD = r.left + tx + 6;
235 if (rx >= bmp.bmWidth + 6) {
237 xD = r.right - bmp.bmWidth - 3;
247 hdcBitmap = CreateCompatibleDC (hdc);
248 SelectObject (hdcBitmap, phdi->hbm);
249 BitBlt (hdc, xD, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
250 DeleteDC (hdcBitmap);
253 if (phdi->fmt & HDF_IMAGE) {
256 /* ImageList_Draw (infoPtr->himl, phdi->iImage,...); */
259 if (((phdi->fmt & HDF_STRING)
260 || (!(phdi->fmt & (HDF_OWNERDRAW|HDF_STRING|HDF_BITMAP|
261 HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */
262 && (phdi->pszText)) {
263 oldBkMode = SetBkMode(hdc, TRANSPARENT);
266 SetTextColor (hdc, bHotTrack ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
267 DrawTextW (hdc, phdi->pszText, -1,
268 &r, uTextJustify|DT_VCENTER|DT_SINGLELINE);
269 if (oldBkMode != TRANSPARENT)
270 SetBkMode(hdc, oldBkMode);
274 return phdi->rect.right;
279 HEADER_Refresh (HWND hwnd, HDC hdc)
281 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
282 HFONT hFont, hOldFont;
287 /* get rect for the bar, adjusted for the border */
288 GetClientRect (hwnd, &rect);
290 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
291 hOldFont = SelectObject (hdc, hFont);
293 /* draw Background */
294 hbrBk = GetSysColorBrush(COLOR_3DFACE);
295 FillRect(hdc, &rect, hbrBk);
298 for (i = 0; i < infoPtr->uNumItem; i++) {
299 x = HEADER_DrawItem (hwnd, hdc, i, FALSE);
302 if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
304 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS)
305 DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
307 DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
310 SelectObject (hdc, hOldFont);
315 HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem)
317 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
318 HFONT hFont, hOldFont;
320 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
321 hOldFont = SelectObject (hdc, hFont);
322 HEADER_DrawItem (hwnd, hdc, iItem, FALSE);
323 SelectObject (hdc, hOldFont);
328 HEADER_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pItem)
330 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
335 GetClientRect (hwnd, &rect);
339 if (PtInRect (&rect, *lpPt))
341 if (infoPtr->uNumItem == 0) {
342 *pFlags |= HHT_NOWHERE;
348 /* somewhere inside */
349 for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
350 rect = infoPtr->items[iCount].rect;
351 width = rect.right - rect.left;
356 if (PtInRect (&rect, *lpPt)) {
357 if (width <= 2 * DIVIDER_WIDTH) {
358 *pFlags |= HHT_ONHEADER;
360 TRACE("ON HEADER %d\n", iCount);
365 rcTest.right = rcTest.left + DIVIDER_WIDTH;
366 if (PtInRect (&rcTest, *lpPt)) {
368 *pFlags |= HHT_ONDIVOPEN;
370 TRACE("ON DIVOPEN %d\n", *pItem);
374 *pFlags |= HHT_ONDIVIDER;
376 TRACE("ON DIVIDER %d\n", *pItem);
382 rcTest.left = rcTest.right - DIVIDER_WIDTH;
383 if (PtInRect (&rcTest, *lpPt)) {
384 *pFlags |= HHT_ONDIVIDER;
386 TRACE("ON DIVIDER %d\n", *pItem);
390 *pFlags |= HHT_ONHEADER;
392 TRACE("ON HEADER %d\n", iCount);
397 /* check for last divider part (on nowhere) */
398 rect = infoPtr->items[infoPtr->uNumItem-1].rect;
399 rect.left = rect.right;
400 rect.right += DIVIDER_WIDTH;
401 if (PtInRect (&rect, *lpPt)) {
403 *pFlags |= HHT_ONDIVOPEN;
404 *pItem = infoPtr->uNumItem - 1;
405 TRACE("ON DIVOPEN %d\n", *pItem);
409 *pFlags |= HHT_ONDIVIDER;
410 *pItem = infoPtr->uNumItem-1;
411 TRACE("ON DIVIDER %d\n", *pItem);
416 *pFlags |= HHT_NOWHERE;
423 if (lpPt->x < rect.left) {
425 *pFlags |= HHT_TOLEFT;
427 else if (lpPt->x > rect.right) {
429 *pFlags |= HHT_TORIGHT;
432 if (lpPt->y < rect.top) {
434 *pFlags |= HHT_ABOVE;
436 else if (lpPt->y > rect.bottom) {
438 *pFlags |= HHT_BELOW;
443 TRACE("flags=0x%X\n", *pFlags);
449 HEADER_DrawTrackLine (HWND hwnd, HDC hdc, INT x)
455 GetClientRect (hwnd, &rect);
457 hOldPen = SelectObject (hdc, GetStockObject (BLACK_PEN));
458 oldRop = SetROP2 (hdc, R2_XORPEN);
459 MoveToEx (hdc, x, rect.top, NULL);
460 LineTo (hdc, x, rect.bottom);
461 SetROP2 (hdc, oldRop);
462 SelectObject (hdc, hOldPen);
467 HEADER_SendSimpleNotify (HWND hwnd, UINT code)
471 nmhdr.hwndFrom = hwnd;
472 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
475 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
476 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
480 HEADER_SendItemChange(HWND hwnd, INT iItem, UINT mask, UINT msg)
482 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
486 nmhdr.hdr.hwndFrom = hwnd;
487 nmhdr.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
488 nmhdr.hdr.code = msg;
491 nmhdr.pitem = &nmitem;
493 nmitem.cxy = infoPtr->items[iItem].cxy;
494 nmitem.hbm = infoPtr->items[iItem].hbm;
495 nmitem.pszText = NULL;
496 nmitem.cchTextMax = 0;
497 nmitem.fmt = infoPtr->items[iItem].fmt;
498 nmitem.lParam = infoPtr->items[iItem].lParam;
499 nmitem.iOrder = infoPtr->items[iItem].iOrder;
500 nmitem.iImage = infoPtr->items[iItem].iImage;
502 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
503 (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
507 HEADER_SendHeaderNotify (HWND hwnd, UINT code, INT iItem)
509 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
513 nmhdr.hdr.hwndFrom = hwnd;
514 nmhdr.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
515 nmhdr.hdr.code = code;
518 nmhdr.pitem = &nmitem;
520 nmitem.cxy = infoPtr->items[iItem].cxy;
521 nmitem.hbm = infoPtr->items[iItem].hbm;
522 nmitem.pszText = NULL;
523 nmitem.cchTextMax = 0;
524 /* nmitem.pszText = infoPtr->items[iItem].pszText; */
525 /* nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
526 nmitem.fmt = infoPtr->items[iItem].fmt;
527 nmitem.lParam = infoPtr->items[iItem].lParam;
528 nmitem.iOrder = infoPtr->items[iItem].iOrder;
529 nmitem.iImage = infoPtr->items[iItem].iImage;
531 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
532 (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
537 HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem)
541 nmhdr.hdr.hwndFrom = hwnd;
542 nmhdr.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
543 nmhdr.hdr.code = code;
548 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
549 (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
554 HEADER_CreateDragImage (HWND hwnd, WPARAM wParam)
556 FIXME("empty stub!\n");
562 HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
564 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
565 INT iItem = (INT)wParam;
567 TRACE("[iItem=%d]\n", iItem);
569 if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
572 if (infoPtr->uNumItem == 1) {
573 TRACE("Simple delete!\n");
574 if (infoPtr->items[0].pszText)
575 COMCTL32_Free (infoPtr->items[0].pszText);
576 COMCTL32_Free (infoPtr->items);
578 infoPtr->uNumItem = 0;
581 HEADER_ITEM *oldItems = infoPtr->items;
582 TRACE("Complex delete! [iItem=%d]\n", iItem);
584 if (infoPtr->items[iItem].pszText)
585 COMCTL32_Free (infoPtr->items[iItem].pszText);
588 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
589 /* pre delete copy */
591 memcpy (&infoPtr->items[0], &oldItems[0],
592 iItem * sizeof(HEADER_ITEM));
595 /* post delete copy */
596 if (iItem < infoPtr->uNumItem) {
597 memcpy (&infoPtr->items[iItem], &oldItems[iItem+1],
598 (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
601 COMCTL32_Free (oldItems);
604 HEADER_SetItemBounds (hwnd);
606 InvalidateRect(hwnd, NULL, FALSE);
613 HEADER_GetImageList (HWND hwnd)
615 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
617 return (LRESULT)infoPtr->himl;
622 HEADER_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
624 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
625 HDITEMA *phdi = (HDITEMA*)lParam;
626 INT nItem = (INT)wParam;
631 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
634 TRACE("[nItem=%d]\n", nItem);
639 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
640 if (phdi->mask & HDI_BITMAP)
641 phdi->hbm = lpItem->hbm;
643 if (phdi->mask & HDI_FORMAT)
644 phdi->fmt = lpItem->fmt;
646 if (phdi->mask & HDI_WIDTH)
647 phdi->cxy = lpItem->cxy;
649 if (phdi->mask & HDI_LPARAM)
650 phdi->lParam = lpItem->lParam;
652 if (phdi->mask & HDI_TEXT) {
653 if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
654 lstrcpynWtoA (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
656 phdi->pszText = LPSTR_TEXTCALLBACKA;
659 if (phdi->mask & HDI_IMAGE)
660 phdi->iImage = lpItem->iImage;
662 if (phdi->mask & HDI_ORDER)
663 phdi->iOrder = lpItem->iOrder;
670 HEADER_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
672 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
673 HDITEMW *phdi = (HDITEMW*)lParam;
674 INT nItem = (INT)wParam;
679 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
682 TRACE("[nItem=%d]\n", nItem);
687 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
688 if (phdi->mask & HDI_BITMAP)
689 phdi->hbm = lpItem->hbm;
691 if (phdi->mask & HDI_FORMAT)
692 phdi->fmt = lpItem->fmt;
694 if (phdi->mask & HDI_WIDTH)
695 phdi->cxy = lpItem->cxy;
697 if (phdi->mask & HDI_LPARAM)
698 phdi->lParam = lpItem->lParam;
700 if (phdi->mask & HDI_TEXT) {
701 if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
702 lstrcpynW (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
704 phdi->pszText = LPSTR_TEXTCALLBACKW;
707 if (phdi->mask & HDI_IMAGE)
708 phdi->iImage = lpItem->iImage;
710 if (phdi->mask & HDI_ORDER)
711 phdi->iOrder = lpItem->iOrder;
717 inline static LRESULT
718 HEADER_GetItemCount (HWND hwnd)
720 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
721 return infoPtr->uNumItem;
726 HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
728 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
729 INT iItem = (INT)wParam;
730 LPRECT lpRect = (LPRECT)lParam;
732 if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
735 lpRect->left = infoPtr->items[iItem].rect.left;
736 lpRect->right = infoPtr->items[iItem].rect.right;
737 lpRect->top = infoPtr->items[iItem].rect.top;
738 lpRect->bottom = infoPtr->items[iItem].rect.bottom;
744 /* << HEADER_GetOrderArray >> */
747 inline static LRESULT
748 HEADER_GetUnicodeFormat (HWND hwnd)
750 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
751 return infoPtr->bUnicode;
756 HEADER_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
758 LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;
760 HEADER_InternalHitTest (hwnd, &phti->pt, &phti->flags, &phti->iItem);
762 if (phti->flags == HHT_ONHEADER)
770 HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
772 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
773 HDITEMA *phdi = (HDITEMA*)lParam;
774 INT nItem = (INT)wParam;
778 if ((phdi == NULL) || (nItem < 0))
781 if (nItem > infoPtr->uNumItem)
782 nItem = infoPtr->uNumItem;
784 if (infoPtr->uNumItem == 0) {
785 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
789 HEADER_ITEM *oldItems = infoPtr->items;
792 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
794 memcpy (&infoPtr->items[1], &oldItems[0],
795 (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM));
799 /* pre insert copy */
801 memcpy (&infoPtr->items[0], &oldItems[0],
802 nItem * sizeof(HEADER_ITEM));
805 /* post insert copy */
806 if (nItem < infoPtr->uNumItem - 1) {
807 memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
808 (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM));
812 COMCTL32_Free (oldItems);
815 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
816 lpItem->bDown = FALSE;
818 if (phdi->mask & HDI_WIDTH)
819 lpItem->cxy = phdi->cxy;
821 if (phdi->mask & HDI_TEXT) {
822 if (!phdi->pszText) /* null pointer check */
824 if (phdi->pszText != LPSTR_TEXTCALLBACKA) {
825 len = strlen (phdi->pszText);
826 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
827 lstrcpyAtoW (lpItem->pszText, phdi->pszText);
830 lpItem->pszText = LPSTR_TEXTCALLBACKW;
833 if (phdi->mask & HDI_FORMAT)
834 lpItem->fmt = phdi->fmt;
836 if (lpItem->fmt == 0)
837 lpItem->fmt = HDF_LEFT;
839 if (phdi->mask & HDI_BITMAP)
840 lpItem->hbm = phdi->hbm;
842 if (phdi->mask & HDI_LPARAM)
843 lpItem->lParam = phdi->lParam;
845 if (phdi->mask & HDI_IMAGE)
846 lpItem->iImage = phdi->iImage;
848 if (phdi->mask & HDI_ORDER)
849 lpItem->iOrder = phdi->iOrder;
851 HEADER_SetItemBounds (hwnd);
853 InvalidateRect(hwnd, NULL, FALSE);
860 HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
862 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
863 HDITEMW *phdi = (HDITEMW*)lParam;
864 INT nItem = (INT)wParam;
868 if ((phdi == NULL) || (nItem < 0))
871 if (nItem > infoPtr->uNumItem)
872 nItem = infoPtr->uNumItem;
874 if (infoPtr->uNumItem == 0) {
875 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
879 HEADER_ITEM *oldItems = infoPtr->items;
882 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
883 /* pre insert copy */
885 memcpy (&infoPtr->items[0], &oldItems[0],
886 nItem * sizeof(HEADER_ITEM));
889 /* post insert copy */
890 if (nItem < infoPtr->uNumItem - 1) {
891 memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
892 (infoPtr->uNumItem - nItem) * sizeof(HEADER_ITEM));
895 COMCTL32_Free (oldItems);
898 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
899 lpItem->bDown = FALSE;
901 if (phdi->mask & HDI_WIDTH)
902 lpItem->cxy = phdi->cxy;
904 if (phdi->mask & HDI_TEXT) {
905 WCHAR wide_null_char = 0;
906 if (!phdi->pszText) /* null pointer check */
907 phdi->pszText = &wide_null_char;
908 if (phdi->pszText != LPSTR_TEXTCALLBACKW) {
909 len = strlenW (phdi->pszText);
910 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
911 strcpyW (lpItem->pszText, phdi->pszText);
914 lpItem->pszText = LPSTR_TEXTCALLBACKW;
917 if (phdi->mask & HDI_FORMAT)
918 lpItem->fmt = phdi->fmt;
920 if (lpItem->fmt == 0)
921 lpItem->fmt = HDF_LEFT;
923 if (phdi->mask & HDI_BITMAP)
924 lpItem->hbm = phdi->hbm;
926 if (phdi->mask & HDI_LPARAM)
927 lpItem->lParam = phdi->lParam;
929 if (phdi->mask & HDI_IMAGE)
930 lpItem->iImage = phdi->iImage;
932 if (phdi->mask & HDI_ORDER)
933 lpItem->iOrder = phdi->iOrder;
935 HEADER_SetItemBounds (hwnd);
937 InvalidateRect(hwnd, NULL, FALSE);
944 HEADER_Layout (HWND hwnd, WPARAM wParam, LPARAM lParam)
946 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
947 LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;
949 lpLayout->pwpos->hwnd = hwnd;
950 lpLayout->pwpos->hwndInsertAfter = 0;
951 lpLayout->pwpos->x = lpLayout->prc->left;
952 lpLayout->pwpos->y = lpLayout->prc->top;
953 lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
954 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_HIDDEN)
955 lpLayout->pwpos->cy = 0;
957 lpLayout->pwpos->cy = infoPtr->nHeight;
958 lpLayout->prc->top += infoPtr->nHeight;
960 lpLayout->pwpos->flags = SWP_NOZORDER;
962 TRACE("Layout x=%d y=%d cx=%d cy=%d\n",
963 lpLayout->pwpos->x, lpLayout->pwpos->y,
964 lpLayout->pwpos->cx, lpLayout->pwpos->cy);
966 infoPtr->bRectsValid = FALSE;
973 HEADER_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
975 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
978 himlOld = infoPtr->himl;
979 infoPtr->himl = (HIMAGELIST)lParam;
981 /* FIXME: Refresh needed??? */
983 return (LRESULT)himlOld;
988 HEADER_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
990 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
991 HDITEMA *phdi = (HDITEMA*)lParam;
992 INT nItem = (INT)wParam;
997 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
1000 TRACE("[nItem=%d]\n", nItem);
1002 if (HEADER_SendItemChange(hwnd, nItem, phdi->mask,HDN_ITEMCHANGINGA))
1005 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1006 if (phdi->mask & HDI_BITMAP)
1007 lpItem->hbm = phdi->hbm;
1009 if (phdi->mask & HDI_FORMAT)
1010 lpItem->fmt = phdi->fmt;
1012 if (phdi->mask & HDI_LPARAM)
1013 lpItem->lParam = phdi->lParam;
1015 if (phdi->mask & HDI_TEXT) {
1016 if (phdi->pszText != LPSTR_TEXTCALLBACKA) {
1017 if (lpItem->pszText) {
1018 COMCTL32_Free (lpItem->pszText);
1019 lpItem->pszText = NULL;
1021 if (phdi->pszText) {
1022 INT len = strlen (phdi->pszText);
1023 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1024 lstrcpyAtoW (lpItem->pszText, phdi->pszText);
1028 lpItem->pszText = LPSTR_TEXTCALLBACKW;
1031 if (phdi->mask & HDI_WIDTH)
1032 lpItem->cxy = phdi->cxy;
1034 if (phdi->mask & HDI_IMAGE)
1035 lpItem->iImage = phdi->iImage;
1037 if (phdi->mask & HDI_ORDER)
1038 lpItem->iOrder = phdi->iOrder;
1040 HEADER_SendItemChange(hwnd,nItem,phdi->mask,HDN_ITEMCHANGEDA);
1042 HEADER_SetItemBounds (hwnd);
1044 InvalidateRect(hwnd, NULL, FALSE);
1051 HEADER_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1053 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1054 HDITEMW *phdi = (HDITEMW*)lParam;
1055 INT nItem = (INT)wParam;
1056 HEADER_ITEM *lpItem;
1060 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
1063 TRACE("[nItem=%d]\n", nItem);
1065 if (HEADER_SendItemChange(hwnd,nItem,phdi->mask,HDN_ITEMCHANGINGW))
1068 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1069 if (phdi->mask & HDI_BITMAP)
1070 lpItem->hbm = phdi->hbm;
1072 if (phdi->mask & HDI_FORMAT)
1073 lpItem->fmt = phdi->fmt;
1075 if (phdi->mask & HDI_LPARAM)
1076 lpItem->lParam = phdi->lParam;
1078 if (phdi->mask & HDI_TEXT) {
1079 if (phdi->pszText != LPSTR_TEXTCALLBACKW) {
1080 if (lpItem->pszText) {
1081 COMCTL32_Free (lpItem->pszText);
1082 lpItem->pszText = NULL;
1084 if (phdi->pszText) {
1085 INT len = strlenW (phdi->pszText);
1086 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1087 strcpyW (lpItem->pszText, phdi->pszText);
1091 lpItem->pszText = LPSTR_TEXTCALLBACKW;
1094 if (phdi->mask & HDI_WIDTH)
1095 lpItem->cxy = phdi->cxy;
1097 if (phdi->mask & HDI_IMAGE)
1098 lpItem->iImage = phdi->iImage;
1100 if (phdi->mask & HDI_ORDER)
1101 lpItem->iOrder = phdi->iOrder;
1103 HEADER_SendItemChange(hwnd, nItem, phdi->mask,HDN_ITEMCHANGEDW);
1105 HEADER_SetItemBounds (hwnd);
1107 InvalidateRect(hwnd, NULL, FALSE);
1113 /* << HEADER_SetOrderArray >> */
1116 inline static LRESULT
1117 HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
1119 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1120 BOOL bTemp = infoPtr->bUnicode;
1122 infoPtr->bUnicode = (BOOL)wParam;
1129 HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1131 HEADER_INFO *infoPtr;
1136 infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
1137 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1139 infoPtr->uNumItem = 0;
1140 infoPtr->nHeight = 20;
1143 infoPtr->bRectsValid = FALSE;
1144 infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
1145 infoPtr->hcurDivider = LoadCursorA (0, IDC_SIZEWEA);
1146 infoPtr->hcurDivopen = LoadCursorA (0, IDC_SIZENSA);
1147 infoPtr->bPressed = FALSE;
1148 infoPtr->bTracking = FALSE;
1149 infoPtr->iMoveItem = 0;
1151 infoPtr->iHotItem = -1;
1152 infoPtr->bUnicode = IsWindowUnicode (hwnd);
1155 hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT));
1156 GetTextMetricsA (hdc, &tm);
1157 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1158 SelectObject (hdc, hOldFont);
1166 HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1168 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1169 HEADER_ITEM *lpItem;
1172 if (infoPtr->items) {
1173 lpItem = (HEADER_ITEM*)infoPtr->items;
1174 for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
1175 if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACKW))
1176 COMCTL32_Free (lpItem->pszText);
1178 COMCTL32_Free (infoPtr->items);
1182 ImageList_Destroy (infoPtr->himl);
1184 COMCTL32_Free (infoPtr);
1185 SetWindowLongA (hwnd, 0, 0);
1190 static inline LRESULT
1191 HEADER_GetFont (HWND hwnd)
1193 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1195 return (LRESULT)infoPtr->hFont;
1200 HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
1206 pt.x = (INT)LOWORD(lParam);
1207 pt.y = (INT)HIWORD(lParam);
1208 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1210 if ((GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER))
1211 HEADER_SendHeaderNotify (hwnd, HDN_ITEMDBLCLICKA, nItem);
1212 else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
1213 HEADER_SendHeaderNotify (hwnd, HDN_DIVIDERDBLCLICKA, nItem);
1220 HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1222 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1223 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1229 pt.x = (INT)LOWORD(lParam);
1230 pt.y = (INT)HIWORD(lParam);
1231 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1233 if ((dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
1235 infoPtr->bCaptured = TRUE;
1236 infoPtr->bPressed = TRUE;
1237 infoPtr->iMoveItem = nItem;
1239 infoPtr->items[nItem].bDown = TRUE;
1241 /* Send WM_CUSTOMDRAW */
1243 HEADER_RefreshItem (hwnd, hdc, nItem);
1244 ReleaseDC (hwnd, hdc);
1246 TRACE("Pressed item %d!\n", nItem);
1248 else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
1249 if (!(HEADER_SendHeaderNotify (hwnd, HDN_BEGINTRACKA, nItem))) {
1251 infoPtr->bCaptured = TRUE;
1252 infoPtr->bTracking = TRUE;
1253 infoPtr->iMoveItem = nItem;
1254 infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
1255 infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;
1257 if (!(dwStyle & HDS_FULLDRAG)) {
1258 infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
1260 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1261 ReleaseDC (hwnd, hdc);
1264 TRACE("Begin tracking item %d!\n", nItem);
1273 HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1275 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1277 *DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1284 pt.x = (INT)SLOWORD(lParam);
1285 pt.y = (INT)SHIWORD(lParam);
1286 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1288 if (infoPtr->bPressed) {
1289 if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
1290 infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
1292 HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
1293 ReleaseDC (hwnd, hdc);
1295 HEADER_SendClickNotify (hwnd, HDN_ITEMCLICKA, infoPtr->iMoveItem);
1297 TRACE("Released item %d!\n", infoPtr->iMoveItem);
1298 infoPtr->bPressed = FALSE;
1300 else if (infoPtr->bTracking) {
1301 TRACE("End tracking item %d!\n", infoPtr->iMoveItem);
1302 infoPtr->bTracking = FALSE;
1304 HEADER_SendHeaderNotify (hwnd, HDN_ENDTRACKA, infoPtr->iMoveItem);
1307 * we want to do this even for HDS_FULLDRAG because this is where
1308 * we send the HDN_ITEMCHANGING and HDN_ITEMCHANGED notifications
1310 * if (!(dwStyle & HDS_FULLDRAG)) {
1314 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1315 ReleaseDC (hwnd, hdc);
1316 if (HEADER_SendItemChange(hwnd, infoPtr->iMoveItem,HDI_WIDTH,
1318 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1320 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
1323 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
1326 HEADER_SendItemChange(hwnd,infoPtr->iMoveItem,HDI_WIDTH,
1328 HEADER_SetItemBounds (hwnd);
1329 InvalidateRect(hwnd, NULL, FALSE);
1335 if (infoPtr->bCaptured) {
1336 infoPtr->bCaptured = FALSE;
1338 HEADER_SendSimpleNotify (hwnd, NM_RELEASEDCAPTURE);
1346 HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1348 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1349 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1355 pt.x = (INT)SLOWORD(lParam);
1356 pt.y = (INT)SHIWORD(lParam);
1357 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1359 if ((dwStyle & HDS_BUTTONS) && (dwStyle & HDS_HOTTRACK)) {
1360 if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
1361 infoPtr->iHotItem = nItem;
1363 infoPtr->iHotItem = -1;
1364 InvalidateRect(hwnd, NULL, FALSE);
1367 if (infoPtr->bCaptured) {
1368 if (infoPtr->bPressed) {
1369 if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
1370 infoPtr->items[infoPtr->iMoveItem].bDown = TRUE;
1372 infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
1374 HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
1375 ReleaseDC (hwnd, hdc);
1377 TRACE("Moving pressed item %d!\n", infoPtr->iMoveItem);
1379 else if (infoPtr->bTracking) {
1380 if (dwStyle & HDS_FULLDRAG) {
1382 * Investigation shows that the changing message occure only
1383 * after tracking is done
1385 *if (HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGINGA, infoPtr->iMoveItem))
1386 * infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1390 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
1393 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
1395 * Invistigation shows that the item changed only occures
1396 * after the tracking is done
1398 * HEADER_SendItemChanged(FALSE,hwnd,infoPtr->iMoveItem,HDI_WIDTH);
1402 HEADER_SetItemBounds (hwnd);
1403 InvalidateRect(hwnd, NULL, FALSE);
1407 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1408 infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset;
1409 if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left)
1410 infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left;
1411 infoPtr->items[infoPtr->iMoveItem].cxy =
1412 infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left;
1413 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1414 ReleaseDC (hwnd, hdc);
1417 HEADER_SendHeaderNotify (hwnd, HDN_TRACKA, infoPtr->iMoveItem);
1418 TRACE("Tracking item %d!\n", infoPtr->iMoveItem);
1422 if ((dwStyle & HDS_BUTTONS) && (dwStyle & HDS_HOTTRACK)) {
1423 FIXME("hot track support!\n");
1431 HEADER_Paint (HWND hwnd, WPARAM wParam)
1436 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1437 HEADER_Refresh (hwnd, hdc);
1439 EndPaint (hwnd, &ps);
1445 HEADER_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1450 pt.x = LOWORD(lParam);
1451 pt.y = HIWORD(lParam);
1453 /* Send a Notify message */
1454 bRet = HEADER_SendSimpleNotify (hwnd, NM_RCLICK);
1456 /* Change to screen coordinate for WM_CONTEXTMENU */
1457 ClientToScreen(hwnd, &pt);
1459 /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
1460 SendMessageA( hwnd, WM_CONTEXTMENU, (WPARAM) hwnd, MAKELPARAM(pt.x, pt.y));
1467 HEADER_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1469 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1474 TRACE("code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
1477 ScreenToClient (hwnd, &pt);
1479 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1481 if (flags == HHT_ONDIVIDER)
1482 SetCursor (infoPtr->hcurDivider);
1483 else if (flags == HHT_ONDIVOPEN)
1484 SetCursor (infoPtr->hcurDivopen);
1486 SetCursor (infoPtr->hcurArrow);
1493 HEADER_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1495 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1497 HFONT hFont, hOldFont;
1500 infoPtr->hFont = (HFONT)wParam;
1502 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
1505 hOldFont = SelectObject (hdc, hFont);
1506 GetTextMetricsA (hdc, &tm);
1507 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1508 SelectObject (hdc, hOldFont);
1511 infoPtr->bRectsValid = FALSE;
1514 InvalidateRect(hwnd, NULL, FALSE);
1521 static LRESULT WINAPI
1522 HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1524 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, msg, wParam, lParam);
1525 if (!HEADER_GetInfoPtr (hwnd) && (msg != WM_CREATE))
1526 return DefWindowProcA (hwnd, msg, wParam, lParam);
1528 case HDM_CREATEDRAGIMAGE:
1529 return HEADER_CreateDragImage (hwnd, wParam);
1531 case HDM_DELETEITEM:
1532 return HEADER_DeleteItem (hwnd, wParam);
1534 case HDM_GETIMAGELIST:
1535 return HEADER_GetImageList (hwnd);
1538 return HEADER_GetItemA (hwnd, wParam, lParam);
1541 return HEADER_GetItemW (hwnd, wParam, lParam);
1543 case HDM_GETITEMCOUNT:
1544 return HEADER_GetItemCount (hwnd);
1546 case HDM_GETITEMRECT:
1547 return HEADER_GetItemRect (hwnd, wParam, lParam);
1549 /* case HDM_GETORDERARRAY: */
1551 case HDM_GETUNICODEFORMAT:
1552 return HEADER_GetUnicodeFormat (hwnd);
1555 return HEADER_HitTest (hwnd, wParam, lParam);
1557 case HDM_INSERTITEMA:
1558 return HEADER_InsertItemA (hwnd, wParam, lParam);
1560 case HDM_INSERTITEMW:
1561 return HEADER_InsertItemW (hwnd, wParam, lParam);
1564 return HEADER_Layout (hwnd, wParam, lParam);
1566 case HDM_SETIMAGELIST:
1567 return HEADER_SetImageList (hwnd, wParam, lParam);
1570 return HEADER_SetItemA (hwnd, wParam, lParam);
1573 return HEADER_SetItemW (hwnd, wParam, lParam);
1575 /* case HDM_SETORDERARRAY: */
1577 case HDM_SETUNICODEFORMAT:
1578 return HEADER_SetUnicodeFormat (hwnd, wParam);
1581 return HEADER_Create (hwnd, wParam, lParam);
1584 return HEADER_Destroy (hwnd, wParam, lParam);
1590 return DLGC_WANTTAB | DLGC_WANTARROWS;
1593 return HEADER_GetFont (hwnd);
1595 case WM_LBUTTONDBLCLK:
1596 return HEADER_LButtonDblClk (hwnd, wParam, lParam);
1598 case WM_LBUTTONDOWN:
1599 return HEADER_LButtonDown (hwnd, wParam, lParam);
1602 return HEADER_LButtonUp (hwnd, wParam, lParam);
1605 return HEADER_MouseMove (hwnd, wParam, lParam);
1607 /* case WM_NOTIFYFORMAT: */
1610 return HEADER_Size (hwnd, wParam);
1613 return HEADER_Paint (hwnd, wParam);
1616 return HEADER_RButtonUp (hwnd, wParam, lParam);
1619 return HEADER_SetCursor (hwnd, wParam, lParam);
1622 return HEADER_SetFont (hwnd, wParam, lParam);
1626 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1627 msg, wParam, lParam );
1628 return DefWindowProcA (hwnd, msg, wParam, lParam);
1635 HEADER_Register (void)
1639 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1640 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
1641 wndClass.lpfnWndProc = (WNDPROC)HEADER_WindowProc;
1642 wndClass.cbClsExtra = 0;
1643 wndClass.cbWndExtra = sizeof(HEADER_INFO *);
1644 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1645 wndClass.lpszClassName = WC_HEADERA;
1647 RegisterClassA (&wndClass);
1652 HEADER_Unregister (void)
1654 UnregisterClassA (WC_HEADERA, (HINSTANCE)NULL);