source: trunk/src/comctl32/header.c@ 1156

Last change on this file since 1156 was 1156, checked in by cbratschi, 26 years ago

* empty log message *

File size: 58.4 KB
Line 
1/* $Id: header.c,v 1.15 1999-10-06 15:41:10 cbratschi Exp $ */
2/*
3 * Header control
4 *
5 * Copyright 1998 Eric Kohl
6 * Copyright 1999 Achim Hasenmueller
7 * Copyright 1999 Christoph Bratschi
8 *
9 * TODO:
10 * - Order list support.
11 * - Control specific cursors (over dividers).
12 * - Custom draw support (including Notifications).
13 * - Drag and Drop support (including Notifications).
14 * - HDS_FILTERBAR
15 *
16 *
17 * Status: Development in progress, a lot to do :)
18 * Version: 5.00 (target)
19 */
20
21#include <string.h>
22
23#include "winbase.h"
24#include "commctrl.h"
25#include "header.h"
26#include "comctl32.h"
27
28
29#define VERT_BORDER 4
30#define DIVIDER_WIDTH 10
31#define MIN_ITEMWIDTH 0
32#define ITEM_FRAMESIZE 2
33#define TEXT_MARGIN 3
34#define TIMER_ID 1
35#define TIMER_MS 200
36
37#define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
38
39static VOID
40HEADER_DrawItemImage(HWND hwnd,HDC hdc,HEADER_INFO* infoPtr,HEADER_ITEM* phdi,RECT* r,INT iItem)
41{
42 if (phdi->fmt & HDF_IMAGE)
43 {
44 INT iImage;
45 IMAGEINFO info;
46 INT x,y,cx,cy,w,h,rx,ry;
47
48 if (phdi->iImage == I_IMAGECALLBACK)
49 {
50 if (IsWindowUnicode(GetParent(hwnd)))
51 {
52 NMHDDISPINFOW nmhdr;
53
54 nmhdr.hdr.hwndFrom = hwnd;
55 nmhdr.hdr.idFrom = GetWindowLongW(hwnd,GWL_ID);
56 nmhdr.hdr.code = HDN_GETDISPINFOW;
57 nmhdr.iItem = iItem;
58 nmhdr.mask = HDI_IMAGE;
59 nmhdr.iImage = 0;
60 nmhdr.lParam = phdi->lParam;
61
62 SendMessageW(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
63
64 iImage = nmhdr.iImage;
65 if (nmhdr.mask & HDI_DI_SETITEM) phdi->iImage = iImage;
66 } else
67 {
68 NMHDDISPINFOA nmhdr;
69
70 nmhdr.hdr.hwndFrom = hwnd;
71 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
72 nmhdr.hdr.code = HDN_GETDISPINFOA;
73 nmhdr.iItem = iItem;
74 nmhdr.mask = HDI_IMAGE;
75 nmhdr.iImage = 0;
76 nmhdr.lParam = phdi->lParam;
77
78 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
79
80 iImage = nmhdr.iImage;
81 if (nmhdr.mask & HDI_DI_SETITEM) phdi->iImage = iImage;
82 }
83 } else iImage = phdi->iImage;
84
85 if (!ImageList_GetImageInfo(infoPtr->himl,phdi->iImage,&info)) return;
86 w = info.rcImage.right-info.rcImage.left;
87 h = info.rcImage.bottom-info.rcImage.top;
88
89 ry = r->bottom-r->top;
90 rx = r->right-r->left;
91
92 if (ry >= h)
93 {
94 cy = h;
95 y = r->top+(ry-h)/2;
96 } else
97 {
98 cy = ry;
99 y = r->top;
100 }
101
102 if (rx >= w+infoPtr->xBmpMargin)
103 cx = w;
104 else
105 cx = MAX(0,rx-w-infoPtr->xBmpMargin);
106
107 if (ImageList_DrawEx(infoPtr->himl,phdi->iImage,hdc,x,y,cx,cy,CLR_NONE,CLR_NONE,ILD_TRANSPARENT))
108 {
109 r->left += w+2*infoPtr->xBmpMargin;
110 }
111 }
112}
113
114static VOID
115HEADER_DrawItemBitmap(HDC hdc,HEADER_INFO* infoPtr,HEADER_ITEM* phdi,RECT* r,WCHAR* pszText,UINT uTextJustify)
116{
117 if ((phdi->fmt & HDF_BITMAP) && !(phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm))
118 {
119 BITMAP bmp;
120 HDC hdcBitmap;
121 INT yD,yS,cx,cy,rx,ry;
122
123 GetObjectA (phdi->hbm,sizeof(BITMAP),(LPVOID)&bmp);
124
125 ry = r->bottom-r->top;
126 rx = r->right-r->left;
127
128 if (ry >= bmp.bmHeight)
129 {
130 cy = bmp.bmHeight;
131 yD = r->top + (ry - bmp.bmHeight) / 2;
132 yS = 0;
133 } else
134 {
135 cy = ry;
136 yD = r->top;
137 yS = (bmp.bmHeight - ry) / 2;
138 }
139
140 if (rx >= bmp.bmWidth+infoPtr->xBmpMargin)
141 cx = bmp.bmWidth;
142 else
143 cx = MAX(0,rx-bmp.bmWidth-infoPtr->xBmpMargin);
144
145 hdcBitmap = CreateCompatibleDC (hdc);
146 SelectObject(hdcBitmap,phdi->hbm);
147 BitBlt (hdc,r->left+infoPtr->xBmpMargin,yD,cx,cy,hdcBitmap,0,yS,SRCCOPY);
148 DeleteDC (hdcBitmap);
149
150 r->left += bmp.bmWidth+2*infoPtr->xBmpMargin;
151 } else if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm))
152 {
153 BITMAP bmp;
154 HDC hdcBitmap;
155 INT xD,yD,yS,cx,cy,rx,ry,tx;
156 RECT textRect;
157
158 GetObjectA (phdi->hbm,sizeof(BITMAP),(LPVOID)&bmp);
159
160 textRect = *r;
161 DrawTextExW(hdc,pszText,lstrlenW(pszText),&textRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT|DT_END_ELLIPSIS,NULL);
162 tx = textRect.right - textRect.left;
163 ry = r->bottom-r->top;
164 rx = r->right-r->left;
165
166 if (ry >= bmp.bmHeight)
167 {
168 cy = bmp.bmHeight;
169 yD = r->top + (ry - bmp.bmHeight) / 2;
170 yS = 0;
171 } else
172 {
173 cy = ry;
174 yD = r->top;
175 yS = (bmp.bmHeight - ry) / 2;
176 }
177
178 if (r->left+tx+bmp.bmWidth+2*infoPtr->xBmpMargin <= r->right)
179 {
180 cx = bmp.bmWidth;
181 if (uTextJustify & DT_LEFT)
182 xD = r->left+tx+infoPtr->xBmpMargin;
183 else
184 {
185 xD = r->right-infoPtr->xBmpMargin-bmp.bmWidth;
186 r->right = xD;
187 }
188 } else
189 {
190 if (rx >= bmp.bmWidth+2*infoPtr->xBmpMargin)
191 {
192 cx = bmp.bmWidth;
193 xD = r->right-bmp.bmWidth-infoPtr->xBmpMargin;
194 r->right = xD-infoPtr->xBmpMargin;
195 } else
196 {
197 cx = MAX(0,rx-infoPtr->xBmpMargin);
198 xD = r->left;
199 r->right = r->left;
200 }
201 }
202
203 hdcBitmap = CreateCompatibleDC(hdc);
204 SelectObject(hdcBitmap,phdi->hbm);
205 BitBlt(hdc,xD,yD,cx,cy,hdcBitmap,0,yS,SRCCOPY);
206 DeleteDC (hdcBitmap);
207 }
208}
209
210static VOID
211HEADER_DrawItemText(HDC hdc,HEADER_INFO* infoPtr,HEADER_ITEM* phdi,RECT* r,WCHAR* pszText,UINT uTextJustify,BOOL bEraseTextBkgnd,BOOL bHotTrack)
212{
213 if ((phdi->fmt & HDF_STRING) && (phdi->pszText))
214 {
215 INT oldBkMode = SetBkMode(hdc,TRANSPARENT);
216
217 if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) || !(phdi->fmt & HDF_IMAGE)) r->left += TEXT_MARGIN;
218 if (!(phdi->fmt & HDF_BITMAP_ON_RIGHT)) r->right -= TEXT_MARGIN;
219 if (r->left >= r->right) return;
220
221 SetTextColor (hdc,GetSysColor(bHotTrack ? COLOR_HOTLIGHT:COLOR_BTNTEXT));
222 if (bEraseTextBkgnd)
223 {
224 HBRUSH hbrBk = GetSysColorBrush(COLOR_3DFACE);
225
226 FillRect(hdc,r,hbrBk);
227 }
228
229 DrawTextExW(hdc,pszText,lstrlenW(pszText),r,uTextJustify|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS,NULL);
230 if (oldBkMode != TRANSPARENT) SetBkMode(hdc,oldBkMode);
231 }
232}
233
234static INT
235HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack,BOOL bEraseTextBkgnd)
236{
237 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
238 HEADER_ITEM *phdi = &infoPtr->items[iItem];
239 RECT r;
240
241 r = phdi->rect;
242 if (r.right - r.left == 0) return phdi->rect.right;
243
244 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS)
245 {
246 if (phdi->bDown)
247 {
248 DrawEdge (hdc,&r,BDR_RAISEDOUTER,BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
249 r.left += 2;
250 r.top += 2;
251 } else
252 DrawEdge(hdc,&r,EDGE_RAISED,BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
253 } else
254 DrawEdge(hdc,&r,EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
255
256 if (r.left >= r.right) return phdi->rect.right;
257
258 if (phdi->fmt & HDF_OWNERDRAW)
259 {
260 DRAWITEMSTRUCT dis;
261 dis.CtlType = ODT_HEADER;
262 dis.CtlID = GetWindowLongA (hwnd, GWL_ID);
263 dis.itemID = iItem;
264 dis.itemAction = ODA_DRAWENTIRE;
265 dis.itemState = phdi->bDown ? ODS_SELECTED : 0;
266 dis.hwndItem = hwnd;
267 dis.hDC = hdc;
268 dis.rcItem = r;
269 dis.itemData = phdi->lParam;
270 SendMessageA (GetParent(hwnd),WM_DRAWITEM,(WPARAM)dis.CtlID,(LPARAM)&dis);
271 } else
272 {
273 UINT uTextJustify;
274 WCHAR* pszText = phdi->pszText;
275
276 if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER)
277 uTextJustify = DT_CENTER;
278 else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
279 uTextJustify = DT_RIGHT;
280 else uTextJustify = DT_LEFT;
281
282 if (phdi->pszText == LPSTR_TEXTCALLBACKW)
283 {
284 if (IsWindowUnicode(GetParent(hwnd)))
285 {
286 NMHDDISPINFOW nmhdr;
287
288 nmhdr.hdr.hwndFrom = hwnd;
289 nmhdr.hdr.idFrom = GetWindowLongW(hwnd,GWL_ID);
290 nmhdr.hdr.code = HDN_GETDISPINFOW;
291 nmhdr.iItem = iItem;
292 nmhdr.mask = HDI_TEXT;
293 nmhdr.cchTextMax = phdi->cchTextMax;
294 nmhdr.pszText = COMCTL32_Alloc(phdi->cchTextMax*sizeof(WCHAR));
295 if (nmhdr.pszText) nmhdr.pszText[0] = 0;
296 nmhdr.lParam = phdi->lParam;
297
298 SendMessageW(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
299
300 pszText = nmhdr.pszText;
301 if (nmhdr.mask & HDI_DI_SETITEM)
302 {
303 INT len = pszText ? lstrlenW(pszText):0;
304
305 if (len)
306 {
307 phdi->pszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
308 lstrcpyW(phdi->pszText,pszText);
309 } else phdi->pszText = NULL;
310 COMCTL32_Free(pszText);
311 pszText = phdi->pszText;
312 }
313 } else
314 {
315 NMHDDISPINFOA nmhdr;
316 INT len;
317
318 nmhdr.hdr.hwndFrom = hwnd;
319 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
320 nmhdr.hdr.code = HDN_GETDISPINFOA;
321 nmhdr.iItem = iItem;
322 nmhdr.mask = HDI_TEXT;
323 nmhdr.cchTextMax = phdi->cchTextMax;
324 nmhdr.pszText = COMCTL32_Alloc(phdi->cchTextMax);
325 if (nmhdr.pszText) nmhdr.pszText[0] = 0;
326 nmhdr.lParam = phdi->lParam;
327
328 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
329
330 len = nmhdr.pszText ? lstrlenA(nmhdr.pszText):0;
331
332 if (len)
333 {
334 pszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
335 lstrcpyAtoW(pszText,nmhdr.pszText);
336 } else pszText = NULL;
337 COMCTL32_Free(nmhdr.pszText);
338
339 if (nmhdr.mask & HDI_DI_SETITEM)
340 phdi->pszText = pszText;
341 }
342 }
343
344 if (!(phdi->fmt & HDI_ORDER) || (phdi->iOrder & (HDF_LEFT | HDF_CENTER)))
345 {
346 HEADER_DrawItemImage(hwnd,hdc,infoPtr,phdi,&r,iItem);
347 if (r.left < r.right)
348 {
349 HEADER_DrawItemBitmap(hdc,infoPtr,phdi,&r,pszText,uTextJustify);
350 if (r.left < r.right)
351 HEADER_DrawItemText(hdc,infoPtr,phdi,&r,pszText,uTextJustify,bEraseTextBkgnd,bHotTrack);
352 }
353 } else
354 {
355 HEADER_DrawItemBitmap(hdc,infoPtr,phdi,&r,pszText,uTextJustify);
356 if (r.left < r.right)
357 {
358 HEADER_DrawItemImage(hwnd,hdc,infoPtr,phdi,&r,iItem);
359 if (r.left < r.right)
360 HEADER_DrawItemText(hdc,infoPtr,phdi,&r,pszText,uTextJustify,bEraseTextBkgnd,bHotTrack);
361 }
362 }
363 if (phdi->pszText == LPSTR_TEXTCALLBACKW) COMCTL32_Free(pszText);
364 }
365
366 return phdi->rect.right;
367}
368
369static void
370HEADER_DrawTrackLine (HWND hwnd, HDC hdc, INT x)
371{
372 RECT rect;
373 HPEN hOldPen;
374 INT oldRop;
375
376 GetClientRect (hwnd, &rect);
377
378 rect.left = x;
379 rect.right = x+1;
380 InvertRect(hdc,&rect);
381/* //CB: Odin bug!!! This code doesn't work:
382 hOldPen = SelectObject (hdc, GetStockObject (BLACK_PEN));
383 oldRop = SetROP2 (hdc, R2_XORPEN);
384 MoveToEx (hdc, x, rect.top, NULL);
385 LineTo (hdc, x, rect.bottom);
386 SetROP2 (hdc, oldRop);
387 SelectObject (hdc, hOldPen);
388*/
389}
390
391static void
392HEADER_Draw(HWND hwnd,HDC hdc)
393{
394 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
395 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
396 HFONT hFont, hOldFont;
397 RECT rect;
398 HBRUSH hbrBk;
399 INT i, x;
400
401 /* get rect for the bar, adjusted for the border */
402 GetClientRect (hwnd, &rect);
403
404 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
405 hOldFont = SelectObject (hdc, hFont);
406
407 /* draw Background */
408 hbrBk = GetSysColorBrush(COLOR_3DFACE);
409 FillRect(hdc, &rect, hbrBk);
410
411 x = rect.left;
412 for (i = 0; i < infoPtr->uNumItem; i++)
413 {
414 x = HEADER_DrawItem(hwnd,hdc,i,infoPtr->iHotItem == i,FALSE);
415 if (x > rect.right)
416 {
417 x = -1;
418 break;
419 }
420 }
421
422 if (x != -1 && (x <= rect.right) && (infoPtr->uNumItem > 0))
423 {
424 rect.left = x;
425 if (dwStyle & HDS_BUTTONS)
426 DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
427 else
428 DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
429 }
430
431 SelectObject (hdc, hOldFont);
432
433 if (infoPtr->bCaptured && infoPtr->bTracking && !(dwStyle & HDS_FULLDRAG)) HEADER_DrawTrackLine(hwnd,hdc,infoPtr->xOldTrack);
434}
435
436
437static void
438HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem)
439{
440 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
441 HFONT hFont, hOldFont;
442
443 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
444 hOldFont = SelectObject (hdc, hFont);
445 HEADER_DrawItem(hwnd,hdc,iItem,infoPtr->iHotItem == iItem,TRUE);
446 SelectObject (hdc, hOldFont);
447}
448
449static void
450HEADER_Refresh(HWND hwnd)
451{
452 HDC hdc,hdcCompatible;
453 HBITMAP bitmap,oldbmp;
454 RECT rect;
455
456 GetClientRect(hwnd,&rect);
457 hdc = GetDC(hwnd);
458 hdcCompatible = CreateCompatibleDC(hdc);
459 bitmap = CreateCompatibleBitmap(hdc,rect.right,rect.bottom);
460 oldbmp = SelectObject(hdcCompatible,bitmap);
461 HEADER_Draw(hwnd,hdcCompatible);
462 BitBlt(hdc,0,0,rect.right,rect.bottom,hdcCompatible,0,0,SRCCOPY);
463 SelectObject(hdcCompatible,oldbmp);
464 DeleteObject(bitmap);
465 DeleteDC(hdcCompatible);
466 ReleaseDC(hwnd,hdc);
467}
468
469static void
470HEADER_SetItemBounds(HWND hwnd,INT start)
471{
472 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
473 HEADER_ITEM *phdi;
474 RECT rect;
475 int i, x;
476
477 if (infoPtr->uNumItem == 0) return;
478
479 GetClientRect(hwnd,&rect);
480
481 x = (start > 0) ? infoPtr->items[start-1].rect.right:rect.left;
482 for (i = start;i < infoPtr->uNumItem;i++)
483 {
484 phdi = &infoPtr->items[i];
485 phdi->rect.top = rect.top;
486 phdi->rect.bottom = rect.bottom;
487 phdi->rect.left = x;
488 phdi->rect.right = phdi->rect.left + phdi->cxy;
489 x = phdi->rect.right;
490 }
491}
492
493static void
494HEADER_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pItem)
495{
496 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
497 RECT rect, rcTest;
498 INT iCount, width,widthCount = 0;
499 BOOL bNoWidth;
500
501 GetClientRect (hwnd, &rect);
502
503 *pFlags = 0;
504 bNoWidth = FALSE;
505 if (PtInRect(&rect,*lpPt))
506 {
507 if (infoPtr->uNumItem == 0)
508 {
509 *pFlags |= HHT_NOWHERE;
510 *pItem = 1;
511// TRACE (header, "NOWHERE\n");
512 return;
513 } else
514 {
515 /* somewhere inside */
516 for (iCount = 0; iCount < infoPtr->uNumItem; iCount++)
517 {
518 rect = infoPtr->items[iCount].rect;
519 width = rect.right - rect.left;
520 if (width == 0)
521 {
522 bNoWidth = TRUE;
523 widthCount = 0;
524 continue;
525 } else widthCount++;
526 if (widthCount > 1) bNoWidth = FALSE;
527 if (PtInRect(&rect,*lpPt))
528 {
529 if (width <= 2 * DIVIDER_WIDTH)
530 {
531 *pFlags |= HHT_ONHEADER;
532 *pItem = iCount;
533// TRACE (header, "ON HEADER %d\n", iCount);
534 return;
535 }
536 if (iCount > 0)
537 {
538 rcTest = rect;
539 rcTest.right = rcTest.left + DIVIDER_WIDTH;
540 if (PtInRect (&rcTest, *lpPt))
541 {
542 if (bNoWidth)
543 {
544 *pFlags |= HHT_ONDIVOPEN;
545 *pItem = iCount - 1;
546// TRACE (header, "ON DIVOPEN %d\n", *pItem);
547 return;
548 } else
549 {
550 *pFlags |= HHT_ONDIVIDER;
551 *pItem = iCount - 1;
552// TRACE (header, "ON DIVIDER %d\n", *pItem);
553 return;
554 }
555 }
556 }
557 rcTest = rect;
558 rcTest.left = rcTest.right - DIVIDER_WIDTH;
559 if (PtInRect (&rcTest, *lpPt))
560 {
561 *pFlags |= HHT_ONDIVIDER;
562 *pItem = iCount;
563// TRACE (header, "ON DIVIDER %d\n", *pItem);
564 return;
565 }
566
567 *pFlags |= HHT_ONHEADER;
568 *pItem = iCount;
569// TRACE (header, "ON HEADER %d\n", iCount);
570 return;
571 }
572 }
573
574 /* check for last divider part (on nowhere) */
575 rect = infoPtr->items[infoPtr->uNumItem-1].rect;
576 rect.left = rect.right;
577 rect.right += DIVIDER_WIDTH;
578 if (widthCount > 0) bNoWidth = FALSE;
579 if (PtInRect (&rect, *lpPt))
580 {
581 if (bNoWidth)
582 {
583 *pFlags |= HHT_ONDIVOPEN;
584 *pItem = infoPtr->uNumItem - 1;
585// TRACE (header, "ON DIVOPEN %d\n", *pItem);
586 return;
587 } else
588 {
589 *pFlags |= HHT_ONDIVIDER;
590 *pItem = infoPtr->uNumItem-1;
591// TRACE (header, "ON DIVIDER %d\n", *pItem);
592 return;
593 }
594 }
595
596 *pFlags |= HHT_NOWHERE;
597 *pItem = 1;
598// TRACE (header, "NOWHERE\n");
599 return;
600 }
601 } else
602 {
603 if (lpPt->x < rect.left)
604 {
605// TRACE (header, "TO LEFT\n");
606 *pFlags |= HHT_TOLEFT;
607 } else if (lpPt->x > rect.right)
608 {
609// TRACE (header, "TO LEFT\n");
610 *pFlags |= HHT_TORIGHT;
611 }
612
613 if (lpPt->y < rect.top)
614 {
615// TRACE (header, "ABOVE\n");
616 *pFlags |= HHT_ABOVE;
617 } else if (lpPt->y > rect.bottom)
618 {
619// TRACE (header, "BELOW\n");
620 *pFlags |= HHT_BELOW;
621 }
622 }
623
624 *pItem = 1;
625// TRACE (header, "flags=0x%X\n", *pFlags);
626 return;
627}
628
629static BOOL
630HEADER_SendSimpleNotify (HWND hwnd, UINT code)
631{
632 NMHDR nmhdr;
633
634 nmhdr.hwndFrom = hwnd;
635 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
636 nmhdr.code = code;
637
638 return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
639 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
640}
641
642static BOOL
643HEADER_SendHeaderNotifyA(HWND hwnd,UINT code,INT iItem,INT iButton)
644{
645 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
646 NMHEADERA nmhdr;
647 HDITEMA nmitem;
648 char* text;
649 BOOL res;
650
651 if (infoPtr->items[iItem].pszText)
652 {
653 INT len = lstrlenW(infoPtr->items[iItem].pszText);
654
655 if (len > 0)
656 {
657 text = COMCTL32_Alloc(len+1);
658 lstrcpyWtoA(text,infoPtr->items[iItem].pszText);
659 } else text = NULL;
660 } else text = NULL;
661
662 nmhdr.hdr.hwndFrom = hwnd;
663 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
664 nmhdr.hdr.code = code;
665 nmhdr.iItem = iItem;
666 nmhdr.iButton = 0;
667 nmhdr.pitem = &nmitem;
668
669 nmitem.mask = 0;
670 nmitem.cxy = infoPtr->items[iItem].cxy;
671 nmitem.hbm = infoPtr->items[iItem].hbm;
672 nmitem.pszText = text;
673 nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax;
674 nmitem.fmt = infoPtr->items[iItem].fmt;
675 nmitem.lParam = infoPtr->items[iItem].lParam;
676 nmitem.iImage = infoPtr->items[iItem].iImage;
677 nmitem.iOrder = infoPtr->items[iItem].iOrder;
678 nmitem.type = infoPtr->items[iItem].type;
679 nmitem.pvFilter = infoPtr->items[iItem].pvFilter;
680
681 res = (BOOL)SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
682
683 if (text) COMCTL32_Free(text);
684
685 return res;
686}
687
688static BOOL
689HEADER_SendHeaderNotifyW(HWND hwnd,UINT code,INT iItem,INT iButton)
690{
691 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
692 NMHEADERW nmhdr;
693 HDITEMW nmitem;
694
695 nmhdr.hdr.hwndFrom = hwnd;
696 nmhdr.hdr.idFrom = GetWindowLongW(hwnd,GWL_ID);
697 nmhdr.hdr.code = code;
698 nmhdr.iItem = iItem;
699 nmhdr.iButton = 0;
700 nmhdr.pitem = &nmitem;
701
702 nmitem.mask = 0;
703 nmitem.cxy = infoPtr->items[iItem].cxy;
704 nmitem.hbm = infoPtr->items[iItem].hbm;
705 nmitem.pszText = infoPtr->items[iItem].pszText;
706 nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax;
707 nmitem.fmt = infoPtr->items[iItem].fmt;
708 nmitem.lParam = infoPtr->items[iItem].lParam;
709 nmitem.iImage = infoPtr->items[iItem].iImage;
710 nmitem.iOrder = infoPtr->items[iItem].iOrder;
711 nmitem.type = infoPtr->items[iItem].type;
712 nmitem.pvFilter = infoPtr->items[iItem].pvFilter;
713
714 return (BOOL)SendMessageW(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
715}
716
717static BOOL
718HEADER_SendItemChanging(HWND hwnd,INT iItem)
719{
720 if (IsWindowUnicode(GetParent(hwnd)))
721 return HEADER_SendHeaderNotifyA(hwnd,HDN_ITEMCHANGINGA,iItem,0);
722 else
723 return HEADER_SendHeaderNotifyW(hwnd,HDN_ITEMCHANGINGW,iItem,0);
724}
725
726static BOOL
727HEADER_SendItemChanged(HWND hwnd,INT iItem)
728{
729 if (IsWindowUnicode(GetParent(hwnd)))
730 return HEADER_SendHeaderNotifyA(hwnd,HDN_ITEMCHANGEDA,iItem,0);
731 else
732 return HEADER_SendHeaderNotifyW(hwnd,HDN_ITEMCHANGEDW,iItem,0);
733}
734
735static BOOL
736HEADER_SendItemDblClick(HWND hwnd,INT iItem,INT iButton)
737{
738 if (IsWindowUnicode(GetParent(hwnd)))
739 return HEADER_SendHeaderNotifyA(hwnd,HDN_ITEMDBLCLICKA,iItem,iButton);
740 else
741 return HEADER_SendHeaderNotifyW(hwnd,HDN_ITEMDBLCLICKW,iItem,iButton);
742}
743
744static BOOL
745HEADER_SendDividerDblClick(HWND hwnd,INT iItem,INT iButton)
746{
747 if (IsWindowUnicode(GetParent(hwnd)))
748 return HEADER_SendHeaderNotifyA(hwnd,HDN_DIVIDERDBLCLICKA,iItem,iButton);
749 else
750 return HEADER_SendHeaderNotifyW(hwnd,HDN_DIVIDERDBLCLICKW,iItem,iButton);
751}
752
753static BOOL
754HEADER_SendBeginTrack(HWND hwnd,INT iItem,INT iButton)
755{
756 if (IsWindowUnicode(GetParent(hwnd)))
757 return HEADER_SendHeaderNotifyA(hwnd,HDN_BEGINTRACKA,iItem,iButton);
758 else
759 return HEADER_SendHeaderNotifyW(hwnd,HDN_BEGINTRACKW,iItem,iButton);
760}
761
762static BOOL
763HEADER_SendEndTrack(HWND hwnd,INT iItem,INT iButton)
764{
765 if (IsWindowUnicode(GetParent(hwnd)))
766 return HEADER_SendHeaderNotifyA(hwnd,HDN_ENDTRACKA,iItem,iButton);
767 else
768 return HEADER_SendHeaderNotifyW(hwnd,HDN_ENDTRACKW,iItem,iButton);
769}
770
771static BOOL
772HEADER_SendTrack(HWND hwnd,INT iItem)
773{
774 if (IsWindowUnicode(GetParent(hwnd)))
775 return HEADER_SendHeaderNotifyA(hwnd,HDN_TRACKA,iItem,0);
776 else
777 return HEADER_SendHeaderNotifyW(hwnd,HDN_TRACKW,iItem,0);
778}
779
780static BOOL
781HEADER_SendClickNotifyA(HWND hwnd,UINT code,INT iItem,INT iButton)
782{
783 NMHEADERA nmhdr;
784
785 nmhdr.hdr.hwndFrom = hwnd;
786 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
787 nmhdr.hdr.code = code;
788 nmhdr.iItem = iItem;
789 nmhdr.iButton = iButton;
790 nmhdr.pitem = NULL;
791
792 return (BOOL)SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
793}
794
795static BOOL
796HEADER_SendClickNotifyW(HWND hwnd,UINT code,INT iItem,INT iButton)
797{
798 NMHEADERW nmhdr;
799
800 nmhdr.hdr.hwndFrom = hwnd;
801 nmhdr.hdr.idFrom = GetWindowLongW(hwnd,GWL_ID);
802 nmhdr.hdr.code = code;
803 nmhdr.iItem = iItem;
804 nmhdr.iButton = iButton;
805 nmhdr.pitem = NULL;
806
807 return (BOOL)SendMessageW(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
808}
809
810static BOOL
811HEADER_SendItemClick(HWND hwnd,INT iItem,INT iButton)
812{
813 if (IsWindowUnicode(GetParent(hwnd)))
814 return HEADER_SendClickNotifyA(hwnd,HDN_ITEMCLICKA,iItem,iButton);
815 else
816 return HEADER_SendClickNotifyW(hwnd,HDN_ITEMCLICKW,iItem,iButton);
817}
818
819static BOOL
820HEADER_SendDragNotify(HWND hwnd,UINT code,INT iItem,INT iButton)
821{
822 NMHEADERA nmhdr;
823
824 nmhdr.hdr.hwndFrom = hwnd;
825 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
826 nmhdr.hdr.code = code;
827 nmhdr.iItem = iItem;
828 nmhdr.iButton = iButton;
829 nmhdr.pitem = NULL;
830
831 return (BOOL)SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
832}
833
834static BOOL
835HEADER_SendFilterBtnClick(HWND hwnd,INT iItem,RECT iRect)
836{
837 NMHDFILTERBTNCLICK nmhdr;
838
839 nmhdr.hdr.hwndFrom = hwnd;
840 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
841 nmhdr.hdr.code = HDN_FILTERBTNCLICK;
842 nmhdr.iItem = iItem;
843 nmhdr.rc = iRect;
844
845 return (BOOL)SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
846}
847
848static BOOL
849HEADER_SendFilterChange(HWND hwnd,INT iItem)
850{
851 NMHEADERA nmhdr;
852
853 nmhdr.hdr.hwndFrom = hwnd;
854 nmhdr.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
855 nmhdr.hdr.code = HDN_FILTERCHANGE;
856 nmhdr.iItem = iItem;
857 nmhdr.iButton = 0;
858 nmhdr.pitem = NULL;
859
860 return (BOOL)SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.hdr.idFrom,(LPARAM)&nmhdr);
861}
862
863static LRESULT
864HEADER_ClearFilter(HWND hwnd,WPARAM wParam,LPARAM lParam)
865{
866 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
867
868 //CB:todo
869 //HDN_FILTERCHANGE
870
871 return 0;
872}
873
874static LRESULT
875HEADER_EditFilter(HWND hwnd,WPARAM wParam,LPARAM lParam)
876{
877 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
878 INT iItem = (INT)wParam;
879
880 if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem)) return 0;
881
882 //CB: todo
883
884 return iItem;
885}
886
887static LRESULT
888HEADER_SetFilterChangeTimeout(HWND hwnd,WPARAM wParam,LPARAM lParam)
889{
890 //CB: todo
891
892 return 0;
893}
894
895static LRESULT
896HEADER_CreateDragImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
897{
898 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
899 INT iItem = (INT)wParam;
900 HEADER_ITEM *phdi;
901 HICON hicon;
902 HIMAGELIST himl;
903
904 if (!infoPtr->himl || (iItem < 0) || (iItem >= (INT)infoPtr->uNumItem)) return 0;
905 phdi = &infoPtr->items[iItem];
906/*
907 hicon = ImageList_GetIcon(infoPtr->himl,phdi->iImage,ILD_BLEND | ILD_TRANSPARENT);
908 if (!hicon) return 0;
909
910 himl = ImageList_Create();
911*/
912 //CB: create and return new imagelist
913
914 return 0;
915}
916
917static LRESULT
918HEADER_SetHotDivider(HWND hwnd,WPARAM wParam,LPARAM lParam)
919{
920 //CB:todo
921
922 return 0;
923}
924
925static LRESULT
926HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
927{
928 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
929 INT iItem = (INT)wParam;
930 HDC hdc;
931
932// TRACE(header, "[iItem=%d]\n", iItem);
933
934 if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem)) return FALSE;
935
936 if (infoPtr->uNumItem == 1)
937 {
938 //clear
939 if (infoPtr->items[0].pszText) COMCTL32_Free(infoPtr->items[0].pszText);
940 COMCTL32_Free (infoPtr->items);
941 infoPtr->items = 0;
942 infoPtr->uNumItem = 0;
943
944 InvalidateRect(hwnd,NULL,FALSE);
945 } else
946 {
947 HEADER_ITEM *oldItems = infoPtr->items;
948// TRACE(header, "Complex delete! [iItem=%d]\n", iItem);
949
950 if (infoPtr->items[iItem].pszText) COMCTL32_Free(infoPtr->items[iItem].pszText);
951
952 infoPtr->uNumItem--;
953 infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
954 /* pre delete copy */
955 if (iItem > 0)
956 memcpy (&infoPtr->items[0], &oldItems[0],iItem*sizeof(HEADER_ITEM));
957
958 /* post delete copy */
959 if (iItem < infoPtr->uNumItem)
960 memcpy (&infoPtr->items[iItem],&oldItems[iItem+1],(infoPtr->uNumItem-iItem)*sizeof(HEADER_ITEM));
961
962 COMCTL32_Free(oldItems);
963
964 if (iItem < infoPtr->uNumItem) HEADER_SetItemBounds(hwnd,iItem);
965
966 HEADER_Refresh(hwnd);
967
968 }
969
970 return TRUE;
971}
972
973static LRESULT
974HEADER_GetBitmapMargin(HWND hwnd,WPARAM wParam,LPARAM lParam)
975{
976 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
977
978 return infoPtr->xBmpMargin;
979}
980
981static LRESULT
982HEADER_SetBitmapMargin(HWND hwnd,WPARAM wParam,LPARAM lParam)
983{
984 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
985 INT oldMargin = infoPtr->xBmpMargin;
986
987 if (infoPtr->xBmpMargin != (INT)wParam)
988 {
989 infoPtr->xBmpMargin = (INT)wParam;
990 HEADER_Refresh(hwnd);
991 }
992
993 return oldMargin;
994}
995
996static LRESULT
997HEADER_GetImageList (HWND hwnd)
998{
999 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1000
1001 return (LRESULT)infoPtr->himl;
1002}
1003
1004
1005static LRESULT
1006HEADER_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1007{
1008 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1009 HDITEMA *phdi = (HDITEMA*)lParam;
1010 INT nItem = (INT)wParam;
1011 HEADER_ITEM *lpItem;
1012
1013 if (!phdi) return FALSE;
1014 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem)) return FALSE;
1015
1016// TRACE (header, "[nItem=%d]\n", nItem);
1017
1018 if (phdi->mask == 0) return TRUE;
1019
1020 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1021
1022 if (phdi->mask & HDI_BITMAP) phdi->hbm = lpItem->hbm;
1023
1024 if (phdi->mask & HDI_FORMAT) phdi->fmt = lpItem->fmt;
1025
1026 if (phdi->mask & HDI_FILTER)
1027 {
1028 phdi->type = lpItem->type;
1029 phdi->pvFilter = lpItem->pvFilter;
1030 }
1031
1032 if (phdi->mask & (HDI_WIDTH | HDI_HEIGHT)) phdi->cxy = lpItem->cxy;
1033
1034 if (phdi->mask & HDI_IMAGE) phdi->iImage = lpItem->iImage;
1035
1036 if (phdi->mask & HDI_LPARAM) phdi->lParam = lpItem->lParam;
1037
1038 if (phdi->mask & HDI_ORDER) phdi->iOrder = lpItem->iOrder;
1039
1040 if (phdi->mask & HDI_TEXT)
1041 {
1042 if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
1043 {
1044 if (lpItem->pszText)
1045 lstrcpynWtoA (phdi->pszText,lpItem->pszText,phdi->cchTextMax);
1046 else
1047 phdi->pszText = NULL;
1048 } else phdi->pszText = LPSTR_TEXTCALLBACKA;
1049 }
1050
1051 return TRUE;
1052}
1053
1054static LRESULT
1055HEADER_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1056{
1057 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1058 HDITEMW *phdi = (HDITEMW*)lParam;
1059 INT nItem = (INT)wParam;
1060 HEADER_ITEM *lpItem;
1061
1062 if (!phdi) return FALSE;
1063 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem)) return FALSE;
1064
1065// TRACE (header, "[nItem=%d]\n", nItem);
1066
1067 if (phdi->mask == 0) return TRUE;
1068
1069 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1070
1071 if (phdi->mask & HDI_BITMAP) phdi->hbm = lpItem->hbm;
1072
1073 if (phdi->mask & HDI_FORMAT) phdi->fmt = lpItem->fmt;
1074
1075 if (phdi->mask & HDI_FILTER)
1076 {
1077 phdi->type = lpItem->type;
1078 phdi->pvFilter = lpItem->pvFilter;
1079 }
1080
1081 if (phdi->mask & (HDI_WIDTH | HDI_HEIGHT)) phdi->cxy = lpItem->cxy;
1082
1083 if (phdi->mask & HDI_IMAGE) phdi->iImage = lpItem->iImage;
1084
1085 if (phdi->mask & HDI_LPARAM) phdi->lParam = lpItem->lParam;
1086
1087 if (phdi->mask & HDI_ORDER) phdi->iOrder = lpItem->iOrder;
1088
1089 if (phdi->mask & HDI_TEXT)
1090 {
1091 if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
1092 {
1093 if (lpItem->pszText)
1094 lstrcpynW (phdi->pszText,lpItem->pszText,phdi->cchTextMax);
1095 else
1096 phdi->pszText = NULL;
1097 } else phdi->pszText = LPSTR_TEXTCALLBACKW;
1098 }
1099
1100 return TRUE;
1101}
1102
1103
1104static LRESULT
1105HEADER_GetItemCount (HWND hwnd)
1106{
1107 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1108
1109 return infoPtr->uNumItem;
1110}
1111
1112
1113static LRESULT
1114HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1115{
1116 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1117 INT iItem = (INT)wParam;
1118 LPRECT lpRect = (LPRECT)lParam;
1119
1120 if (!lpRect || (iItem < 0) || (iItem >= (INT)infoPtr->uNumItem)) return FALSE;
1121
1122 lpRect->left = infoPtr->items[iItem].rect.left;
1123 lpRect->right = infoPtr->items[iItem].rect.right;
1124 lpRect->top = infoPtr->items[iItem].rect.top;
1125 lpRect->bottom = infoPtr->items[iItem].rect.bottom;
1126
1127 return TRUE;
1128}
1129
1130static LRESULT
1131HEADER_GetOrderArray(HWND hwnd,WPARAM wParam,LPARAM lParam)
1132{
1133 //CB: todo
1134
1135 return 0;
1136}
1137
1138static LRESULT
1139HEADER_SetOrderArray(HWND hwnd,WPARAM wParam,LPARAM lParam)
1140{
1141 //CB: todo
1142 HEADER_SetItemBounds(hwnd,0);
1143 HEADER_Refresh(hwnd);
1144
1145 return 0;
1146}
1147
1148static LRESULT
1149HEADER_OrderToIndex(HWND hwnd,WPARAM wParam,LPARAM lParam)
1150{
1151 //CB:todo
1152
1153 return 0;
1154}
1155
1156static LRESULT
1157HEADER_GetUnicodeFormat (HWND hwnd)
1158{
1159 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1160
1161 return infoPtr->bUnicode;
1162}
1163
1164
1165static LRESULT
1166HEADER_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1167{
1168 LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;
1169
1170 HEADER_InternalHitTest (hwnd, &phti->pt, &phti->flags, &phti->iItem);
1171
1172 return phti->iItem;
1173}
1174
1175
1176static LRESULT
1177HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1178{
1179 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1180 HDITEMA *phdi = (HDITEMA*)lParam;
1181 INT nItem = (INT)wParam;
1182 HEADER_ITEM *lpItem;
1183
1184 if ((phdi == NULL) || (nItem < 0)) return -1;
1185
1186 if (nItem > infoPtr->uNumItem) nItem = infoPtr->uNumItem;
1187
1188 if (infoPtr->uNumItem == 0)
1189 {
1190 infoPtr->items = COMCTL32_Alloc(sizeof(HEADER_ITEM));
1191 infoPtr->uNumItem++;
1192 } else
1193 {
1194 HEADER_ITEM *oldItems = infoPtr->items;
1195
1196 infoPtr->uNumItem++;
1197 infoPtr->items = COMCTL32_Alloc(sizeof(HEADER_ITEM)*infoPtr->uNumItem);
1198 if (nItem == 0)
1199 memcpy (&infoPtr->items[1],&oldItems[0],(infoPtr->uNumItem-1)*sizeof(HEADER_ITEM));
1200 else
1201 {
1202 /* pre insert copy */
1203 memcpy (&infoPtr->items[0],&oldItems[0],nItem*sizeof(HEADER_ITEM));
1204
1205 /* post insert copy */
1206 if (nItem < infoPtr->uNumItem-1)
1207 memcpy (&infoPtr->items[nItem+1],&oldItems[nItem],(infoPtr->uNumItem - nItem)*sizeof(HEADER_ITEM));
1208 }
1209
1210 COMCTL32_Free (oldItems);
1211 }
1212
1213 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1214 lpItem->bDown = FALSE;
1215
1216 lpItem->cxy = (phdi->mask & HDI_WIDTH || phdi->mask & HDI_HEIGHT) ? phdi->cxy:0;
1217
1218 if (phdi->mask & HDI_TEXT)
1219 {
1220 if (!phdi->pszText) lpItem->pszText = NULL;
1221 else if (phdi->pszText != LPSTR_TEXTCALLBACKA)
1222 {
1223 INT len;
1224
1225 len = lstrlenA(phdi->pszText);
1226 if (len == 0) lpItem->pszText = NULL; else
1227 {
1228 lpItem->pszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
1229 lstrcpyAtoW(lpItem->pszText,phdi->pszText);
1230 }
1231 } else lpItem->pszText = LPSTR_TEXTCALLBACKW;
1232 lpItem->cchTextMax = phdi->cchTextMax;
1233 } else
1234 {
1235 lpItem->pszText = NULL;
1236 lpItem->cchTextMax = 0;
1237 }
1238
1239 lpItem->fmt = (phdi->mask & HDI_FORMAT) ? phdi->fmt:HDF_LEFT;
1240 if (lpItem->fmt == 0) lpItem->fmt = HDF_LEFT;
1241
1242 lpItem->lParam = (phdi->mask & HDI_LPARAM) ? phdi->lParam:0;
1243
1244 lpItem->iImage = (phdi->mask & HDI_IMAGE) ? phdi->iImage:0;
1245
1246 lpItem->iOrder = (phdi->mask & HDI_ORDER) ? phdi->iOrder:HDF_LEFT;
1247
1248 lpItem->hbm = (phdi->mask & HDI_BITMAP) ? phdi->hbm:0;
1249
1250 if (phdi->mask & HDI_FILTER)
1251 {
1252 lpItem->type = phdi->type;
1253 lpItem->pvFilter = phdi->pvFilter;
1254 }
1255
1256 HEADER_SetItemBounds (hwnd,nItem);
1257 HEADER_Refresh(hwnd);
1258
1259 return nItem;
1260}
1261
1262static LRESULT
1263HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1264{
1265 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1266 HDITEMW *phdi = (HDITEMW*)lParam;
1267 INT nItem = (INT)wParam;
1268 HEADER_ITEM *lpItem;
1269
1270 if ((phdi == NULL) || (nItem < 0)) return -1;
1271
1272 if (nItem > infoPtr->uNumItem) nItem = infoPtr->uNumItem;
1273
1274 if (infoPtr->uNumItem == 0)
1275 {
1276 infoPtr->items = COMCTL32_Alloc(sizeof(HEADER_ITEM));
1277 infoPtr->uNumItem++;
1278 } else
1279 {
1280 HEADER_ITEM *oldItems = infoPtr->items;
1281
1282 infoPtr->uNumItem++;
1283 infoPtr->items = COMCTL32_Alloc(sizeof(HEADER_ITEM)*infoPtr->uNumItem);
1284 if (nItem == 0)
1285 memcpy (&infoPtr->items[1],&oldItems[0],(infoPtr->uNumItem-1)*sizeof(HEADER_ITEM));
1286 else
1287 {
1288 /* pre insert copy */
1289 memcpy (&infoPtr->items[0],&oldItems[0],nItem*sizeof(HEADER_ITEM));
1290
1291 /* post insert copy */
1292 if (nItem < infoPtr->uNumItem-1)
1293 memcpy (&infoPtr->items[nItem+1],&oldItems[nItem],(infoPtr->uNumItem - nItem)*sizeof(HEADER_ITEM));
1294 }
1295
1296 COMCTL32_Free (oldItems);
1297 }
1298
1299 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1300 lpItem->bDown = FALSE;
1301
1302 lpItem->cxy = (phdi->mask & HDI_WIDTH || phdi->mask & HDI_HEIGHT) ? phdi->cxy:0;
1303
1304 if (phdi->mask & HDI_TEXT)
1305 {
1306 if (!phdi->pszText) lpItem->pszText = NULL;
1307 else if (phdi->pszText != LPSTR_TEXTCALLBACKW)
1308 {
1309 INT len;
1310
1311 len = lstrlenW(phdi->pszText);
1312 if (len == 0) lpItem->pszText = NULL; else
1313 {
1314 lpItem->pszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
1315 lstrcpyW(lpItem->pszText,phdi->pszText);
1316 }
1317 } else lpItem->pszText = LPSTR_TEXTCALLBACKW;
1318 lpItem->cchTextMax = phdi->cchTextMax;
1319 } else
1320 {
1321 lpItem->pszText = NULL;
1322 lpItem->cchTextMax = 0;
1323 }
1324
1325 lpItem->fmt = (phdi->mask & HDI_FORMAT) ? phdi->fmt:HDF_LEFT;
1326 if (lpItem->fmt == 0) lpItem->fmt = HDF_LEFT;
1327
1328 lpItem->lParam = (phdi->mask & HDI_LPARAM) ? phdi->lParam:0;
1329
1330 lpItem->iImage = (phdi->mask & HDI_IMAGE) ? phdi->iImage:0;
1331
1332 lpItem->iOrder = (phdi->mask & HDI_ORDER) ? phdi->iOrder:HDF_LEFT;
1333
1334 lpItem->hbm = (phdi->mask & HDI_BITMAP) ? phdi->hbm:0;
1335
1336 if (phdi->mask & HDI_FILTER)
1337 {
1338 lpItem->type = phdi->type;
1339 lpItem->pvFilter = phdi->pvFilter;
1340 }
1341
1342 HEADER_SetItemBounds (hwnd,nItem);
1343 HEADER_Refresh(hwnd);
1344
1345 return nItem;
1346}
1347
1348
1349static LRESULT
1350HEADER_Layout (HWND hwnd, WPARAM wParam, LPARAM lParam)
1351{
1352 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1353 LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;
1354
1355 if (!lpLayout) return FALSE;
1356
1357 lpLayout->pwpos->hwnd = hwnd;
1358 lpLayout->pwpos->hwndInsertAfter = 0;
1359 lpLayout->pwpos->x = lpLayout->prc->left;
1360 lpLayout->pwpos->y = lpLayout->prc->top;
1361 lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
1362 if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_HIDDEN)
1363 lpLayout->pwpos->cy = 0;
1364 else
1365 lpLayout->pwpos->cy = infoPtr->nHeight;
1366 lpLayout->pwpos->flags = SWP_NOZORDER;
1367
1368// TRACE (header, "Layout x=%d y=%d cx=%d cy=%d\n",
1369// lpLayout->pwpos->x, lpLayout->pwpos->y,
1370// lpLayout->pwpos->cx, lpLayout->pwpos->cy);
1371
1372 return TRUE;
1373}
1374
1375
1376static LRESULT
1377HEADER_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1378{
1379 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1380 HIMAGELIST himlOld;
1381
1382 himlOld = infoPtr->himl;
1383 infoPtr->himl = (HIMAGELIST)lParam;
1384
1385 HEADER_Refresh(hwnd);
1386
1387 return (LRESULT)himlOld;
1388}
1389
1390
1391static LRESULT
1392HEADER_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1393{
1394 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1395 HDITEMA *phdi = (HDITEMA*)lParam;
1396 INT nItem = (INT)wParam;
1397 HEADER_ITEM *lpItem;
1398 HDC hdc;
1399
1400 if (phdi == NULL) return FALSE;
1401 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem)) return FALSE;
1402 if (phdi->mask == 0) return TRUE;
1403
1404// TRACE (header, "[nItem=%d]\n", nItem);
1405 if (HEADER_SendItemChanging(hwnd,nItem)) return FALSE;
1406
1407 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1408
1409 if (phdi->mask & HDI_BITMAP) lpItem->hbm = phdi->hbm;
1410
1411 if (phdi->mask & HDI_FORMAT) lpItem->fmt = phdi->fmt;
1412
1413 if (phdi->mask & HDI_FILTER)
1414 {
1415 lpItem->type = lpItem->type;
1416 lpItem->pvFilter = lpItem->pvFilter;
1417 }
1418
1419 if (phdi->mask & (HDI_WIDTH | HDI_WIDTH)) lpItem->cxy = phdi->cxy;
1420
1421 if (phdi->mask & HDI_IMAGE) lpItem->iImage = phdi->iImage;
1422
1423 if (phdi->mask & HDI_LPARAM) lpItem->lParam = phdi->lParam;
1424
1425 if (phdi->mask & HDI_ORDER) lpItem->iOrder = phdi->iOrder;
1426
1427 if (phdi->mask & HDI_TEXT)
1428 {
1429 if (phdi->pszText != LPSTR_TEXTCALLBACKA)
1430 {
1431 if (lpItem->pszText)
1432 {
1433 COMCTL32_Free (lpItem->pszText);
1434 lpItem->pszText = NULL;
1435 }
1436 if (phdi->pszText)
1437 {
1438 INT len = lstrlenA (phdi->pszText);
1439
1440 if (len)
1441 {
1442 lpItem->pszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
1443 lstrcpyAtoW(lpItem->pszText,phdi->pszText);
1444 }
1445 }
1446 } else
1447 {
1448 if (lpItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpItem->pszText);
1449 lpItem->pszText = LPSTR_TEXTCALLBACKW;
1450 }
1451 }
1452
1453 HEADER_SendItemChanged(hwnd,nItem);
1454
1455 HEADER_SetItemBounds(hwnd,0);
1456 HEADER_Refresh(hwnd);
1457
1458 return TRUE;
1459}
1460
1461
1462static LRESULT
1463HEADER_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1464{
1465 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1466 HDITEMW *phdi = (HDITEMW*)lParam;
1467 INT nItem = (INT)wParam;
1468 HEADER_ITEM *lpItem;
1469 HDC hdc;
1470
1471 if (phdi == NULL) return FALSE;
1472 if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem)) return FALSE;
1473 if (phdi->mask == 0) return TRUE;
1474
1475// TRACE (header, "[nItem=%d]\n", nItem);
1476
1477 if (HEADER_SendItemChanging(hwnd,nItem)) return FALSE;
1478
1479 lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
1480
1481 if (phdi->mask & HDI_BITMAP) lpItem->hbm = phdi->hbm;
1482
1483 if (phdi->mask & HDI_FORMAT) lpItem->fmt = phdi->fmt;
1484
1485 if (phdi->mask & HDI_FILTER)
1486 {
1487 lpItem->type = lpItem->type;
1488 lpItem->pvFilter = lpItem->pvFilter;
1489 }
1490
1491 if (phdi->mask & (HDI_WIDTH | HDI_WIDTH)) lpItem->cxy = phdi->cxy;
1492
1493 if (phdi->mask & HDI_IMAGE) lpItem->iImage = phdi->iImage;
1494
1495 if (phdi->mask & HDI_LPARAM) lpItem->lParam = phdi->lParam;
1496
1497 if (phdi->mask & HDI_ORDER) lpItem->iOrder = phdi->iOrder;
1498
1499 if (phdi->mask & HDI_TEXT)
1500 {
1501 if (phdi->pszText != LPSTR_TEXTCALLBACKW)
1502 {
1503 if (lpItem->pszText)
1504 {
1505 COMCTL32_Free(lpItem->pszText);
1506 lpItem->pszText = NULL;
1507 }
1508 if (phdi->pszText)
1509 {
1510 INT len = lstrlenW(phdi->pszText);
1511
1512 if (len)
1513 {
1514 lpItem->pszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
1515 lstrcpyW(lpItem->pszText,phdi->pszText);
1516 }
1517 }
1518 } else
1519 {
1520 if (lpItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpItem->pszText);
1521 lpItem->pszText = LPSTR_TEXTCALLBACKW;
1522 }
1523 }
1524
1525 HEADER_SendItemChanged(hwnd,nItem);
1526
1527 HEADER_SetItemBounds(hwnd,0);
1528 HEADER_Refresh(hwnd);
1529
1530 return TRUE;
1531}
1532
1533static LRESULT
1534HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
1535{
1536 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1537 BOOL bTemp = infoPtr->bUnicode;
1538
1539 infoPtr->bUnicode = (BOOL)wParam;
1540
1541 return bTemp;
1542}
1543
1544
1545static LRESULT
1546HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1547{
1548 HEADER_INFO *infoPtr;
1549 TEXTMETRICA tm;
1550 HFONT hOldFont;
1551 HDC hdc;
1552
1553 infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
1554 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1555
1556 infoPtr->uNumItem = 0;
1557 infoPtr->hFont = 0;
1558 infoPtr->items = 0;
1559 infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
1560 infoPtr->hcurDivider = LoadCursorA (0, IDC_SIZEWEA);
1561 infoPtr->hcurDivopen = LoadCursorA (0, IDC_SIZENSA);
1562 infoPtr->bCaptured = FALSE;
1563 infoPtr->bPressed = FALSE;
1564 infoPtr->bTracking = FALSE;
1565 infoPtr->bDragDrop = FALSE;
1566 infoPtr->bTimer = FALSE;
1567 infoPtr->iMoveItem = 0;
1568 infoPtr->himl = 0;
1569 infoPtr->dragImage = 0;
1570 infoPtr->iHotItem = -1;
1571 infoPtr->xBmpMargin = 3*GetSystemMetrics(SM_CXEDGE);
1572 infoPtr->bUnicode = IsWindowUnicode(hwnd);
1573
1574 hdc = GetDC (0);
1575 hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT));
1576 GetTextMetricsA (hdc, &tm);
1577 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1578 SelectObject (hdc, hOldFont);
1579 ReleaseDC (0, hdc);
1580
1581 return 0;
1582}
1583
1584
1585static LRESULT
1586HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1587{
1588 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1589 HEADER_ITEM *lpItem;
1590 INT nItem;
1591
1592 if (infoPtr->items) {
1593 lpItem = (HEADER_ITEM*)infoPtr->items;
1594 for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
1595 if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACKW))
1596 COMCTL32_Free (lpItem->pszText);
1597 }
1598 COMCTL32_Free (infoPtr->items);
1599 }
1600
1601 if (infoPtr->himl)
1602 ImageList_Destroy (infoPtr->himl);
1603
1604 COMCTL32_Free (infoPtr);
1605
1606 return 0;
1607}
1608
1609static LRESULT
1610HEADER_EraseBackground(HWND hwnd,WPARAM wParam,LPARAM lParam)
1611{
1612 return TRUE;
1613}
1614
1615static LRESULT
1616HEADER_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam)
1617{
1618 return DLGC_WANTTAB | DLGC_WANTARROWS;
1619}
1620
1621static LRESULT
1622HEADER_GetFont (HWND hwnd)
1623{
1624 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1625
1626 return (LRESULT)infoPtr->hFont;
1627}
1628
1629
1630static LRESULT
1631HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
1632{
1633 POINT pt;
1634 UINT flags;
1635 INT nItem;
1636
1637 pt.x = (INT)LOWORD(lParam);
1638 pt.y = (INT)HIWORD(lParam);
1639 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1640
1641 if ((GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER))
1642 HEADER_SendItemDblClick(hwnd,nItem,0);
1643 else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
1644 HEADER_SendDividerDblClick(hwnd,nItem,0);
1645
1646 return 0;
1647}
1648
1649
1650static LRESULT
1651HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1652{
1653 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1654 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1655 POINT pt;
1656 UINT flags;
1657 INT nItem;
1658 HDC hdc;
1659
1660 pt.x = (SHORT)LOWORD(lParam);
1661 pt.y = (SHORT)HIWORD(lParam);
1662 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1663
1664 if ((dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER))
1665 {
1666 SetCapture (hwnd);
1667 infoPtr->bCaptured = TRUE;
1668 infoPtr->bPressed = TRUE;
1669 infoPtr->iMoveItem = nItem;
1670
1671 infoPtr->items[nItem].bDown = TRUE;
1672
1673 /* Send WM_CUSTOMDRAW */
1674 hdc = GetDC (hwnd);
1675 HEADER_RefreshItem (hwnd, hdc, nItem);
1676 ReleaseDC (hwnd, hdc);
1677
1678// TRACE (header, "Pressed item %d!\n", nItem);
1679 } else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
1680 {
1681 if (!(HEADER_SendBeginTrack(hwnd,nItem,0)))
1682 {
1683 SetCapture (hwnd);
1684 infoPtr->bCaptured = TRUE;
1685 infoPtr->bTracking = TRUE;
1686 infoPtr->bTrackOpen = flags == HHT_ONDIVOPEN;
1687 infoPtr->iMoveItem = nItem;
1688 infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
1689 infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;
1690
1691 if (!(dwStyle & HDS_FULLDRAG))
1692 {
1693 infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
1694 hdc = GetDC (hwnd);
1695 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1696 ReleaseDC (hwnd, hdc);
1697 }
1698
1699// TRACE (header, "Begin tracking item %d!\n", nItem);
1700 }
1701 }
1702
1703 return 0;
1704}
1705
1706
1707static LRESULT
1708HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1709{
1710 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1711 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1712 POINT pt;
1713 UINT flags;
1714 INT nItem, nWidth;
1715 HDC hdc;
1716
1717 pt.x = (SHORT)LOWORD(lParam);
1718 pt.y = (SHORT)HIWORD(lParam);
1719 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1720
1721 if (infoPtr->bPressed)
1722 {
1723 if (PtInRect(&infoPtr->items[infoPtr->iMoveItem].rect,pt))
1724 {
1725 infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
1726 hdc = GetDC(hwnd);
1727 HEADER_RefreshItem(hwnd,hdc,infoPtr->iMoveItem);
1728 ReleaseDC(hwnd,hdc);
1729
1730 HEADER_SendItemClick(hwnd,infoPtr->iMoveItem,0);
1731 }
1732// TRACE (header, "Released item %d!\n", infoPtr->iMoveItem);
1733 infoPtr->bPressed = FALSE;
1734 } else if (infoPtr->bTracking)
1735 {
1736// TRACE (header, "End tracking item %d!\n", infoPtr->iMoveItem);
1737 infoPtr->bTracking = FALSE;
1738
1739 HEADER_SendEndTrack(hwnd,infoPtr->iMoveItem,0);
1740
1741 if (!(dwStyle & HDS_FULLDRAG))
1742 {
1743 hdc = GetDC (hwnd);
1744 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
1745 ReleaseDC (hwnd, hdc);
1746 if (HEADER_SendItemChanging(hwnd,infoPtr->iMoveItem))
1747 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1748 else
1749 {
1750 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
1751 if (nWidth < MIN_ITEMWIDTH) nWidth = MIN_ITEMWIDTH;
1752
1753 if (infoPtr->nOldWidth != nWidth)
1754 {
1755 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
1756 HEADER_SendItemChanged(hwnd,infoPtr->iMoveItem);
1757
1758 HEADER_SetItemBounds (hwnd,infoPtr->iMoveItem);
1759
1760 HEADER_Refresh(hwnd);
1761 }
1762 }
1763 }
1764 }
1765
1766 if (infoPtr->bCaptured)
1767 {
1768 infoPtr->bCaptured = FALSE;
1769 ReleaseCapture();
1770 HEADER_SendSimpleNotify(hwnd,NM_RELEASEDCAPTURE);
1771 }
1772
1773 return 0;
1774}
1775
1776
1777static LRESULT
1778HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1779{
1780 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
1781 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1782 POINT pt;
1783 UINT flags;
1784 INT nItem, nWidth;
1785 HDC hdc;
1786
1787 pt.x = (SHORT)LOWORD(lParam);
1788 pt.y = (SHORT)HIWORD(lParam);
1789 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
1790
1791 if (dwStyle & HDS_BUTTONS && dwStyle & HDS_HOTTRACK) //CB: check with no buttons
1792 {
1793 INT newItem;
1794
1795 if (infoPtr->bCaptured && infoPtr->bPressed && PtInRect(&infoPtr->items[infoPtr->iMoveItem].rect,pt))
1796 newItem = infoPtr->iMoveItem;
1797 else
1798 {
1799 if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
1800 newItem = nItem;
1801 else
1802 newItem = -1;
1803 }
1804 if (newItem != infoPtr->iHotItem)
1805 {
1806 infoPtr->iHotItem = newItem;
1807 HEADER_Refresh(hwnd);
1808 }
1809 if (!infoPtr->bTimer && infoPtr->iHotItem != -1)
1810 {
1811 infoPtr->bTimer = TRUE;
1812 SetTimer(hwnd,TIMER_ID,TIMER_MS,NULL);
1813 } else if (infoPtr->bTimer && infoPtr->iHotItem == -1)
1814 {
1815 KillTimer(hwnd,TIMER_ID);
1816 infoPtr->bTimer = FALSE;
1817 }
1818 }
1819
1820 if (infoPtr->bCaptured)
1821 {
1822 if (infoPtr->bPressed)
1823 {
1824 if (dwStyle & HDS_DRAGDROP && (infoPtr->bDragDrop || !HEADER_SendDragNotify(hwnd,HDN_BEGINDRAG,infoPtr->iMoveItem,0)))
1825 {
1826 if (!infoPtr->bDragDrop)
1827 {
1828 infoPtr->bDragDrop = TRUE;
1829 infoPtr->dragImage = (HIMAGELIST)HEADER_CreateDragImage(hwnd,0,0);
1830 }
1831 //CB:todo
1832 } else
1833 {
1834 BOOL newDown;
1835
1836 if (PtInRect(&infoPtr->items[infoPtr->iMoveItem].rect,pt))
1837 newDown = TRUE;
1838 else
1839 newDown = FALSE;
1840
1841 if (newDown != infoPtr->items[infoPtr->iMoveItem].bDown)
1842 {
1843 infoPtr->items[infoPtr->iMoveItem].bDown = newDown;
1844 hdc = GetDC (hwnd);
1845 HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
1846 ReleaseDC (hwnd, hdc);
1847 }
1848 }
1849// TRACE (header, "Moving pressed item %d!\n", infoPtr->iMoveItem);
1850 } else if (infoPtr->bTracking)
1851 {
1852 if (dwStyle & HDS_FULLDRAG)
1853 {
1854 if (HEADER_SendItemChanging(hwnd,infoPtr->iMoveItem))
1855 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1856 else
1857 {
1858 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
1859 if (nWidth < MIN_ITEMWIDTH) nWidth = MIN_ITEMWIDTH;
1860 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
1861 HEADER_SendItemChanged(hwnd,infoPtr->iMoveItem);
1862 }
1863 HEADER_SetItemBounds (hwnd,infoPtr->iMoveItem);
1864 HEADER_Refresh(hwnd);
1865 } else
1866 {
1867 INT lastPos = infoPtr->xOldTrack;
1868
1869 hdc = GetDC (hwnd);
1870 infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset;
1871 if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left+MIN_ITEMWIDTH)
1872 infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left+MIN_ITEMWIDTH;
1873 infoPtr->items[infoPtr->iMoveItem].cxy =
1874 infoPtr->xOldTrack-infoPtr->items[infoPtr->iMoveItem].rect.left;
1875 if (lastPos != infoPtr->xOldTrack)
1876 {
1877 HEADER_DrawTrackLine(hwnd,hdc,lastPos);
1878 HEADER_DrawTrackLine(hwnd,hdc,infoPtr->xOldTrack);
1879 }
1880 ReleaseDC (hwnd, hdc);
1881 }
1882
1883 HEADER_SendTrack(hwnd,infoPtr->iMoveItem);
1884// TRACE (header, "Tracking item %d!\n", infoPtr->iMoveItem);
1885 }
1886 }
1887
1888 return 0;
1889}
1890
1891static LRESULT
1892HEADER_Size(HWND hwnd,WPARAM wParam,LPARAM lParam)
1893{
1894 HEADER_SetItemBounds(hwnd,0);
1895
1896 return DefWindowProcA(hwnd,WM_SIZE,wParam,lParam);
1897}
1898
1899static LRESULT
1900HEADER_Timer(HWND hwnd,WPARAM wParam,LPARAM lParam)
1901{
1902 POINT point;
1903 RECT rect;
1904
1905 GetCursorPos(&point);
1906 ScreenToClient(hwnd,&point);
1907 GetClientRect(hwnd,&rect);
1908 if (!PtInRect(&rect,point))
1909 {
1910 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1911
1912 infoPtr->iHotItem = -1;
1913 infoPtr->bTimer = FALSE;
1914 HEADER_Refresh(hwnd);
1915
1916 KillTimer(hwnd,TIMER_ID);
1917 }
1918
1919 return 0;
1920}
1921
1922static LRESULT
1923HEADER_KeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
1924{
1925 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1926 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1927 HDC hdc;
1928
1929 if (wParam == VK_ESCAPE && infoPtr->bCaptured && infoPtr->bTracking)
1930 {
1931 infoPtr->bTracking = FALSE;
1932
1933 HEADER_SendEndTrack(hwnd,infoPtr->iMoveItem,0);
1934 hdc = GetDC(hwnd);
1935 HEADER_DrawTrackLine(hwnd,hdc,infoPtr->xOldTrack);
1936 ReleaseDC(hwnd,hdc);
1937 if (dwStyle & HDS_FULLDRAG)
1938 {
1939 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1940 HEADER_Refresh(hwnd);
1941 }
1942
1943 infoPtr->bCaptured = FALSE;
1944 ReleaseCapture();
1945 HEADER_SendSimpleNotify(hwnd,NM_RELEASEDCAPTURE);
1946
1947 return TRUE;
1948 }
1949
1950 return DefWindowProcA(WM_KEYDOWN,hwnd,wParam,lParam);
1951}
1952
1953static LRESULT
1954HEADER_CaptureChanged(HWND hwnd,WPARAM wParam,LPARAM lParam)
1955{
1956 HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
1957 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1958 HDC hdc;
1959
1960 if (infoPtr->bCaptured && infoPtr->bTracking)
1961 {
1962 infoPtr->bTracking = FALSE;
1963
1964 HEADER_SendEndTrack(hwnd,infoPtr->iMoveItem,0);
1965 hdc = GetDC(hwnd);
1966 HEADER_DrawTrackLine(hwnd,hdc,infoPtr->xOldTrack);
1967 ReleaseDC(hwnd,hdc);
1968 if (dwStyle & HDS_FULLDRAG)
1969 {
1970 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
1971 HEADER_Refresh(hwnd);
1972 }
1973 }
1974
1975 return 0;
1976}
1977
1978static LRESULT
1979HEADER_Paint (HWND hwnd, WPARAM wParam)
1980{
1981 HDC hdc;
1982 PAINTSTRUCT ps;
1983
1984 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1985 HEADER_Draw (hwnd, hdc);
1986 if(!wParam)
1987 EndPaint (hwnd, &ps);
1988
1989 return 0;
1990}
1991
1992
1993static LRESULT
1994HEADER_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1995{
1996 return HEADER_SendSimpleNotify (hwnd, NM_RCLICK);
1997}
1998
1999
2000static LRESULT
2001HEADER_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2002{
2003 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
2004 POINT pt;
2005 UINT flags;
2006 INT nItem;
2007
2008// TRACE (header, "code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
2009
2010 GetCursorPos (&pt);
2011 ScreenToClient (hwnd, &pt);
2012
2013 HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
2014
2015 if (infoPtr->bCaptured)
2016 {
2017 if (infoPtr->bTracking)
2018 {
2019 if (infoPtr->bTrackOpen) SetCursor(infoPtr->hcurDivopen);
2020 else SetCursor(infoPtr->hcurDivider);
2021 } else SetCursor(infoPtr->hcurArrow);
2022
2023 return 0;
2024 }
2025
2026 if (flags == HHT_ONDIVIDER)
2027 SetCursor (infoPtr->hcurDivider);
2028 else if (flags == HHT_ONDIVOPEN)
2029 SetCursor (infoPtr->hcurDivopen);
2030 else
2031 SetCursor (infoPtr->hcurArrow);
2032
2033 return 0;
2034}
2035
2036
2037static LRESULT
2038HEADER_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2039{
2040 HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
2041 TEXTMETRICA tm;
2042 HFONT hFont, hOldFont;
2043 HDC hdc;
2044
2045 infoPtr->hFont = (HFONT)wParam;
2046
2047 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
2048
2049 hdc = GetDC (0);
2050 hOldFont = SelectObject (hdc, hFont);
2051 GetTextMetricsA (hdc, &tm);
2052 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
2053 SelectObject (hdc, hOldFont);
2054 ReleaseDC (0, hdc);
2055
2056 if (lParam) HEADER_Refresh(hwnd);
2057
2058 return 0;
2059}
2060
2061
2062static LRESULT WINAPI
2063HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2064{
2065 switch (msg)
2066 {
2067 case HDM_CLEARFILTER:
2068 return HEADER_ClearFilter(hwnd,wParam,lParam);
2069
2070 case HDM_CREATEDRAGIMAGE:
2071 return HEADER_CreateDragImage (hwnd,wParam,lParam);
2072
2073 case HDM_DELETEITEM:
2074 return HEADER_DeleteItem (hwnd, wParam);
2075
2076 case HDM_EDITFILTER:
2077 return HEADER_EditFilter(hwnd,wParam,lParam);
2078
2079 case HDM_GETBITMAPMARGIN:
2080 return HEADER_GetBitmapMargin(hwnd,wParam,lParam);
2081
2082 case HDM_GETIMAGELIST:
2083 return HEADER_GetImageList (hwnd);
2084
2085 case HDM_GETITEMA:
2086 return HEADER_GetItemA (hwnd, wParam, lParam);
2087
2088 case HDM_GETITEMW:
2089 return HEADER_GetItemW (hwnd, wParam, lParam);
2090
2091 case HDM_GETITEMCOUNT:
2092 return HEADER_GetItemCount (hwnd);
2093
2094 case HDM_GETITEMRECT:
2095 return HEADER_GetItemRect (hwnd, wParam, lParam);
2096
2097 case HDM_GETORDERARRAY:
2098 return HEADER_GetOrderArray(hwnd,wParam,lParam);
2099
2100 case HDM_GETUNICODEFORMAT:
2101 return HEADER_GetUnicodeFormat (hwnd);
2102
2103 case HDM_HITTEST:
2104 return HEADER_HitTest (hwnd, wParam, lParam);
2105
2106 case HDM_INSERTITEMA:
2107 return HEADER_InsertItemA (hwnd, wParam, lParam);
2108
2109 case HDM_INSERTITEMW:
2110 return HEADER_InsertItemW (hwnd, wParam, lParam);
2111
2112 case HDM_LAYOUT:
2113 return HEADER_Layout (hwnd, wParam, lParam);
2114
2115 case HDM_ORDERTOINDEX:
2116 return HEADER_OrderToIndex(hwnd,wParam,lParam);
2117
2118 case HDM_SETBITMAPMARGIN:
2119 return HEADER_SetBitmapMargin(hwnd,wParam,lParam);
2120
2121 case HDM_SETFILTERCHANGETIMEOUT:
2122 return HEADER_SetFilterChangeTimeout(hwnd,wParam,lParam);
2123
2124 case HDM_SETHOTDIVIDER:
2125 return HEADER_SetHotDivider(hwnd,wParam,lParam);
2126
2127 case HDM_SETIMAGELIST:
2128 return HEADER_SetImageList (hwnd, wParam, lParam);
2129
2130 case HDM_SETITEMA:
2131 return HEADER_SetItemA (hwnd, wParam, lParam);
2132
2133 case HDM_SETITEMW:
2134 return HEADER_SetItemW (hwnd, wParam, lParam);
2135
2136 case HDM_SETORDERARRAY:
2137 return HEADER_SetOrderArray(hwnd,wParam,lParam);
2138
2139 case HDM_SETUNICODEFORMAT:
2140 return HEADER_SetUnicodeFormat (hwnd, wParam);
2141
2142 case WM_CAPTURECHANGED:
2143 return HEADER_CaptureChanged(hwnd,wParam,lParam);
2144
2145 case WM_CREATE:
2146 return HEADER_Create (hwnd, wParam, lParam);
2147
2148 case WM_DESTROY:
2149 return HEADER_Destroy (hwnd, wParam, lParam);
2150
2151 case WM_ERASEBKGND:
2152 return HEADER_EraseBackground(hwnd,wParam,lParam);
2153
2154 case WM_GETDLGCODE:
2155 return HEADER_GetDlgCode(hwnd,wParam,lParam);
2156
2157 case WM_GETFONT:
2158 return HEADER_GetFont (hwnd);
2159
2160 case WM_KEYDOWN:
2161 return HEADER_KeyDown(hwnd,wParam,lParam);
2162
2163 case WM_LBUTTONDBLCLK:
2164 return HEADER_LButtonDblClk (hwnd, wParam, lParam);
2165
2166 case WM_LBUTTONDOWN:
2167 return HEADER_LButtonDown (hwnd, wParam, lParam);
2168
2169 case WM_LBUTTONUP:
2170 return HEADER_LButtonUp (hwnd, wParam, lParam);
2171
2172 case WM_MOUSEMOVE:
2173 return HEADER_MouseMove (hwnd, wParam, lParam);
2174
2175/* case WM_NOTIFYFORMAT: */
2176
2177 case WM_PAINT:
2178 return HEADER_Paint(hwnd,wParam);
2179
2180 case WM_RBUTTONUP:
2181 return HEADER_RButtonUp (hwnd, wParam, lParam);
2182
2183 case WM_SETCURSOR:
2184 return HEADER_SetCursor (hwnd, wParam, lParam);
2185
2186 case WM_SETFONT:
2187 return HEADER_SetFont (hwnd, wParam, lParam);
2188
2189 case WM_SIZE:
2190 return HEADER_Size(hwnd,wParam,lParam);
2191
2192 case WM_TIMER:
2193 return HEADER_Timer(hwnd,wParam,lParam);
2194
2195 default:
2196// if (msg >= WM_USER)
2197// ERR (header, "unknown msg %04x wp=%04x lp=%08lx\n",
2198// msg, wParam, lParam );
2199 return DefWindowProcA (hwnd, msg, wParam, lParam);
2200 }
2201 return 0;
2202}
2203
2204
2205VOID
2206HEADER_Register (VOID)
2207{
2208 WNDCLASSA wndClass;
2209
2210 if (GlobalFindAtomA (WC_HEADERA)) return;
2211
2212 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2213 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
2214 wndClass.lpfnWndProc = (WNDPROC)HEADER_WindowProc;
2215 wndClass.cbClsExtra = 0;
2216 wndClass.cbWndExtra = sizeof(HEADER_INFO *);
2217 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2218 wndClass.lpszClassName = WC_HEADERA;
2219
2220 RegisterClassA (&wndClass);
2221}
2222
2223
2224VOID
2225HEADER_Unregister (VOID)
2226{
2227 if (GlobalFindAtomA (WC_HEADERA))
2228 UnregisterClassA (WC_HEADERA, (HINSTANCE)NULL);
2229}
2230
Note: See TracBrowser for help on using the repository browser.