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.
30 #define __HDM_LAYOUT_HACK__
34 #define DIVIDER_WIDTH 10
36 #define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
40 HEADER_DrawItem (HWND hwnd
, HDC hdc
, INT iItem
, BOOL bHotTrack
)
42 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
43 HEADER_ITEM
*phdi
= &infoPtr
->items
[iItem
];
48 if (r
.right
- r
.left
== 0)
49 return phdi
->rect
.right
;
51 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) {
53 DrawEdge (hdc
, &r
, BDR_RAISEDOUTER
,
54 BF_RECT
| BF_FLAT
| BF_MIDDLE
| BF_ADJUST
);
59 DrawEdge (hdc
, &r
, EDGE_RAISED
,
60 BF_RECT
| BF_SOFT
| BF_MIDDLE
| BF_ADJUST
);
63 DrawEdge (hdc
, &r
, EDGE_ETCHED
, BF_BOTTOM
| BF_RIGHT
| BF_ADJUST
);
65 if (phdi
->fmt
& HDF_OWNERDRAW
) {
67 dis
.CtlType
= ODT_HEADER
;
68 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
70 dis
.itemAction
= ODA_DRAWENTIRE
;
71 dis
.itemState
= phdi
->bDown
? ODS_SELECTED
: 0;
75 dis
.itemData
= phdi
->lParam
;
76 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
77 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
80 UINT uTextJustify
= DT_LEFT
;
82 if ((phdi
->fmt
& HDF_JUSTIFYMASK
) == HDF_CENTER
)
83 uTextJustify
= DT_CENTER
;
84 else if ((phdi
->fmt
& HDF_JUSTIFYMASK
) == HDF_RIGHT
)
85 uTextJustify
= DT_RIGHT
;
87 if ((phdi
->fmt
& HDF_BITMAP
) && (phdi
->hbm
)) {
90 INT yD
, yS
, cx
, cy
, rx
, ry
;
92 GetObjectA (phdi
->hbm
, sizeof(BITMAP
), (LPVOID
)&bmp
);
94 ry
= r
.bottom
- r
.top
;
95 rx
= r
.right
- r
.left
;
97 if (ry
>= bmp
.bmHeight
) {
99 yD
= r
.top
+ (ry
- bmp
.bmHeight
) / 2;
105 yS
= (bmp
.bmHeight
- ry
) / 2;
109 if (rx
>= bmp
.bmWidth
+ 6) {
116 hdcBitmap
= CreateCompatibleDC (hdc
);
117 SelectObject (hdcBitmap
, phdi
->hbm
);
118 BitBlt (hdc
, r
.left
+ 3, yD
, cx
, cy
, hdcBitmap
, 0, yS
, SRCCOPY
);
119 DeleteDC (hdcBitmap
);
121 r
.left
+= (bmp
.bmWidth
+ 3);
125 if ((phdi
->fmt
& HDF_BITMAP_ON_RIGHT
) && (phdi
->hbm
)) {
128 INT xD
, yD
, yS
, cx
, cy
, rx
, ry
, tx
;
131 GetObjectA (phdi
->hbm
, sizeof(BITMAP
), (LPVOID
)&bmp
);
134 DrawTextW (hdc
, phdi
->pszText
, lstrlenW (phdi
->pszText
),
135 &textRect
, DT_LEFT
|DT_VCENTER
|DT_SINGLELINE
|DT_CALCRECT
);
136 tx
= textRect
.right
- textRect
.left
;
137 ry
= r
.bottom
- r
.top
;
138 rx
= r
.right
- r
.left
;
140 if (ry
>= bmp
.bmHeight
) {
142 yD
= r
.top
+ (ry
- bmp
.bmHeight
) / 2;
148 yS
= (bmp
.bmHeight
- ry
) / 2;
152 if (r
.left
+ tx
+ bmp
.bmWidth
+ 9 <= r
.right
) {
154 xD
= r
.left
+ tx
+ 6;
157 if (rx
>= bmp
.bmWidth
+ 6) {
159 xD
= r
.right
- bmp
.bmWidth
- 3;
169 hdcBitmap
= CreateCompatibleDC (hdc
);
170 SelectObject (hdcBitmap
, phdi
->hbm
);
171 BitBlt (hdc
, xD
, yD
, cx
, cy
, hdcBitmap
, 0, yS
, SRCCOPY
);
172 DeleteDC (hdcBitmap
);
175 if (phdi
->fmt
& HDF_IMAGE
) {
178 /* ImageList_Draw (infoPtr->himl, phdi->iImage,...); */
181 if ((phdi
->fmt
& HDF_STRING
) && (phdi
->pszText
)) {
182 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
185 SetTextColor (hdc
, bHotTrack
? COLOR_HIGHLIGHT
: COLOR_BTNTEXT
);
186 DrawTextW (hdc
, phdi
->pszText
, lstrlenW (phdi
->pszText
),
187 &r
, uTextJustify
|DT_VCENTER
|DT_SINGLELINE
);
188 if (oldBkMode
!= TRANSPARENT
)
189 SetBkMode(hdc
, oldBkMode
);
193 return phdi
->rect
.right
;
198 HEADER_Refresh (HWND hwnd
, HDC hdc
)
200 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
201 HFONT hFont
, hOldFont
;
206 /* get rect for the bar, adjusted for the border */
207 GetClientRect (hwnd
, &rect
);
209 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
210 hOldFont
= SelectObject (hdc
, hFont
);
212 /* draw Background */
213 hbrBk
= GetSysColorBrush(COLOR_3DFACE
);
214 FillRect(hdc
, &rect
, hbrBk
);
217 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
218 x
= HEADER_DrawItem (hwnd
, hdc
, i
, FALSE
);
221 if ((x
<= rect
.right
) && (infoPtr
->uNumItem
> 0)) {
223 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
)
224 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_TOP
|BF_LEFT
|BF_BOTTOM
|BF_SOFT
);
226 DrawEdge (hdc
, &rect
, EDGE_ETCHED
, BF_BOTTOM
);
229 SelectObject (hdc
, hOldFont
);
234 HEADER_RefreshItem (HWND hwnd
, HDC hdc
, INT iItem
)
236 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
237 HFONT hFont
, hOldFont
;
239 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
240 hOldFont
= SelectObject (hdc
, hFont
);
241 HEADER_DrawItem (hwnd
, hdc
, iItem
, FALSE
);
242 SelectObject (hdc
, hOldFont
);
247 HEADER_SetItemBounds (HWND hwnd
)
249 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
254 if (infoPtr
->uNumItem
== 0)
257 GetClientRect (hwnd
, &rect
);
260 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
261 phdi
= &infoPtr
->items
[i
];
262 phdi
->rect
.top
= rect
.top
;
263 phdi
->rect
.bottom
= rect
.bottom
;
265 phdi
->rect
.right
= phdi
->rect
.left
+ phdi
->cxy
;
266 x
= phdi
->rect
.right
;
272 HEADER_ForceItemBounds (HWND hwnd
, INT cy
)
274 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
278 if (infoPtr
->uNumItem
== 0)
282 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
283 phdi
= &infoPtr
->items
[i
];
285 phdi
->rect
.bottom
= cy
;
287 phdi
->rect
.right
= phdi
->rect
.left
+ phdi
->cxy
;
288 x
= phdi
->rect
.right
;
294 HEADER_InternalHitTest (HWND hwnd
, LPPOINT lpPt
, UINT
*pFlags
, INT
*pItem
)
296 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
301 GetClientRect (hwnd
, &rect
);
305 if (PtInRect (&rect
, *lpPt
))
307 if (infoPtr
->uNumItem
== 0) {
308 *pFlags
|= HHT_NOWHERE
;
310 TRACE (header
, "NOWHERE\n");
314 /* somewhere inside */
315 for (iCount
= 0; iCount
< infoPtr
->uNumItem
; iCount
++) {
316 rect
= infoPtr
->items
[iCount
].rect
;
317 width
= rect
.right
- rect
.left
;
322 if (PtInRect (&rect
, *lpPt
)) {
323 if (width
<= 2 * DIVIDER_WIDTH
) {
324 *pFlags
|= HHT_ONHEADER
;
326 TRACE (header
, "ON HEADER %d\n", iCount
);
331 rcTest
.right
= rcTest
.left
+ DIVIDER_WIDTH
;
332 if (PtInRect (&rcTest
, *lpPt
)) {
334 *pFlags
|= HHT_ONDIVOPEN
;
336 TRACE (header
, "ON DIVOPEN %d\n", *pItem
);
340 *pFlags
|= HHT_ONDIVIDER
;
342 TRACE (header
, "ON DIVIDER %d\n", *pItem
);
348 rcTest
.left
= rcTest
.right
- DIVIDER_WIDTH
;
349 if (PtInRect (&rcTest
, *lpPt
)) {
350 *pFlags
|= HHT_ONDIVIDER
;
352 TRACE (header
, "ON DIVIDER %d\n", *pItem
);
356 *pFlags
|= HHT_ONHEADER
;
358 TRACE (header
, "ON HEADER %d\n", iCount
);
363 /* check for last divider part (on nowhere) */
364 rect
= infoPtr
->items
[infoPtr
->uNumItem
-1].rect
;
365 rect
.left
= rect
.right
;
366 rect
.right
+= DIVIDER_WIDTH
;
367 if (PtInRect (&rect
, *lpPt
)) {
369 *pFlags
|= HHT_ONDIVOPEN
;
370 *pItem
= infoPtr
->uNumItem
- 1;
371 TRACE (header
, "ON DIVOPEN %d\n", *pItem
);
375 *pFlags
|= HHT_ONDIVIDER
;
376 *pItem
= infoPtr
->uNumItem
-1;
377 TRACE (header
, "ON DIVIDER %d\n", *pItem
);
382 *pFlags
|= HHT_NOWHERE
;
384 TRACE (header
, "NOWHERE\n");
389 if (lpPt
->x
< rect
.left
) {
390 TRACE (header
, "TO LEFT\n");
391 *pFlags
|= HHT_TOLEFT
;
393 else if (lpPt
->x
> rect
.right
) {
394 TRACE (header
, "TO LEFT\n");
395 *pFlags
|= HHT_TORIGHT
;
398 if (lpPt
->y
< rect
.top
) {
399 TRACE (header
, "ABOVE\n");
400 *pFlags
|= HHT_ABOVE
;
402 else if (lpPt
->y
> rect
.bottom
) {
403 TRACE (header
, "BELOW\n");
404 *pFlags
|= HHT_BELOW
;
409 TRACE (header
, "flags=0x%X\n", *pFlags
);
415 HEADER_DrawTrackLine (HWND hwnd
, HDC hdc
, INT x
)
421 GetClientRect (hwnd
, &rect
);
423 hOldPen
= SelectObject (hdc
, GetStockObject (BLACK_PEN
));
424 oldRop
= SetROP2 (hdc
, R2_XORPEN
);
425 MoveToEx (hdc
, x
, rect
.top
, NULL
);
426 LineTo (hdc
, x
, rect
.bottom
);
427 SetROP2 (hdc
, oldRop
);
428 SelectObject (hdc
, hOldPen
);
433 HEADER_SendSimpleNotify (HWND hwnd
, UINT code
)
437 nmhdr
.hwndFrom
= hwnd
;
438 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
441 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
442 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
447 HEADER_SendHeaderNotify (HWND hwnd
, UINT code
, INT iItem
)
449 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
453 nmhdr
.hdr
.hwndFrom
= hwnd
;
454 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
455 nmhdr
.hdr
.code
= code
;
458 nmhdr
.pitem
= &nmitem
;
460 nmitem
.cxy
= infoPtr
->items
[iItem
].cxy
;
461 nmitem
.hbm
= infoPtr
->items
[iItem
].hbm
;
462 nmitem
.pszText
= NULL
;
463 nmitem
.cchTextMax
= 0;
464 /* nmitem.pszText = infoPtr->items[iItem].pszText; */
465 /* nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
466 nmitem
.fmt
= infoPtr
->items
[iItem
].fmt
;
467 nmitem
.lParam
= infoPtr
->items
[iItem
].lParam
;
468 nmitem
.iOrder
= infoPtr
->items
[iItem
].iOrder
;
469 nmitem
.iImage
= infoPtr
->items
[iItem
].iImage
;
471 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
472 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
477 HEADER_SendClickNotify (HWND hwnd
, UINT code
, INT iItem
)
481 nmhdr
.hdr
.hwndFrom
= hwnd
;
482 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
483 nmhdr
.hdr
.code
= code
;
488 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
489 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
494 HEADER_CreateDragImage (HWND hwnd
, WPARAM wParam
)
496 FIXME (header
, "empty stub!\n");
502 HEADER_DeleteItem (HWND hwnd
, WPARAM wParam
)
504 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr(hwnd
);
505 INT iItem
= (INT
)wParam
;
508 TRACE(header
, "[iItem=%d]\n", iItem
);
510 if ((iItem
< 0) || (iItem
>= (INT
)infoPtr
->uNumItem
))
513 if (infoPtr
->uNumItem
== 1) {
514 TRACE(header
, "Simple delete!\n");
515 if (infoPtr
->items
[0].pszText
)
516 COMCTL32_Free (infoPtr
->items
[0].pszText
);
517 COMCTL32_Free (infoPtr
->items
);
519 infoPtr
->uNumItem
= 0;
522 HEADER_ITEM
*oldItems
= infoPtr
->items
;
523 TRACE(header
, "Complex delete! [iItem=%d]\n", iItem
);
525 if (infoPtr
->items
[iItem
].pszText
)
526 COMCTL32_Free (infoPtr
->items
[iItem
].pszText
);
529 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
530 /* pre delete copy */
532 memcpy (&infoPtr
->items
[0], &oldItems
[0],
533 iItem
* sizeof(HEADER_ITEM
));
536 /* post delete copy */
537 if (iItem
< infoPtr
->uNumItem
) {
538 memcpy (&infoPtr
->items
[iItem
], &oldItems
[iItem
+1],
539 (infoPtr
->uNumItem
- iItem
) * sizeof(HEADER_ITEM
));
542 COMCTL32_Free (oldItems
);
545 HEADER_SetItemBounds (hwnd
);
548 HEADER_Refresh (hwnd
, hdc
);
549 ReleaseDC (hwnd
, hdc
);
556 HEADER_GetImageList (HWND hwnd
)
558 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
560 return (LRESULT
)infoPtr
->himl
;
565 HEADER_GetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
567 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
568 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
569 INT nItem
= (INT
)wParam
;
574 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
577 TRACE (header
, "[nItem=%d]\n", nItem
);
582 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
583 if (phdi
->mask
& HDI_BITMAP
)
584 phdi
->hbm
= lpItem
->hbm
;
586 if (phdi
->mask
& HDI_FORMAT
)
587 phdi
->fmt
= lpItem
->fmt
;
589 if (phdi
->mask
& HDI_WIDTH
)
590 phdi
->cxy
= lpItem
->cxy
;
592 if (phdi
->mask
& HDI_LPARAM
)
593 phdi
->lParam
= lpItem
->lParam
;
595 if (phdi
->mask
& HDI_TEXT
) {
596 if (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
)
597 lstrcpynWtoA (phdi
->pszText
, lpItem
->pszText
, phdi
->cchTextMax
);
599 phdi
->pszText
= LPSTR_TEXTCALLBACKA
;
602 if (phdi
->mask
& HDI_IMAGE
)
603 phdi
->iImage
= lpItem
->iImage
;
605 if (phdi
->mask
& HDI_ORDER
)
606 phdi
->iOrder
= lpItem
->iOrder
;
613 HEADER_GetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
615 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
616 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
617 INT nItem
= (INT
)wParam
;
622 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
625 TRACE (header
, "[nItem=%d]\n", nItem
);
630 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
631 if (phdi
->mask
& HDI_BITMAP
)
632 phdi
->hbm
= lpItem
->hbm
;
634 if (phdi
->mask
& HDI_FORMAT
)
635 phdi
->fmt
= lpItem
->fmt
;
637 if (phdi
->mask
& HDI_WIDTH
)
638 phdi
->cxy
= lpItem
->cxy
;
640 if (phdi
->mask
& HDI_LPARAM
)
641 phdi
->lParam
= lpItem
->lParam
;
643 if (phdi
->mask
& HDI_TEXT
) {
644 if (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
)
645 lstrcpynW (phdi
->pszText
, lpItem
->pszText
, phdi
->cchTextMax
);
647 phdi
->pszText
= LPSTR_TEXTCALLBACKW
;
650 if (phdi
->mask
& HDI_IMAGE
)
651 phdi
->iImage
= lpItem
->iImage
;
653 if (phdi
->mask
& HDI_ORDER
)
654 phdi
->iOrder
= lpItem
->iOrder
;
660 __inline__
static LRESULT
661 HEADER_GetItemCount (HWND hwnd
)
663 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
664 return infoPtr
->uNumItem
;
669 HEADER_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
671 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
672 INT iItem
= (INT
)wParam
;
673 LPRECT lpRect
= (LPRECT
)lParam
;
675 if ((iItem
< 0) || (iItem
>= (INT
)infoPtr
->uNumItem
))
678 lpRect
->left
= infoPtr
->items
[iItem
].rect
.left
;
679 lpRect
->right
= infoPtr
->items
[iItem
].rect
.right
;
680 lpRect
->top
= infoPtr
->items
[iItem
].rect
.top
;
681 lpRect
->bottom
= infoPtr
->items
[iItem
].rect
.bottom
;
687 /* << HEADER_GetOrderArray >> */
690 __inline__
static LRESULT
691 HEADER_GetUnicodeFormat (HWND hwnd
)
693 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
694 return infoPtr
->bUnicode
;
699 HEADER_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
701 LPHDHITTESTINFO phti
= (LPHDHITTESTINFO
)lParam
;
703 HEADER_InternalHitTest (hwnd
, &phti
->pt
, &phti
->flags
, &phti
->iItem
);
710 HEADER_InsertItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
712 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
713 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
714 INT nItem
= (INT
)wParam
;
719 if ((phdi
== NULL
) || (nItem
< 0))
722 if (nItem
> infoPtr
->uNumItem
)
723 nItem
= infoPtr
->uNumItem
;
725 if (infoPtr
->uNumItem
== 0) {
726 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
730 HEADER_ITEM
*oldItems
= infoPtr
->items
;
733 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
735 memcpy (&infoPtr
->items
[1], &oldItems
[0],
736 (infoPtr
->uNumItem
-1) * sizeof(HEADER_ITEM
));
740 /* pre insert copy */
742 memcpy (&infoPtr
->items
[0], &oldItems
[0],
743 nItem
* sizeof(HEADER_ITEM
));
746 /* post insert copy */
747 if (nItem
< infoPtr
->uNumItem
- 1) {
748 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
749 (infoPtr
->uNumItem
- nItem
) * sizeof(HEADER_ITEM
));
753 COMCTL32_Free (oldItems
);
756 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
757 lpItem
->bDown
= FALSE
;
759 if (phdi
->mask
& HDI_WIDTH
)
760 lpItem
->cxy
= phdi
->cxy
;
762 if (phdi
->mask
& HDI_TEXT
) {
763 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
764 len
= lstrlenA (phdi
->pszText
);
765 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
766 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
769 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
772 if (phdi
->mask
& HDI_FORMAT
)
773 lpItem
->fmt
= phdi
->fmt
;
775 if (lpItem
->fmt
== 0)
776 lpItem
->fmt
= HDF_LEFT
;
778 if (phdi
->mask
& HDI_BITMAP
)
779 lpItem
->hbm
= phdi
->hbm
;
781 if (phdi
->mask
& HDI_LPARAM
)
782 lpItem
->lParam
= phdi
->lParam
;
784 if (phdi
->mask
& HDI_IMAGE
)
785 lpItem
->iImage
= phdi
->iImage
;
787 if (phdi
->mask
& HDI_ORDER
)
788 lpItem
->iOrder
= phdi
->iOrder
;
790 HEADER_SetItemBounds (hwnd
);
793 HEADER_Refresh (hwnd
, hdc
);
794 ReleaseDC (hwnd
, hdc
);
801 HEADER_InsertItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
803 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
804 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
805 INT nItem
= (INT
)wParam
;
810 if ((phdi
== NULL
) || (nItem
< 0))
813 if (nItem
> infoPtr
->uNumItem
)
814 nItem
= infoPtr
->uNumItem
;
816 if (infoPtr
->uNumItem
== 0) {
817 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
821 HEADER_ITEM
*oldItems
= infoPtr
->items
;
824 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
825 /* pre insert copy */
827 memcpy (&infoPtr
->items
[0], &oldItems
[0],
828 nItem
* sizeof(HEADER_ITEM
));
831 /* post insert copy */
832 if (nItem
< infoPtr
->uNumItem
- 1) {
833 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
834 (infoPtr
->uNumItem
- nItem
) * sizeof(HEADER_ITEM
));
837 COMCTL32_Free (oldItems
);
840 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
841 lpItem
->bDown
= FALSE
;
843 if (phdi
->mask
& HDI_WIDTH
)
844 lpItem
->cxy
= phdi
->cxy
;
846 if (phdi
->mask
& HDI_TEXT
) {
847 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
848 len
= lstrlenW (phdi
->pszText
);
849 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
850 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
853 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
856 if (phdi
->mask
& HDI_FORMAT
)
857 lpItem
->fmt
= phdi
->fmt
;
859 if (lpItem
->fmt
== 0)
860 lpItem
->fmt
= HDF_LEFT
;
862 if (phdi
->mask
& HDI_BITMAP
)
863 lpItem
->hbm
= phdi
->hbm
;
865 if (phdi
->mask
& HDI_LPARAM
)
866 lpItem
->lParam
= phdi
->lParam
;
868 if (phdi
->mask
& HDI_IMAGE
)
869 lpItem
->iImage
= phdi
->iImage
;
871 if (phdi
->mask
& HDI_ORDER
)
872 lpItem
->iOrder
= phdi
->iOrder
;
874 HEADER_SetItemBounds (hwnd
);
877 HEADER_Refresh (hwnd
, hdc
);
878 ReleaseDC (hwnd
, hdc
);
885 HEADER_Layout (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
887 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
888 LPHDLAYOUT lpLayout
= (LPHDLAYOUT
)lParam
;
890 lpLayout
->pwpos
->hwnd
= hwnd
;
891 lpLayout
->pwpos
->hwndInsertAfter
= 0;
892 lpLayout
->pwpos
->x
= lpLayout
->prc
->left
;
893 lpLayout
->pwpos
->y
= lpLayout
->prc
->top
;
894 lpLayout
->pwpos
->cx
= lpLayout
->prc
->right
- lpLayout
->prc
->left
;
895 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_HIDDEN
)
896 lpLayout
->pwpos
->cy
= 0;
898 lpLayout
->pwpos
->cy
= infoPtr
->nHeight
;
899 lpLayout
->pwpos
->flags
= SWP_NOZORDER
;
901 TRACE (header
, "Layout x=%d y=%d cx=%d cy=%d\n",
902 lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
903 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
);
905 HEADER_ForceItemBounds (hwnd
, lpLayout
->pwpos
->cy
);
908 #ifdef __HDM_LAYOUT_HACK__
909 MoveWindow (lpLayout
->pwpos
->hwnd
, lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
910 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
, TRUE
);
918 HEADER_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
920 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
923 himlOld
= infoPtr
->himl
;
924 infoPtr
->himl
= (HIMAGELIST
)lParam
;
926 /* FIXME: Refresh needed??? */
928 return (LRESULT
)himlOld
;
933 HEADER_SetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
935 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
936 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
937 INT nItem
= (INT
)wParam
;
943 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
946 TRACE (header
, "[nItem=%d]\n", nItem
);
948 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, nItem
))
951 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
952 if (phdi
->mask
& HDI_BITMAP
)
953 lpItem
->hbm
= phdi
->hbm
;
955 if (phdi
->mask
& HDI_FORMAT
)
956 lpItem
->fmt
= phdi
->fmt
;
958 if (phdi
->mask
& HDI_LPARAM
)
959 lpItem
->lParam
= phdi
->lParam
;
961 if (phdi
->mask
& HDI_TEXT
) {
962 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
963 if (lpItem
->pszText
) {
964 COMCTL32_Free (lpItem
->pszText
);
965 lpItem
->pszText
= NULL
;
968 INT len
= lstrlenA (phdi
->pszText
);
969 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
970 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
974 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
977 if (phdi
->mask
& HDI_WIDTH
)
978 lpItem
->cxy
= phdi
->cxy
;
980 if (phdi
->mask
& HDI_IMAGE
)
981 lpItem
->iImage
= phdi
->iImage
;
983 if (phdi
->mask
& HDI_ORDER
)
984 lpItem
->iOrder
= phdi
->iOrder
;
986 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, nItem
);
988 HEADER_SetItemBounds (hwnd
);
990 HEADER_Refresh (hwnd
, hdc
);
991 ReleaseDC (hwnd
, hdc
);
998 HEADER_SetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1000 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1001 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
1002 INT nItem
= (INT
)wParam
;
1003 HEADER_ITEM
*lpItem
;
1008 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
1011 TRACE (header
, "[nItem=%d]\n", nItem
);
1013 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, nItem
))
1016 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
1017 if (phdi
->mask
& HDI_BITMAP
)
1018 lpItem
->hbm
= phdi
->hbm
;
1020 if (phdi
->mask
& HDI_FORMAT
)
1021 lpItem
->fmt
= phdi
->fmt
;
1023 if (phdi
->mask
& HDI_LPARAM
)
1024 lpItem
->lParam
= phdi
->lParam
;
1026 if (phdi
->mask
& HDI_TEXT
) {
1027 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
1028 if (lpItem
->pszText
) {
1029 COMCTL32_Free (lpItem
->pszText
);
1030 lpItem
->pszText
= NULL
;
1032 if (phdi
->pszText
) {
1033 INT len
= lstrlenW (phdi
->pszText
);
1034 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1035 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
1039 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
1042 if (phdi
->mask
& HDI_WIDTH
)
1043 lpItem
->cxy
= phdi
->cxy
;
1045 if (phdi
->mask
& HDI_IMAGE
)
1046 lpItem
->iImage
= phdi
->iImage
;
1048 if (phdi
->mask
& HDI_ORDER
)
1049 lpItem
->iOrder
= phdi
->iOrder
;
1051 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, nItem
);
1053 HEADER_SetItemBounds (hwnd
);
1055 HEADER_Refresh (hwnd
, hdc
);
1056 ReleaseDC (hwnd
, hdc
);
1062 /* << HEADER_SetOrderArray >> */
1065 __inline__
static LRESULT
1066 HEADER_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
1068 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1069 BOOL bTemp
= infoPtr
->bUnicode
;
1071 infoPtr
->bUnicode
= (BOOL
)wParam
;
1078 HEADER_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1080 HEADER_INFO
*infoPtr
;
1085 infoPtr
= (HEADER_INFO
*)COMCTL32_Alloc (sizeof(HEADER_INFO
));
1086 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
1088 infoPtr
->uNumItem
= 0;
1089 infoPtr
->nHeight
= 20;
1092 infoPtr
->hcurArrow
= LoadCursorA (0, IDC_ARROWA
);
1093 infoPtr
->hcurDivider
= LoadCursorA (0, IDC_SIZEWEA
);
1094 infoPtr
->hcurDivopen
= LoadCursorA (0, IDC_SIZENSA
);
1095 infoPtr
->bPressed
= FALSE
;
1096 infoPtr
->bTracking
= FALSE
;
1097 infoPtr
->iMoveItem
= 0;
1099 infoPtr
->iHotItem
= -1;
1100 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
1103 hOldFont
= SelectObject (hdc
, GetStockObject (SYSTEM_FONT
));
1104 GetTextMetricsA (hdc
, &tm
);
1105 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1106 SelectObject (hdc
, hOldFont
);
1114 HEADER_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1116 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1117 HEADER_ITEM
*lpItem
;
1120 if (infoPtr
->items
) {
1121 lpItem
= (HEADER_ITEM
*)infoPtr
->items
;
1122 for (nItem
= 0; nItem
< infoPtr
->uNumItem
; nItem
++, lpItem
++) {
1123 if ((lpItem
->pszText
) && (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
))
1124 COMCTL32_Free (lpItem
->pszText
);
1126 COMCTL32_Free (infoPtr
->items
);
1130 ImageList_Destroy (infoPtr
->himl
);
1132 COMCTL32_Free (infoPtr
);
1138 static __inline__ LRESULT
1139 HEADER_GetFont (HWND hwnd
)
1141 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1143 return (LRESULT
)infoPtr
->hFont
;
1148 HEADER_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1154 pt
.x
= (INT
)LOWORD(lParam
);
1155 pt
.y
= (INT
)HIWORD(lParam
);
1156 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1158 if ((GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) && (flags
== HHT_ONHEADER
))
1159 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMDBLCLICKA
, nItem
);
1160 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
))
1161 HEADER_SendHeaderNotify (hwnd
, HDN_DIVIDERDBLCLICKA
, nItem
);
1168 HEADER_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1170 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1171 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1177 pt
.x
= (INT
)LOWORD(lParam
);
1178 pt
.y
= (INT
)HIWORD(lParam
);
1179 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1181 if ((dwStyle
& HDS_BUTTONS
) && (flags
== HHT_ONHEADER
)) {
1183 infoPtr
->bCaptured
= TRUE
;
1184 infoPtr
->bPressed
= TRUE
;
1185 infoPtr
->iMoveItem
= nItem
;
1187 infoPtr
->items
[nItem
].bDown
= TRUE
;
1189 /* Send WM_CUSTOMDRAW */
1191 HEADER_RefreshItem (hwnd
, hdc
, nItem
);
1192 ReleaseDC (hwnd
, hdc
);
1194 TRACE (header
, "Pressed item %d!\n", nItem
);
1196 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
)) {
1197 if (!(HEADER_SendHeaderNotify (hwnd
, HDN_BEGINTRACKA
, nItem
))) {
1199 infoPtr
->bCaptured
= TRUE
;
1200 infoPtr
->bTracking
= TRUE
;
1201 infoPtr
->iMoveItem
= nItem
;
1202 infoPtr
->nOldWidth
= infoPtr
->items
[nItem
].cxy
;
1203 infoPtr
->xTrackOffset
= infoPtr
->items
[nItem
].rect
.right
- pt
.x
;
1205 if (!(dwStyle
& HDS_FULLDRAG
)) {
1206 infoPtr
->xOldTrack
= infoPtr
->items
[nItem
].rect
.right
;
1208 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1209 ReleaseDC (hwnd
, hdc
);
1212 TRACE (header
, "Begin tracking item %d!\n", nItem
);
1221 HEADER_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1223 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1224 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1230 pt
.x
= (INT
)LOWORD(lParam
);
1231 pt
.y
= (INT
)HIWORD(lParam
);
1232 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1234 if (infoPtr
->bPressed
) {
1235 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
)) {
1236 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1238 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1239 ReleaseDC (hwnd
, hdc
);
1241 HEADER_SendClickNotify (hwnd
, HDN_ITEMCLICKA
, infoPtr
->iMoveItem
);
1243 TRACE (header
, "Released item %d!\n", infoPtr
->iMoveItem
);
1244 infoPtr
->bPressed
= FALSE
;
1246 else if (infoPtr
->bTracking
) {
1247 TRACE (header
, "End tracking item %d!\n", infoPtr
->iMoveItem
);
1248 infoPtr
->bTracking
= FALSE
;
1250 HEADER_SendHeaderNotify (hwnd
, HDN_ENDTRACKA
, infoPtr
->iMoveItem
);
1252 if (!(dwStyle
& HDS_FULLDRAG
)) {
1254 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1255 ReleaseDC (hwnd
, hdc
);
1256 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, infoPtr
->iMoveItem
))
1257 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1259 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1262 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1263 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
, infoPtr
->iMoveItem
);
1266 HEADER_SetItemBounds (hwnd
);
1268 HEADER_Refresh (hwnd
, hdc
);
1269 ReleaseDC (hwnd
, hdc
);
1273 if (infoPtr
->bCaptured
) {
1274 infoPtr
->bCaptured
= FALSE
;
1276 HEADER_SendSimpleNotify (hwnd
, NM_RELEASEDCAPTURE
);
1284 HEADER_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1286 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1287 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1293 pt
.x
= (INT
)LOWORD(lParam
);
1294 pt
.y
= (INT
)HIWORD(lParam
);
1295 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1297 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1298 if (flags
& (HHT_ONHEADER
| HHT_ONDIVIDER
| HHT_ONDIVOPEN
))
1299 infoPtr
->iHotItem
= nItem
;
1301 infoPtr
->iHotItem
= -1;
1303 HEADER_Refresh (hwnd
, hdc
);
1304 ReleaseDC (hwnd
, hdc
);
1307 if (infoPtr
->bCaptured
) {
1308 if (infoPtr
->bPressed
) {
1309 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
))
1310 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= TRUE
;
1312 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1314 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1315 ReleaseDC (hwnd
, hdc
);
1317 TRACE (header
, "Moving pressed item %d!\n", infoPtr
->iMoveItem
);
1319 else if (infoPtr
->bTracking
) {
1320 if (dwStyle
& HDS_FULLDRAG
) {
1321 if (HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGINGA
, infoPtr
->iMoveItem
))
1322 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1324 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1327 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1328 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMCHANGEDA
,
1329 infoPtr
->iMoveItem
);
1331 HEADER_SetItemBounds (hwnd
);
1333 HEADER_Refresh (hwnd
, hdc
);
1334 ReleaseDC (hwnd
, hdc
);
1338 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1339 infoPtr
->xOldTrack
= pt
.x
+ infoPtr
->xTrackOffset
;
1340 if (infoPtr
->xOldTrack
< infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
)
1341 infoPtr
->xOldTrack
= infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1342 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
=
1343 infoPtr
->xOldTrack
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1344 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1345 ReleaseDC (hwnd
, hdc
);
1348 HEADER_SendHeaderNotify (hwnd
, HDN_TRACKA
, infoPtr
->iMoveItem
);
1349 TRACE (header
, "Tracking item %d!\n", infoPtr
->iMoveItem
);
1353 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1354 FIXME (header
, "hot track support!\n");
1362 HEADER_Paint (HWND hwnd
, WPARAM wParam
)
1367 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1368 HEADER_Refresh (hwnd
, hdc
);
1370 EndPaint (hwnd
, &ps
);
1376 HEADER_RButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1378 return HEADER_SendSimpleNotify (hwnd
, NM_RCLICK
);
1383 HEADER_SetCursor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1385 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1390 TRACE (header
, "code=0x%X id=0x%X\n", LOWORD(lParam
), HIWORD(lParam
));
1393 ScreenToClient (hwnd
, &pt
);
1395 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1397 if (flags
== HHT_ONDIVIDER
)
1398 SetCursor (infoPtr
->hcurDivider
);
1399 else if (flags
== HHT_ONDIVOPEN
)
1400 SetCursor (infoPtr
->hcurDivopen
);
1402 SetCursor (infoPtr
->hcurArrow
);
1409 HEADER_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1411 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1413 HFONT hFont
, hOldFont
;
1416 infoPtr
->hFont
= (HFONT
)wParam
;
1418 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
1421 hOldFont
= SelectObject (hdc
, hFont
);
1422 GetTextMetricsA (hdc
, &tm
);
1423 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1424 SelectObject (hdc
, hOldFont
);
1428 HEADER_ForceItemBounds (hwnd
, infoPtr
->nHeight
);
1430 HEADER_Refresh (hwnd
, hdc
);
1431 ReleaseDC (hwnd
, hdc
);
1439 HEADER_WindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1442 case HDM_CREATEDRAGIMAGE
:
1443 return HEADER_CreateDragImage (hwnd
, wParam
);
1445 case HDM_DELETEITEM
:
1446 return HEADER_DeleteItem (hwnd
, wParam
);
1448 case HDM_GETIMAGELIST
:
1449 return HEADER_GetImageList (hwnd
);
1452 return HEADER_GetItemA (hwnd
, wParam
, lParam
);
1455 return HEADER_GetItemW (hwnd
, wParam
, lParam
);
1457 case HDM_GETITEMCOUNT
:
1458 return HEADER_GetItemCount (hwnd
);
1460 case HDM_GETITEMRECT
:
1461 return HEADER_GetItemRect (hwnd
, wParam
, lParam
);
1463 /* case HDM_GETORDERARRAY: */
1465 case HDM_GETUNICODEFORMAT
:
1466 return HEADER_GetUnicodeFormat (hwnd
);
1469 return HEADER_HitTest (hwnd
, wParam
, lParam
);
1471 case HDM_INSERTITEMA
:
1472 return HEADER_InsertItemA (hwnd
, wParam
, lParam
);
1474 case HDM_INSERTITEMW
:
1475 return HEADER_InsertItemW (hwnd
, wParam
, lParam
);
1478 return HEADER_Layout (hwnd
, wParam
, lParam
);
1480 case HDM_SETIMAGELIST
:
1481 return HEADER_SetImageList (hwnd
, wParam
, lParam
);
1484 return HEADER_SetItemA (hwnd
, wParam
, lParam
);
1487 return HEADER_SetItemW (hwnd
, wParam
, lParam
);
1489 /* case HDM_SETORDERARRAY: */
1491 case HDM_SETUNICODEFORMAT
:
1492 return HEADER_SetUnicodeFormat (hwnd
, wParam
);
1496 return HEADER_Create (hwnd
, wParam
, lParam
);
1499 return HEADER_Destroy (hwnd
, wParam
, lParam
);
1505 return DLGC_WANTTAB
| DLGC_WANTARROWS
;
1508 return HEADER_GetFont (hwnd
);
1510 case WM_LBUTTONDBLCLK
:
1511 return HEADER_LButtonDblClk (hwnd
, wParam
, lParam
);
1513 case WM_LBUTTONDOWN
:
1514 return HEADER_LButtonDown (hwnd
, wParam
, lParam
);
1517 return HEADER_LButtonUp (hwnd
, wParam
, lParam
);
1520 return HEADER_MouseMove (hwnd
, wParam
, lParam
);
1522 /* case WM_NOTIFYFORMAT: */
1525 return HEADER_Paint (hwnd
, wParam
);
1528 return HEADER_RButtonUp (hwnd
, wParam
, lParam
);
1531 return HEADER_SetCursor (hwnd
, wParam
, lParam
);
1534 return HEADER_SetFont (hwnd
, wParam
, lParam
);
1538 ERR (header
, "unknown msg %04x wp=%04x lp=%08lx\n",
1539 msg
, wParam
, lParam
);
1540 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1547 HEADER_Register (VOID
)
1551 if (GlobalFindAtomA (WC_HEADERA
)) return;
1553 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1554 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
1555 wndClass
.lpfnWndProc
= (WNDPROC
)HEADER_WindowProc
;
1556 wndClass
.cbClsExtra
= 0;
1557 wndClass
.cbWndExtra
= sizeof(HEADER_INFO
*);
1558 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1559 wndClass
.lpszClassName
= WC_HEADERA
;
1561 RegisterClassA (&wndClass
);
1566 HEADER_Unregister (VOID
)
1568 if (GlobalFindAtomA (WC_HEADERA
))
1569 UnregisterClassA (WC_HEADERA
, (HINSTANCE
)NULL
);