Small fixes.
[wine] / dlls / comctl32 / listview.c
1 /*
2  * Listview control
3  *
4  * Copyright 1998 Eric Kohl
5  *
6  * NOTES
7  *   This is just a dummy control. An author is needed! Any volunteers?
8  *   I will only improve this control once in a while.
9  *     Eric <ekohl@abo.rhein-zeitung.de>
10  *
11  * TODO:
12  *   - Most messages.
13  *   - Most notifications.
14  */
15
16 #include "windows.h"
17 #include "commctrl.h"
18 #include "listview.h"
19 #include "win.h"
20 #include "debug.h"
21
22
23 #define LISTVIEW_GetInfoPtr(wndPtr) ((LISTVIEW_INFO *)wndPtr->wExtra[0])
24
25
26 static VOID
27 LISTVIEW_Refresh (WND *wndPtr, HDC32 hdc)
28 {
29 //    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
30
31
32
33 }
34
35
36
37 // << LISTVIEW_ApproximateViewRect >>
38 // << LISTVIEW_Arrange >>
39 // << LISTVIEW_CreateDragImage >>
40
41
42 static LRESULT
43 LISTVIEW_DeleteAllItems (WND *wndPtr)
44 {
45     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
46     INT32 nItem;
47     LISTVIEW_ITEM *lpItem;
48     NMLISTVIEW nmlv;
49     BOOL32 bNotify;
50
51     if (infoPtr->nItemCount == 0)
52         return TRUE;
53
54     TRACE (listview, "\n");
55
56     /* send LVN_DELETEALLITEMS notification */
57     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
58     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
59     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
60     nmlv.hdr.code     = LVN_DELETEALLITEMS;
61     nmlv.iItem        = -1;
62     bNotify =
63         !(BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
64                                  (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
65
66     nmlv.hdr.code     = LVN_DELETEITEM;
67
68     for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) {
69         /* send notification */
70         if (bNotify) {
71             nmlv.iItem = nItem;
72             SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
73                             (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
74         }
75
76         /* get item pointer */
77         lpItem = (LISTVIEW_ITEM*)DPA_GetPtr (infoPtr->hdpaItems, nItem);
78         if (lpItem) {
79             /* delete item strings */
80             if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
81                 COMCTL32_Free (lpItem->pszText);
82
83             /* free item data */
84             COMCTL32_Free (lpItem);
85         }
86     }
87
88     DPA_DeleteAllPtrs (infoPtr->hdpaItems);
89     infoPtr->nItemCount = 0;
90
91     return TRUE;
92 }
93
94
95 static LRESULT
96 LISTVIEW_DeleteColumn (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
97 {
98     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
99     INT32 nColumn = (INT32)wParam;
100
101     /* FIXME ??? */
102     if (infoPtr->nItemCount > 0)
103         return FALSE;
104
105     if (!SendMessage32A (infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0))
106         return FALSE;
107
108     infoPtr->nColumnCount--;
109
110     FIXME (listview, "semi stub!\n");
111
112     return TRUE;
113 }
114
115
116 static LRESULT
117 LISTVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
118 {
119     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
120     INT32 nItem = (INT32)wParam;
121     LISTVIEW_ITEM *lpItem;
122     NMLISTVIEW nmlv;
123
124     if ((nItem < 0) || (nItem >= infoPtr->nItemCount))
125         return FALSE;
126
127     TRACE (listview, "(%d)\n", nItem);
128
129     /* send notification */
130     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
131     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
132     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
133     nmlv.hdr.code     = LVN_DELETEITEM;
134     nmlv.iItem        = nItem;
135     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
136                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
137
138     /* remove from item array */
139     lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr (infoPtr->hdpaItems, nItem);
140
141     /* delete item strings */
142     if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
143         COMCTL32_Free (lpItem->pszText);
144
145     /* free item data */
146     COMCTL32_Free (lpItem);
147
148     infoPtr->nItemCount--;
149
150     return TRUE;
151 }
152
153
154 // << LISTVIEW_EditLabel >>
155 // << LISTVIEW_EnsureVisible >>
156 // << LISTVIEW_FindItem >>
157
158
159 static LRESULT
160 LISTVIEW_GetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
161 {
162     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
163
164     return infoPtr->clrBk;
165 }
166
167
168 // << LISTVIEW_GetBkImage >>
169 // << LISTVIEW_GetCallbackMask >>
170
171
172 static LRESULT
173 LISTVIEW_GetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
174 {
175     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
176     LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
177     INT32 nIndex = (INT32)wParam;
178     HDITEM32A hdi;
179
180     if (!lpcol)
181         return FALSE;
182
183     TRACE (listview, "(%d %p)\n", nIndex, lpcol);
184
185     ZeroMemory (&hdi, sizeof(HDITEM32A));
186
187     if (lpcol->mask & LVCF_FMT)
188         hdi.mask |= HDI_FORMAT;
189
190     if (lpcol->mask & LVCF_WIDTH)
191         hdi.mask |= HDI_WIDTH;
192
193     if (lpcol->mask & LVCF_TEXT)
194         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
195
196     if (lpcol->mask & LVCF_IMAGE)
197         hdi.mask |= HDI_IMAGE;
198
199     if (lpcol->mask & LVCF_ORDER)
200         hdi.mask |= HDI_ORDER;
201
202     if (!SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
203                     wParam, (LPARAM)&hdi))
204         return FALSE;
205
206     if (lpcol->mask & LVCF_FMT) {
207         lpcol->fmt = 0;
208
209         if (hdi.fmt & HDF_LEFT)
210             lpcol->fmt |= LVCFMT_LEFT;
211         else if (hdi.fmt & HDF_RIGHT)
212             lpcol->fmt |= LVCFMT_RIGHT;
213         else if (hdi.fmt & HDF_CENTER)
214             lpcol->fmt |= LVCFMT_CENTER;
215
216         if (hdi.fmt & HDF_IMAGE)
217             lpcol->fmt |= LVCFMT_COL_HAS_IMAGES;
218     }
219
220     if (lpcol->mask & LVCF_WIDTH)
221         lpcol->cx = hdi.cxy;
222
223     if ((lpcol->mask & LVCF_TEXT) && (lpcol->pszText) && (hdi.pszText))
224         lstrcpyn32A (lpcol->pszText, hdi.pszText, lpcol->cchTextMax);
225
226     if (lpcol->mask & LVCF_IMAGE)
227         lpcol->iImage = hdi.iImage;
228
229     if (lpcol->mask & LVCF_ORDER)
230         lpcol->iOrder = hdi.iOrder;
231
232     return TRUE;
233 }
234
235
236 // << LISTVIEW_GetColumn32W >>
237 // << LISTVIEW_GetColumnOrderArray >>
238
239
240 __inline__ static LRESULT
241 LISTVIEW_GetColumnWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
242 {
243     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
244     HDITEM32A hdi;
245
246     hdi.mask = HDI_WIDTH;
247     if (SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A,
248                         wParam, (LPARAM)&hdi))
249         return hdi.cxy;
250
251     return 0;
252 }
253
254
255 // << LISTVIEW_GetCountPerPage >>
256 // << LISTVIEW_GetEditControl >>
257 // << LISTVIEW_GetExtendedListviewStyle >>
258
259
260 __inline__ static LRESULT
261 LISTVIEW_GetHeader (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
262 {
263     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
264
265     return infoPtr->hwndHeader;
266 }
267
268
269 // << LISTVIEW_GetHotCursor >>
270 // << LISTVIEW_GetHotItem >>
271 // << LISTVIEW_GetHoverTime >>
272
273
274 static LRESULT
275 LISTVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
276 {
277     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
278
279     TRACE (listview, "(0x%08x)\n", wParam);
280
281     switch (wParam) {
282         case LVSIL_NORMAL:
283             return (LRESULT)infoPtr->himlNormal;
284
285         case LVSIL_SMALL:
286             return (LRESULT)infoPtr->himlSmall;
287
288         case LVSIL_STATE:
289             return (LRESULT)infoPtr->himlState;
290     }
291
292     return (LRESULT)NULL;
293 }
294
295
296 // << LISTVIEW_GetISearchString >>
297
298
299 static LRESULT
300 LISTVIEW_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
301 {
302     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
303     LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
304     LISTVIEW_ITEM *lpRow, *lpSubItem;
305
306     if (!lpItem)
307         return FALSE;
308
309     if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
310         return FALSE;
311
312     if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
313         return FALSE;
314
315     FIXME (listview, "(%d %d %p)\n",
316            lpItem->iItem, lpItem->iSubItem, lpItem);
317
318     lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
319     if (!lpRow)
320         return FALSE;
321
322     lpSubItem = &lpRow[lpItem->iSubItem];
323     if (!lpSubItem)
324         return FALSE;
325
326     if (lpItem->mask & LVIF_STATE)
327         lpItem->state = lpSubItem->state & lpItem->stateMask;
328
329     if (lpItem->mask & LVIF_TEXT) {
330         if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
331             lpItem->pszText = LPSTR_TEXTCALLBACK32A;
332         else
333             Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
334                            lpItem->cchTextMax);
335     }
336
337     if (lpItem->mask & LVIF_IMAGE)
338          lpItem->iImage = lpSubItem->iImage;
339
340     if (lpItem->mask & LVIF_PARAM)
341         lpItem->lParam = lpSubItem->lParam;
342
343     if (lpItem->mask & LVIF_INDENT)
344         lpItem->iIndent = lpSubItem->iIndent;
345
346     return TRUE;
347 }
348
349
350 // << LISTVIEW_GetItem32W >>
351
352
353 __inline__ static LRESULT
354 LISTVIEW_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
355 {
356     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
357     return infoPtr->nItemCount;
358 }
359
360
361 static LRESULT
362 LISTVIEW_GetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
363 {
364     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
365     LPPOINT32 lpPt = (LPPOINT32)lParam;
366     INT32 nIndex = (INT32)wParam;
367
368     if (!lpPt)
369         return FALSE;
370     if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
371         return FALSE;
372
373     FIXME (listview, "returning position [0,0]!\n");
374     lpPt->x = 0;
375     lpPt->y = 0;
376
377     return TRUE;
378 }
379
380
381 // << LISTVIEW_GetItemRect >>
382 // << LISTVIEW_GetItemSpacing >>
383 // << LISTVIEW_GetItemState >>
384
385
386 static LRESULT
387 LISTVIEW_GetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
388 {
389     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
390     LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
391     INT32 nItem = (INT32)wParam;
392     LISTVIEW_ITEM *lpRow, *lpSubItem;
393
394     TRACE (listview, "(%d %p)\n", nItem, lpItem);
395
396     lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
397     if (!lpRow)
398         return 0;
399
400     lpSubItem = &lpRow[lpItem->iSubItem];
401     if (!lpSubItem)
402         return 0;
403
404     if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) {
405         lpItem->pszText = LPSTR_TEXTCALLBACK32A;
406         return 0;
407     }
408     else
409         return Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText,
410                               lpItem->cchTextMax);
411 }
412
413
414 // << LISTVIEW_GetItemText32A >>
415
416
417 static LRESULT
418 LISTVIEW_GetNextItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
419 {
420     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
421     INT32 nStart = (INT32)wParam;
422     UINT32 uFlags = (UINT32)LOWORD(lParam);
423
424     FIXME (listview, "(%d, 0x%x): semi stub!\n", nStart, uFlags);
425
426     if (infoPtr->nItemCount <= 0)
427         return -1;
428
429     /* just a simple (preliminary) hack */
430     if (nStart == -1)
431         return 0;
432     else if (nStart < infoPtr->nItemCount - 1)
433         return nStart + 1;
434     else
435         return -1;
436
437     return -1;
438 }
439
440
441 // << LISTVIEW_GetNumberOfWorkAreas >>
442 // << LISTVIEW_GetOrigin >>
443
444
445 static LRESULT
446 LISTVIEW_GetSelectedCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
447 {
448     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
449
450     TRACE (listview, ": empty stub (returns 0)!\n");
451
452     return 0;
453 }
454
455
456 // << LISTVIEW_GetSelectionMark >>
457
458
459 static LRESULT
460 LISTVIEW_GetStringWidth32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
461 {
462     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
463     LPSTR lpsz = (LPSTR)lParam;
464     HFONT32 hFont, hOldFont;
465     HDC32 hdc;
466     SIZE32 size;
467
468     if (!lpsz)
469         return 0;
470
471     TRACE (listview, "(%s)\n", lpsz);
472
473     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
474     hdc = GetDC32 (0);
475     hOldFont = SelectObject32 (hdc, hFont);
476     GetTextExtentPoint32A (hdc, lpsz, lstrlen32A(lpsz), &size);
477     SelectObject32 (hdc, hOldFont);
478     ReleaseDC32 (0, hdc);
479
480     TRACE (listview, "-- ret=%d\n", size.cx);
481
482     return (LRESULT)size.cx;
483 }
484
485
486
487
488 __inline__ static LRESULT
489 LISTVIEW_GetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
490 {
491     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
492
493     return infoPtr->clrTextBk;
494 }
495
496
497 __inline__ static LRESULT
498 LISTVIEW_GetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
499 {
500     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
501
502     return infoPtr->clrText;
503 }
504
505
506 static LRESULT
507 LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
508 {
509     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
510     LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
511     INT32 nIndex = (INT32)wParam;
512     HDITEM32A hdi;
513     INT32 nResult;
514
515     if ((!lpcol) || (infoPtr->nItemCount > 0))
516         return -1;
517
518     FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
519
520     ZeroMemory (&hdi, sizeof(HDITEM32A));
521
522     if (lpcol->mask & LVCF_FMT) {
523         if (nIndex == 0)
524             hdi.fmt |= HDF_LEFT;
525         else if (lpcol->fmt & LVCFMT_LEFT)
526             hdi.fmt |= HDF_LEFT;
527         else if (lpcol->fmt & LVCFMT_RIGHT)
528             hdi.fmt |= HDF_RIGHT;
529         else if (lpcol->fmt & LVCFMT_CENTER)
530             hdi.fmt |= HDF_CENTER;
531
532         if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
533             hdi.fmt |= HDF_IMAGE;
534             
535         hdi.mask |= HDI_FORMAT;
536     }
537
538     if (lpcol->mask & LVCF_WIDTH) {
539         hdi.mask |= HDI_WIDTH;
540         hdi.cxy = lpcol->cx;
541     }
542     
543     if (lpcol->mask & LVCF_TEXT) {
544         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
545         hdi.pszText = lpcol->pszText;
546         hdi.fmt |= HDF_STRING;
547     }
548
549     if (lpcol->mask & LVCF_IMAGE) {
550         hdi.mask |= HDI_IMAGE;
551         hdi.iImage = lpcol->iImage;
552     }
553
554     if (lpcol->mask & LVCF_ORDER) {
555         hdi.mask |= HDI_ORDER;
556         hdi.iOrder = lpcol->iOrder;
557     }
558
559     nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A,
560                               wParam, (LPARAM)&hdi);
561     if (nResult == -1)
562         return -1;
563
564     infoPtr->nColumnCount++;
565
566     return nResult;
567 }
568
569
570 // << LISTVIEW_InsertColumn32W >>
571
572
573 static LRESULT
574 LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
575 {
576     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
577     LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
578     LISTVIEW_ITEM *lpListItem;
579     INT32 nIndex;
580     NMLISTVIEW nmlv;
581
582     if (!lpItem)
583         return -1;
584
585     if ((!infoPtr->nColumnCount) || (lpItem->iSubItem))
586         return -1;
587
588     FIXME (listview, "(%d %p)\n", lpItem->iItem, lpItem);
589     FIXME (listview, "(%p %p)\n", infoPtr, infoPtr->hdpaItems);
590
591     lpListItem = (LISTVIEW_ITEM*)COMCTL32_Alloc (infoPtr->nColumnCount * sizeof(LISTVIEW_ITEM));
592     nIndex = DPA_InsertPtr (infoPtr->hdpaItems, lpItem->iItem, lpListItem);
593     if (nIndex == -1)
594         return -1;
595
596     if (lpItem->mask & LVIF_STATE)
597         lpListItem[0].state = lpItem->state;
598
599     if (lpItem->mask & LVIF_TEXT) {
600         if (lpItem->pszText == LPSTR_TEXTCALLBACK32A)
601             lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A;
602         else
603             Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText);
604     }
605
606     if (lpItem->mask & LVIF_IMAGE)
607         lpListItem[0].iImage = lpItem->iImage;
608
609     if (lpItem->mask & LVIF_PARAM)
610         lpListItem[0].lParam = lpItem->lParam;
611
612     if (lpItem->mask & LVIF_INDENT)
613         lpListItem[0].iIndent = lpItem->iIndent;
614
615     infoPtr->nItemCount++;
616
617     /* send notification */
618     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
619     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
620     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
621     nmlv.hdr.code     = LVN_INSERTITEM;
622     nmlv.iItem        = nIndex;
623     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
624                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
625
626     return nIndex;
627 }
628
629
630 // << LISTVIEW_InsertItem32W >>
631
632
633 static LRESULT
634 LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
635 {
636 //    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
637
638     FIXME (listview, "(%d - %d): empty stub!\n",
639            (INT32)wParam, (INT32)lParam);
640
641     return TRUE;
642 }
643
644
645
646 static LRESULT
647 LISTVIEW_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
648 {
649     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
650
651     if (!infoPtr)
652         return FALSE;
653
654     /* set background color */
655     TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
656     infoPtr->clrBk = (COLORREF)lParam;
657
658     return TRUE;
659 }
660
661
662 static LRESULT
663 LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
664 {
665     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
666     LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
667     INT32 nIndex = (INT32)wParam;
668     HDITEM32A hdi;
669
670     if (!lpcol)
671         return -1;
672
673     FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
674
675     ZeroMemory (&hdi, sizeof(HDITEM32A));
676
677     if (lpcol->mask & LVCF_FMT) {
678         if (nIndex == 0)
679             hdi.fmt |= HDF_LEFT;
680         else if (lpcol->fmt & LVCFMT_LEFT)
681             hdi.fmt |= HDF_LEFT;
682         else if (lpcol->fmt & LVCFMT_RIGHT)
683             hdi.fmt |= HDF_RIGHT;
684         else if (lpcol->fmt & LVCFMT_CENTER)
685             hdi.fmt |= HDF_CENTER;
686
687         if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
688             hdi.fmt |= HDF_IMAGE;
689             
690         hdi.mask |= HDI_FORMAT;
691     }
692
693     if (lpcol->mask & LVCF_WIDTH) {
694         hdi.mask |= HDI_WIDTH;
695         hdi.cxy = lpcol->cx;
696     }
697     
698     if (lpcol->mask & LVCF_TEXT) {
699         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
700         hdi.pszText = lpcol->pszText;
701         hdi.fmt |= HDF_STRING;
702     }
703
704     if (lpcol->mask & LVCF_IMAGE) {
705         hdi.mask |= HDI_IMAGE;
706         hdi.iImage = lpcol->iImage;
707     }
708
709     if (lpcol->mask & LVCF_ORDER) {
710         hdi.mask |= HDI_ORDER;
711         hdi.iOrder = lpcol->iOrder;
712     }
713
714     return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A,
715                                     wParam, (LPARAM)&hdi);
716 }
717
718
719
720
721 static LRESULT
722 LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
723 {
724     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
725     HIMAGELIST himlTemp = 0;
726
727     TRACE (listview, "(0x%08x 0x%08lx)\n", wParam, lParam);
728
729     switch (wParam) {
730         case LVSIL_NORMAL:
731             himlTemp = infoPtr->himlNormal;
732             infoPtr->himlNormal = (HIMAGELIST)lParam;
733             return (LRESULT)himlTemp;
734
735         case LVSIL_SMALL:
736             himlTemp = infoPtr->himlSmall;
737             infoPtr->himlSmall = (HIMAGELIST)lParam;
738             return (LRESULT)himlTemp;
739
740         case LVSIL_STATE:
741             himlTemp = infoPtr->himlState;
742             infoPtr->himlState = (HIMAGELIST)lParam;
743             return (LRESULT)himlTemp;
744     }
745
746     return (LRESULT)NULL;
747 }
748
749
750
751 static LRESULT
752 LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
753 {
754     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
755     LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
756     LISTVIEW_ITEM *lpRow, *lpSubItem;
757     NMLISTVIEW nmlv;
758
759     if (!lpItem)
760         return FALSE;
761
762     if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
763         return FALSE;
764
765     if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
766         return FALSE;
767
768     /* send LVN_ITEMCHANGING notification */
769     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
770     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
771     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
772     nmlv.hdr.code     = LVN_ITEMCHANGING;
773     nmlv.iItem        = lpItem->iItem;
774     nmlv.iSubItem     = lpItem->iSubItem;
775     nmlv.uChanged     = lpItem->mask;
776
777     if (!SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
778                          (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv))
779         return FALSE;
780
781     TRACE (listview, "(%d %d %p)\n",
782            lpItem->iItem, lpItem->iSubItem, lpItem);
783
784     lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
785     if (!lpRow)
786         return FALSE;
787
788     lpSubItem = &lpRow[lpItem->iSubItem];
789     if (!lpSubItem)
790         return FALSE;
791
792     if (lpItem->mask & LVIF_STATE)
793         lpSubItem->state = (lpSubItem->state & lpItem->stateMask) | lpItem->state;
794
795     if (lpItem->mask & LVIF_TEXT) {
796         if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) {
797             if ((lpSubItem->pszText) &&
798                 (lpSubItem->pszText != LPSTR_TEXTCALLBACK32A))
799                 COMCTL32_Free (lpSubItem->pszText);
800             lpSubItem->pszText = LPSTR_TEXTCALLBACK32A;
801         }
802         else {
803             if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
804                 lpSubItem->pszText = NULL;
805             Str_SetPtr32A (&lpSubItem->pszText, lpItem->pszText);
806         }
807     }
808
809     if (lpItem->mask & LVIF_IMAGE)
810         lpSubItem->iImage = lpItem->iImage;
811
812     if (lpItem->mask & LVIF_PARAM)
813         lpSubItem->lParam = lpItem->lParam;
814
815     if (lpItem->mask & LVIF_INDENT)
816         lpSubItem->iIndent = lpItem->iIndent;
817
818     /* send LVN_ITEMCHANGED notification */
819     nmlv.hdr.code = LVN_ITEMCHANGED;
820     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
821                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
822
823     return TRUE;
824 }
825
826
827 // << LISTVIEW_SetItem32W >>
828 // << LISTVIEW_SetItemCount >>
829
830
831 static LRESULT
832 LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
833 {
834     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
835     INT32 nIndex = (INT32)wParam;
836
837     if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
838         return FALSE;
839
840     FIXME (listview, "setting position [%d, %d]!\n",
841            (INT32)LOWORD(lParam), (INT32)HIWORD(lParam));
842
843     /* FIXME: set position */
844
845     return TRUE;
846 }
847
848
849 static LRESULT
850 LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
851 {
852     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
853
854     if (!infoPtr)
855         return FALSE;
856
857     /* set text background color */
858     TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
859     infoPtr->clrTextBk = (COLORREF)lParam;
860
861     return TRUE;
862 }
863
864
865 static LRESULT
866 LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
867 {
868     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
869
870     if (!infoPtr)
871         return FALSE;
872
873     /* set text color */
874     TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
875     infoPtr->clrText = (COLORREF)lParam;
876
877     return TRUE;
878 }
879
880
881
882 static LRESULT
883 LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
884 {
885 //    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
886
887     FIXME (listview, "empty stub!\n");
888
889     /* fake success */
890     return TRUE;
891 }
892
893
894
895
896 static LRESULT
897 LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
898 {
899     /* info structure is created at NCCreate */
900     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
901     LOGFONT32A logFont;
902     DWORD dwStyle = WS_CHILD | WS_VISIBLE; 
903
904     TRACE (listview, "styles 0x%08lx 0x%08lx\n",
905            wndPtr->dwStyle, wndPtr->dwExStyle);
906
907     /* initialize info structure */
908     infoPtr->clrBk = CLR_NONE;
909     infoPtr->clrText = RGB(0, 0, 0); /* preliminary */
910     infoPtr->clrTextBk = RGB(255, 255, 255); /* preliminary */
911
912     if (!(wndPtr->dwStyle & LVS_REPORT) ||
913          (wndPtr->dwStyle & LVS_NOCOLUMNHEADER))
914         dwStyle |= HDS_HIDDEN;
915     if (!(wndPtr->dwStyle & LVS_NOSORTHEADER))
916         dwStyle |= HDS_BUTTONS;
917
918     /* create header */
919     infoPtr->hwndHeader =
920         CreateWindow32A (WC_HEADER32A, "", dwStyle,
921                          0, 0, 0, 0, wndPtr->hwndSelf,
922                          (HMENU32)0, wndPtr->hInstance, NULL);
923
924     /* get default font (icon title) */
925     SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
926     infoPtr->hDefaultFont = CreateFontIndirect32A (&logFont);
927     infoPtr->hFont = infoPtr->hDefaultFont;
928
929     /* set header font */
930     SendMessage32A (infoPtr->hwndHeader, WM_SETFONT,
931                     (WPARAM32)infoPtr->hFont, (LPARAM)TRUE);
932
933     infoPtr->hdpaItems = DPA_Create (10);
934
935     return 0;
936 }
937
938
939 static LRESULT
940 LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
941 {
942     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
943
944     /* delete all items */
945     LISTVIEW_DeleteAllItems (wndPtr);
946
947     /* destroy dpa */
948     DPA_Destroy (infoPtr->hdpaItems);
949
950     /* destroy header */
951     if (infoPtr->hwndHeader)
952         DestroyWindow32 (infoPtr->hwndHeader);
953
954     /* destroy font */
955     infoPtr->hFont = (HFONT32)0;
956     if (infoPtr->hDefaultFont)
957         DeleteObject32 (infoPtr->hDefaultFont);
958
959     
960
961     return 0;
962 }
963
964
965 static LRESULT
966 LISTVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
967 {
968     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
969
970     if (infoPtr->clrBk == CLR_NONE) {
971         return SendMessage32A (GetParent32 (wndPtr->hwndSelf),
972                                WM_ERASEBKGND, wParam, lParam);
973     }
974     else {
975         HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
976         FillRect32 ((HDC32)wParam, &infoPtr->rcList, hBrush);
977         DeleteObject32 (hBrush);
978         return FALSE;
979     }
980
981     return TRUE;
982 }
983
984
985 __inline__ static LRESULT
986 LISTVIEW_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
987 {
988     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
989
990     return infoPtr->hFont;
991 }
992
993
994 // << LISTVIEW_HScroll >>
995 // << LISTVIEW_KeyDown >>
996
997
998 static LRESULT
999 LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1000 {
1001     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1002     NMHDR nmh;
1003
1004     FIXME (listview, "semi stub!\n");
1005
1006     nmh.hwndFrom = wndPtr->hwndSelf;
1007     nmh.idFrom   = wndPtr->wIDmenu;
1008     nmh.code = NM_KILLFOCUS;
1009
1010     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1011                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
1012
1013     infoPtr->bFocus = FALSE;
1014
1015     return 0;
1016 }
1017
1018
1019 static LRESULT
1020 LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1021 {
1022     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1023     NMLISTVIEW nmlv;
1024
1025     FIXME (listview, "semi stub!\n");
1026
1027     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1028     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1029     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1030     nmlv.hdr.code = NM_DBLCLK;
1031     nmlv.iItem    = -1;
1032     nmlv.iSubItem = 0;
1033     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1034     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1035
1036     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1037                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1038
1039     return 0;
1040 }
1041
1042
1043 static LRESULT
1044 LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1045 {
1046     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1047     NMLISTVIEW nmlv;
1048
1049     FIXME (listview, "semi stub!\n");
1050
1051     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1052     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1053     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1054     nmlv.hdr.code = NM_CLICK;
1055     nmlv.iItem    = -1;
1056     nmlv.iSubItem = 0;
1057     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1058     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1059
1060     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1061                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1062
1063     if (!infoPtr->bFocus)
1064         SetFocus32 (wndPtr->hwndSelf);
1065
1066     return 0;
1067 }
1068
1069
1070 static LRESULT
1071 LISTVIEW_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1072 {
1073     LISTVIEW_INFO *infoPtr;
1074
1075     /* allocate memory for info structure */
1076     infoPtr = (LISTVIEW_INFO *)COMCTL32_Alloc (sizeof(LISTVIEW_INFO));
1077     wndPtr->wExtra[0] = (DWORD)infoPtr;
1078
1079     if (infoPtr == NULL) {
1080         ERR (listview, "could not allocate info memory!\n");
1081         return 0;
1082     }
1083
1084     if ((LISTVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) {
1085         ERR (listview, "pointer assignment error!\n");
1086         return 0;
1087     }
1088
1089     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
1090 }
1091
1092
1093 static LRESULT
1094 LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1095 {
1096     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1097
1098
1099
1100
1101     /* free list view info data */
1102     COMCTL32_Free (infoPtr);
1103
1104     return 0;
1105 }
1106
1107
1108 static LRESULT
1109 LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1110 {
1111     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1112     LPNMHDR lpnmh = (LPNMHDR)lParam;
1113
1114     if (lpnmh->hwndFrom == infoPtr->hwndHeader) {
1115
1116         FIXME (listview, "WM_NOTIFY from header!\n");
1117     }
1118     else {
1119
1120         FIXME (listview, "WM_NOTIFY from unknown source!\n");
1121     }
1122
1123     return 0;
1124 }
1125
1126
1127 static LRESULT
1128 LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam)
1129 {
1130     HDC32 hdc;
1131     PAINTSTRUCT32 ps;
1132
1133     hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1134     LISTVIEW_Refresh (wndPtr, hdc);
1135     if (!wParam)
1136         EndPaint32 (wndPtr->hwndSelf, &ps);
1137     return 0;
1138 }
1139
1140
1141 static LRESULT
1142 LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1143 {
1144     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1145     NMLISTVIEW nmlv;
1146
1147     FIXME (listview, "semi stub!\n");
1148
1149     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1150     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1151     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1152     nmlv.hdr.code = NM_RDBLCLK;
1153     nmlv.iItem    = -1;
1154     nmlv.iSubItem = 0;
1155     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1156     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1157
1158     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1159                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1160
1161     return 0;
1162 }
1163
1164
1165 static LRESULT
1166 LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1167 {
1168     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1169     NMLISTVIEW nmlv;
1170
1171     FIXME (listview, "semi stub!\n");
1172
1173     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1174     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1175     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1176     nmlv.hdr.code = NM_RCLICK;
1177     nmlv.iItem    = -1;
1178     nmlv.iSubItem = 0;
1179     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1180     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1181
1182     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1183                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1184
1185     return 0;
1186 }
1187
1188
1189 static LRESULT
1190 LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1191 {
1192     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1193     NMHDR nmh;
1194
1195     FIXME (listview, "semi stub!\n");
1196
1197     nmh.hwndFrom = wndPtr->hwndSelf;
1198     nmh.idFrom   = wndPtr->wIDmenu;
1199     nmh.code = NM_SETFOCUS;
1200
1201     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1202                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
1203
1204     infoPtr->bFocus = TRUE;
1205
1206     return 0;
1207 }
1208
1209
1210 static LRESULT
1211 LISTVIEW_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1212 {
1213     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1214     HFONT32 hFont = (HFONT32)wParam;
1215
1216     infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
1217
1218     /* set header font */
1219     SendMessage32A (infoPtr->hwndHeader, WM_SETFONT, wParam, lParam);
1220
1221     /* reinitialize the listview */
1222     
1223
1224
1225     if (lParam) {
1226         /* force redraw */
1227
1228
1229     }
1230
1231     return 0;
1232 }
1233
1234
1235
1236
1237 static LRESULT
1238 LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1239 {
1240     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1241
1242     GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList);
1243
1244     if (wndPtr->dwStyle & LVS_REPORT) {
1245         HDLAYOUT hl;
1246         WINDOWPOS32 wp;
1247         RECT32 rc;
1248
1249         rc.top = 0;
1250         rc.left = 0;
1251         rc.right = LOWORD(lParam);
1252         rc.bottom = HIWORD(lParam);
1253
1254         hl.prc = &rc;
1255         hl.pwpos = &wp;
1256         SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);
1257
1258         SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf,
1259                         wp.x, wp.y, wp.cx, wp.cy, wp.flags);
1260
1261         infoPtr->rcList.top += wp.cy;
1262     }
1263
1264     return 0;
1265 }
1266
1267
1268 LRESULT WINAPI
1269 LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1270 {
1271     WND *wndPtr = WIN_FindWndPtr(hwnd);
1272
1273     switch (uMsg)
1274     {
1275 //      case LVM_APPROXIMATEVIEWRECT:
1276 //      case LVM_ARRANGE:
1277 //      case LVM_CREATEDRAGIMAGE:
1278
1279         case LVM_DELETEALLITEMS:
1280             return LISTVIEW_DeleteAllItems (wndPtr);
1281
1282         case LVM_DELETECOLUMN:
1283             return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam);
1284
1285         case LVM_DELETEITEM:
1286             return LISTVIEW_DeleteItem (wndPtr, wParam, lParam);
1287
1288 //      case LVM_EDITLABEL:
1289 //      case LVM_ENSUREVISIBLE:
1290 //      case LVM_FINDITEM:
1291
1292         case LVM_GETBKCOLOR:
1293             return LISTVIEW_GetBkColor (wndPtr, wParam, lParam);
1294
1295 //      case LVM_GETBKIMAGE:
1296 //      case LVM_GETCALLBACKMASK:
1297
1298         case LVM_GETCOLUMN32A:
1299             return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam);
1300
1301 //      case LVM_GETCOLUMN32W:
1302 //      case LVM_GETCOLUMNORDERARRAY:
1303
1304         case LVM_GETCOLUMNWIDTH:
1305             return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam);
1306
1307 //      case LVM_GETCOUNTPERPAGE:
1308 //      case LVM_GETEDITCONTROL:
1309 //      case LVM_GETEXTENDEDLISTVIEWSTYLE:
1310
1311         case LVM_GETHEADER:
1312             return LISTVIEW_GetHeader (wndPtr, wParam, lParam);
1313
1314 //      case LVM_GETHOTCURSOR:
1315 //      case LVM_GETHOTITEM:
1316 //      case LVM_GETHOVERTIME:
1317
1318         case LVM_GETIMAGELIST:
1319             return LISTVIEW_GetImageList (wndPtr, wParam, lParam);
1320
1321 //      case LVM_GETISEARCHSTRING:
1322
1323         case LVM_GETITEM32A:
1324             return LISTVIEW_GetItem32A (wndPtr, wParam, lParam);
1325
1326 //      case LVM_GETITEM32W:
1327
1328         case LVM_GETITEMCOUNT:
1329             return LISTVIEW_GetItemCount (wndPtr, wParam, lParam);
1330
1331         case LVM_GETITEMPOSITION:
1332             return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam);
1333
1334 //      case LVM_GETITEMRECT:
1335 //      case LVM_GETITEMSPACING:
1336 //      case LVM_GETITEMSTATE:
1337
1338         case LVM_GETITEMTEXT32A:
1339             return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam);
1340
1341 //      case LVM_GETITEMTEXT32W:
1342
1343         case LVM_GETNEXTITEM:
1344             return LISTVIEW_GetNextItem (wndPtr, wParam, lParam);
1345
1346 //      case LVM_GETNUMBEROFWORKAREAS:
1347 //      case LVM_GETORIGIN:
1348
1349         case LVM_GETSELECTEDCOUNT:
1350             return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam);
1351
1352 //      case LVM_GETSELECTIONMARK:
1353
1354         case LVM_GETSTRINGWIDTH32A:
1355             return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam);
1356
1357 //      case LVM_GETSTRINGWIDTH32W:
1358 //      case LVM_GETSUBITEMRECT:
1359
1360         case LVM_GETTEXTBKCOLOR:
1361             return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam);
1362
1363         case LVM_GETTEXTCOLOR:
1364             return LISTVIEW_GetTextColor (wndPtr, wParam, lParam);
1365
1366 //      case LVM_GETTOOLTIPS:
1367 //      case LVM_GETTOPINDEX:
1368 //      case LVM_GETUNICODEFORMAT:
1369 //      case LVM_GETVIEWRECT:
1370 //      case LVM_GETWORKAREAS:
1371 //      case LVM_HITTEST:
1372
1373         case LVM_INSERTCOLUMN32A:
1374             return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam);
1375
1376 //      case LVM_INSERTCOLUMN32W:
1377
1378         case LVM_INSERTITEM32A:
1379             return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam);
1380
1381 //      case LVM_INSERTITEM32W:
1382
1383         case LVM_REDRAWITEMS:
1384             return LISTVIEW_RedrawItems (wndPtr, wParam, lParam);
1385
1386 //      case LVM_SCROLL:
1387
1388         case LVM_SETBKCOLOR:
1389             return LISTVIEW_SetBkColor (wndPtr, wParam, lParam);
1390
1391 //      case LVM_SETBKIMAGE:
1392 //      case LVM_SETCALLBACKMASK:
1393
1394         case LVM_SETCOLUMN32A:
1395             return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam);
1396
1397 //      case LVM_SETCOLUMN32W:
1398 //      case LVM_SETCOLUMNORDERARRAY:
1399 //      case LVM_SETCOLUMNWIDTH:
1400 //      case LVM_SETEXTENDEDLISTVIEWSTYLE:
1401 //      case LVM_SETHOTCURSOR:
1402 //      case LVM_SETHOTITEM:
1403 //      case LVM_SETHOVERTIME:
1404 //      case LVM_SETICONSPACING:
1405         
1406         case LVM_SETIMAGELIST:
1407             return LISTVIEW_SetImageList (wndPtr, wParam, lParam);
1408
1409         case LVM_SETITEM32A:
1410             return LISTVIEW_SetItem32A (wndPtr, wParam, lParam);
1411
1412 //      case LVM_SETITEM32W:
1413 //      case LVM_SETITEMCOUNT:
1414
1415         case LVM_SETITEMPOSITION:
1416             return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam);
1417
1418 //      case LVM_SETITEMPOSITION32:
1419 //      case LVM_SETITEMSTATE:
1420 //      case LVM_SETITEMTEXT:
1421 //      case LVM_SETSELECTIONMARK:
1422
1423         case LVM_SETTEXTBKCOLOR:
1424             return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam);
1425
1426         case LVM_SETTEXTCOLOR:
1427             return LISTVIEW_SetTextColor (wndPtr, wParam, lParam);
1428
1429 //      case LVM_SETTOOLTIPS:
1430 //      case LVM_SETUNICODEFORMAT:
1431 //      case LVM_SETWORKAREAS:
1432
1433         case LVM_SORTITEMS:
1434             return LISTVIEW_SortItems (wndPtr, wParam, lParam);
1435
1436 //      case LVM_SUBITEMHITTEST:
1437 //      case LVM_UPDATE:
1438
1439
1440
1441 //      case WM_CHAR:
1442 //      case WM_COMMAND:
1443
1444         case WM_CREATE:
1445             return LISTVIEW_Create (wndPtr, wParam, lParam);
1446
1447         case WM_DESTROY:
1448             return LISTVIEW_Destroy (wndPtr, wParam, lParam);
1449
1450         case WM_ERASEBKGND:
1451             return LISTVIEW_EraseBackground (wndPtr, wParam, lParam);
1452
1453         case WM_GETDLGCODE:
1454             return DLGC_WANTTAB | DLGC_WANTARROWS;
1455
1456         case WM_GETFONT:
1457             return LISTVIEW_GetFont (wndPtr, wParam, lParam);
1458
1459 //      case WM_HSCROLL:
1460 //      case WM_KEYDOWN:
1461
1462         case WM_KILLFOCUS:
1463             return LISTVIEW_KillFocus (wndPtr, wParam, lParam);
1464
1465         case WM_LBUTTONDBLCLK:
1466             return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam);
1467
1468         case WM_LBUTTONDOWN:
1469             return LISTVIEW_LButtonDown (wndPtr, wParam, lParam);
1470
1471 //      case WM_MOUSEMOVE:
1472 //          return LISTVIEW_MouseMove (wndPtr, wParam, lParam);
1473
1474         case WM_NCCREATE:
1475             return LISTVIEW_NCCreate (wndPtr, wParam, lParam);
1476
1477         case WM_NCDESTROY:
1478             return LISTVIEW_NCDestroy (wndPtr, wParam, lParam);
1479
1480         case WM_NOTIFY:
1481             return LISTVIEW_Notify (wndPtr, wParam, lParam);
1482
1483         case WM_PAINT:
1484             return LISTVIEW_Paint (wndPtr, wParam);
1485
1486         case WM_RBUTTONDBLCLK:
1487             return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam);
1488
1489         case WM_RBUTTONDOWN:
1490             return LISTVIEW_RButtonDown (wndPtr, wParam, lParam);
1491
1492         case WM_SETFOCUS:
1493             return LISTVIEW_SetFocus (wndPtr, wParam, lParam);
1494
1495         case WM_SETFONT:
1496             return LISTVIEW_SetFont (wndPtr, wParam, lParam);
1497
1498 //      case WM_SETREDRAW:
1499
1500         case WM_SIZE:
1501             return LISTVIEW_Size (wndPtr, wParam, lParam);
1502
1503 //      case WM_TIMER:
1504 //      case WM_VSCROLL:
1505 //      case WM_WINDOWPOSCHANGED:
1506 //      case WM_WININICHANGE:
1507
1508         default:
1509             if (uMsg >= WM_USER)
1510                 ERR (listview, "unknown msg %04x wp=%08x lp=%08lx\n",
1511                      uMsg, wParam, lParam);
1512             return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1513     }
1514     return 0;
1515 }
1516
1517
1518 void
1519 LISTVIEW_Register (void)
1520 {
1521     WNDCLASS32A wndClass;
1522
1523     if (GlobalFindAtom32A (WC_LISTVIEW32A)) return;
1524
1525     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1526     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
1527     wndClass.lpfnWndProc   = (WNDPROC32)LISTVIEW_WindowProc;
1528     wndClass.cbClsExtra    = 0;
1529     wndClass.cbWndExtra    = sizeof(LISTVIEW_INFO *);
1530     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
1531     wndClass.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1);
1532     wndClass.lpszClassName = WC_LISTVIEW32A;
1533  
1534     RegisterClass32A (&wndClass);
1535 }
1536