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 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
768 len
= lstrlenA (phdi
->pszText
);
769 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
770 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
773 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
776 if (phdi
->mask
& HDI_FORMAT
)
777 lpItem
->fmt
= phdi
->fmt
;
779 if (lpItem
->fmt
== 0)
780 lpItem
->fmt
= HDF_LEFT
;
782 if (phdi
->mask
& HDI_BITMAP
)
783 lpItem
->hbm
= phdi
->hbm
;
785 if (phdi
->mask
& HDI_LPARAM
)
786 lpItem
->lParam
= phdi
->lParam
;
788 if (phdi
->mask
& HDI_IMAGE
)
789 lpItem
->iImage
= phdi
->iImage
;
791 if (phdi
->mask
& HDI_ORDER
)
792 lpItem
->iOrder
= phdi
->iOrder
;
794 HEADER_SetItemBounds (hwnd
);
797 HEADER_Refresh (hwnd
, hdc
);
798 ReleaseDC (hwnd
, hdc
);
805 HEADER_InsertItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
807 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
808 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
809 INT nItem
= (INT
)wParam
;
814 if ((phdi
== NULL
) || (nItem
< 0))
817 if (nItem
> infoPtr
->uNumItem
)
818 nItem
= infoPtr
->uNumItem
;
820 if (infoPtr
->uNumItem
== 0) {
821 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
825 HEADER_ITEM
*oldItems
= infoPtr
->items
;
828 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
829 /* pre insert copy */
831 memcpy (&infoPtr
->items
[0], &oldItems
[0],
832 nItem
* sizeof(HEADER_ITEM
));
835 /* post insert copy */
836 if (nItem
< infoPtr
->uNumItem
- 1) {
837 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
838 (infoPtr
->uNumItem
- nItem
) * sizeof(HEADER_ITEM
));
841 COMCTL32_Free (oldItems
);
844 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
845 lpItem
->bDown
= FALSE
;
847 if (phdi
->mask
& HDI_WIDTH
)
848 lpItem
->cxy
= phdi
->cxy
;
850 if (phdi
->mask
& HDI_TEXT
) {
851 WCHAR wide_null_char
= 0;
852 if (!phdi
->pszText
) /* null pointer check */
853 phdi
->pszText
= &wide_null_char
;
854 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
855 len
= lstrlenW (phdi
->pszText
);
856 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
857 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
860 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
863 if (phdi
->mask
& HDI_FORMAT
)
864 lpItem
->fmt
= phdi
->fmt
;
866 if (lpItem
->fmt
== 0)
867 lpItem
->fmt
= HDF_LEFT
;
869 if (phdi
->mask
& HDI_BITMAP
)
870 lpItem
->hbm
= phdi
->hbm
;
872 if (phdi
->mask
& HDI_LPARAM
)
873 lpItem
->lParam
= phdi
->lParam
;
875 if (phdi
->mask
& HDI_IMAGE
)
876 lpItem
->iImage
= phdi
->iImage
;
878 if (phdi
->mask
& HDI_ORDER
)
879 lpItem
->iOrder
= phdi
->iOrder
;
881 HEADER_SetItemBounds (hwnd
);
884 HEADER_Refresh (hwnd
, hdc
);
885 ReleaseDC (hwnd
, hdc
);
892 HEADER_Layout (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
894 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
895 LPHDLAYOUT lpLayout
= (LPHDLAYOUT
)lParam
;
897 lpLayout
->pwpos
->hwnd
= hwnd
;
898 lpLayout
->pwpos
->hwndInsertAfter
= 0;
899 lpLayout
->pwpos
->x
= lpLayout
->prc
->left
;
900 lpLayout
->pwpos
->y
= lpLayout
->prc
->top
;
901 lpLayout
->pwpos
->cx
= lpLayout
->prc
->right
- lpLayout
->prc
->left
;
902 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_HIDDEN
)
903 lpLayout
->pwpos
->cy
= 0;
905 lpLayout
->pwpos
->cy
= infoPtr
->nHeight
;
906 lpLayout
->pwpos
->flags
= SWP_NOZORDER
;
908 TRACE (header
, "Layout x=%d y=%d cx=%d cy=%d\n",
909 lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
910 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
);
912 HEADER_ForceItemBounds (hwnd
, lpLayout
->pwpos
->cy
);
915 #ifdef __HDM_LAYOUT_HACK__
916 MoveWindow (lpLayout
->pwpos
->hwnd
, lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
917 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
, TRUE
);
925 HEADER_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
927 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
930 himlOld
= infoPtr
->himl
;
931 infoPtr
->himl
= (HIMAGELIST
)lParam
;
933 /* FIXME: Refresh needed??? */
935 return (LRESULT
)himlOld
;
940 HEADER_SetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
942 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
943 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
944 INT nItem
= (INT
)wParam
;
950 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
953 TRACE (header
, "[nItem=%d]\n", nItem
);
955 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, nItem
))
958 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
959 if (phdi
->mask
& HDI_BITMAP
)
960 lpItem
->hbm
= phdi
->hbm
;
962 if (phdi
->mask
& HDI_FORMAT
)
963 lpItem
->fmt
= phdi
->fmt
;
965 if (phdi
->mask
& HDI_LPARAM
)
966 lpItem
->lParam
= phdi
->lParam
;
968 if (phdi
->mask
& HDI_TEXT
) {
969 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
970 if (lpItem
->pszText
) {
971 COMCTL32_Free (lpItem
->pszText
);
972 lpItem
->pszText
= NULL
;
975 INT len
= lstrlenA (phdi
->pszText
);
976 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
977 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
981 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
984 if (phdi
->mask
& HDI_WIDTH
)
985 lpItem
->cxy
= phdi
->cxy
;
987 if (phdi
->mask
& HDI_IMAGE
)
988 lpItem
->iImage
= phdi
->iImage
;
990 if (phdi
->mask
& HDI_ORDER
)
991 lpItem
->iOrder
= phdi
->iOrder
;
993 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, nItem
);
995 HEADER_SetItemBounds (hwnd
);
997 HEADER_Refresh (hwnd
, hdc
);
998 ReleaseDC (hwnd
, hdc
);
1005 HEADER_SetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1007 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1008 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
1009 INT nItem
= (INT
)wParam
;
1010 HEADER_ITEM
*lpItem
;
1015 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
1018 TRACE (header
, "[nItem=%d]\n", nItem
);
1020 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, nItem
))
1023 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
1024 if (phdi
->mask
& HDI_BITMAP
)
1025 lpItem
->hbm
= phdi
->hbm
;
1027 if (phdi
->mask
& HDI_FORMAT
)
1028 lpItem
->fmt
= phdi
->fmt
;
1030 if (phdi
->mask
& HDI_LPARAM
)
1031 lpItem
->lParam
= phdi
->lParam
;
1033 if (phdi
->mask
& HDI_TEXT
) {
1034 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
1035 if (lpItem
->pszText
) {
1036 COMCTL32_Free (lpItem
->pszText
);
1037 lpItem
->pszText
= NULL
;
1039 if (phdi
->pszText
) {
1040 INT len
= lstrlenW (phdi
->pszText
);
1041 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1042 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
1046 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
1049 if (phdi
->mask
& HDI_WIDTH
)
1050 lpItem
->cxy
= phdi
->cxy
;
1052 if (phdi
->mask
& HDI_IMAGE
)
1053 lpItem
->iImage
= phdi
->iImage
;
1055 if (phdi
->mask
& HDI_ORDER
)
1056 lpItem
->iOrder
= phdi
->iOrder
;
1058 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, nItem
);
1060 HEADER_SetItemBounds (hwnd
);
1062 HEADER_Refresh (hwnd
, hdc
);
1063 ReleaseDC (hwnd
, hdc
);
1069 /* << HEADER_SetOrderArray >> */
1072 inline static LRESULT
1073 HEADER_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
1075 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1076 BOOL bTemp
= infoPtr
->bUnicode
;
1078 infoPtr
->bUnicode
= (BOOL
)wParam
;
1085 HEADER_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1087 HEADER_INFO
*infoPtr
;
1092 infoPtr
= (HEADER_INFO
*)COMCTL32_Alloc (sizeof(HEADER_INFO
));
1093 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
1095 infoPtr
->uNumItem
= 0;
1096 infoPtr
->nHeight
= 20;
1099 infoPtr
->hcurArrow
= LoadCursorA (0, IDC_ARROWA
);
1100 infoPtr
->hcurDivider
= LoadCursorA (0, IDC_SIZEWEA
);
1101 infoPtr
->hcurDivopen
= LoadCursorA (0, IDC_SIZENSA
);
1102 infoPtr
->bPressed
= FALSE
;
1103 infoPtr
->bTracking
= FALSE
;
1104 infoPtr
->iMoveItem
= 0;
1106 infoPtr
->iHotItem
= -1;
1107 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
1110 hOldFont
= SelectObject (hdc
, GetStockObject (SYSTEM_FONT
));
1111 GetTextMetricsA (hdc
, &tm
);
1112 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1113 SelectObject (hdc
, hOldFont
);
1121 HEADER_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1123 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1124 HEADER_ITEM
*lpItem
;
1127 if (infoPtr
->items
) {
1128 lpItem
= (HEADER_ITEM
*)infoPtr
->items
;
1129 for (nItem
= 0; nItem
< infoPtr
->uNumItem
; nItem
++, lpItem
++) {
1130 if ((lpItem
->pszText
) && (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
))
1131 COMCTL32_Free (lpItem
->pszText
);
1133 COMCTL32_Free (infoPtr
->items
);
1137 ImageList_Destroy (infoPtr
->himl
);
1139 COMCTL32_Free (infoPtr
);
1145 static inline LRESULT
1146 HEADER_GetFont (HWND hwnd
)
1148 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1150 return (LRESULT
)infoPtr
->hFont
;
1155 HEADER_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1161 pt
.x
= (INT
)LOWORD(lParam
);
1162 pt
.y
= (INT
)HIWORD(lParam
);
1163 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1165 if ((GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) && (flags
== HHT_ONHEADER
))
1166 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMDBLCLICKA
, nItem
);
1167 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
))
1168 HEADER_SendHeaderNotify (hwnd
, HDN_DIVIDERDBLCLICKA
, nItem
);
1175 HEADER_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1177 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1178 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1184 pt
.x
= (INT
)LOWORD(lParam
);
1185 pt
.y
= (INT
)HIWORD(lParam
);
1186 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1188 if ((dwStyle
& HDS_BUTTONS
) && (flags
== HHT_ONHEADER
)) {
1190 infoPtr
->bCaptured
= TRUE
;
1191 infoPtr
->bPressed
= TRUE
;
1192 infoPtr
->iMoveItem
= nItem
;
1194 infoPtr
->items
[nItem
].bDown
= TRUE
;
1196 /* Send WM_CUSTOMDRAW */
1198 HEADER_RefreshItem (hwnd
, hdc
, nItem
);
1199 ReleaseDC (hwnd
, hdc
);
1201 TRACE (header
, "Pressed item %d!\n", nItem
);
1203 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
)) {
1204 if (!(HEADER_SendHeaderNotify (hwnd
, HDN_BEGINTRACKA
, nItem
))) {
1206 infoPtr
->bCaptured
= TRUE
;
1207 infoPtr
->bTracking
= TRUE
;
1208 infoPtr
->iMoveItem
= nItem
;
1209 infoPtr
->nOldWidth
= infoPtr
->items
[nItem
].cxy
;
1210 infoPtr
->xTrackOffset
= infoPtr
->items
[nItem
].rect
.right
- pt
.x
;
1212 if (!(dwStyle
& HDS_FULLDRAG
)) {
1213 infoPtr
->xOldTrack
= infoPtr
->items
[nItem
].rect
.right
;
1215 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1216 ReleaseDC (hwnd
, hdc
);
1219 TRACE (header
, "Begin tracking item %d!\n", nItem
);
1228 HEADER_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1230 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1231 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1237 pt
.x
= (INT
)LOWORD(lParam
);
1238 pt
.y
= (INT
)HIWORD(lParam
);
1239 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1241 if (infoPtr
->bPressed
) {
1242 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
)) {
1243 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1245 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1246 ReleaseDC (hwnd
, hdc
);
1248 HEADER_SendClickNotify (hwnd
, HDN_ITEMCLICKA
, infoPtr
->iMoveItem
);
1250 TRACE (header
, "Released item %d!\n", infoPtr
->iMoveItem
);
1251 infoPtr
->bPressed
= FALSE
;
1253 else if (infoPtr
->bTracking
) {
1254 TRACE (header
, "End tracking item %d!\n", infoPtr
->iMoveItem
);
1255 infoPtr
->bTracking
= FALSE
;
1257 HEADER_SendHeaderNotify (hwnd
, HDN_ENDTRACKA
, infoPtr
->iMoveItem
);
1259 if (!(dwStyle
& HDS_FULLDRAG
)) {
1261 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1262 ReleaseDC (hwnd
, hdc
);
1263 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, infoPtr
->iMoveItem
))
1264 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1266 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1269 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1270 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, infoPtr
->iMoveItem
);
1273 HEADER_SetItemBounds (hwnd
);
1275 HEADER_Refresh (hwnd
, hdc
);
1276 ReleaseDC (hwnd
, hdc
);
1280 if (infoPtr
->bCaptured
) {
1281 infoPtr
->bCaptured
= FALSE
;
1283 HEADER_SendSimpleNotify (hwnd
, NM_RELEASEDCAPTURE
);
1291 HEADER_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1293 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1294 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1300 pt
.x
= (INT
)LOWORD(lParam
);
1301 pt
.y
= (INT
)HIWORD(lParam
);
1302 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1304 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1305 if (flags
& (HHT_ONHEADER
| HHT_ONDIVIDER
| HHT_ONDIVOPEN
))
1306 infoPtr
->iHotItem
= nItem
;
1308 infoPtr
->iHotItem
= -1;
1310 HEADER_Refresh (hwnd
, hdc
);
1311 ReleaseDC (hwnd
, hdc
);
1314 if (infoPtr
->bCaptured
) {
1315 if (infoPtr
->bPressed
) {
1316 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
))
1317 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= TRUE
;
1319 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1321 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1322 ReleaseDC (hwnd
, hdc
);
1324 TRACE (header
, "Moving pressed item %d!\n", infoPtr
->iMoveItem
);
1326 else if (infoPtr
->bTracking
) {
1327 if (dwStyle
& HDS_FULLDRAG
) {
1328 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, infoPtr
->iMoveItem
))
1329 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1331 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1334 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1335 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
,
1336 infoPtr
->iMoveItem
);
1338 HEADER_SetItemBounds (hwnd
);
1340 HEADER_Refresh (hwnd
, hdc
);
1341 ReleaseDC (hwnd
, hdc
);
1345 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1346 infoPtr
->xOldTrack
= pt
.x
+ infoPtr
->xTrackOffset
;
1347 if (infoPtr
->xOldTrack
< infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
)
1348 infoPtr
->xOldTrack
= infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1349 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
=
1350 infoPtr
->xOldTrack
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1351 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1352 ReleaseDC (hwnd
, hdc
);
1355 HEADER_SendHeaderNotify (hwnd
, HDN_TRACKA
, infoPtr
->iMoveItem
);
1356 TRACE (header
, "Tracking item %d!\n", infoPtr
->iMoveItem
);
1360 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1361 FIXME (header
, "hot track support!\n");
1369 HEADER_Paint (HWND hwnd
, WPARAM wParam
)
1374 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1375 HEADER_Refresh (hwnd
, hdc
);
1377 EndPaint (hwnd
, &ps
);
1383 HEADER_RButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1385 return HEADER_SendSimpleNotify (hwnd
, NM_RCLICK
);
1390 HEADER_SetCursor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1392 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1397 TRACE (header
, "code=0x%X id=0x%X\n", LOWORD(lParam
), HIWORD(lParam
));
1400 ScreenToClient (hwnd
, &pt
);
1402 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1404 if (flags
== HHT_ONDIVIDER
)
1405 SetCursor (infoPtr
->hcurDivider
);
1406 else if (flags
== HHT_ONDIVOPEN
)
1407 SetCursor (infoPtr
->hcurDivopen
);
1409 SetCursor (infoPtr
->hcurArrow
);
1416 HEADER_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1418 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1420 HFONT hFont
, hOldFont
;
1423 infoPtr
->hFont
= (HFONT
)wParam
;
1425 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
1428 hOldFont
= SelectObject (hdc
, hFont
);
1429 GetTextMetricsA (hdc
, &tm
);
1430 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1431 SelectObject (hdc
, hOldFont
);
1435 HEADER_ForceItemBounds (hwnd
, infoPtr
->nHeight
);
1437 HEADER_Refresh (hwnd
, hdc
);
1438 ReleaseDC (hwnd
, hdc
);
1446 HEADER_WindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1449 case HDM_CREATEDRAGIMAGE
:
1450 return HEADER_CreateDragImage (hwnd
, wParam
);
1452 case HDM_DELETEITEM
:
1453 return HEADER_DeleteItem (hwnd
, wParam
);
1455 case HDM_GETIMAGELIST
:
1456 return HEADER_GetImageList (hwnd
);
1459 return HEADER_GetItemA (hwnd
, wParam
, lParam
);
1462 return HEADER_GetItemW (hwnd
, wParam
, lParam
);
1464 case HDM_GETITEMCOUNT
:
1465 return HEADER_GetItemCount (hwnd
);
1467 case HDM_GETITEMRECT
:
1468 return HEADER_GetItemRect (hwnd
, wParam
, lParam
);
1470 /* case HDM_GETORDERARRAY: */
1472 case HDM_GETUNICODEFORMAT
:
1473 return HEADER_GetUnicodeFormat (hwnd
);
1476 return HEADER_HitTest (hwnd
, wParam
, lParam
);
1478 case HDM_INSERTITEMA
:
1479 return HEADER_InsertItemA (hwnd
, wParam
, lParam
);
1481 case HDM_INSERTITEMW
:
1482 return HEADER_InsertItemW (hwnd
, wParam
, lParam
);
1485 return HEADER_Layout (hwnd
, wParam
, lParam
);
1487 case HDM_SETIMAGELIST
:
1488 return HEADER_SetImageList (hwnd
, wParam
, lParam
);
1491 return HEADER_SetItemA (hwnd
, wParam
, lParam
);
1494 return HEADER_SetItemW (hwnd
, wParam
, lParam
);
1496 /* case HDM_SETORDERARRAY: */
1498 case HDM_SETUNICODEFORMAT
:
1499 return HEADER_SetUnicodeFormat (hwnd
, wParam
);
1503 return HEADER_Create (hwnd
, wParam
, lParam
);
1506 return HEADER_Destroy (hwnd
, wParam
, lParam
);
1512 return DLGC_WANTTAB
| DLGC_WANTARROWS
;
1515 return HEADER_GetFont (hwnd
);
1517 case WM_LBUTTONDBLCLK
:
1518 return HEADER_LButtonDblClk (hwnd
, wParam
, lParam
);
1520 case WM_LBUTTONDOWN
:
1521 return HEADER_LButtonDown (hwnd
, wParam
, lParam
);
1524 return HEADER_LButtonUp (hwnd
, wParam
, lParam
);
1527 return HEADER_MouseMove (hwnd
, wParam
, lParam
);
1529 /* case WM_NOTIFYFORMAT: */
1532 return HEADER_Paint (hwnd
, wParam
);
1535 return HEADER_RButtonUp (hwnd
, wParam
, lParam
);
1538 return HEADER_SetCursor (hwnd
, wParam
, lParam
);
1541 return HEADER_SetFont (hwnd
, wParam
, lParam
);
1545 ERR (header
, "unknown msg %04x wp=%04x lp=%08lx\n",
1546 msg
, wParam
, lParam
);
1547 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1554 HEADER_Register (VOID
)
1558 if (GlobalFindAtomA (WC_HEADERA
)) return;
1560 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1561 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
1562 wndClass
.lpfnWndProc
= (WNDPROC
)HEADER_WindowProc
;
1563 wndClass
.cbClsExtra
= 0;
1564 wndClass
.cbWndExtra
= sizeof(HEADER_INFO
*);
1565 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1566 wndClass
.lpszClassName
= WC_HEADERA
;
1568 RegisterClassA (&wndClass
);
1573 HEADER_Unregister (VOID
)
1575 if (GlobalFindAtomA (WC_HEADERA
))
1576 UnregisterClassA (WC_HEADERA
, (HINSTANCE
)NULL
);