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

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

* empty log message *

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