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.
27 #include "debugtools.h"
29 DEFAULT_DEBUG_CHANNEL(header
)
33 #define DIVIDER_WIDTH 10
35 #define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
39 HEADER_SetItemBounds (HWND hwnd
)
41 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
46 infoPtr
->bRectsValid
= TRUE
;
48 if (infoPtr
->uNumItem
== 0)
51 GetClientRect (hwnd
, &rect
);
54 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
55 phdi
= &infoPtr
->items
[i
];
56 phdi
->rect
.top
= rect
.top
;
57 phdi
->rect
.bottom
= rect
.bottom
;
59 phdi
->rect
.right
= phdi
->rect
.left
+ phdi
->cxy
;
65 HEADER_Size (HWND hwnd
, WPARAM wParam
)
67 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
69 infoPtr
->bRectsValid
= FALSE
;
76 HEADER_DrawItem (HWND hwnd
, HDC hdc
, INT iItem
, BOOL bHotTrack
)
78 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
79 HEADER_ITEM
*phdi
= &infoPtr
->items
[iItem
];
83 if (!infoPtr
->bRectsValid
)
84 HEADER_SetItemBounds(hwnd
);
87 if (r
.right
- r
.left
== 0)
88 return phdi
->rect
.right
;
90 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) {
92 DrawEdge (hdc
, &r
, BDR_RAISEDOUTER
,
93 BF_RECT
| BF_FLAT
| BF_MIDDLE
| BF_ADJUST
);
98 DrawEdge (hdc
, &r
, EDGE_RAISED
,
99 BF_RECT
| BF_SOFT
| BF_MIDDLE
| BF_ADJUST
);
102 DrawEdge (hdc
, &r
, EDGE_ETCHED
, BF_BOTTOM
| BF_RIGHT
| BF_ADJUST
);
104 if (phdi
->fmt
& HDF_OWNERDRAW
) {
106 dis
.CtlType
= ODT_HEADER
;
107 dis
.CtlID
= GetWindowLongA (hwnd
, GWL_ID
);
109 dis
.itemAction
= ODA_DRAWENTIRE
;
110 dis
.itemState
= phdi
->bDown
? ODS_SELECTED
: 0;
114 dis
.itemData
= phdi
->lParam
;
115 SendMessageA (GetParent (hwnd
), WM_DRAWITEM
,
116 (WPARAM
)dis
.CtlID
, (LPARAM
)&dis
);
119 UINT uTextJustify
= DT_LEFT
;
121 if ((phdi
->fmt
& HDF_JUSTIFYMASK
) == HDF_CENTER
)
122 uTextJustify
= DT_CENTER
;
123 else if ((phdi
->fmt
& HDF_JUSTIFYMASK
) == HDF_RIGHT
)
124 uTextJustify
= DT_RIGHT
;
126 if ((phdi
->fmt
& HDF_BITMAP
) && (phdi
->hbm
)) {
129 INT yD
, yS
, cx
, cy
, rx
, ry
;
131 GetObjectA (phdi
->hbm
, sizeof(BITMAP
), (LPVOID
)&bmp
);
133 ry
= r
.bottom
- r
.top
;
134 rx
= r
.right
- r
.left
;
136 if (ry
>= bmp
.bmHeight
) {
138 yD
= r
.top
+ (ry
- bmp
.bmHeight
) / 2;
144 yS
= (bmp
.bmHeight
- ry
) / 2;
148 if (rx
>= bmp
.bmWidth
+ 6) {
155 hdcBitmap
= CreateCompatibleDC (hdc
);
156 SelectObject (hdcBitmap
, phdi
->hbm
);
157 BitBlt (hdc
, r
.left
+ 3, yD
, cx
, cy
, hdcBitmap
, 0, yS
, SRCCOPY
);
158 DeleteDC (hdcBitmap
);
160 r
.left
+= (bmp
.bmWidth
+ 3);
164 if ((phdi
->fmt
& HDF_BITMAP_ON_RIGHT
) && (phdi
->hbm
)) {
167 INT xD
, yD
, yS
, cx
, cy
, rx
, ry
, tx
;
170 GetObjectA (phdi
->hbm
, sizeof(BITMAP
), (LPVOID
)&bmp
);
173 DrawTextW (hdc
, phdi
->pszText
, lstrlenW (phdi
->pszText
),
174 &textRect
, DT_LEFT
|DT_VCENTER
|DT_SINGLELINE
|DT_CALCRECT
);
175 tx
= textRect
.right
- textRect
.left
;
176 ry
= r
.bottom
- r
.top
;
177 rx
= r
.right
- r
.left
;
179 if (ry
>= bmp
.bmHeight
) {
181 yD
= r
.top
+ (ry
- bmp
.bmHeight
) / 2;
187 yS
= (bmp
.bmHeight
- ry
) / 2;
191 if (r
.left
+ tx
+ bmp
.bmWidth
+ 9 <= r
.right
) {
193 xD
= r
.left
+ tx
+ 6;
196 if (rx
>= bmp
.bmWidth
+ 6) {
198 xD
= r
.right
- bmp
.bmWidth
- 3;
208 hdcBitmap
= CreateCompatibleDC (hdc
);
209 SelectObject (hdcBitmap
, phdi
->hbm
);
210 BitBlt (hdc
, xD
, yD
, cx
, cy
, hdcBitmap
, 0, yS
, SRCCOPY
);
211 DeleteDC (hdcBitmap
);
214 if (phdi
->fmt
& HDF_IMAGE
) {
217 /* ImageList_Draw (infoPtr->himl, phdi->iImage,...); */
220 if (((phdi
->fmt
& HDF_STRING
)
221 || (!(phdi
->fmt
& (HDF_OWNERDRAW
|HDF_STRING
|HDF_BITMAP
|
222 HDF_BITMAP_ON_RIGHT
|HDF_IMAGE
)))) /* no explicit format specified? */
223 && (phdi
->pszText
)) {
224 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
227 SetTextColor (hdc
, bHotTrack
? COLOR_HIGHLIGHT
: COLOR_BTNTEXT
);
228 DrawTextW (hdc
, phdi
->pszText
, lstrlenW (phdi
->pszText
),
229 &r
, uTextJustify
|DT_VCENTER
|DT_SINGLELINE
);
230 if (oldBkMode
!= TRANSPARENT
)
231 SetBkMode(hdc
, oldBkMode
);
235 return phdi
->rect
.right
;
240 HEADER_Refresh (HWND hwnd
, HDC hdc
)
242 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
243 HFONT hFont
, hOldFont
;
248 /* get rect for the bar, adjusted for the border */
249 GetClientRect (hwnd
, &rect
);
251 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
252 hOldFont
= SelectObject (hdc
, hFont
);
254 /* draw Background */
255 hbrBk
= GetSysColorBrush(COLOR_3DFACE
);
256 FillRect(hdc
, &rect
, hbrBk
);
259 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
260 x
= HEADER_DrawItem (hwnd
, hdc
, i
, FALSE
);
263 if ((x
<= rect
.right
) && (infoPtr
->uNumItem
> 0)) {
265 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
)
266 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_TOP
|BF_LEFT
|BF_BOTTOM
|BF_SOFT
);
268 DrawEdge (hdc
, &rect
, EDGE_ETCHED
, BF_BOTTOM
);
271 SelectObject (hdc
, hOldFont
);
276 HEADER_RefreshItem (HWND hwnd
, HDC hdc
, INT iItem
)
278 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
279 HFONT hFont
, hOldFont
;
281 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
282 hOldFont
= SelectObject (hdc
, hFont
);
283 HEADER_DrawItem (hwnd
, hdc
, iItem
, FALSE
);
284 SelectObject (hdc
, hOldFont
);
289 HEADER_InternalHitTest (HWND hwnd
, LPPOINT lpPt
, UINT
*pFlags
, INT
*pItem
)
291 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
296 GetClientRect (hwnd
, &rect
);
300 if (PtInRect (&rect
, *lpPt
))
302 if (infoPtr
->uNumItem
== 0) {
303 *pFlags
|= HHT_NOWHERE
;
309 /* somewhere inside */
310 for (iCount
= 0; iCount
< infoPtr
->uNumItem
; iCount
++) {
311 rect
= infoPtr
->items
[iCount
].rect
;
312 width
= rect
.right
- rect
.left
;
317 if (PtInRect (&rect
, *lpPt
)) {
318 if (width
<= 2 * DIVIDER_WIDTH
) {
319 *pFlags
|= HHT_ONHEADER
;
321 TRACE("ON HEADER %d\n", iCount
);
326 rcTest
.right
= rcTest
.left
+ DIVIDER_WIDTH
;
327 if (PtInRect (&rcTest
, *lpPt
)) {
329 *pFlags
|= HHT_ONDIVOPEN
;
331 TRACE("ON DIVOPEN %d\n", *pItem
);
335 *pFlags
|= HHT_ONDIVIDER
;
337 TRACE("ON DIVIDER %d\n", *pItem
);
343 rcTest
.left
= rcTest
.right
- DIVIDER_WIDTH
;
344 if (PtInRect (&rcTest
, *lpPt
)) {
345 *pFlags
|= HHT_ONDIVIDER
;
347 TRACE("ON DIVIDER %d\n", *pItem
);
351 *pFlags
|= HHT_ONHEADER
;
353 TRACE("ON HEADER %d\n", iCount
);
358 /* check for last divider part (on nowhere) */
359 rect
= infoPtr
->items
[infoPtr
->uNumItem
-1].rect
;
360 rect
.left
= rect
.right
;
361 rect
.right
+= DIVIDER_WIDTH
;
362 if (PtInRect (&rect
, *lpPt
)) {
364 *pFlags
|= HHT_ONDIVOPEN
;
365 *pItem
= infoPtr
->uNumItem
- 1;
366 TRACE("ON DIVOPEN %d\n", *pItem
);
370 *pFlags
|= HHT_ONDIVIDER
;
371 *pItem
= infoPtr
->uNumItem
-1;
372 TRACE("ON DIVIDER %d\n", *pItem
);
377 *pFlags
|= HHT_NOWHERE
;
384 if (lpPt
->x
< rect
.left
) {
386 *pFlags
|= HHT_TOLEFT
;
388 else if (lpPt
->x
> rect
.right
) {
390 *pFlags
|= HHT_TORIGHT
;
393 if (lpPt
->y
< rect
.top
) {
395 *pFlags
|= HHT_ABOVE
;
397 else if (lpPt
->y
> rect
.bottom
) {
399 *pFlags
|= HHT_BELOW
;
404 TRACE("flags=0x%X\n", *pFlags
);
410 HEADER_DrawTrackLine (HWND hwnd
, HDC hdc
, INT x
)
416 GetClientRect (hwnd
, &rect
);
418 hOldPen
= SelectObject (hdc
, GetStockObject (BLACK_PEN
));
419 oldRop
= SetROP2 (hdc
, R2_XORPEN
);
420 MoveToEx (hdc
, x
, rect
.top
, NULL
);
421 LineTo (hdc
, x
, rect
.bottom
);
422 SetROP2 (hdc
, oldRop
);
423 SelectObject (hdc
, hOldPen
);
428 HEADER_SendSimpleNotify (HWND hwnd
, UINT code
)
432 nmhdr
.hwndFrom
= hwnd
;
433 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
436 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
437 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
441 HEADER_SendItemChange(HWND hwnd
, INT iItem
, UINT mask
, UINT msg
)
443 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
447 nmhdr
.hdr
.hwndFrom
= hwnd
;
448 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
449 nmhdr
.hdr
.code
= msg
;
452 nmhdr
.pitem
= &nmitem
;
454 nmitem
.cxy
= infoPtr
->items
[iItem
].cxy
;
455 nmitem
.hbm
= infoPtr
->items
[iItem
].hbm
;
456 nmitem
.pszText
= NULL
;
457 nmitem
.cchTextMax
= 0;
458 nmitem
.fmt
= infoPtr
->items
[iItem
].fmt
;
459 nmitem
.lParam
= infoPtr
->items
[iItem
].lParam
;
460 nmitem
.iOrder
= infoPtr
->items
[iItem
].iOrder
;
461 nmitem
.iImage
= infoPtr
->items
[iItem
].iImage
;
463 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
464 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
468 HEADER_SendHeaderNotify (HWND hwnd
, UINT code
, INT iItem
)
470 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
474 nmhdr
.hdr
.hwndFrom
= hwnd
;
475 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
476 nmhdr
.hdr
.code
= code
;
479 nmhdr
.pitem
= &nmitem
;
481 nmitem
.cxy
= infoPtr
->items
[iItem
].cxy
;
482 nmitem
.hbm
= infoPtr
->items
[iItem
].hbm
;
483 nmitem
.pszText
= NULL
;
484 nmitem
.cchTextMax
= 0;
485 /* nmitem.pszText = infoPtr->items[iItem].pszText; */
486 /* nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
487 nmitem
.fmt
= infoPtr
->items
[iItem
].fmt
;
488 nmitem
.lParam
= infoPtr
->items
[iItem
].lParam
;
489 nmitem
.iOrder
= infoPtr
->items
[iItem
].iOrder
;
490 nmitem
.iImage
= infoPtr
->items
[iItem
].iImage
;
492 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
493 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
498 HEADER_SendClickNotify (HWND hwnd
, UINT code
, INT iItem
)
502 nmhdr
.hdr
.hwndFrom
= hwnd
;
503 nmhdr
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
504 nmhdr
.hdr
.code
= code
;
509 return (BOOL
)SendMessageA (GetParent (hwnd
), WM_NOTIFY
,
510 (WPARAM
)nmhdr
.hdr
.idFrom
, (LPARAM
)&nmhdr
);
515 HEADER_CreateDragImage (HWND hwnd
, WPARAM wParam
)
517 FIXME("empty stub!\n");
523 HEADER_DeleteItem (HWND hwnd
, WPARAM wParam
)
525 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr(hwnd
);
526 INT iItem
= (INT
)wParam
;
528 TRACE("[iItem=%d]\n", iItem
);
530 if ((iItem
< 0) || (iItem
>= (INT
)infoPtr
->uNumItem
))
533 if (infoPtr
->uNumItem
== 1) {
534 TRACE("Simple delete!\n");
535 if (infoPtr
->items
[0].pszText
)
536 COMCTL32_Free (infoPtr
->items
[0].pszText
);
537 COMCTL32_Free (infoPtr
->items
);
539 infoPtr
->uNumItem
= 0;
542 HEADER_ITEM
*oldItems
= infoPtr
->items
;
543 TRACE("Complex delete! [iItem=%d]\n", iItem
);
545 if (infoPtr
->items
[iItem
].pszText
)
546 COMCTL32_Free (infoPtr
->items
[iItem
].pszText
);
549 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
550 /* pre delete copy */
552 memcpy (&infoPtr
->items
[0], &oldItems
[0],
553 iItem
* sizeof(HEADER_ITEM
));
556 /* post delete copy */
557 if (iItem
< infoPtr
->uNumItem
) {
558 memcpy (&infoPtr
->items
[iItem
], &oldItems
[iItem
+1],
559 (infoPtr
->uNumItem
- iItem
) * sizeof(HEADER_ITEM
));
562 COMCTL32_Free (oldItems
);
565 HEADER_SetItemBounds (hwnd
);
567 InvalidateRect(hwnd
, NULL
, FALSE
);
574 HEADER_GetImageList (HWND hwnd
)
576 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
578 return (LRESULT
)infoPtr
->himl
;
583 HEADER_GetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
585 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
586 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
587 INT nItem
= (INT
)wParam
;
592 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
595 TRACE("[nItem=%d]\n", nItem
);
600 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
601 if (phdi
->mask
& HDI_BITMAP
)
602 phdi
->hbm
= lpItem
->hbm
;
604 if (phdi
->mask
& HDI_FORMAT
)
605 phdi
->fmt
= lpItem
->fmt
;
607 if (phdi
->mask
& HDI_WIDTH
)
608 phdi
->cxy
= lpItem
->cxy
;
610 if (phdi
->mask
& HDI_LPARAM
)
611 phdi
->lParam
= lpItem
->lParam
;
613 if (phdi
->mask
& HDI_TEXT
) {
614 if (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
)
615 lstrcpynWtoA (phdi
->pszText
, lpItem
->pszText
, phdi
->cchTextMax
);
617 phdi
->pszText
= LPSTR_TEXTCALLBACKA
;
620 if (phdi
->mask
& HDI_IMAGE
)
621 phdi
->iImage
= lpItem
->iImage
;
623 if (phdi
->mask
& HDI_ORDER
)
624 phdi
->iOrder
= lpItem
->iOrder
;
631 HEADER_GetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
633 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
634 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
635 INT nItem
= (INT
)wParam
;
640 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
643 TRACE("[nItem=%d]\n", nItem
);
648 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
649 if (phdi
->mask
& HDI_BITMAP
)
650 phdi
->hbm
= lpItem
->hbm
;
652 if (phdi
->mask
& HDI_FORMAT
)
653 phdi
->fmt
= lpItem
->fmt
;
655 if (phdi
->mask
& HDI_WIDTH
)
656 phdi
->cxy
= lpItem
->cxy
;
658 if (phdi
->mask
& HDI_LPARAM
)
659 phdi
->lParam
= lpItem
->lParam
;
661 if (phdi
->mask
& HDI_TEXT
) {
662 if (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
)
663 lstrcpynW (phdi
->pszText
, lpItem
->pszText
, phdi
->cchTextMax
);
665 phdi
->pszText
= LPSTR_TEXTCALLBACKW
;
668 if (phdi
->mask
& HDI_IMAGE
)
669 phdi
->iImage
= lpItem
->iImage
;
671 if (phdi
->mask
& HDI_ORDER
)
672 phdi
->iOrder
= lpItem
->iOrder
;
678 inline static LRESULT
679 HEADER_GetItemCount (HWND hwnd
)
681 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
682 return infoPtr
->uNumItem
;
687 HEADER_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
689 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
690 INT iItem
= (INT
)wParam
;
691 LPRECT lpRect
= (LPRECT
)lParam
;
693 if ((iItem
< 0) || (iItem
>= (INT
)infoPtr
->uNumItem
))
696 lpRect
->left
= infoPtr
->items
[iItem
].rect
.left
;
697 lpRect
->right
= infoPtr
->items
[iItem
].rect
.right
;
698 lpRect
->top
= infoPtr
->items
[iItem
].rect
.top
;
699 lpRect
->bottom
= infoPtr
->items
[iItem
].rect
.bottom
;
705 /* << HEADER_GetOrderArray >> */
708 inline static LRESULT
709 HEADER_GetUnicodeFormat (HWND hwnd
)
711 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
712 return infoPtr
->bUnicode
;
717 HEADER_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
719 LPHDHITTESTINFO phti
= (LPHDHITTESTINFO
)lParam
;
721 HEADER_InternalHitTest (hwnd
, &phti
->pt
, &phti
->flags
, &phti
->iItem
);
723 if (phti
->flags
== HHT_ONHEADER
)
731 HEADER_InsertItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
733 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
734 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
735 INT nItem
= (INT
)wParam
;
739 if ((phdi
== NULL
) || (nItem
< 0))
742 if (nItem
> infoPtr
->uNumItem
)
743 nItem
= infoPtr
->uNumItem
;
745 if (infoPtr
->uNumItem
== 0) {
746 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
750 HEADER_ITEM
*oldItems
= infoPtr
->items
;
753 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
755 memcpy (&infoPtr
->items
[1], &oldItems
[0],
756 (infoPtr
->uNumItem
-1) * sizeof(HEADER_ITEM
));
760 /* pre insert copy */
762 memcpy (&infoPtr
->items
[0], &oldItems
[0],
763 nItem
* sizeof(HEADER_ITEM
));
766 /* post insert copy */
767 if (nItem
< infoPtr
->uNumItem
- 1) {
768 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
769 (infoPtr
->uNumItem
- nItem
- 1) * sizeof(HEADER_ITEM
));
773 COMCTL32_Free (oldItems
);
776 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
777 lpItem
->bDown
= FALSE
;
779 if (phdi
->mask
& HDI_WIDTH
)
780 lpItem
->cxy
= phdi
->cxy
;
782 if (phdi
->mask
& HDI_TEXT
) {
783 if (!phdi
->pszText
) /* null pointer check */
785 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
786 len
= lstrlenA (phdi
->pszText
);
787 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
788 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
791 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
794 if (phdi
->mask
& HDI_FORMAT
)
795 lpItem
->fmt
= phdi
->fmt
;
797 if (lpItem
->fmt
== 0)
798 lpItem
->fmt
= HDF_LEFT
;
800 if (phdi
->mask
& HDI_BITMAP
)
801 lpItem
->hbm
= phdi
->hbm
;
803 if (phdi
->mask
& HDI_LPARAM
)
804 lpItem
->lParam
= phdi
->lParam
;
806 if (phdi
->mask
& HDI_IMAGE
)
807 lpItem
->iImage
= phdi
->iImage
;
809 if (phdi
->mask
& HDI_ORDER
)
810 lpItem
->iOrder
= phdi
->iOrder
;
812 HEADER_SetItemBounds (hwnd
);
814 InvalidateRect(hwnd
, NULL
, FALSE
);
821 HEADER_InsertItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
823 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
824 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
825 INT nItem
= (INT
)wParam
;
829 if ((phdi
== NULL
) || (nItem
< 0))
832 if (nItem
> infoPtr
->uNumItem
)
833 nItem
= infoPtr
->uNumItem
;
835 if (infoPtr
->uNumItem
== 0) {
836 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
));
840 HEADER_ITEM
*oldItems
= infoPtr
->items
;
843 infoPtr
->items
= COMCTL32_Alloc (sizeof (HEADER_ITEM
) * infoPtr
->uNumItem
);
844 /* pre insert copy */
846 memcpy (&infoPtr
->items
[0], &oldItems
[0],
847 nItem
* sizeof(HEADER_ITEM
));
850 /* post insert copy */
851 if (nItem
< infoPtr
->uNumItem
- 1) {
852 memcpy (&infoPtr
->items
[nItem
+1], &oldItems
[nItem
],
853 (infoPtr
->uNumItem
- nItem
) * sizeof(HEADER_ITEM
));
856 COMCTL32_Free (oldItems
);
859 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
860 lpItem
->bDown
= FALSE
;
862 if (phdi
->mask
& HDI_WIDTH
)
863 lpItem
->cxy
= phdi
->cxy
;
865 if (phdi
->mask
& HDI_TEXT
) {
866 WCHAR wide_null_char
= 0;
867 if (!phdi
->pszText
) /* null pointer check */
868 phdi
->pszText
= &wide_null_char
;
869 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
870 len
= lstrlenW (phdi
->pszText
);
871 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
872 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
875 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
878 if (phdi
->mask
& HDI_FORMAT
)
879 lpItem
->fmt
= phdi
->fmt
;
881 if (lpItem
->fmt
== 0)
882 lpItem
->fmt
= HDF_LEFT
;
884 if (phdi
->mask
& HDI_BITMAP
)
885 lpItem
->hbm
= phdi
->hbm
;
887 if (phdi
->mask
& HDI_LPARAM
)
888 lpItem
->lParam
= phdi
->lParam
;
890 if (phdi
->mask
& HDI_IMAGE
)
891 lpItem
->iImage
= phdi
->iImage
;
893 if (phdi
->mask
& HDI_ORDER
)
894 lpItem
->iOrder
= phdi
->iOrder
;
896 HEADER_SetItemBounds (hwnd
);
898 InvalidateRect(hwnd
, NULL
, FALSE
);
905 HEADER_Layout (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
907 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
908 LPHDLAYOUT lpLayout
= (LPHDLAYOUT
)lParam
;
910 lpLayout
->pwpos
->hwnd
= hwnd
;
911 lpLayout
->pwpos
->hwndInsertAfter
= 0;
912 lpLayout
->pwpos
->x
= lpLayout
->prc
->left
;
913 lpLayout
->pwpos
->y
= lpLayout
->prc
->top
;
914 lpLayout
->pwpos
->cx
= lpLayout
->prc
->right
- lpLayout
->prc
->left
;
915 if (GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_HIDDEN
)
916 lpLayout
->pwpos
->cy
= 0;
918 lpLayout
->pwpos
->cy
= infoPtr
->nHeight
;
919 lpLayout
->prc
->top
+= infoPtr
->nHeight
;
921 lpLayout
->pwpos
->flags
= SWP_NOZORDER
;
923 TRACE("Layout x=%d y=%d cx=%d cy=%d\n",
924 lpLayout
->pwpos
->x
, lpLayout
->pwpos
->y
,
925 lpLayout
->pwpos
->cx
, lpLayout
->pwpos
->cy
);
927 infoPtr
->bRectsValid
= FALSE
;
934 HEADER_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
936 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
939 himlOld
= infoPtr
->himl
;
940 infoPtr
->himl
= (HIMAGELIST
)lParam
;
942 /* FIXME: Refresh needed??? */
944 return (LRESULT
)himlOld
;
949 HEADER_SetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
951 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
952 HDITEMA
*phdi
= (HDITEMA
*)lParam
;
953 INT nItem
= (INT
)wParam
;
958 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
961 TRACE("[nItem=%d]\n", nItem
);
963 if (HEADER_SendItemChange(hwnd
, nItem
, phdi
->mask
,HDN_ITEMCHANGINGA
))
966 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
967 if (phdi
->mask
& HDI_BITMAP
)
968 lpItem
->hbm
= phdi
->hbm
;
970 if (phdi
->mask
& HDI_FORMAT
)
971 lpItem
->fmt
= phdi
->fmt
;
973 if (phdi
->mask
& HDI_LPARAM
)
974 lpItem
->lParam
= phdi
->lParam
;
976 if (phdi
->mask
& HDI_TEXT
) {
977 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKA
) {
978 if (lpItem
->pszText
) {
979 COMCTL32_Free (lpItem
->pszText
);
980 lpItem
->pszText
= NULL
;
983 INT len
= lstrlenA (phdi
->pszText
);
984 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
985 lstrcpyAtoW (lpItem
->pszText
, phdi
->pszText
);
989 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
992 if (phdi
->mask
& HDI_WIDTH
)
993 lpItem
->cxy
= phdi
->cxy
;
995 if (phdi
->mask
& HDI_IMAGE
)
996 lpItem
->iImage
= phdi
->iImage
;
998 if (phdi
->mask
& HDI_ORDER
)
999 lpItem
->iOrder
= phdi
->iOrder
;
1001 HEADER_SendItemChange(hwnd
,nItem
,phdi
->mask
,HDN_ITEMCHANGEDA
);
1003 HEADER_SetItemBounds (hwnd
);
1005 InvalidateRect(hwnd
, NULL
, FALSE
);
1012 HEADER_SetItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1014 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1015 HDITEMW
*phdi
= (HDITEMW
*)lParam
;
1016 INT nItem
= (INT
)wParam
;
1017 HEADER_ITEM
*lpItem
;
1021 if ((nItem
< 0) || (nItem
>= (INT
)infoPtr
->uNumItem
))
1024 TRACE("[nItem=%d]\n", nItem
);
1026 if (HEADER_SendItemChange(hwnd
,nItem
,phdi
->mask
,HDN_ITEMCHANGINGW
))
1029 lpItem
= (HEADER_ITEM
*)&infoPtr
->items
[nItem
];
1030 if (phdi
->mask
& HDI_BITMAP
)
1031 lpItem
->hbm
= phdi
->hbm
;
1033 if (phdi
->mask
& HDI_FORMAT
)
1034 lpItem
->fmt
= phdi
->fmt
;
1036 if (phdi
->mask
& HDI_LPARAM
)
1037 lpItem
->lParam
= phdi
->lParam
;
1039 if (phdi
->mask
& HDI_TEXT
) {
1040 if (phdi
->pszText
!= LPSTR_TEXTCALLBACKW
) {
1041 if (lpItem
->pszText
) {
1042 COMCTL32_Free (lpItem
->pszText
);
1043 lpItem
->pszText
= NULL
;
1045 if (phdi
->pszText
) {
1046 INT len
= lstrlenW (phdi
->pszText
);
1047 lpItem
->pszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1048 lstrcpyW (lpItem
->pszText
, phdi
->pszText
);
1052 lpItem
->pszText
= LPSTR_TEXTCALLBACKW
;
1055 if (phdi
->mask
& HDI_WIDTH
)
1056 lpItem
->cxy
= phdi
->cxy
;
1058 if (phdi
->mask
& HDI_IMAGE
)
1059 lpItem
->iImage
= phdi
->iImage
;
1061 if (phdi
->mask
& HDI_ORDER
)
1062 lpItem
->iOrder
= phdi
->iOrder
;
1064 HEADER_SendItemChange(hwnd
, nItem
, phdi
->mask
,HDN_ITEMCHANGEDW
);
1066 HEADER_SetItemBounds (hwnd
);
1068 InvalidateRect(hwnd
, NULL
, FALSE
);
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
->bRectsValid
= FALSE
;
1105 infoPtr
->hcurArrow
= LoadCursorA (0, IDC_ARROWA
);
1106 infoPtr
->hcurDivider
= LoadCursorA (0, IDC_SIZEWEA
);
1107 infoPtr
->hcurDivopen
= LoadCursorA (0, IDC_SIZENSA
);
1108 infoPtr
->bPressed
= FALSE
;
1109 infoPtr
->bTracking
= FALSE
;
1110 infoPtr
->iMoveItem
= 0;
1112 infoPtr
->iHotItem
= -1;
1113 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
1116 hOldFont
= SelectObject (hdc
, GetStockObject (SYSTEM_FONT
));
1117 GetTextMetricsA (hdc
, &tm
);
1118 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1119 SelectObject (hdc
, hOldFont
);
1127 HEADER_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1129 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1130 HEADER_ITEM
*lpItem
;
1133 if (infoPtr
->items
) {
1134 lpItem
= (HEADER_ITEM
*)infoPtr
->items
;
1135 for (nItem
= 0; nItem
< infoPtr
->uNumItem
; nItem
++, lpItem
++) {
1136 if ((lpItem
->pszText
) && (lpItem
->pszText
!= LPSTR_TEXTCALLBACKW
))
1137 COMCTL32_Free (lpItem
->pszText
);
1139 COMCTL32_Free (infoPtr
->items
);
1143 ImageList_Destroy (infoPtr
->himl
);
1145 COMCTL32_Free (infoPtr
);
1146 SetWindowLongA (hwnd
, 0, 0);
1151 static inline LRESULT
1152 HEADER_GetFont (HWND hwnd
)
1154 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1156 return (LRESULT
)infoPtr
->hFont
;
1161 HEADER_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1167 pt
.x
= (INT
)LOWORD(lParam
);
1168 pt
.y
= (INT
)HIWORD(lParam
);
1169 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1171 if ((GetWindowLongA (hwnd
, GWL_STYLE
) & HDS_BUTTONS
) && (flags
== HHT_ONHEADER
))
1172 HEADER_SendHeaderNotify (hwnd
, HDN_ITEMDBLCLICKA
, nItem
);
1173 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
))
1174 HEADER_SendHeaderNotify (hwnd
, HDN_DIVIDERDBLCLICKA
, nItem
);
1181 HEADER_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1183 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1184 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1190 pt
.x
= (INT
)LOWORD(lParam
);
1191 pt
.y
= (INT
)HIWORD(lParam
);
1192 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1194 if ((dwStyle
& HDS_BUTTONS
) && (flags
== HHT_ONHEADER
)) {
1196 infoPtr
->bCaptured
= TRUE
;
1197 infoPtr
->bPressed
= TRUE
;
1198 infoPtr
->iMoveItem
= nItem
;
1200 infoPtr
->items
[nItem
].bDown
= TRUE
;
1202 /* Send WM_CUSTOMDRAW */
1204 HEADER_RefreshItem (hwnd
, hdc
, nItem
);
1205 ReleaseDC (hwnd
, hdc
);
1207 TRACE("Pressed item %d!\n", nItem
);
1209 else if ((flags
== HHT_ONDIVIDER
) || (flags
== HHT_ONDIVOPEN
)) {
1210 if (!(HEADER_SendHeaderNotify (hwnd
, HDN_BEGINTRACKA
, nItem
))) {
1212 infoPtr
->bCaptured
= TRUE
;
1213 infoPtr
->bTracking
= TRUE
;
1214 infoPtr
->iMoveItem
= nItem
;
1215 infoPtr
->nOldWidth
= infoPtr
->items
[nItem
].cxy
;
1216 infoPtr
->xTrackOffset
= infoPtr
->items
[nItem
].rect
.right
- pt
.x
;
1218 if (!(dwStyle
& HDS_FULLDRAG
)) {
1219 infoPtr
->xOldTrack
= infoPtr
->items
[nItem
].rect
.right
;
1221 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1222 ReleaseDC (hwnd
, hdc
);
1225 TRACE("Begin tracking item %d!\n", nItem
);
1234 HEADER_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1236 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1238 *DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1245 pt
.x
= (INT
)SLOWORD(lParam
);
1246 pt
.y
= (INT
)SHIWORD(lParam
);
1247 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1249 if (infoPtr
->bPressed
) {
1250 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
)) {
1251 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1253 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1254 ReleaseDC (hwnd
, hdc
);
1256 HEADER_SendClickNotify (hwnd
, HDN_ITEMCLICKA
, infoPtr
->iMoveItem
);
1258 TRACE("Released item %d!\n", infoPtr
->iMoveItem
);
1259 infoPtr
->bPressed
= FALSE
;
1261 else if (infoPtr
->bTracking
) {
1262 TRACE("End tracking item %d!\n", infoPtr
->iMoveItem
);
1263 infoPtr
->bTracking
= FALSE
;
1265 HEADER_SendHeaderNotify (hwnd
, HDN_ENDTRACKA
, infoPtr
->iMoveItem
);
1268 * we want to do this even for HDS_FULLDRAG because this is where
1269 * we send the HDN_ITEMCHANGING and HDN_ITEMCHANGED notifications
1271 * if (!(dwStyle & HDS_FULLDRAG)) {
1275 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1276 ReleaseDC (hwnd
, hdc
);
1277 if (HEADER_SendItemChange(hwnd
, infoPtr
->iMoveItem
,HDI_WIDTH
,
1279 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= infoPtr
->nOldWidth
;
1281 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1284 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1287 HEADER_SendItemChange(hwnd
,infoPtr
->iMoveItem
,HDI_WIDTH
,
1289 HEADER_SetItemBounds (hwnd
);
1290 InvalidateRect(hwnd
, NULL
, FALSE
);
1296 if (infoPtr
->bCaptured
) {
1297 infoPtr
->bCaptured
= FALSE
;
1299 HEADER_SendSimpleNotify (hwnd
, NM_RELEASEDCAPTURE
);
1307 HEADER_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1309 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1310 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1316 pt
.x
= (INT
)SLOWORD(lParam
);
1317 pt
.y
= (INT
)SHIWORD(lParam
);
1318 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1320 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1321 if (flags
& (HHT_ONHEADER
| HHT_ONDIVIDER
| HHT_ONDIVOPEN
))
1322 infoPtr
->iHotItem
= nItem
;
1324 infoPtr
->iHotItem
= -1;
1325 InvalidateRect(hwnd
, NULL
, FALSE
);
1328 if (infoPtr
->bCaptured
) {
1329 if (infoPtr
->bPressed
) {
1330 if ((nItem
== infoPtr
->iMoveItem
) && (flags
== HHT_ONHEADER
))
1331 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= TRUE
;
1333 infoPtr
->items
[infoPtr
->iMoveItem
].bDown
= FALSE
;
1335 HEADER_RefreshItem (hwnd
, hdc
, infoPtr
->iMoveItem
);
1336 ReleaseDC (hwnd
, hdc
);
1338 TRACE("Moving pressed item %d!\n", infoPtr
->iMoveItem
);
1340 else if (infoPtr
->bTracking
) {
1341 if (dwStyle
& HDS_FULLDRAG
) {
1343 * Investigation shows that the changing message occure only
1344 * after tracking is done
1346 *if (HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGINGA, infoPtr->iMoveItem))
1347 * infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1351 nWidth
= pt
.x
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
+ infoPtr
->xTrackOffset
;
1354 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
= nWidth
;
1356 * Invistigation shows that the item changed only occures
1357 * after the tracking is done
1359 * HEADER_SendItemChanged(FALSE,hwnd,infoPtr->iMoveItem,HDI_WIDTH);
1363 HEADER_SetItemBounds (hwnd
);
1364 InvalidateRect(hwnd
, NULL
, FALSE
);
1368 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1369 infoPtr
->xOldTrack
= pt
.x
+ infoPtr
->xTrackOffset
;
1370 if (infoPtr
->xOldTrack
< infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
)
1371 infoPtr
->xOldTrack
= infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1372 infoPtr
->items
[infoPtr
->iMoveItem
].cxy
=
1373 infoPtr
->xOldTrack
- infoPtr
->items
[infoPtr
->iMoveItem
].rect
.left
;
1374 HEADER_DrawTrackLine (hwnd
, hdc
, infoPtr
->xOldTrack
);
1375 ReleaseDC (hwnd
, hdc
);
1378 HEADER_SendHeaderNotify (hwnd
, HDN_TRACKA
, infoPtr
->iMoveItem
);
1379 TRACE("Tracking item %d!\n", infoPtr
->iMoveItem
);
1383 if ((dwStyle
& HDS_BUTTONS
) && (dwStyle
& HDS_HOTTRACK
)) {
1384 FIXME("hot track support!\n");
1392 HEADER_Paint (HWND hwnd
, WPARAM wParam
)
1397 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1398 HEADER_Refresh (hwnd
, hdc
);
1400 EndPaint (hwnd
, &ps
);
1406 HEADER_RButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1411 pt
.x
= LOWORD(lParam
);
1412 pt
.y
= HIWORD(lParam
);
1414 /* Send a Notify message */
1415 bRet
= HEADER_SendSimpleNotify (hwnd
, NM_RCLICK
);
1417 /* Change to screen coordinate for WM_CONTEXTMENU */
1418 ClientToScreen(hwnd
, &pt
);
1420 /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
1421 SendMessageA( hwnd
, WM_CONTEXTMENU
, (WPARAM
) hwnd
, MAKELPARAM(pt
.x
, pt
.y
));
1428 HEADER_SetCursor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1430 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1435 TRACE("code=0x%X id=0x%X\n", LOWORD(lParam
), HIWORD(lParam
));
1438 ScreenToClient (hwnd
, &pt
);
1440 HEADER_InternalHitTest (hwnd
, &pt
, &flags
, &nItem
);
1442 if (flags
== HHT_ONDIVIDER
)
1443 SetCursor (infoPtr
->hcurDivider
);
1444 else if (flags
== HHT_ONDIVOPEN
)
1445 SetCursor (infoPtr
->hcurDivopen
);
1447 SetCursor (infoPtr
->hcurArrow
);
1454 HEADER_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1456 HEADER_INFO
*infoPtr
= HEADER_GetInfoPtr (hwnd
);
1458 HFONT hFont
, hOldFont
;
1461 infoPtr
->hFont
= (HFONT
)wParam
;
1463 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
1466 hOldFont
= SelectObject (hdc
, hFont
);
1467 GetTextMetricsA (hdc
, &tm
);
1468 infoPtr
->nHeight
= tm
.tmHeight
+ VERT_BORDER
;
1469 SelectObject (hdc
, hOldFont
);
1472 infoPtr
->bRectsValid
= FALSE
;
1475 InvalidateRect(hwnd
, NULL
, FALSE
);
1482 static LRESULT WINAPI
1483 HEADER_WindowProc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1485 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd
, msg
, wParam
, lParam
);
1486 if (!HEADER_GetInfoPtr (hwnd
) && (msg
!= WM_CREATE
))
1487 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1489 case HDM_CREATEDRAGIMAGE
:
1490 return HEADER_CreateDragImage (hwnd
, wParam
);
1492 case HDM_DELETEITEM
:
1493 return HEADER_DeleteItem (hwnd
, wParam
);
1495 case HDM_GETIMAGELIST
:
1496 return HEADER_GetImageList (hwnd
);
1499 return HEADER_GetItemA (hwnd
, wParam
, lParam
);
1502 return HEADER_GetItemW (hwnd
, wParam
, lParam
);
1504 case HDM_GETITEMCOUNT
:
1505 return HEADER_GetItemCount (hwnd
);
1507 case HDM_GETITEMRECT
:
1508 return HEADER_GetItemRect (hwnd
, wParam
, lParam
);
1510 /* case HDM_GETORDERARRAY: */
1512 case HDM_GETUNICODEFORMAT
:
1513 return HEADER_GetUnicodeFormat (hwnd
);
1516 return HEADER_HitTest (hwnd
, wParam
, lParam
);
1518 case HDM_INSERTITEMA
:
1519 return HEADER_InsertItemA (hwnd
, wParam
, lParam
);
1521 case HDM_INSERTITEMW
:
1522 return HEADER_InsertItemW (hwnd
, wParam
, lParam
);
1525 return HEADER_Layout (hwnd
, wParam
, lParam
);
1527 case HDM_SETIMAGELIST
:
1528 return HEADER_SetImageList (hwnd
, wParam
, lParam
);
1531 return HEADER_SetItemA (hwnd
, wParam
, lParam
);
1534 return HEADER_SetItemW (hwnd
, wParam
, lParam
);
1536 /* case HDM_SETORDERARRAY: */
1538 case HDM_SETUNICODEFORMAT
:
1539 return HEADER_SetUnicodeFormat (hwnd
, wParam
);
1542 return HEADER_Create (hwnd
, wParam
, lParam
);
1545 return HEADER_Destroy (hwnd
, wParam
, lParam
);
1551 return DLGC_WANTTAB
| DLGC_WANTARROWS
;
1554 return HEADER_GetFont (hwnd
);
1556 case WM_LBUTTONDBLCLK
:
1557 return HEADER_LButtonDblClk (hwnd
, wParam
, lParam
);
1559 case WM_LBUTTONDOWN
:
1560 return HEADER_LButtonDown (hwnd
, wParam
, lParam
);
1563 return HEADER_LButtonUp (hwnd
, wParam
, lParam
);
1566 return HEADER_MouseMove (hwnd
, wParam
, lParam
);
1568 /* case WM_NOTIFYFORMAT: */
1571 return HEADER_Size (hwnd
, wParam
);
1574 return HEADER_Paint (hwnd
, wParam
);
1577 return HEADER_RButtonUp (hwnd
, wParam
, lParam
);
1580 return HEADER_SetCursor (hwnd
, wParam
, lParam
);
1583 return HEADER_SetFont (hwnd
, wParam
, lParam
);
1587 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
1588 msg
, wParam
, lParam
);
1589 return DefWindowProcA (hwnd
, msg
, wParam
, lParam
);
1596 HEADER_Register (void)
1600 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
1601 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
1602 wndClass
.lpfnWndProc
= (WNDPROC
)HEADER_WindowProc
;
1603 wndClass
.cbClsExtra
= 0;
1604 wndClass
.cbWndExtra
= sizeof(HEADER_INFO
*);
1605 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
1606 wndClass
.lpszClassName
= WC_HEADERA
;
1608 RegisterClassA (&wndClass
);
1613 HEADER_Unregister (void)
1615 UnregisterClassA (WC_HEADERA
, (HINSTANCE
)NULL
);