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

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

NC fixes

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