Added preliminary hit testing. Makes regedit.exe happy ;-)
[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_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
508 {
509 //    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
510     LPLVHITTESTINFO lpht = (LPLVHITTESTINFO)lParam;
511
512     FIXME (listview, "(%p): stub!\n", lpht);
513
514     /* FIXME: preliminary */
515     lpht->flags = LVHT_NOWHERE;
516     lpht->iItem = -1;
517     lpht->iSubItem = 0;
518
519     return -1;
520 }
521
522
523 static LRESULT
524 LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
525 {
526     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
527     LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
528     INT32 nIndex = (INT32)wParam;
529     HDITEM32A hdi;
530     INT32 nResult;
531
532     if ((!lpcol) || (infoPtr->nItemCount > 0))
533         return -1;
534
535     FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
536
537     ZeroMemory (&hdi, sizeof(HDITEM32A));
538
539     if (lpcol->mask & LVCF_FMT) {
540         if (nIndex == 0)
541             hdi.fmt |= HDF_LEFT;
542         else if (lpcol->fmt & LVCFMT_LEFT)
543             hdi.fmt |= HDF_LEFT;
544         else if (lpcol->fmt & LVCFMT_RIGHT)
545             hdi.fmt |= HDF_RIGHT;
546         else if (lpcol->fmt & LVCFMT_CENTER)
547             hdi.fmt |= HDF_CENTER;
548
549         if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
550             hdi.fmt |= HDF_IMAGE;
551             
552         hdi.mask |= HDI_FORMAT;
553     }
554
555     if (lpcol->mask & LVCF_WIDTH) {
556         hdi.mask |= HDI_WIDTH;
557         hdi.cxy = lpcol->cx;
558     }
559     
560     if (lpcol->mask & LVCF_TEXT) {
561         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
562         hdi.pszText = lpcol->pszText;
563         hdi.fmt |= HDF_STRING;
564     }
565
566     if (lpcol->mask & LVCF_IMAGE) {
567         hdi.mask |= HDI_IMAGE;
568         hdi.iImage = lpcol->iImage;
569     }
570
571     if (lpcol->mask & LVCF_ORDER) {
572         hdi.mask |= HDI_ORDER;
573         hdi.iOrder = lpcol->iOrder;
574     }
575
576     nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A,
577                               wParam, (LPARAM)&hdi);
578     if (nResult == -1)
579         return -1;
580
581     infoPtr->nColumnCount++;
582
583     return nResult;
584 }
585
586
587 // << LISTVIEW_InsertColumn32W >>
588
589
590 static LRESULT
591 LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
592 {
593     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
594     LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
595     LISTVIEW_ITEM *lpListItem;
596     INT32 nIndex;
597     NMLISTVIEW nmlv;
598
599     if (!lpItem)
600         return -1;
601
602     if ((!infoPtr->nColumnCount) || (lpItem->iSubItem))
603         return -1;
604
605     FIXME (listview, "(%d %p)\n", lpItem->iItem, lpItem);
606     FIXME (listview, "(%p %p)\n", infoPtr, infoPtr->hdpaItems);
607
608     lpListItem = (LISTVIEW_ITEM*)COMCTL32_Alloc (infoPtr->nColumnCount * sizeof(LISTVIEW_ITEM));
609     nIndex = DPA_InsertPtr (infoPtr->hdpaItems, lpItem->iItem, lpListItem);
610     if (nIndex == -1)
611         return -1;
612
613     if (lpItem->mask & LVIF_STATE)
614         lpListItem[0].state = lpItem->state;
615
616     if (lpItem->mask & LVIF_TEXT) {
617         if (lpItem->pszText == LPSTR_TEXTCALLBACK32A)
618             lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A;
619         else
620             Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText);
621     }
622
623     if (lpItem->mask & LVIF_IMAGE)
624         lpListItem[0].iImage = lpItem->iImage;
625
626     if (lpItem->mask & LVIF_PARAM)
627         lpListItem[0].lParam = lpItem->lParam;
628
629     if (lpItem->mask & LVIF_INDENT)
630         lpListItem[0].iIndent = lpItem->iIndent;
631
632     infoPtr->nItemCount++;
633
634     /* send notification */
635     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
636     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
637     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
638     nmlv.hdr.code     = LVN_INSERTITEM;
639     nmlv.iItem        = nIndex;
640     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
641                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
642
643     return nIndex;
644 }
645
646
647 // << LISTVIEW_InsertItem32W >>
648
649
650 static LRESULT
651 LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
652 {
653 //    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
654
655     FIXME (listview, "(%d - %d): empty stub!\n",
656            (INT32)wParam, (INT32)lParam);
657
658     return TRUE;
659 }
660
661
662
663 static LRESULT
664 LISTVIEW_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
665 {
666     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
667
668     if (!infoPtr)
669         return FALSE;
670
671     /* set background color */
672     TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
673     infoPtr->clrBk = (COLORREF)lParam;
674
675     return TRUE;
676 }
677
678
679 static LRESULT
680 LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
681 {
682     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
683     LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam;
684     INT32 nIndex = (INT32)wParam;
685     HDITEM32A hdi;
686
687     if (!lpcol)
688         return -1;
689
690     FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol);
691
692     ZeroMemory (&hdi, sizeof(HDITEM32A));
693
694     if (lpcol->mask & LVCF_FMT) {
695         if (nIndex == 0)
696             hdi.fmt |= HDF_LEFT;
697         else if (lpcol->fmt & LVCFMT_LEFT)
698             hdi.fmt |= HDF_LEFT;
699         else if (lpcol->fmt & LVCFMT_RIGHT)
700             hdi.fmt |= HDF_RIGHT;
701         else if (lpcol->fmt & LVCFMT_CENTER)
702             hdi.fmt |= HDF_CENTER;
703
704         if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES)
705             hdi.fmt |= HDF_IMAGE;
706             
707         hdi.mask |= HDI_FORMAT;
708     }
709
710     if (lpcol->mask & LVCF_WIDTH) {
711         hdi.mask |= HDI_WIDTH;
712         hdi.cxy = lpcol->cx;
713     }
714     
715     if (lpcol->mask & LVCF_TEXT) {
716         hdi.mask |= (HDI_TEXT | HDI_FORMAT);
717         hdi.pszText = lpcol->pszText;
718         hdi.fmt |= HDF_STRING;
719     }
720
721     if (lpcol->mask & LVCF_IMAGE) {
722         hdi.mask |= HDI_IMAGE;
723         hdi.iImage = lpcol->iImage;
724     }
725
726     if (lpcol->mask & LVCF_ORDER) {
727         hdi.mask |= HDI_ORDER;
728         hdi.iOrder = lpcol->iOrder;
729     }
730
731     return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A,
732                                     wParam, (LPARAM)&hdi);
733 }
734
735
736
737
738 static LRESULT
739 LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
740 {
741     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
742     HIMAGELIST himlTemp = 0;
743
744     TRACE (listview, "(0x%08x 0x%08lx)\n", wParam, lParam);
745
746     switch (wParam) {
747         case LVSIL_NORMAL:
748             himlTemp = infoPtr->himlNormal;
749             infoPtr->himlNormal = (HIMAGELIST)lParam;
750             return (LRESULT)himlTemp;
751
752         case LVSIL_SMALL:
753             himlTemp = infoPtr->himlSmall;
754             infoPtr->himlSmall = (HIMAGELIST)lParam;
755             return (LRESULT)himlTemp;
756
757         case LVSIL_STATE:
758             himlTemp = infoPtr->himlState;
759             infoPtr->himlState = (HIMAGELIST)lParam;
760             return (LRESULT)himlTemp;
761     }
762
763     return (LRESULT)NULL;
764 }
765
766
767
768 static LRESULT
769 LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
770 {
771     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
772     LPLVITEM32A lpItem = (LPLVITEM32A)lParam;
773     LISTVIEW_ITEM *lpRow, *lpSubItem;
774     NMLISTVIEW nmlv;
775
776     if (!lpItem)
777         return FALSE;
778
779     if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount))
780         return FALSE;
781
782     if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount))
783         return FALSE;
784
785     /* send LVN_ITEMCHANGING notification */
786     ZeroMemory (&nmlv, sizeof (NMLISTVIEW));
787     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
788     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
789     nmlv.hdr.code     = LVN_ITEMCHANGING;
790     nmlv.iItem        = lpItem->iItem;
791     nmlv.iSubItem     = lpItem->iSubItem;
792     nmlv.uChanged     = lpItem->mask;
793
794     if (!SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
795                          (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv))
796         return FALSE;
797
798     TRACE (listview, "(%d %d %p)\n",
799            lpItem->iItem, lpItem->iSubItem, lpItem);
800
801     lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem);
802     if (!lpRow)
803         return FALSE;
804
805     lpSubItem = &lpRow[lpItem->iSubItem];
806     if (!lpSubItem)
807         return FALSE;
808
809     if (lpItem->mask & LVIF_STATE)
810         lpSubItem->state = (lpSubItem->state & lpItem->stateMask) | lpItem->state;
811
812     if (lpItem->mask & LVIF_TEXT) {
813         if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) {
814             if ((lpSubItem->pszText) &&
815                 (lpSubItem->pszText != LPSTR_TEXTCALLBACK32A))
816                 COMCTL32_Free (lpSubItem->pszText);
817             lpSubItem->pszText = LPSTR_TEXTCALLBACK32A;
818         }
819         else {
820             if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A)
821                 lpSubItem->pszText = NULL;
822             Str_SetPtr32A (&lpSubItem->pszText, lpItem->pszText);
823         }
824     }
825
826     if (lpItem->mask & LVIF_IMAGE)
827         lpSubItem->iImage = lpItem->iImage;
828
829     if (lpItem->mask & LVIF_PARAM)
830         lpSubItem->lParam = lpItem->lParam;
831
832     if (lpItem->mask & LVIF_INDENT)
833         lpSubItem->iIndent = lpItem->iIndent;
834
835     /* send LVN_ITEMCHANGED notification */
836     nmlv.hdr.code = LVN_ITEMCHANGED;
837     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
838                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
839
840     return TRUE;
841 }
842
843
844 // << LISTVIEW_SetItem32W >>
845 // << LISTVIEW_SetItemCount >>
846
847
848 static LRESULT
849 LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
850 {
851     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
852     INT32 nIndex = (INT32)wParam;
853
854     if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount))
855         return FALSE;
856
857     FIXME (listview, "setting position [%d, %d]!\n",
858            (INT32)LOWORD(lParam), (INT32)HIWORD(lParam));
859
860     /* FIXME: set position */
861
862     return TRUE;
863 }
864
865
866 static LRESULT
867 LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
868 {
869     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
870
871     if (!infoPtr)
872         return FALSE;
873
874     /* set text background color */
875     TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
876     infoPtr->clrTextBk = (COLORREF)lParam;
877
878     return TRUE;
879 }
880
881
882 static LRESULT
883 LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
884 {
885     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
886
887     if (!infoPtr)
888         return FALSE;
889
890     /* set text color */
891     TRACE (listview, "0x%06lx\n", (COLORREF)lParam);
892     infoPtr->clrText = (COLORREF)lParam;
893
894     return TRUE;
895 }
896
897
898
899 static LRESULT
900 LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
901 {
902 //    LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
903
904     FIXME (listview, "empty stub!\n");
905
906     /* fake success */
907     return TRUE;
908 }
909
910
911
912
913 static LRESULT
914 LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
915 {
916     /* info structure is created at NCCreate */
917     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
918     LOGFONT32A logFont;
919     DWORD dwStyle = WS_CHILD | WS_VISIBLE; 
920
921     TRACE (listview, "styles 0x%08lx 0x%08lx\n",
922            wndPtr->dwStyle, wndPtr->dwExStyle);
923
924     /* initialize info structure */
925     infoPtr->clrBk = CLR_NONE;
926     infoPtr->clrText = RGB(0, 0, 0); /* preliminary */
927     infoPtr->clrTextBk = RGB(255, 255, 255); /* preliminary */
928
929     if (!(wndPtr->dwStyle & LVS_REPORT) ||
930          (wndPtr->dwStyle & LVS_NOCOLUMNHEADER))
931         dwStyle |= HDS_HIDDEN;
932     if (!(wndPtr->dwStyle & LVS_NOSORTHEADER))
933         dwStyle |= HDS_BUTTONS;
934
935     /* create header */
936     infoPtr->hwndHeader =
937         CreateWindow32A (WC_HEADER32A, "", dwStyle,
938                          0, 0, 0, 0, wndPtr->hwndSelf,
939                          (HMENU32)0, wndPtr->hInstance, NULL);
940
941     /* get default font (icon title) */
942     SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
943     infoPtr->hDefaultFont = CreateFontIndirect32A (&logFont);
944     infoPtr->hFont = infoPtr->hDefaultFont;
945
946     /* set header font */
947     SendMessage32A (infoPtr->hwndHeader, WM_SETFONT,
948                     (WPARAM32)infoPtr->hFont, (LPARAM)TRUE);
949
950     infoPtr->hdpaItems = DPA_Create (10);
951
952     return 0;
953 }
954
955
956 static LRESULT
957 LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
958 {
959     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
960
961     /* delete all items */
962     LISTVIEW_DeleteAllItems (wndPtr);
963
964     /* destroy dpa */
965     DPA_Destroy (infoPtr->hdpaItems);
966
967     /* destroy header */
968     if (infoPtr->hwndHeader)
969         DestroyWindow32 (infoPtr->hwndHeader);
970
971     /* destroy font */
972     infoPtr->hFont = (HFONT32)0;
973     if (infoPtr->hDefaultFont)
974         DeleteObject32 (infoPtr->hDefaultFont);
975
976     
977
978     return 0;
979 }
980
981
982 static LRESULT
983 LISTVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
984 {
985     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
986
987     if (infoPtr->clrBk == CLR_NONE) {
988         return SendMessage32A (GetParent32 (wndPtr->hwndSelf),
989                                WM_ERASEBKGND, wParam, lParam);
990     }
991     else {
992         HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
993         FillRect32 ((HDC32)wParam, &infoPtr->rcList, hBrush);
994         DeleteObject32 (hBrush);
995         return FALSE;
996     }
997
998     return TRUE;
999 }
1000
1001
1002 __inline__ static LRESULT
1003 LISTVIEW_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1004 {
1005     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1006
1007     return infoPtr->hFont;
1008 }
1009
1010
1011 // << LISTVIEW_HScroll >>
1012 // << LISTVIEW_KeyDown >>
1013
1014
1015 static LRESULT
1016 LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1017 {
1018     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1019     NMHDR nmh;
1020
1021     FIXME (listview, "semi stub!\n");
1022
1023     nmh.hwndFrom = wndPtr->hwndSelf;
1024     nmh.idFrom   = wndPtr->wIDmenu;
1025     nmh.code = NM_KILLFOCUS;
1026
1027     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1028                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
1029
1030     infoPtr->bFocus = FALSE;
1031
1032     return 0;
1033 }
1034
1035
1036 static LRESULT
1037 LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1038 {
1039     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1040     NMLISTVIEW nmlv;
1041
1042     FIXME (listview, "semi stub!\n");
1043
1044     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1045     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1046     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1047     nmlv.hdr.code = NM_DBLCLK;
1048     nmlv.iItem    = -1;
1049     nmlv.iSubItem = 0;
1050     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1051     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1052
1053     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1054                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1055
1056     return 0;
1057 }
1058
1059
1060 static LRESULT
1061 LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1062 {
1063     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1064     NMLISTVIEW nmlv;
1065
1066     FIXME (listview, "semi stub!\n");
1067
1068     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1069     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1070     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1071     nmlv.hdr.code = NM_CLICK;
1072     nmlv.iItem    = -1;
1073     nmlv.iSubItem = 0;
1074     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1075     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1076
1077     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1078                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1079
1080     if (!infoPtr->bFocus)
1081         SetFocus32 (wndPtr->hwndSelf);
1082
1083     return 0;
1084 }
1085
1086
1087 static LRESULT
1088 LISTVIEW_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1089 {
1090     LISTVIEW_INFO *infoPtr;
1091
1092     /* allocate memory for info structure */
1093     infoPtr = (LISTVIEW_INFO *)COMCTL32_Alloc (sizeof(LISTVIEW_INFO));
1094     wndPtr->wExtra[0] = (DWORD)infoPtr;
1095
1096     if (infoPtr == NULL) {
1097         ERR (listview, "could not allocate info memory!\n");
1098         return 0;
1099     }
1100
1101     if ((LISTVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) {
1102         ERR (listview, "pointer assignment error!\n");
1103         return 0;
1104     }
1105
1106     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
1107 }
1108
1109
1110 static LRESULT
1111 LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1112 {
1113     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1114
1115
1116
1117
1118     /* free list view info data */
1119     COMCTL32_Free (infoPtr);
1120
1121     return 0;
1122 }
1123
1124
1125 static LRESULT
1126 LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1127 {
1128     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1129     LPNMHDR lpnmh = (LPNMHDR)lParam;
1130
1131     if (lpnmh->hwndFrom == infoPtr->hwndHeader) {
1132
1133         FIXME (listview, "WM_NOTIFY from header!\n");
1134     }
1135     else {
1136
1137         FIXME (listview, "WM_NOTIFY from unknown source!\n");
1138     }
1139
1140     return 0;
1141 }
1142
1143
1144 static LRESULT
1145 LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam)
1146 {
1147     HDC32 hdc;
1148     PAINTSTRUCT32 ps;
1149
1150     hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1151     LISTVIEW_Refresh (wndPtr, hdc);
1152     if (!wParam)
1153         EndPaint32 (wndPtr->hwndSelf, &ps);
1154     return 0;
1155 }
1156
1157
1158 static LRESULT
1159 LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1160 {
1161     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1162     NMLISTVIEW nmlv;
1163
1164     FIXME (listview, "semi stub!\n");
1165
1166     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1167     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1168     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1169     nmlv.hdr.code = NM_RDBLCLK;
1170     nmlv.iItem    = -1;
1171     nmlv.iSubItem = 0;
1172     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1173     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1174
1175     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1176                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1177
1178     return 0;
1179 }
1180
1181
1182 static LRESULT
1183 LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1184 {
1185     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1186     NMLISTVIEW nmlv;
1187
1188     FIXME (listview, "semi stub!\n");
1189
1190     ZeroMemory (&nmlv, sizeof(NMLISTVIEW));
1191     nmlv.hdr.hwndFrom = wndPtr->hwndSelf;
1192     nmlv.hdr.idFrom   = wndPtr->wIDmenu;
1193     nmlv.hdr.code = NM_RCLICK;
1194     nmlv.iItem    = -1;
1195     nmlv.iSubItem = 0;
1196     nmlv.ptAction.x = (INT32)LOWORD(lParam);
1197     nmlv.ptAction.y = (INT32)HIWORD(lParam);
1198
1199     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1200                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv);
1201
1202     return 0;
1203 }
1204
1205
1206 static LRESULT
1207 LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1208 {
1209     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1210     NMHDR nmh;
1211
1212     FIXME (listview, "semi stub!\n");
1213
1214     nmh.hwndFrom = wndPtr->hwndSelf;
1215     nmh.idFrom   = wndPtr->wIDmenu;
1216     nmh.code = NM_SETFOCUS;
1217
1218     SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1219                     (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh);
1220
1221     infoPtr->bFocus = TRUE;
1222
1223     return 0;
1224 }
1225
1226
1227 static LRESULT
1228 LISTVIEW_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1229 {
1230     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1231     HFONT32 hFont = (HFONT32)wParam;
1232
1233     infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
1234
1235     /* set header font */
1236     SendMessage32A (infoPtr->hwndHeader, WM_SETFONT, wParam, lParam);
1237
1238     /* reinitialize the listview */
1239     
1240
1241
1242     if (lParam) {
1243         /* force redraw */
1244
1245
1246     }
1247
1248     return 0;
1249 }
1250
1251
1252
1253
1254 static LRESULT
1255 LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1256 {
1257     LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr);
1258
1259     GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList);
1260
1261     if (wndPtr->dwStyle & LVS_REPORT) {
1262         HDLAYOUT hl;
1263         WINDOWPOS32 wp;
1264         RECT32 rc;
1265
1266         rc.top = 0;
1267         rc.left = 0;
1268         rc.right = LOWORD(lParam);
1269         rc.bottom = HIWORD(lParam);
1270
1271         hl.prc = &rc;
1272         hl.pwpos = &wp;
1273         SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl);
1274
1275         SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf,
1276                         wp.x, wp.y, wp.cx, wp.cy, wp.flags);
1277
1278         infoPtr->rcList.top += wp.cy;
1279     }
1280
1281     return 0;
1282 }
1283
1284
1285 LRESULT WINAPI
1286 LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1287 {
1288     WND *wndPtr = WIN_FindWndPtr(hwnd);
1289
1290     switch (uMsg)
1291     {
1292 //      case LVM_APPROXIMATEVIEWRECT:
1293 //      case LVM_ARRANGE:
1294 //      case LVM_CREATEDRAGIMAGE:
1295
1296         case LVM_DELETEALLITEMS:
1297             return LISTVIEW_DeleteAllItems (wndPtr);
1298
1299         case LVM_DELETECOLUMN:
1300             return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam);
1301
1302         case LVM_DELETEITEM:
1303             return LISTVIEW_DeleteItem (wndPtr, wParam, lParam);
1304
1305 //      case LVM_EDITLABEL:
1306 //      case LVM_ENSUREVISIBLE:
1307 //      case LVM_FINDITEM:
1308
1309         case LVM_GETBKCOLOR:
1310             return LISTVIEW_GetBkColor (wndPtr, wParam, lParam);
1311
1312 //      case LVM_GETBKIMAGE:
1313 //      case LVM_GETCALLBACKMASK:
1314
1315         case LVM_GETCOLUMN32A:
1316             return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam);
1317
1318 //      case LVM_GETCOLUMN32W:
1319 //      case LVM_GETCOLUMNORDERARRAY:
1320
1321         case LVM_GETCOLUMNWIDTH:
1322             return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam);
1323
1324 //      case LVM_GETCOUNTPERPAGE:
1325 //      case LVM_GETEDITCONTROL:
1326 //      case LVM_GETEXTENDEDLISTVIEWSTYLE:
1327
1328         case LVM_GETHEADER:
1329             return LISTVIEW_GetHeader (wndPtr, wParam, lParam);
1330
1331 //      case LVM_GETHOTCURSOR:
1332 //      case LVM_GETHOTITEM:
1333 //      case LVM_GETHOVERTIME:
1334
1335         case LVM_GETIMAGELIST:
1336             return LISTVIEW_GetImageList (wndPtr, wParam, lParam);
1337
1338 //      case LVM_GETISEARCHSTRING:
1339
1340         case LVM_GETITEM32A:
1341             return LISTVIEW_GetItem32A (wndPtr, wParam, lParam);
1342
1343 //      case LVM_GETITEM32W:
1344
1345         case LVM_GETITEMCOUNT:
1346             return LISTVIEW_GetItemCount (wndPtr, wParam, lParam);
1347
1348         case LVM_GETITEMPOSITION:
1349             return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam);
1350
1351 //      case LVM_GETITEMRECT:
1352 //      case LVM_GETITEMSPACING:
1353 //      case LVM_GETITEMSTATE:
1354
1355         case LVM_GETITEMTEXT32A:
1356             return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam);
1357
1358 //      case LVM_GETITEMTEXT32W:
1359
1360         case LVM_GETNEXTITEM:
1361             return LISTVIEW_GetNextItem (wndPtr, wParam, lParam);
1362
1363 //      case LVM_GETNUMBEROFWORKAREAS:
1364 //      case LVM_GETORIGIN:
1365
1366         case LVM_GETSELECTEDCOUNT:
1367             return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam);
1368
1369 //      case LVM_GETSELECTIONMARK:
1370
1371         case LVM_GETSTRINGWIDTH32A:
1372             return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam);
1373
1374 //      case LVM_GETSTRINGWIDTH32W:
1375 //      case LVM_GETSUBITEMRECT:
1376
1377         case LVM_GETTEXTBKCOLOR:
1378             return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam);
1379
1380         case LVM_GETTEXTCOLOR:
1381             return LISTVIEW_GetTextColor (wndPtr, wParam, lParam);
1382
1383 //      case LVM_GETTOOLTIPS:
1384 //      case LVM_GETTOPINDEX:
1385 //      case LVM_GETUNICODEFORMAT:
1386 //      case LVM_GETVIEWRECT:
1387 //      case LVM_GETWORKAREAS:
1388
1389         case LVM_HITTEST:
1390             return LISTVIEW_HitTest (wndPtr, wParam, lParam);
1391
1392         case LVM_INSERTCOLUMN32A:
1393             return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam);
1394
1395 //      case LVM_INSERTCOLUMN32W:
1396
1397         case LVM_INSERTITEM32A:
1398             return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam);
1399
1400 //      case LVM_INSERTITEM32W:
1401
1402         case LVM_REDRAWITEMS:
1403             return LISTVIEW_RedrawItems (wndPtr, wParam, lParam);
1404
1405 //      case LVM_SCROLL:
1406
1407         case LVM_SETBKCOLOR:
1408             return LISTVIEW_SetBkColor (wndPtr, wParam, lParam);
1409
1410 //      case LVM_SETBKIMAGE:
1411 //      case LVM_SETCALLBACKMASK:
1412
1413         case LVM_SETCOLUMN32A:
1414             return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam);
1415
1416 //      case LVM_SETCOLUMN32W:
1417 //      case LVM_SETCOLUMNORDERARRAY:
1418 //      case LVM_SETCOLUMNWIDTH:
1419 //      case LVM_SETEXTENDEDLISTVIEWSTYLE:
1420 //      case LVM_SETHOTCURSOR:
1421 //      case LVM_SETHOTITEM:
1422 //      case LVM_SETHOVERTIME:
1423 //      case LVM_SETICONSPACING:
1424         
1425         case LVM_SETIMAGELIST:
1426             return LISTVIEW_SetImageList (wndPtr, wParam, lParam);
1427
1428         case LVM_SETITEM32A:
1429             return LISTVIEW_SetItem32A (wndPtr, wParam, lParam);
1430
1431 //      case LVM_SETITEM32W:
1432 //      case LVM_SETITEMCOUNT:
1433
1434         case LVM_SETITEMPOSITION:
1435             return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam);
1436
1437 //      case LVM_SETITEMPOSITION32:
1438 //      case LVM_SETITEMSTATE:
1439 //      case LVM_SETITEMTEXT:
1440 //      case LVM_SETSELECTIONMARK:
1441
1442         case LVM_SETTEXTBKCOLOR:
1443             return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam);
1444
1445         case LVM_SETTEXTCOLOR:
1446             return LISTVIEW_SetTextColor (wndPtr, wParam, lParam);
1447
1448 //      case LVM_SETTOOLTIPS:
1449 //      case LVM_SETUNICODEFORMAT:
1450 //      case LVM_SETWORKAREAS:
1451
1452         case LVM_SORTITEMS:
1453             return LISTVIEW_SortItems (wndPtr, wParam, lParam);
1454
1455 //      case LVM_SUBITEMHITTEST:
1456 //      case LVM_UPDATE:
1457
1458
1459
1460 //      case WM_CHAR:
1461 //      case WM_COMMAND:
1462
1463         case WM_CREATE:
1464             return LISTVIEW_Create (wndPtr, wParam, lParam);
1465
1466         case WM_DESTROY:
1467             return LISTVIEW_Destroy (wndPtr, wParam, lParam);
1468
1469         case WM_ERASEBKGND:
1470             return LISTVIEW_EraseBackground (wndPtr, wParam, lParam);
1471
1472         case WM_GETDLGCODE:
1473             return DLGC_WANTTAB | DLGC_WANTARROWS;
1474
1475         case WM_GETFONT:
1476             return LISTVIEW_GetFont (wndPtr, wParam, lParam);
1477
1478 //      case WM_HSCROLL:
1479 //      case WM_KEYDOWN:
1480
1481         case WM_KILLFOCUS:
1482             return LISTVIEW_KillFocus (wndPtr, wParam, lParam);
1483
1484         case WM_LBUTTONDBLCLK:
1485             return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam);
1486
1487         case WM_LBUTTONDOWN:
1488             return LISTVIEW_LButtonDown (wndPtr, wParam, lParam);
1489
1490 //      case WM_MOUSEMOVE:
1491 //          return LISTVIEW_MouseMove (wndPtr, wParam, lParam);
1492
1493         case WM_NCCREATE:
1494             return LISTVIEW_NCCreate (wndPtr, wParam, lParam);
1495
1496         case WM_NCDESTROY:
1497             return LISTVIEW_NCDestroy (wndPtr, wParam, lParam);
1498
1499         case WM_NOTIFY:
1500             return LISTVIEW_Notify (wndPtr, wParam, lParam);
1501
1502         case WM_PAINT:
1503             return LISTVIEW_Paint (wndPtr, wParam);
1504
1505         case WM_RBUTTONDBLCLK:
1506             return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam);
1507
1508         case WM_RBUTTONDOWN:
1509             return LISTVIEW_RButtonDown (wndPtr, wParam, lParam);
1510
1511         case WM_SETFOCUS:
1512             return LISTVIEW_SetFocus (wndPtr, wParam, lParam);
1513
1514         case WM_SETFONT:
1515             return LISTVIEW_SetFont (wndPtr, wParam, lParam);
1516
1517 //      case WM_SETREDRAW:
1518
1519         case WM_SIZE:
1520             return LISTVIEW_Size (wndPtr, wParam, lParam);
1521
1522 //      case WM_TIMER:
1523 //      case WM_VSCROLL:
1524 //      case WM_WINDOWPOSCHANGED:
1525 //      case WM_WININICHANGE:
1526
1527         default:
1528             if (uMsg >= WM_USER)
1529                 ERR (listview, "unknown msg %04x wp=%08x lp=%08lx\n",
1530                      uMsg, wParam, lParam);
1531             return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1532     }
1533     return 0;
1534 }
1535
1536
1537 VOID
1538 LISTVIEW_Register (VOID)
1539 {
1540     WNDCLASS32A wndClass;
1541
1542     if (GlobalFindAtom32A (WC_LISTVIEW32A)) return;
1543
1544     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1545     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
1546     wndClass.lpfnWndProc   = (WNDPROC32)LISTVIEW_WindowProc;
1547     wndClass.cbClsExtra    = 0;
1548     wndClass.cbWndExtra    = sizeof(LISTVIEW_INFO *);
1549     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
1550     wndClass.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1);
1551     wndClass.lpszClassName = WC_LISTVIEW32A;
1552  
1553     RegisterClass32A (&wndClass);
1554 }
1555
1556
1557 VOID
1558 LISTVIEW_Unregister (VOID)
1559 {
1560     if (GlobalFindAtom32A (WC_LISTVIEW32A))
1561         UnregisterClass32A (WC_LISTVIEW32A, (HINSTANCE32)NULL);
1562 }
1563