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.
29 DEFAULT_DEBUG_CHANNEL(header
)
32 #define __HDM_LAYOUT_HACK__
36 #define DIVIDER_WIDTH 10
38 #define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
42 HEADER_DrawItem (HWND hwnd
, HDC hdc
, INT iItem
, BOOL bHotTrack
)
44 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
45 HEADER_ITEM
*phdi
= &infoPtr
->items
[iItem
];
50 if (r
.right
- r
.left
== 0)
51 return phdi
->rect
.right
;
53 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) {
55 DrawEdge (hdc
, &r
, BDR_RAISEDOUTER
,
56 BF_RECT
| BF_FLAT
| BF_MIDDLE
| BF_ADJUST
);
61 DrawEdge (hdc
, &r
, EDGE_RAISED
,
62 BF_RECT
| BF_SOFT
| BF_MIDDLE
| BF_ADJUST
);
65 DrawEdge (hdc
, &r
, EDGE_ETCHED
, BF_BOTTOM
| BF_RIGHT
| BF_ADJUST
);
67 if (phdi
->fmt
& HDF_OWNERDRAW
) {
69 dis
.CtlType
= ODT_HEADER
;
70 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
72 dis
.itemAction
= ODA_DRAWENTIRE
;
73 dis
.itemState
= phdi
->bDown
? ODS_SELECTED
: 0;
77 dis
.itemData
= phdi
->lParam
;
78 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
79 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
82 UINT uTextJustify
= DT_LEFT
;
84 if ((phdi
->fmt
& HDF_JUSTIFYMASK
) == HDF_CENTER
)
85 uTextJustify
= DT_CENTER
;
86 else if ((phdi
->fmt
& HDF_JUSTIFYMASK
) == HDF_RIGHT
)
87 uTextJustify
= DT_RIGHT
;
89 if ((phdi
->fmt
& HDF_BITMAP
) && (phdi
->hbm
)) {
92 INT yD
, yS
, cx
, cy
, rx
, ry
;
94 GetObjectA (phdi
->hbm
, sizeof(BITMAP
), (LPVOID
)&bmp
);
96 ry
= r
.bottom
- r
.top
;
97 rx
= r
.right
- r
.left
;
99 if (ry
>= bmp
.bmHeight
) {
101 yD
= r
.top
+ (ry
- bmp
.bmHeight
) / 2;
107 yS
= (bmp
.bmHeight
- ry
) / 2;
111 if (rx
>= bmp
.bmWidth
+ 6) {
118 hdcBitmap
= CreateCompatibleDC (hdc
);
119 SelectObject (hdcBitmap
, phdi
->hbm
);
120 BitBlt (hdc
, r
.left
+ 3, yD
, cx
, cy
, hdcBitmap
, 0, yS
, SRCCOPY
);
121 DeleteDC (hdcBitmap
);
123 r
.left
+= (bmp
.bmWidth
+ 3);
127 if ((phdi
->fmt
& HDF_BITMAP_ON_RIGHT
) && (phdi
->hbm
)) {
130 INT xD
, yD
, yS
, cx
, cy
, rx
, ry
, tx
;
133 GetObjectA (phdi
->hbm
, sizeof(BITMAP
), (LPVOID
)&bmp
);
136 DrawTextW (hdc
, phdi
->pszText
, lstrlenW (phdi
->pszText
),
137 &textRect
, DT_LEFT
|DT_VCENTER
|DT_SINGLELINE
|DT_CALCRECT
);
138 tx
= textRect
.right
- textRect
.left
;
139 ry
= r
.bottom
- r
.top
;
140 rx
= r
.right
- r
.left
;
142 if (ry
>= bmp
.bmHeight
) {
144 yD
= r
.top
+ (ry
- bmp
.bmHeight
) / 2;
150 yS
= (bmp
.bmHeight
- ry
) / 2;
154 if (r
.left
+ tx
+ bmp
.bmWidth
+ 9 <= r
.right
) {
156 xD
= r
.left
+ tx
+ 6;
159 if (rx
>= bmp
.bmWidth
+ 6) {
161 xD
= r
.right
- bmp
.bmWidth
- 3;
171 hdcBitmap
= CreateCompatibleDC (hdc
);
172 SelectObject (hdcBitmap
, phdi
->hbm
);
173 BitBlt (hdc
, xD
, yD
, cx
, cy
, hdcBitmap
, 0, yS
, SRCCOPY
);
174 DeleteDC (hdcBitmap
);
177 if (phdi
->fmt
& HDF_IMAGE
) {
180 /* ImageList_Draw (infoPtr->himl, phdi->iImage,...); */
183 if ((phdi
->fmt
& HDF_STRING
) && (phdi
->pszText
)) {
184 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
187 SetTextColor (hdc
, bHotTrack
? COLOR_HIGHLIGHT
: COLOR_BTNTEXT
);
188 DrawTextW (hdc
, phdi
->pszText
, lstrlenW (phdi
->pszText
),
189 &r
, uTextJustify
|DT_VCENTER
|DT_SINGLELINE
);
190 if (oldBkMode
!= TRANSPARENT
)
191 SetBkMode(hdc
, oldBkMode
);
195 return phdi
->rect
.right
;
200 HEADER_Refresh (HWND hwnd
, HDC hdc
)
202 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
203 HFONT hFont
, hOldFont
;
208 /* get rect for the bar, adjusted for the border */
209 GetClientRect (hwnd
, &rect
);
211 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
212 hOldFont
= SelectObject (hdc
, hFont
);
214 /* draw Background */
215 hbrBk
= GetSysColorBrush(COLOR_3DFACE
);
216 FillRect(hdc
, &rect
, hbrBk
);
219 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
220 x
= HEADER_DrawItem (hwnd
, hdc
, i
, FALSE
);
223 if ((x
<= rect
.right
) && (infoPtr
->uNumItem
> 0)) {
225 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
)
226 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_TOP
|BF_LEFT
|BF_BOTTOM
|BF_SOFT
);
228 DrawEdge (hdc
, &rect
, EDGE_ETCHED
, BF_BOTTOM
);
231 SelectObject (hdc
, hOldFont
);
236 HEADER_RefreshItem (HWND hwnd
, HDC hdc
, INT iItem
)
238 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
239 HFONT hFont
, hOldFont
;
241 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
242 hOldFont
= SelectObject (hdc
, hFont
);
243 HEADER_DrawItem (hwnd
, hdc
, iItem
, FALSE
);
244 SelectObject (hdc
, hOldFont
);
249 HEADER_SetItemBounds (HWND hwnd
)
251 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
256 if (infoPtr
->uNumItem
== 0)
259 GetClientRect (hwnd
, &rect
);
262 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
263 phdi
= &infoPtr
->items
[i
];
264 phdi
->rect
.top
= rect
.top
;
265 phdi
->rect
.bottom
= rect
.bottom
;
267 phdi
->rect
.right
= phdi
->rect
.left
+ phdi
->cxy
;
268 x
= phdi
->rect
.right
;
274 HEADER_ForceItemBounds (HWND hwnd
, INT cy
)
276 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
280 if (infoPtr
->uNumItem
== 0)
284 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
285 phdi
= &infoPtr
->items
[i
];
287 phdi
->rect
.bottom
= cy
;
289 phdi
->rect
.right
= phdi
->rect
.left
+ phdi
->cxy
;
290 x
= phdi
->rect
.right
;
296 HEADER_InternalHitTest (HWND hwnd
, LPPOINT lpPt
, UINT
*pFlags
, INT
*pItem
)
298 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
303 GetClientRect (hwnd
, &rect
);
307 if (PtInRect (&rect
, *lpPt
))
309 if (infoPtr
->uNumItem
== 0) {
310 *pFlags
|= HHT_NOWHERE
;
312 TRACE (header
, "NOWHERE\n");
316 /* somewhere inside */
317 for (iCount
= 0; iCount
< infoPtr
->uNumItem
; iCount
++) {
318 rect
= infoPtr
->items
[iCount
].rect
;
319 width
= rect
.right
- rect
.left
;
324 if (PtInRect (&rect
, *lpPt
)) {
325 if (width
<= 2 * DIVIDER_WIDTH
) {
326 *pFlags
|= HHT_ONHEADER
;
328 TRACE (header
, "ON HEADER %d\n", iCount
);
333 rcTest
.right
= rcTest
.left
+ DIVIDER_WIDTH
;
334 if (PtInRect (&rcTest
, *lpPt
)) {
336 *pFlags
|= HHT_ONDIVOPEN
;
338 TRACE (header
, "ON DIVOPEN %d\n", *pItem
);
342 *pFlags
|= HHT_ONDIVIDER
;
344 TRACE (header
, "ON DIVIDER %d\n", *pItem
);
350 rcTest
.left
= rcTest
.right
- DIVIDER_WIDTH
;
351 if (PtInRect (&rcTest
, *lpPt
)) {
352 *pFlags
|= HHT_ONDIVIDER
;
354 TRACE (header
, "ON DIVIDER %d\n", *pItem
);
358 *pFlags
|= HHT_ONHEADER
;
360 TRACE (header
, "ON HEADER %d\n", iCount
);
365 /* check for last divider part (on nowhere) */
366 rect
= infoPtr
->items
[infoPtr
->uNumItem
-1].rect
;
367 rect
.left
= rect
.right
;
368 rect
.right
+= DIVIDER_WIDTH
;
369 if (PtInRect (&rect
, *lpPt
)) {
371 *pFlags
|= HHT_ONDIVOPEN
;
372 *pItem
= infoPtr
->uNumItem
- 1;
373 TRACE (header
, "ON DIVOPEN %d\n", *pItem
);
377 *pFlags
|= HHT_ONDIVIDER
;
378 *pItem
= infoPtr
->uNumItem
-1;
379 TRACE (header
, "ON DIVIDER %d\n", *pItem
);
384 *pFlags
|= HHT_NOWHERE
;
386 TRACE (header
, "NOWHERE\n");
391 if (lpPt
->x
< rect
.left
) {
392 TRACE (header
, "TO LEFT\n");
393 *pFlags
|= HHT_TOLEFT
;
395 else if (lpPt
->x
> rect
.right
) {
396 TRACE (header
, "TO LEFT\n");
397 *pFlags
|= HHT_TORIGHT
;
400 if (lpPt
->y
< rect
.top
) {
401 TRACE (header
, "ABOVE\n");
402 *pFlags
|= HHT_ABOVE
;
404 else if (lpPt
->y
> rect
.bottom
) {
405 TRACE (header
, "BELOW\n");
406 *pFlags
|= HHT_BELOW
;
411 TRACE (header
, "flags=0x%X\n", *pFlags
);
417 HEADER_DrawTrackLine (HWND hwnd
, HDC hdc
, INT x
)
423 GetClientRect (hwnd
, &rect
);
425 hOldPen
= SelectObject (hdc
, GetStockObject (BLACK_PEN
));
426 oldRop
= SetROP2 (hdc
, R2_XORPEN
);
427 MoveToEx (hdc
, x
, rect
.top
, NULL
);
428 LineTo (hdc
, x
, rect
.bottom
);
429 SetROP2 (hdc
, oldRop
);
430 SelectObject (hdc
, hOldPen
);
435 HEADER_SendSimpleNotify (HWND hwnd
, UINT code
)
439 nmhdr
.hwndFrom
= hwnd
;
440 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
443 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
444 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
449 HEADER_SendHeaderNotify (HWND hwnd
, UINT code
, INT iItem
)
451 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
455 nmhdr
.hdr
.hwndFrom
= hwnd
;
456 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
457 nmhdr
.hdr
.code
= code
;
460 nmhdr
.pitem
= &nmitem
;
462 nmitem
.cxy
= infoPtr
->items
[iItem
].cxy
;
463 nmitem
.hbm
= infoPtr
->items
[iItem
].hbm
;
464 nmitem
.pszText
= NULL
;
465 nmitem
.cchTextMax
= 0;
466 /* nmitem.pszText = infoPtr->items[iItem].pszText; */
467 /* nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
468 nmitem
.fmt
= infoPtr
->items
[iItem
].fmt
;
469 nmitem
.lParam
= infoPtr
->items
[iItem
].lParam
;
470 nmitem
.iOrder
= infoPtr
->items
[iItem
].iOrder
;
471 nmitem
.iImage
= infoPtr
->items
[iItem
].iImage
;
473 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
474 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
479 HEADER_SendClickNotify (HWND hwnd
, UINT code
, INT iItem
)
483 nmhdr
.hdr
.hwndFrom
= hwnd
;
484 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
485 nmhdr
.hdr
.code
= code
;
490 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
491 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
496 HEADER_CreateDragImage (HWND hwnd
, WPARAM wParam
)
498 FIXME (header
, "empty stub!\n");
504 HEADER_DeleteItem (HWND hwnd
, WPARAM wParam
)
506 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr(hwnd
);
507 INT iItem
= (INT
)wParam
;
510 TRACE(header
, "[iItem=%d]\n", iItem
);
512 if ((iItem
< 0) || (iItem
>= (INT
)infoPtr
->uNumItem
))
515 if (infoPtr
->uNumItem
== 1) {
516 TRACE(header
, "Simple delete!\n");
517 if (infoPtr
->items
[0].pszText
)
518 COMCTL32_Free (infoPtr
->items
[0].pszText
);
519 COMCTL32_Free (infoPtr
->items
);
521 infoPtr
->uNumItem
= 0;
524 HEADER_ITEM
*oldItems
= infoPtr
->items
;
525 TRACE(header
, "Complex delete! [iItem=%d]\n", iItem
);
527 if (infoPtr
->items
[iItem
].pszText
)
528 COMCTL32_Free (infoPtr
->items
[iItem
].pszText
);
531 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
532 /* pre delete copy */
534 memcpy (&infoPtr
->items
[0], &oldItems
[0],
535 iItem
* sizeof(HEADER_ITEM
));
538 /* post delete copy */
539 if (iItem
< infoPtr
->uNumItem
) {
540 memcpy (&infoPtr
->items
[iItem
], &oldItems
[iItem
+1],
541 (infoPtr
->uNumItem
- iItem
) * sizeof(HEADER_ITEM
));
544 COMCTL32_Free (oldItems
);
547 HEADER_SetItemBounds (hwnd
);
550 HEADER_Refresh (hwnd
, hdc
);
551 ReleaseDC (hwnd
, hdc
);
558 HEADER_GetImageList (HWND hwnd
)
560 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
562 return (LRESULT
)infoPtr
->himl
;
567 HEADER_GetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
569 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
570 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
571 INT nItem
= (INT
)wParam
;
576 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
579 TRACE (header
, "[nItem=%d]\n", nItem
);
584 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
585 if (phdi
->mask
& HDI_BITMAP
)
586 phdi
->hbm
= lpItem
->hbm
;
588 if (phdi
->mask
& HDI_FORMAT
)
589 phdi
->fmt
= lpItem
->fmt
;
591 if (phdi
->mask
& HDI_WIDTH
)
592 phdi
->cxy
= lpItem
->cxy
;
594 if (phdi
->mask
& HDI_LPARAM
)
595 phdi
->lParam
= lpItem
->lParam
;
597 if (phdi
->mask
& HDI_TEXT
) {
598 if (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
)
599 lstrcpynWtoA (phdi
->pszText
, lpItem
->pszText
, phdi
->cchTextMax
);
601 phdi
->pszText
= LPSTR_TEXTCALLBACKA
;
604 if (phdi
->mask
& HDI_IMAGE
)
605 phdi
->iImage
= lpItem
->iImage
;
607 if (phdi
->mask
& HDI_ORDER
)
608 phdi
->iOrder
= lpItem
->iOrder
;
615 HEADER_GetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
617 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
618 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
619 INT nItem
= (INT
)wParam
;
624 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
627 TRACE (header
, "[nItem=%d]\n", nItem
);
632 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
633 if (phdi
->mask
& HDI_BITMAP
)
634 phdi
->hbm
= lpItem
->hbm
;
636 if (phdi
->mask
& HDI_FORMAT
)
637 phdi
->fmt
= lpItem
->fmt
;
639 if (phdi
->mask
& HDI_WIDTH
)
640 phdi
->cxy
= lpItem
->cxy
;
642 if (phdi
->mask
& HDI_LPARAM
)
643 phdi
->lParam
= lpItem
->lParam
;
645 if (phdi
->mask
& HDI_TEXT
) {
646 if (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
)
647 lstrcpynW (phdi
->pszText
, lpItem
->pszText
, phdi
->cchTextMax
);
649 phdi
->pszText
= LPSTR_TEXTCALLBACKW
;
652 if (phdi
->mask
& HDI_IMAGE
)
653 phdi
->iImage
= lpItem
->iImage
;
655 if (phdi
->mask
& HDI_ORDER
)
656 phdi
->iOrder
= lpItem
->iOrder
;
662 __inline__
static LRESULT
663 HEADER_GetItemCount (HWND hwnd
)
665 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
666 return infoPtr
->uNumItem
;
671 HEADER_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
673 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
674 INT iItem
= (INT
)wParam
;
675 LPRECT lpRect
= (LPRECT
)lParam
;
677 if ((iItem
< 0) || (iItem
>= (INT
)infoPtr
->uNumItem
))
680 lpRect
->left
= infoPtr
->items
[iItem
].rect
.left
;
681 lpRect
->right
= infoPtr
->items
[iItem
].rect
.right
;
682 lpRect
->top
= infoPtr
->items
[iItem
].rect
.top
;
683 lpRect
->bottom
= infoPtr
->items
[iItem
].rect
.bottom
;
689 /* << HEADER_GetOrderArray >> */
692 __inline__
static LRESULT
693 HEADER_GetUnicodeFormat (HWND hwnd
)
695 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
696 return infoPtr
->bUnicode
;
701 HEADER_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
703 LPHDHITTESTINFO phti
= (LPHDHITTESTINFO
)lParam
;
705 HEADER_InternalHitTest (hwnd
, &phti
->pt
, &phti
->flags
, &phti
->iItem
);
712 HEADER_InsertItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
714 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
715 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
716 INT nItem
= (INT
)wParam
;
721 if ((phdi
== NULL
) || (nItem
< 0))
724 if (nItem
> infoPtr
->uNumItem
)
725 nItem
= infoPtr
->uNumItem
;
727 if (infoPtr
->uNumItem
== 0) {
728 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
732 HEADER_ITEM
*oldItems
= infoPtr
->items
;
735 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
737 memcpy (&infoPtr
->items
[1], &oldItems
[0],
738 (infoPtr
->uNumItem
-1) * sizeof(HEADER_ITEM
));
742 /* pre insert copy */
744 memcpy (&infoPtr
->items
[0], &oldItems
[0],
745 nItem
* sizeof(HEADER_ITEM
));
748 /* post insert copy */
749 if (nItem
< infoPtr
->uNumItem
- 1) {
750 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
751 (infoPtr
->uNumItem
- nItem
) * sizeof(HEADER_ITEM
));
755 COMCTL32_Free (oldItems
);
758 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
759 lpItem
->bDown
= FALSE
;
761 if (phdi
->mask
& HDI_WIDTH
)
762 lpItem
->cxy
= phdi
->cxy
;
764 if (phdi
->mask
& HDI_TEXT
) {
765 if (!phdi
->pszText
) /* null pointer check */
767 lpItem
->pszText
= COMCTL32_Alloc(sizeof(WCHAR
));
768 lstrcpyAtoW(lpItem
->pszText
, "");
770 else if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
771 len
= lstrlenA (phdi
->pszText
);
772 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
773 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
776 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
779 if (phdi
->mask
& HDI_FORMAT
)
780 lpItem
->fmt
= phdi
->fmt
;
782 if (lpItem
->fmt
== 0)
783 lpItem
->fmt
= HDF_LEFT
;
785 if (phdi
->mask
& HDI_BITMAP
)
786 lpItem
->hbm
= phdi
->hbm
;
788 if (phdi
->mask
& HDI_LPARAM
)
789 lpItem
->lParam
= phdi
->lParam
;
791 if (phdi
->mask
& HDI_IMAGE
)
792 lpItem
->iImage
= phdi
->iImage
;
794 if (phdi
->mask
& HDI_ORDER
)
795 lpItem
->iOrder
= phdi
->iOrder
;
797 HEADER_SetItemBounds (hwnd
);
800 HEADER_Refresh (hwnd
, hdc
);
801 ReleaseDC (hwnd
, hdc
);
808 HEADER_InsertItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
810 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
811 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
812 INT nItem
= (INT
)wParam
;
817 if ((phdi
== NULL
) || (nItem
< 0))
820 if (nItem
> infoPtr
->uNumItem
)
821 nItem
= infoPtr
->uNumItem
;
823 if (infoPtr
->uNumItem
== 0) {
824 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
828 HEADER_ITEM
*oldItems
= infoPtr
->items
;
831 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
832 /* pre insert copy */
834 memcpy (&infoPtr
->items
[0], &oldItems
[0],
835 nItem
* sizeof(HEADER_ITEM
));
838 /* post insert copy */
839 if (nItem
< infoPtr
->uNumItem
- 1) {
840 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
841 (infoPtr
->uNumItem
- nItem
) * sizeof(HEADER_ITEM
));
844 COMCTL32_Free (oldItems
);
847 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
848 lpItem
->bDown
= FALSE
;
850 if (phdi
->mask
& HDI_WIDTH
)
851 lpItem
->cxy
= phdi
->cxy
;
853 if (phdi
->mask
& HDI_TEXT
) {
854 if (!phdi
->pszText
) /* null pointer check */
856 lpItem
->pszText
= COMCTL32_Alloc(sizeof(WCHAR
));
857 lstrcpyAtoW(lpItem
->pszText
, "");
859 else if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
860 len
= lstrlenW (phdi
->pszText
);
861 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
862 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
865 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
868 if (phdi
->mask
& HDI_FORMAT
)
869 lpItem
->fmt
= phdi
->fmt
;
871 if (lpItem
->fmt
== 0)
872 lpItem
->fmt
= HDF_LEFT
;
874 if (phdi
->mask
& HDI_BITMAP
)
875 lpItem
->hbm
= phdi
->hbm
;
877 if (phdi
->mask
& HDI_LPARAM
)
878 lpItem
->lParam
= phdi
->lParam
;
880 if (phdi
->mask
& HDI_IMAGE
)
881 lpItem
->iImage
= phdi
->iImage
;
883 if (phdi
->mask
& HDI_ORDER
)
884 lpItem
->iOrder
= phdi
->iOrder
;
886 HEADER_SetItemBounds (hwnd
);
889 HEADER_Refresh (hwnd
, hdc
);
890 ReleaseDC (hwnd
, hdc
);
897 HEADER_Layout (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
899 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
900 LPHDLAYOUT lpLayout
= (LPHDLAYOUT
)lParam
;
902 lpLayout
->pwpos
->hwnd
= hwnd
;
903 lpLayout
->pwpos
->hwndInsertAfter
= 0;
904 lpLayout
->pwpos
->x
= lpLayout
->prc
->left
;
905 lpLayout
->pwpos
->y
= lpLayout
->prc
->top
;
906 lpLayout
->pwpos
->cx
= lpLayout
->prc
->right
- lpLayout
->prc
->left
;
907 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_HIDDEN
)
908 lpLayout
->pwpos
->cy
= 0;
910 lpLayout
->pwpos
->cy
= infoPtr
->nHeight
;
911 lpLayout
->pwpos
->flags
= SWP_NOZORDER
;
913 TRACE (header
, "Layout x=%d y=%d cx=%d cy=%d\n",
914 lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
915 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
);
917 HEADER_ForceItemBounds (hwnd
, lpLayout
->pwpos
->cy
);
920 #ifdef __HDM_LAYOUT_HACK__
921 MoveWindow (lpLayout
->pwpos
->hwnd
, lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
922 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
, TRUE
);
930 HEADER_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
932 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
935 himlOld
= infoPtr
->himl
;
936 infoPtr
->himl
= (HIMAGELIST
)lParam
;
938 /* FIXME: Refresh needed??? */
940 return (LRESULT
)himlOld
;
945 HEADER_SetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
947 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
948 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
949 INT nItem
= (INT
)wParam
;
955 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
958 TRACE (header
, "[nItem=%d]\n", nItem
);
960 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, nItem
))
963 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
964 if (phdi
->mask
& HDI_BITMAP
)
965 lpItem
->hbm
= phdi
->hbm
;
967 if (phdi
->mask
& HDI_FORMAT
)
968 lpItem
->fmt
= phdi
->fmt
;
970 if (phdi
->mask
& HDI_LPARAM
)
971 lpItem
->lParam
= phdi
->lParam
;
973 if (phdi
->mask
& HDI_TEXT
) {
974 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
975 if (lpItem
->pszText
) {
976 COMCTL32_Free (lpItem
->pszText
);
977 lpItem
->pszText
= NULL
;
980 INT len
= lstrlenA (phdi
->pszText
);
981 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
982 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
986 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
989 if (phdi
->mask
& HDI_WIDTH
)
990 lpItem
->cxy
= phdi
->cxy
;
992 if (phdi
->mask
& HDI_IMAGE
)
993 lpItem
->iImage
= phdi
->iImage
;
995 if (phdi
->mask
& HDI_ORDER
)
996 lpItem
->iOrder
= phdi
->iOrder
;
998 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, nItem
);
1000 HEADER_SetItemBounds (hwnd
);
1002 HEADER_Refresh (hwnd
, hdc
);
1003 ReleaseDC (hwnd
, hdc
);
1010 HEADER_SetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1012 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1013 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
1014 INT nItem
= (INT
)wParam
;
1015 HEADER_ITEM
*lpItem
;
1020 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
1023 TRACE (header
, "[nItem=%d]\n", nItem
);
1025 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, nItem
))
1028 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
1029 if (phdi
->mask
& HDI_BITMAP
)
1030 lpItem
->hbm
= phdi
->hbm
;
1032 if (phdi
->mask
& HDI_FORMAT
)
1033 lpItem
->fmt
= phdi
->fmt
;
1035 if (phdi
->mask
& HDI_LPARAM
)
1036 lpItem
->lParam
= phdi
->lParam
;
1038 if (phdi
->mask
& HDI_TEXT
) {
1039 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
1040 if (lpItem
->pszText
) {
1041 COMCTL32_Free (lpItem
->pszText
);
1042 lpItem
->pszText
= NULL
;
1044 if (phdi
->pszText
) {
1045 INT len
= lstrlenW (phdi
->pszText
);
1046 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1047 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
1051 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
1054 if (phdi
->mask
& HDI_WIDTH
)
1055 lpItem
->cxy
= phdi
->cxy
;
1057 if (phdi
->mask
& HDI_IMAGE
)
1058 lpItem
->iImage
= phdi
->iImage
;
1060 if (phdi
->mask
& HDI_ORDER
)
1061 lpItem
->iOrder
= phdi
->iOrder
;
1063 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, nItem
);
1065 HEADER_SetItemBounds (hwnd
);
1067 HEADER_Refresh (hwnd
, hdc
);
1068 ReleaseDC (hwnd
, hdc
);
1074 /* << HEADER_SetOrderArray >> */
1077 __inline__
static LRESULT
1078 HEADER_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
1080 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1081 BOOL bTemp
= infoPtr
->bUnicode
;
1083 infoPtr
->bUnicode
= (BOOL
)wParam
;
1090 HEADER_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1092 HEADER_INFO
*infoPtr
;
1097 infoPtr
= (HEADER_INFO
*)COMCTL32_Alloc (sizeof(HEADER_INFO
));
1098 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
1100 infoPtr
->uNumItem
= 0;
1101 infoPtr
->nHeight
= 20;
1104 infoPtr
->hcurArrow
= LoadCursorA (0, IDC_ARROWA
);
1105 infoPtr
->hcurDivider
= LoadCursorA (0, IDC_SIZEWEA
);
1106 infoPtr
->hcurDivopen
= LoadCursorA (0, IDC_SIZENSA
);
1107 infoPtr
->bPressed
= FALSE
;
1108 infoPtr
->bTracking
= FALSE
;
1109 infoPtr
->iMoveItem
= 0;
1111 infoPtr
->iHotItem
= -1;
1112 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
1115 hOldFont
= SelectObject (hdc
, GetStockObject (SYSTEM_FONT
));
1116 GetTextMetricsA (hdc
, &tm
);
1117 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1118 SelectObject (hdc
, hOldFont
);
1126 HEADER_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1128 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1129 HEADER_ITEM
*lpItem
;
1132 if (infoPtr
->items
) {
1133 lpItem
= (HEADER_ITEM
*)infoPtr
->items
;
1134 for (nItem
= 0; nItem
< infoPtr
->uNumItem
; nItem
++, lpItem
++) {
1135 if ((lpItem
->pszText
) && (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
))
1136 COMCTL32_Free (lpItem
->pszText
);
1138 COMCTL32_Free (infoPtr
->items
);
1142 ImageList_Destroy (infoPtr
->himl
);
1144 COMCTL32_Free (infoPtr
);
1150 static __inline__ LRESULT
1151 HEADER_GetFont (HWND hwnd
)
1153 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1155 return (LRESULT
)infoPtr
->hFont
;
1160 HEADER_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1166 pt
.x
= (INT
)LOWORD(lParam
);
1167 pt
.y
= (INT
)HIWORD(lParam
);
1168 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1170 if ((GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) && (flags
== HHT_ONHEADER
))
1171 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMDBLCLICKA
, nItem
);
1172 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
))
1173 HEADER_SendHeaderNotify (hwnd
, HDN_DIVIDERDBLCLICKA
, nItem
);
1180 HEADER_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1182 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1183 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1189 pt
.x
= (INT
)LOWORD(lParam
);
1190 pt
.y
= (INT
)HIWORD(lParam
);
1191 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1193 if ((dwStyle
& HDS_BUTTONS
) && (flags
== HHT_ONHEADER
)) {
1195 infoPtr
->bCaptured
= TRUE
;
1196 infoPtr
->bPressed
= TRUE
;
1197 infoPtr
->iMoveItem
= nItem
;
1199 infoPtr
->items
[nItem
].bDown
= TRUE
;
1201 /* Send WM_CUSTOMDRAW */
1203 HEADER_RefreshItem (hwnd
, hdc
, nItem
);
1204 ReleaseDC (hwnd
, hdc
);
1206 TRACE (header
, "Pressed item %d!\n", nItem
);
1208 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
)) {
1209 if (!(HEADER_SendHeaderNotify (hwnd
, HDN_BEGINTRACKA
, nItem
))) {
1211 infoPtr
->bCaptured
= TRUE
;
1212 infoPtr
->bTracking
= TRUE
;
1213 infoPtr
->iMoveItem
= nItem
;
1214 infoPtr
->nOldWidth
= infoPtr
->items
[nItem
].cxy
;
1215 infoPtr
->xTrackOffset
= infoPtr
->items
[nItem
].rect
.right
- pt
.x
;
1217 if (!(dwStyle
& HDS_FULLDRAG
)) {
1218 infoPtr
->xOldTrack
= infoPtr
->items
[nItem
].rect
.right
;
1220 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1221 ReleaseDC (hwnd
, hdc
);
1224 TRACE (header
, "Begin tracking item %d!\n", nItem
);
1233 HEADER_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1235 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1236 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1242 pt
.x
= (INT
)LOWORD(lParam
);
1243 pt
.y
= (INT
)HIWORD(lParam
);
1244 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1246 if (infoPtr
->bPressed
) {
1247 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
)) {
1248 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1250 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1251 ReleaseDC (hwnd
, hdc
);
1253 HEADER_SendClickNotify (hwnd
, HDN_ITEMCLICKA
, infoPtr
->iMoveItem
);
1255 TRACE (header
, "Released item %d!\n", infoPtr
->iMoveItem
);
1256 infoPtr
->bPressed
= FALSE
;
1258 else if (infoPtr
->bTracking
) {
1259 TRACE (header
, "End tracking item %d!\n", infoPtr
->iMoveItem
);
1260 infoPtr
->bTracking
= FALSE
;
1262 HEADER_SendHeaderNotify (hwnd
, HDN_ENDTRACKA
, infoPtr
->iMoveItem
);
1264 if (!(dwStyle
& HDS_FULLDRAG
)) {
1266 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1267 ReleaseDC (hwnd
, hdc
);
1268 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, infoPtr
->iMoveItem
))
1269 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1271 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1274 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1275 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, infoPtr
->iMoveItem
);
1278 HEADER_SetItemBounds (hwnd
);
1280 HEADER_Refresh (hwnd
, hdc
);
1281 ReleaseDC (hwnd
, hdc
);
1285 if (infoPtr
->bCaptured
) {
1286 infoPtr
->bCaptured
= FALSE
;
1288 HEADER_SendSimpleNotify (hwnd
, NM_RELEASEDCAPTURE
);
1296 HEADER_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1298 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1299 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1305 pt
.x
= (INT
)LOWORD(lParam
);
1306 pt
.y
= (INT
)HIWORD(lParam
);
1307 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1309 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1310 if (flags
& (HHT_ONHEADER
| HHT_ONDIVIDER
| HHT_ONDIVOPEN
))
1311 infoPtr
->iHotItem
= nItem
;
1313 infoPtr
->iHotItem
= -1;
1315 HEADER_Refresh (hwnd
, hdc
);
1316 ReleaseDC (hwnd
, hdc
);
1319 if (infoPtr
->bCaptured
) {
1320 if (infoPtr
->bPressed
) {
1321 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
))
1322 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= TRUE
;
1324 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1326 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1327 ReleaseDC (hwnd
, hdc
);
1329 TRACE (header
, "Moving pressed item %d!\n", infoPtr
->iMoveItem
);
1331 else if (infoPtr
->bTracking
) {
1332 if (dwStyle
& HDS_FULLDRAG
) {
1333 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, infoPtr
->iMoveItem
))
1334 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1336 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1339 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1340 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
,
1341 infoPtr
->iMoveItem
);
1343 HEADER_SetItemBounds (hwnd
);
1345 HEADER_Refresh (hwnd
, hdc
);
1346 ReleaseDC (hwnd
, hdc
);
1350 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1351 infoPtr
->xOldTrack
= pt
.x
+ infoPtr
->xTrackOffset
;
1352 if (infoPtr
->xOldTrack
< infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
)
1353 infoPtr
->xOldTrack
= infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1354 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
=
1355 infoPtr
->xOldTrack
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1356 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1357 ReleaseDC (hwnd
, hdc
);
1360 HEADER_SendHeaderNotify (hwnd
, HDN_TRACKA
, infoPtr
->iMoveItem
);
1361 TRACE (header
, "Tracking item %d!\n", infoPtr
->iMoveItem
);
1365 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1366 FIXME (header
, "hot track support!\n");
1374 HEADER_Paint (HWND hwnd
, WPARAM wParam
)
1379 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1380 HEADER_Refresh (hwnd
, hdc
);
1382 EndPaint (hwnd
, &ps
);
1388 HEADER_RButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1390 return HEADER_SendSimpleNotify (hwnd
, NM_RCLICK
);
1395 HEADER_SetCursor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1397 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1402 TRACE (header
, "code=0x%X id=0x%X\n", LOWORD(lParam
), HIWORD(lParam
));
1405 ScreenToClient (hwnd
, &pt
);
1407 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1409 if (flags
== HHT_ONDIVIDER
)
1410 SetCursor (infoPtr
->hcurDivider
);
1411 else if (flags
== HHT_ONDIVOPEN
)
1412 SetCursor (infoPtr
->hcurDivopen
);
1414 SetCursor (infoPtr
->hcurArrow
);
1421 HEADER_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1423 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1425 HFONT hFont
, hOldFont
;
1428 infoPtr
->hFont
= (HFONT
)wParam
;
1430 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
1433 hOldFont
= SelectObject (hdc
, hFont
);
1434 GetTextMetricsA (hdc
, &tm
);
1435 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1436 SelectObject (hdc
, hOldFont
);
1440 HEADER_ForceItemBounds (hwnd
, infoPtr
->nHeight
);
1442 HEADER_Refresh (hwnd
, hdc
);
1443 ReleaseDC (hwnd
, hdc
);
1451 HEADER_WindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1454 case HDM_CREATEDRAGIMAGE
:
1455 return HEADER_CreateDragImage (hwnd
, wParam
);
1457 case HDM_DELETEITEM
:
1458 return HEADER_DeleteItem (hwnd
, wParam
);
1460 case HDM_GETIMAGELIST
:
1461 return HEADER_GetImageList (hwnd
);
1464 return HEADER_GetItemA (hwnd
, wParam
, lParam
);
1467 return HEADER_GetItemW (hwnd
, wParam
, lParam
);
1469 case HDM_GETITEMCOUNT
:
1470 return HEADER_GetItemCount (hwnd
);
1472 case HDM_GETITEMRECT
:
1473 return HEADER_GetItemRect (hwnd
, wParam
, lParam
);
1475 /* case HDM_GETORDERARRAY: */
1477 case HDM_GETUNICODEFORMAT
:
1478 return HEADER_GetUnicodeFormat (hwnd
);
1481 return HEADER_HitTest (hwnd
, wParam
, lParam
);
1483 case HDM_INSERTITEMA
:
1484 return HEADER_InsertItemA (hwnd
, wParam
, lParam
);
1486 case HDM_INSERTITEMW
:
1487 return HEADER_InsertItemW (hwnd
, wParam
, lParam
);
1490 return HEADER_Layout (hwnd
, wParam
, lParam
);
1492 case HDM_SETIMAGELIST
:
1493 return HEADER_SetImageList (hwnd
, wParam
, lParam
);
1496 return HEADER_SetItemA (hwnd
, wParam
, lParam
);
1499 return HEADER_SetItemW (hwnd
, wParam
, lParam
);
1501 /* case HDM_SETORDERARRAY: */
1503 case HDM_SETUNICODEFORMAT
:
1504 return HEADER_SetUnicodeFormat (hwnd
, wParam
);
1508 return HEADER_Create (hwnd
, wParam
, lParam
);
1511 return HEADER_Destroy (hwnd
, wParam
, lParam
);
1517 return DLGC_WANTTAB
| DLGC_WANTARROWS
;
1520 return HEADER_GetFont (hwnd
);
1522 case WM_LBUTTONDBLCLK
:
1523 return HEADER_LButtonDblClk (hwnd
, wParam
, lParam
);
1525 case WM_LBUTTONDOWN
:
1526 return HEADER_LButtonDown (hwnd
, wParam
, lParam
);
1529 return HEADER_LButtonUp (hwnd
, wParam
, lParam
);
1532 return HEADER_MouseMove (hwnd
, wParam
, lParam
);
1534 /* case WM_NOTIFYFORMAT: */
1537 return HEADER_Paint (hwnd
, wParam
);
1540 return HEADER_RButtonUp (hwnd
, wParam
, lParam
);
1543 return HEADER_SetCursor (hwnd
, wParam
, lParam
);
1546 return HEADER_SetFont (hwnd
, wParam
, lParam
);
1550 ERR (header
, "unknown msg %04x wp=%04x lp=%08lx\n",
1551 msg
, wParam
, lParam
);
1552 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1559 HEADER_Register (VOID
)
1563 if (GlobalFindAtomA (WC_HEADERA
)) return;
1565 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1566 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
1567 wndClass
.lpfnWndProc
= (WNDPROC
)HEADER_WindowProc
;
1568 wndClass
.cbClsExtra
= 0;
1569 wndClass
.cbWndExtra
= sizeof(HEADER_INFO
*);
1570 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1571 wndClass
.lpszClassName
= WC_HEADERA
;
1573 RegisterClassA (&wndClass
);
1578 HEADER_Unregister (VOID
)
1580 if (GlobalFindAtomA (WC_HEADERA
))
1581 UnregisterClassA (WC_HEADERA
, (HINSTANCE
)NULL
);