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