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

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

Drag&drop support

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