]> git.saurik.com Git - wxWidgets.git/blame - src/msw/listctrl.cpp
Cured DC/GDI object leak; listbox window proc restored from debugging
[wxWidgets.git] / src / msw / listctrl.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: listctrl.cpp
3// Purpose: wxListCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "listctrl.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx.h"
25#endif
26
27#if defined(__WIN95__)
28
29#include "wx/listctrl.h"
30
31#include "wx/msw/private.h"
32
33#ifndef __GNUWIN32__
34#include <commctrl.h>
35#endif
36
37#ifdef __GNUWIN32__
38#include "wx/msw/gnuwin32/extra.h"
39#endif
40
41static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem);
42static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem, HWND getFullInfo = 0);
43
44#if !USE_SHARED_LIBRARY
45IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
46IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
47
48#endif
49
50wxListCtrl::wxListCtrl(void)
51{
52 m_imageListNormal = NULL;
53 m_imageListSmall = NULL;
54 m_imageListState = NULL;
55 m_baseStyle = 0;
56 m_colCount = 0;
57}
58
59bool wxListCtrl::Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
60 const long style, const wxValidator& validator, const wxString& name)
61{
62 m_imageListNormal = NULL;
63 m_imageListSmall = NULL;
64 m_imageListState = NULL;
65 m_colCount = 0;
66
67 wxSystemSettings settings;
68 SetBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_WINDOW));
69 SetForegroundColour(parent->GetDefaultForegroundColour());
70
71 SetValidator(validator);
72 SetName(name);
73
74 int x = pos.x;
75 int y = pos.y;
76 int width = size.x;
77 int height = size.y;
78
79 m_windowStyle = style;
80
81 SetParent(parent);
82
83 if (width <= 0)
84 width = 100;
85 if (height <= 0)
86 height = 30;
87 if (x < 0)
88 x = 0;
89 if (y < 0)
90 y = 0;
91
92 m_windowId = (id == -1) ? NewControlId() : id;
93
94 DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP;
95
96 bool want3D;
97 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
98
99 // Even with extended styles, need to combine with WS_BORDER
100 // for them to look right.
101 if (want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
102 (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER))
103 wstyle |= WS_BORDER;
104
105 wstyle |= LVS_SHAREIMAGELISTS;
106 m_baseStyle = wstyle;
107
108 long oldStyle = 0; // Dummy
109 wstyle |= ConvertToMSWStyle(oldStyle, m_windowStyle);
110
111 // Create the ListView control.
112 HWND hWndListControl = CreateWindowEx(exStyle,
113 WC_LISTVIEW,
114 "",
115 wstyle,
116 x, y, width, height,
117 (HWND) parent->GetHWND(),
118 (HMENU)m_windowId,
119 wxGetInstance(),
120 NULL );
121
122 m_hWnd = (WXHWND) hWndListControl;
123 if (parent) parent->AddChild(this);
124
125 SubclassWin((WXHWND) m_hWnd);
126
127 return TRUE;
128}
129
130wxListCtrl::~wxListCtrl(void)
131{
132 m_textCtrl.SetHWND((WXHWND) NULL);
133}
134
135// Add or remove a single window style
136void wxListCtrl::SetSingleStyle(const long style, const bool add)
137{
138 long flag = GetWindowStyleFlag();
139
140 // Get rid of conflicting styles
141 if ( add )
142 {
143 if ( style & wxLC_MASK_TYPE)
144 flag = flag & ~wxLC_MASK_TYPE ;
145 if ( style & wxLC_MASK_ALIGN )
146 flag = flag & ~wxLC_MASK_ALIGN ;
147 if ( style & wxLC_MASK_SORT )
148 flag = flag & ~wxLC_MASK_SORT ;
149 }
150
151 if ( flag & style )
152 {
153 if ( !add )
154 flag -= style;
155 }
156 else
157 {
158 if ( add )
159 {
160 flag |= style;
161 }
162 }
163
164 m_windowStyle = flag;
165
166 RecreateWindow();
167}
168
169// Set the whole window style
170void wxListCtrl::SetWindowStyleFlag(const long flag)
171{
172 m_windowStyle = flag;
173
174 RecreateWindow();
175}
176
177void wxListCtrl::RecreateWindow(void)
178{
179 if ( GetHWND() )
180 {
181 long oldStyle = 0;
182 long style = ConvertToMSWStyle(oldStyle, m_windowStyle);
183 style |= m_baseStyle;
184// ::SetWindowLong((HWND) GetHWND(), GWL_STYLE, style);
185
186 // The following recreation of the window appears to be necessary
187 // because SetWindowLong doesn't seem to do it.
188
189 int x, y, width, height;
190 GetPosition(&x, &y);
191 GetSize(&width, &height);
192
193 UnsubclassWin();
194 ::DestroyWindow((HWND) GetHWND());
195
196 // Experimental
197 // Recreate the ListView control: unfortunately I can't
198 // make it work by using SetWindowLong.
199 bool want3D;
200 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
201 HWND hWndListControl = CreateWindowEx(exStyle,
202 WC_LISTVIEW,
203 "",
204 style,
205 x, y, width, height,
206 (HWND) GetParent()->GetHWND(),
207 (HMENU)m_windowId,
208 wxGetInstance(),
209 NULL );
210
211 m_hWnd = (WXHWND) hWndListControl;
212 SubclassWin((WXHWND) m_hWnd);
213
214 if ( m_imageListNormal )
215 SetImageList(m_imageListNormal, wxIMAGE_LIST_NORMAL);
216 if ( m_imageListSmall )
217 SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL);
218 if ( m_imageListState )
219 SetImageList(m_imageListState, wxIMAGE_LIST_STATE);
220 }
221}
222
223// Can be just a single style, or a bitlist
224long wxListCtrl::ConvertToMSWStyle(long& oldStyle, const long style) const
225{
226 long wstyle = 0;
227 if ( style & wxLC_ICON )
228 {
229 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
230 oldStyle -= LVS_SMALLICON;
231 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
232 oldStyle -= LVS_REPORT;
233 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
234 oldStyle -= LVS_LIST;
235 wstyle |= LVS_ICON;
236 }
237
238 if ( style & wxLC_SMALL_ICON )
239 {
240 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
241 oldStyle -= LVS_ICON;
242 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
243 oldStyle -= LVS_REPORT;
244 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
245 oldStyle -= LVS_LIST;
246 wstyle |= LVS_SMALLICON;
247 }
248
249 if ( style & wxLC_LIST )
250 {
251 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
252 oldStyle -= LVS_ICON;
253 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
254 oldStyle -= LVS_REPORT;
255 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
256 oldStyle -= LVS_SMALLICON;
257 wstyle |= LVS_LIST;
258 }
259
260 if ( style & wxLC_REPORT )
261 {
262 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
263 oldStyle -= LVS_ICON;
264 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
265 oldStyle -= LVS_LIST;
266 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
267 oldStyle -= LVS_SMALLICON;
268 wstyle |= LVS_REPORT;
269 }
270
271 if ( style & wxLC_ALIGN_LEFT )
272 {
273 if ( oldStyle & LVS_ALIGNTOP )
274 oldStyle -= LVS_ALIGNTOP;
275 wstyle |= LVS_ALIGNLEFT;
276 }
277
278 if ( style & wxLC_ALIGN_TOP )
279 {
280 if ( oldStyle & LVS_ALIGNLEFT )
281 oldStyle -= LVS_ALIGNLEFT;
282 wstyle |= LVS_ALIGNTOP;
283 }
284
285 if ( style & wxLC_AUTOARRANGE )
286 wstyle |= LVS_AUTOARRANGE;
287
288 // Apparently, no such style (documentation wrong?)
289/*
290 if ( style & wxLC_BUTTON )
291 wstyle |= LVS_BUTTON;
292*/
293
294 if ( style & wxLC_NO_SORT_HEADER )
295 wstyle |= LVS_NOSORTHEADER;
296
297 if ( style & wxLC_NO_HEADER )
298 wstyle |= LVS_NOCOLUMNHEADER;
299
300 if ( style & wxLC_EDIT_LABELS )
301 wstyle |= LVS_EDITLABELS;
302
303 if ( style & wxLC_SINGLE_SEL )
304 wstyle |= LVS_SINGLESEL;
305
306 if ( style & wxLC_SORT_ASCENDING )
307 {
308 if ( oldStyle & LVS_SORTDESCENDING )
309 oldStyle -= LVS_SORTDESCENDING;
310 wstyle |= LVS_SORTASCENDING;
311 }
312
313 if ( style & wxLC_SORT_DESCENDING )
314 {
315 if ( oldStyle & LVS_SORTASCENDING )
316 oldStyle -= LVS_SORTASCENDING;
317 wstyle |= LVS_SORTDESCENDING;
318 }
319
320 return wstyle;
321}
322
323// Sets the background colour (GetBackgroundColour already implicit in
324// wxWindow class)
325void wxListCtrl::SetBackgroundColour(const wxColour& col)
326{
327 wxWindow::SetBackgroundColour(col);
328
329 ListView_SetBkColor((HWND) GetHWND(), PALETTERGB(col.Red(), col.Green(), col.Blue()));
330}
331
332// Gets information about this column
333bool wxListCtrl::GetColumn(const int col, wxListItem& item) const
334{
335 LV_COLUMN lvCol;
336 lvCol.mask = 0;
337 lvCol.fmt = 0;
338 lvCol.pszText = NULL;
339
340 if ( item.m_mask & wxLIST_MASK_TEXT )
341 {
342 lvCol.mask |= LVCF_TEXT;
343 lvCol.pszText = new char[513];
344 lvCol.cchTextMax = 512;
345 }
346
347 bool success = (ListView_GetColumn((HWND) GetHWND(), col, & lvCol) != 0);
348
349// item.m_subItem = lvCol.iSubItem;
350 item.m_width = lvCol.cx;
351
352 if ( (item.m_mask & wxLIST_MASK_TEXT) && lvCol.pszText )
353 {
354 item.m_text = lvCol.pszText;
355 delete[] lvCol.pszText;
356 }
357
358 if ( item.m_mask & wxLIST_MASK_FORMAT )
359 {
360 if (lvCol.fmt == LVCFMT_LEFT)
361 item.m_format = wxLIST_FORMAT_LEFT;
362 else if (lvCol.fmt == LVCFMT_RIGHT)
363 item.m_format = wxLIST_FORMAT_RIGHT;
364 else if (lvCol.fmt == LVCFMT_CENTER)
365 item.m_format = wxLIST_FORMAT_CENTRE;
366 }
367
368 return success;
369}
370
371// Sets information about this column
372bool wxListCtrl::SetColumn(const int col, wxListItem& item)
373{
374 LV_COLUMN lvCol;
375 lvCol.mask = 0;
376 lvCol.fmt = 0;
377 lvCol.pszText = NULL;
378
379 if ( item.m_mask & wxLIST_MASK_TEXT )
380 {
381 lvCol.mask |= LVCF_TEXT;
382 lvCol.pszText = WXSTRINGCAST item.m_text;
383 lvCol.cchTextMax = 0; // Ignored
384 }
385 if ( item.m_mask & wxLIST_MASK_FORMAT )
386 {
387 lvCol.mask |= LVCF_FMT;
388
389 if ( item.m_format == wxLIST_FORMAT_LEFT )
390 lvCol.fmt = LVCFMT_LEFT;
391 if ( item.m_format == wxLIST_FORMAT_RIGHT )
392 lvCol.fmt = LVCFMT_RIGHT;
393 if ( item.m_format == wxLIST_FORMAT_CENTRE )
394 lvCol.fmt = LVCFMT_CENTER;
395 }
396
397 if ( item.m_mask & wxLIST_MASK_WIDTH )
398 {
399 lvCol.mask |= LVCF_WIDTH;
400 lvCol.cx = item.m_width;
401
402 if ( lvCol.cx == wxLIST_AUTOSIZE)
403 lvCol.cx = LVSCW_AUTOSIZE;
404 else if ( lvCol.cx == wxLIST_AUTOSIZE_USEHEADER)
405 lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
406 }
407 lvCol.mask |= LVCF_SUBITEM;
408 lvCol.iSubItem = col;
409 return (ListView_SetColumn((HWND) GetHWND(), col, & lvCol) != 0);
410}
411
412// Gets the column width
413int wxListCtrl::GetColumnWidth(const int col) const
414{
415 return ListView_GetColumnWidth((HWND) GetHWND(), col);
416}
417
418// Sets the column width
419bool wxListCtrl::SetColumnWidth(const int col, const int width)
420{
421 int col2 = col;
422 if ( m_windowStyle & wxLC_LIST )
423 col2 = -1;
424
425 int width2 = width;
426 if ( width2 == wxLIST_AUTOSIZE)
427 width2 = LVSCW_AUTOSIZE;
428 else if ( width2 == wxLIST_AUTOSIZE_USEHEADER)
429 width2 = LVSCW_AUTOSIZE_USEHEADER;
430
431 return (ListView_SetColumnWidth((HWND) GetHWND(), col2, width2) != 0);
432}
433
434// Gets the number of items that can fit vertically in the
435// visible area of the list control (list or report view)
436// or the total number of items in the list control (icon
437// or small icon view)
438int wxListCtrl::GetCountPerPage(void) const
439{
440 return ListView_GetCountPerPage((HWND) GetHWND());
441}
442
443// Gets the edit control for editing labels.
444wxTextCtrl& wxListCtrl::GetEditControl(void) const
445{
446 HWND hWnd = (HWND) ListView_GetEditControl((HWND) GetHWND());
447 ((wxListCtrl *)this)->m_textCtrl.SetHWND((WXHWND) hWnd);
448 return (wxTextCtrl&)m_textCtrl;
449}
450
451// Gets information about the item
452bool wxListCtrl::GetItem(wxListItem& info) const
453{
454 LV_ITEM lvItem;
455 lvItem.pszText = NULL;
456 if ( info.m_mask & wxLIST_MASK_TEXT )
457 {
458 lvItem.pszText = new char[513];
459 lvItem.cchTextMax = 512;
460 }
461 bool success = (::SendMessage((HWND) GetHWND(), LVM_GETITEM, 0, (LPARAM)& lvItem) != 0);
462
463 if ( !success )
464 {
465 if (lvItem.pszText)
466 delete[] lvItem.pszText;
467
468 return FALSE;
469 }
470
471 wxConvertFromMSWListItem(this, info, lvItem);
472
473 if (lvItem.pszText)
474 delete[] lvItem.pszText;
475
476 return success;
477}
478
479// Sets information about the item
480bool wxListCtrl::SetItem(wxListItem& info)
481{
482 LV_ITEM item;
483 wxConvertToMSWListItem(this, info, item);
484 item.cchTextMax = 0;
485 return (ListView_SetItem((HWND) GetHWND(), &item) != 0);
486}
487
488long wxListCtrl::SetItem(const long index, const int col, const wxString& label, const int imageId)
489{
490 wxListItem info;
491 info.m_text = label;
492 info.m_mask = wxLIST_MASK_TEXT;
493 info.m_itemId = index;
494 info.m_col = col;
495 if ( imageId > -1 )
496 {
497 info.m_image = imageId;
498 info.m_mask |= wxLIST_MASK_IMAGE;
499 }
500 return SetItem(info);
501}
502
503
504// Gets the item state
505int wxListCtrl::GetItemState(const long item, const long stateMask) const
506{
507 wxListItem info;
508
509 info.m_mask = wxLIST_MASK_STATE ;
510 info.m_stateMask = stateMask;
511 info.m_itemId = item;
512
513 if (!GetItem(info))
514 return 0;
515
516 return info.m_state;
517}
518
519// Sets the item state
520bool wxListCtrl::SetItemState(const long item, const long state, const long stateMask)
521{
522 wxListItem info;
523
524 info.m_mask = wxLIST_MASK_STATE ;
525 info.m_state = state;
526 info.m_stateMask = stateMask;
527 info.m_itemId = item;
528
529 return SetItem(info);
530}
531
532// Sets the item image
533bool wxListCtrl::SetItemImage(const long item, const int image, const int selImage)
534{
535 wxListItem info;
536
537 info.m_mask = wxLIST_MASK_IMAGE ;
538 info.m_image = image;
539 info.m_itemId = item;
540
541 return SetItem(info);
542}
543
544// Gets the item text
545wxString wxListCtrl::GetItemText(const long item) const
546{
547 wxListItem info;
548
549 info.m_mask = wxLIST_MASK_TEXT ;
550 info.m_itemId = item;
551
552 if (!GetItem(info))
553 return wxString("");
554 return info.m_text;
555}
556
557// Sets the item text
558void wxListCtrl::SetItemText(const long item, const wxString& str)
559{
560 wxListItem info;
561
562 info.m_mask = wxLIST_MASK_TEXT ;
563 info.m_itemId = item;
564 info.m_text = str;
565
566 SetItem(info);
567}
568
569// Gets the item data
570long wxListCtrl::GetItemData(const long item) const
571{
572 wxListItem info;
573
574 info.m_mask = wxLIST_MASK_DATA ;
575 info.m_itemId = item;
576
577 if (!GetItem(info))
578 return 0;
579 return info.m_data;
580}
581
582// Sets the item data
583bool wxListCtrl::SetItemData(const long item, long data)
584{
585 wxListItem info;
586
587 info.m_mask = wxLIST_MASK_DATA ;
588 info.m_itemId = item;
589 info.m_data = data;
590
591 return SetItem(info);
592}
593
594// Gets the item rectangle
595bool wxListCtrl::GetItemRect(const long item, wxRectangle& rect, const int code) const
596{
597 RECT rect2;
598
599 int code2 = LVIR_BOUNDS;
600 if ( code == wxLIST_RECT_BOUNDS )
601 code2 = LVIR_BOUNDS;
602 else if ( code == wxLIST_RECT_ICON )
603 code2 = LVIR_ICON;
604 else if ( code == wxLIST_RECT_LABEL )
605 code2 = LVIR_LABEL;
606
607 bool success = (ListView_GetItemRect((HWND) GetHWND(), (int) item, &rect2, code2) != 0);
608
609 rect.x = rect2.left;
610 rect.y = rect2.top;
611 rect.width = rect2.right - rect2.left;
612 rect.height = rect2.bottom - rect2.left;
613 return success;
614}
615
616// Gets the item position
617bool wxListCtrl::GetItemPosition(const long item, wxPoint& pos) const
618{
619 POINT pt;
620
621 bool success = (ListView_GetItemPosition((HWND) GetHWND(), (int) item, &pt) != 0);
622
623 pos.x = pt.x; pos.y = pt.y;
624 return success;
625}
626
627// Sets the item position.
628bool wxListCtrl::SetItemPosition(const long item, const wxPoint& pos)
629{
630 return (ListView_SetItemPosition((HWND) GetHWND(), (int) item, pos.x, pos.y) != 0);
631}
632
633// Gets the number of items in the list control
634int wxListCtrl::GetItemCount(void) const
635{
636 return ListView_GetItemCount((HWND) GetHWND());
637}
638
639// Retrieves the spacing between icons in pixels.
640// If small is TRUE, gets the spacing for the small icon
641// view, otherwise the large icon view.
642int wxListCtrl::GetItemSpacing(bool isSmall) const
643{
644 return ListView_GetItemSpacing((HWND) GetHWND(), (BOOL) isSmall);
645}
646
647// Gets the number of selected items in the list control
648int wxListCtrl::GetSelectedItemCount(void) const
649{
650 return ListView_GetSelectedCount((HWND) GetHWND());
651}
652
653// Gets the text colour of the listview
654wxColour wxListCtrl::GetTextColour(void) const
655{
656 COLORREF ref = ListView_GetTextColor((HWND) GetHWND());
657 wxColour col(GetRValue(ref), GetGValue(ref), GetBValue(ref));
658 return col;
659}
660
661// Sets the text colour of the listview
662void wxListCtrl::SetTextColour(const wxColour& col)
663{
664 ListView_SetTextColor((HWND) GetHWND(), PALETTERGB(col.Red(), col.Blue(), col.Green()));
665}
666
667// Gets the index of the topmost visible item when in
668// list or report view
669long wxListCtrl::GetTopItem(void) const
670{
671 return (long) ListView_GetTopIndex((HWND) GetHWND());
672}
673
674// Searches for an item, starting from 'item'.
675// 'geometry' is one of
676// wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
677// 'state' is a state bit flag, one or more of
678// wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
679// item can be -1 to find the first item that matches the
680// specified flags.
681// Returns the item or -1 if unsuccessful.
682long wxListCtrl::GetNextItem(const long item, int geom, int state) const
683{
684 long flags = 0;
685
686 if ( geom == wxLIST_NEXT_ABOVE )
687 flags |= LVNI_ABOVE;
688 if ( geom == wxLIST_NEXT_ALL )
689 flags |= LVNI_ALL;
690 if ( geom == wxLIST_NEXT_BELOW )
691 flags |= LVNI_BELOW;
692 if ( geom == wxLIST_NEXT_LEFT )
693 flags |= LVNI_TOLEFT;
694 if ( geom == wxLIST_NEXT_RIGHT )
695 flags |= LVNI_TORIGHT;
696
697 if ( state & wxLIST_STATE_CUT )
698 flags |= LVNI_CUT;
699 if ( state & wxLIST_STATE_DROPHILITED )
700 flags |= LVNI_DROPHILITED;
701 if ( state & wxLIST_STATE_FOCUSED )
702 flags |= LVNI_FOCUSED;
703 if ( state & wxLIST_STATE_SELECTED )
704 flags |= LVNI_SELECTED;
705
706 return (long) ListView_GetNextItem((HWND) GetHWND(), item, flags);
707}
708
709
710wxImageList *wxListCtrl::GetImageList(const int which) const
711{
712 if ( which == wxIMAGE_LIST_NORMAL )
713 {
714 return m_imageListNormal;
715 }
716 else if ( which == wxIMAGE_LIST_SMALL )
717 {
718 return m_imageListSmall;
719 }
720 else if ( which == wxIMAGE_LIST_STATE )
721 {
722 return m_imageListState;
723 }
724 return NULL;
725}
726
727void wxListCtrl::SetImageList(wxImageList *imageList, const int which)
728{
729 int flags = 0;
730 if ( which == wxIMAGE_LIST_NORMAL )
731 {
732 flags = LVSIL_NORMAL;
733 m_imageListNormal = imageList;
734 }
735 else if ( which == wxIMAGE_LIST_SMALL )
736 {
737 flags = LVSIL_SMALL;
738 m_imageListSmall = imageList;
739 }
740 else if ( which == wxIMAGE_LIST_STATE )
741 {
742 flags = LVSIL_STATE;
743 m_imageListState = imageList;
744 }
745 ListView_SetImageList((HWND) GetHWND(), (HIMAGELIST) imageList ? imageList->GetHIMAGELIST() : 0, flags);
746}
747
748// Operations
749////////////////////////////////////////////////////////////////////////////
750
751// Arranges the items
752bool wxListCtrl::Arrange(const int flag)
753{
754 UINT code = 0;
755 if ( flag == wxLIST_ALIGN_LEFT )
756 code = LVA_ALIGNLEFT;
757 else if ( flag == wxLIST_ALIGN_TOP )
758 code = LVA_ALIGNTOP;
759 else if ( flag == wxLIST_ALIGN_DEFAULT )
760 code = LVA_DEFAULT;
761 else if ( flag == wxLIST_ALIGN_SNAP_TO_GRID )
762 code = LVA_SNAPTOGRID;
763
764 return (ListView_Arrange((HWND) GetHWND(), code) != 0);
765}
766
767// Deletes an item
768bool wxListCtrl::DeleteItem(const long item)
769{
770 return (ListView_DeleteItem((HWND) GetHWND(), (int) item) != 0);
771}
772
773// Deletes all items
774bool wxListCtrl::DeleteAllItems(void)
775{
776 return (ListView_DeleteAllItems((HWND) GetHWND()) != 0);
777}
778
779// Deletes all items
780bool wxListCtrl::DeleteAllColumns(void)
781{
782 int i;
783 for ( i = 0; i < m_colCount; i++)
784 {
785 if (ListView_DeleteColumn((HWND) GetHWND(), 0) != 0)
786 m_colCount --;
787 }
788 return (m_colCount == 0);
789}
790
791// Deletes a column
792bool wxListCtrl::DeleteColumn(const int col)
793{
794 bool success = (ListView_DeleteColumn((HWND) GetHWND(), col) != 0);
795
796 if ( success && (m_colCount > 0) )
797 m_colCount --;
798 return success;
799}
800
801// Clears items, and columns if there are any.
802void wxListCtrl::ClearAll(void)
803{
804 DeleteAllItems();
805 if ( m_colCount > 0 )
806 DeleteAllColumns();
807}
808
809// Edits a label
810wxTextCtrl& wxListCtrl::Edit(const long item)
811{
812 HWND hWnd = (HWND) ListView_EditLabel((HWND) GetHWND(), (int) item);
813 m_textCtrl.SetHWND((WXHWND) hWnd);
814 return m_textCtrl;
815}
816
817// Ensures this item is visible
818bool wxListCtrl::EnsureVisible(const long item)
819{
820 return (ListView_EnsureVisible((HWND) GetHWND(), (int) item, FALSE) != 0);
821}
822
823// Find an item whose label matches this string, starting from the item after 'start'
824// or the beginning if 'start' is -1.
825long wxListCtrl::FindItem(const long start, const wxString& str, const bool partial)
826{
827 LV_FINDINFO findInfo;
828
829 findInfo.flags = LVFI_STRING;
830 if ( partial )
831 findInfo.flags |= LVFI_STRING;
832 findInfo.psz = WXSTRINGCAST str;
833
834 return ListView_FindItem((HWND) GetHWND(), (int) start, & findInfo);
835}
836
837// Find an item whose data matches this data, starting from the item after 'start'
838// or the beginning if 'start' is -1.
839long wxListCtrl::FindItem(const long start, const long data)
840{
841 LV_FINDINFO findInfo;
842
843 findInfo.flags = LVFI_PARAM;
844 findInfo.lParam = data;
845
846 return ListView_FindItem((HWND) GetHWND(), (int) start, & findInfo);
847}
848
849// Find an item nearest this position in the specified direction, starting from
850// the item after 'start' or the beginning if 'start' is -1.
851long wxListCtrl::FindItem(const long start, const wxPoint& pt, const int direction)
852{
853 LV_FINDINFO findInfo;
854
855 findInfo.flags = LVFI_NEARESTXY;
856 findInfo.pt.x = pt.x;
857 findInfo.pt.y = pt.y;
858 findInfo.vkDirection = VK_RIGHT;
859
860 if ( direction == wxLIST_FIND_UP )
861 findInfo.vkDirection = VK_UP;
862 else if ( direction == wxLIST_FIND_DOWN )
863 findInfo.vkDirection = VK_DOWN;
864 else if ( direction == wxLIST_FIND_LEFT )
865 findInfo.vkDirection = VK_LEFT;
866 else if ( direction == wxLIST_FIND_RIGHT )
867 findInfo.vkDirection = VK_RIGHT;
868
869 return ListView_FindItem((HWND) GetHWND(), (int) start, & findInfo);
870}
871
872// Determines which item (if any) is at the specified point,
873// giving details in 'flags' (see wxLIST_HITTEST_... flags above)
874long wxListCtrl::HitTest(const wxPoint& point, int& flags)
875{
876 LV_HITTESTINFO hitTestInfo;
877 hitTestInfo.pt.x = (int) point.x;
878 hitTestInfo.pt.y = (int) point.y;
879
880 ListView_HitTest((HWND) GetHWND(), & hitTestInfo);
881
882 flags = 0;
883 if ( hitTestInfo.flags & LVHT_ABOVE )
884 flags |= wxLIST_HITTEST_ABOVE;
885 if ( hitTestInfo.flags & LVHT_BELOW )
886 flags |= wxLIST_HITTEST_BELOW;
887 if ( hitTestInfo.flags & LVHT_NOWHERE )
888 flags |= wxLIST_HITTEST_NOWHERE;
889 if ( hitTestInfo.flags & LVHT_ONITEMICON )
890 flags |= wxLIST_HITTEST_ONITEMICON;
891 if ( hitTestInfo.flags & LVHT_ONITEMLABEL )
892 flags |= wxLIST_HITTEST_ONITEMLABEL;
893 if ( hitTestInfo.flags & LVHT_ONITEMSTATEICON )
894 flags |= wxLIST_HITTEST_ONITEMSTATEICON;
895 if ( hitTestInfo.flags & LVHT_TOLEFT )
896 flags |= wxLIST_HITTEST_TOLEFT;
897 if ( hitTestInfo.flags & LVHT_TORIGHT )
898 flags |= wxLIST_HITTEST_TORIGHT;
899
900 return (long) hitTestInfo.iItem ;
901}
902
903// Inserts an item, returning the index of the new item if successful,
904// -1 otherwise.
905// TOD: Should also have some further convenience functions
906// which don't require setting a wxListItem object
907long wxListCtrl::InsertItem(wxListItem& info)
908{
909 LV_ITEM item;
910 wxConvertToMSWListItem(this, info, item);
911
912 return (long) ListView_InsertItem((HWND) GetHWND(), & item);
913}
914
915long wxListCtrl::InsertItem(const long index, const wxString& label)
916{
917 wxListItem info;
918 info.m_text = label;
919 info.m_mask = wxLIST_MASK_TEXT;
920 info.m_itemId = index;
921 return InsertItem(info);
922}
923
924// Inserts an image item
925long wxListCtrl::InsertItem(const long index, const int imageIndex)
926{
927 wxListItem info;
928 info.m_image = imageIndex;
929 info.m_mask = wxLIST_MASK_IMAGE;
930 info.m_itemId = index;
931 return InsertItem(info);
932}
933
934// Inserts an image/string item
935long wxListCtrl::InsertItem(const long index, const wxString& label, const int imageIndex)
936{
937 wxListItem info;
938 info.m_image = imageIndex;
939 info.m_text = label;
940 info.m_mask = wxLIST_MASK_IMAGE | wxLIST_MASK_TEXT;
941 info.m_itemId = index;
942 return InsertItem(info);
943}
944
945// For list view mode (only), inserts a column.
946long wxListCtrl::InsertColumn(const long col, wxListItem& item)
947{
948 LV_COLUMN lvCol;
949 lvCol.mask = 0;
950 lvCol.fmt = 0;
951 lvCol.pszText = NULL;
952
953 if ( item.m_mask & wxLIST_MASK_TEXT )
954 {
955 lvCol.mask |= LVCF_TEXT;
956 lvCol.pszText = WXSTRINGCAST item.m_text;
957 lvCol.cchTextMax = 0; // Ignored
958 }
959 if ( item.m_mask & wxLIST_MASK_FORMAT )
960 {
961 lvCol.mask |= LVCF_FMT;
962
963 if ( item.m_format == wxLIST_FORMAT_LEFT )
964 lvCol.fmt = LVCFMT_LEFT;
965 if ( item.m_format == wxLIST_FORMAT_RIGHT )
966 lvCol.fmt = LVCFMT_RIGHT;
967 if ( item.m_format == wxLIST_FORMAT_CENTRE )
968 lvCol.fmt = LVCFMT_CENTER;
969 }
970
971 if ( item.m_mask & wxLIST_MASK_WIDTH )
972 {
973 lvCol.mask |= LVCF_WIDTH;
974 lvCol.cx = item.m_width;
975
976 if ( lvCol.cx == wxLIST_AUTOSIZE)
977 lvCol.cx = LVSCW_AUTOSIZE;
978 else if ( lvCol.cx == wxLIST_AUTOSIZE_USEHEADER)
979 lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
980 }
981 lvCol.mask |= LVCF_SUBITEM;
982 lvCol.iSubItem = col;
983
984 bool success = (ListView_InsertColumn((HWND) GetHWND(), col, & lvCol) != 0);
985 if ( success )
986 m_colCount ++;
987 return success;
988}
989
990long wxListCtrl::InsertColumn(const long col, const wxString& heading, const int format,
991 const int width)
992{
993 wxListItem item;
994 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
995 item.m_text = heading;
996 if ( width > -1 )
997 {
998 item.m_mask |= wxLIST_MASK_WIDTH;
999 item.m_width = width;
1000 }
1001 item.m_format = format;
1002
1003 return InsertColumn(col, item);
1004}
1005
1006// Scrolls the list control. If in icon, small icon or report view mode,
1007// x specifies the number of pixels to scroll. If in list view mode, x
1008// specifies the number of columns to scroll.
1009// If in icon, small icon or list view mode, y specifies the number of pixels
1010// to scroll. If in report view mode, y specifies the number of lines to scroll.
1011bool wxListCtrl::ScrollList(const int dx, const int dy)
1012{
1013 return (ListView_Scroll((HWND) GetHWND(), dx, dy) != 0);
1014}
1015
1016// Sort items.
1017
1018// fn is a function which takes 3 long arguments: item1, item2, data.
1019// item1 is the long data associated with a first item (NOT the index).
1020// item2 is the long data associated with a second item (NOT the index).
1021// data is the same value as passed to SortItems.
1022// The return value is a negative number if the first item should precede the second
1023// item, a positive number of the second item should precede the first,
1024// or zero if the two items are equivalent.
1025
1026// data is arbitrary data to be passed to the sort function.
1027bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data)
1028{
1029 return (ListView_SortItems((HWND) GetHWND(), (PFNLVCOMPARE) fn, data) != 0);
1030}
1031
1032bool wxListCtrl::MSWCommand(const WXUINT cmd, const WXWORD id)
1033{
1034 if (cmd == EN_UPDATE)
1035 {
1036 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
1037 event.SetEventObject( this );
1038 ProcessCommand(event);
1039 return TRUE;
1040 }
1041 else if (cmd == EN_KILLFOCUS)
1042 {
1043 wxCommandEvent event(wxEVT_KILL_FOCUS, id);
1044 event.SetEventObject( this );
1045 ProcessCommand(event);
1046 return TRUE;
1047 }
1048 else return FALSE;
1049}
1050
1051bool wxListCtrl::MSWNotify(const WXWPARAM wParam, const WXLPARAM lParam)
1052{
1053 wxListEvent event(0, m_windowId);
1054 int eventType = 0;
1055 NMHDR *hdr1 = (NMHDR *) lParam;
1056 switch ( hdr1->code )
1057 {
1058 case LVN_BEGINDRAG:
1059 {
1060 eventType = wxEVT_COMMAND_LIST_BEGIN_DRAG;
1061 NM_LISTVIEW *hdr = (NM_LISTVIEW *)lParam;
1062 event.m_itemIndex = hdr->iItem;
1063 event.m_pointDrag.x = hdr->ptAction.x;
1064 event.m_pointDrag.y = hdr->ptAction.y;
1065 break;
1066 }
1067 case LVN_BEGINLABELEDIT:
1068 {
1069 eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT;
1070 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1071 wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND());
1072 break;
1073 }
1074 case LVN_BEGINRDRAG:
1075 {
1076 eventType = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
1077 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1078 event.m_itemIndex = hdr->iItem;
1079 event.m_pointDrag.x = hdr->ptAction.x;
1080 event.m_pointDrag.y = hdr->ptAction.y;
1081 break;
1082 }
1083 case LVN_COLUMNCLICK:
1084 {
1085 eventType = wxEVT_COMMAND_LIST_COL_CLICK;
1086 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1087 event.m_itemIndex = -1;
1088 event.m_col = hdr->iSubItem;
1089 break;
1090 }
1091 case LVN_DELETEALLITEMS:
1092 {
1093 eventType = wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS;
1094// NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1095 event.m_itemIndex = -1;
1096 break;
1097 }
1098 case LVN_DELETEITEM:
1099 {
1100 eventType = wxEVT_COMMAND_LIST_DELETE_ITEM;
1101 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1102 event.m_itemIndex = hdr->iItem;
1103 break;
1104 }
1105 case LVN_ENDLABELEDIT:
1106 {
1107 eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
1108 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1109 wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND());
1110 if ( info->item.pszText == NULL || info->item.iItem == -1 )
1111 event.m_cancelled = TRUE;
1112 break;
1113 }
1114 case LVN_GETDISPINFO:
1115 {
1116// return FALSE;
1117 // TODO: some text buffering here, I think
1118 // TODO: API for getting Windows to retrieve values
1119 // on demand.
1120 eventType = wxEVT_COMMAND_LIST_GET_INFO;
1121 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1122 wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND());
1123 break;
1124 }
1125 case LVN_INSERTITEM:
1126 {
1127 eventType = wxEVT_COMMAND_LIST_INSERT_ITEM;
1128 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1129 event.m_itemIndex = hdr->iItem;
1130 break;
1131 }
1132 case LVN_ITEMCHANGED:
1133 {
1134 // This needs to be sent to wxListCtrl as a rather more
1135 // concrete event. For now, just detect a selection
1136 // or deselection.
1137 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1138 if ( (hdr->uNewState & LVIS_SELECTED) && !(hdr->uOldState & LVIS_SELECTED) )
1139 {
1140 eventType = wxEVT_COMMAND_LIST_ITEM_SELECTED;
1141 event.m_itemIndex = hdr->iItem;
1142 }
1143 else if ( !(hdr->uNewState & LVIS_SELECTED) && (hdr->uOldState & LVIS_SELECTED) )
1144 {
1145 eventType = wxEVT_COMMAND_LIST_ITEM_DESELECTED;
1146 event.m_itemIndex = hdr->iItem;
1147 }
1148 else
1149 return FALSE;
1150 break;
1151 }
1152 case LVN_KEYDOWN:
1153 {
1154 eventType = wxEVT_COMMAND_LIST_KEY_DOWN;
1155 LV_KEYDOWN *info = (LV_KEYDOWN *)lParam;
1156 event.m_code = wxCharCodeMSWToWX(info->wVKey);
1157 break;
1158 }
1159 case LVN_SETDISPINFO:
1160 {
1161 eventType = wxEVT_COMMAND_LIST_SET_INFO;
1162 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1163 wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND());
1164 break;
1165 }
1166
1167 default :
1168 return wxControl::MSWNotify(wParam, lParam);
1169 break;
1170 }
1171
1172 event.SetEventObject( this );
1173 event.SetEventType(eventType);
1174
1175 if ( !GetEventHandler()->ProcessEvent(event) )
1176 return FALSE;
1177
1178 if (hdr1->code == LVN_GETDISPINFO)
1179 {
1180 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1181 if ( info->item.mask & LVIF_TEXT )
1182 {
1183 if ( !event.m_item.m_text.IsNull() )
1184 {
1185 info->item.pszText = AddPool(event.m_item.m_text);
1186 info->item.cchTextMax = strlen(info->item.pszText) + 1;
1187 }
1188 }
1189// wxConvertToMSWListItem(this, event.m_item, info->item);
1190 }
1191
1192 return TRUE;
1193}
1194
1195char *wxListCtrl::AddPool(const wxString& str)
1196{
1197 // Remove the first element if 3 strings exist
1198 if ( m_stringPool.Number() == 3 )
1199 {
1200 wxNode *node = m_stringPool.First();
1201 delete[] (char *)node->Data();
1202 delete node;
1203 }
1204 wxNode *node = m_stringPool.Add((char *) (const char *)str);
1205 return (char *)node->Data();
1206}
1207
1208// List item structure
1209wxListItem::wxListItem(void)
1210{
1211 m_mask = 0;
1212 m_itemId = 0;
1213 m_col = 0;
1214 m_state = 0;
1215 m_stateMask = 0;
1216 m_image = 0;
1217 m_data = 0;
1218
1219 m_format = wxLIST_FORMAT_CENTRE;
1220 m_width = 0;
1221}
1222
1223static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem, HWND getFullInfo)
1224{
1225 info.m_data = lvItem.lParam;
1226 info.m_mask = 0;
1227 info.m_state = 0;
1228 info.m_stateMask = 0;
1229 info.m_itemId = lvItem.iItem;
1230
1231 long oldMask = lvItem.mask;
1232
1233 bool needText = FALSE;
1234 if (getFullInfo != 0)
1235 {
1236 if ( lvItem.mask & LVIF_TEXT )
1237 needText = FALSE;
1238 else
1239 needText = TRUE;
1240
1241 if ( needText )
1242 {
1243 lvItem.pszText = new char[513];
1244 lvItem.cchTextMax = 512;
1245 }
1246// lvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM ;
1247 lvItem.mask |= LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM ;
1248 ::SendMessage(getFullInfo, LVM_GETITEM, 0, (LPARAM)& lvItem) ;
1249 }
1250
1251 if ( lvItem.mask & LVIF_STATE )
1252 {
1253 info.m_mask |= wxLIST_MASK_STATE;
1254
1255 if ( lvItem.stateMask & LVIS_CUT)
1256 {
1257 info.m_stateMask |= wxLIST_STATE_CUT ;
1258 if ( lvItem.state & LVIS_CUT )
1259 info.m_state |= wxLIST_STATE_CUT ;
1260 }
1261 if ( lvItem.stateMask & LVIS_DROPHILITED)
1262 {
1263 info.m_stateMask |= wxLIST_STATE_DROPHILITED ;
1264 if ( lvItem.state & LVIS_DROPHILITED )
1265 info.m_state |= wxLIST_STATE_DROPHILITED ;
1266 }
1267 if ( lvItem.stateMask & LVIS_FOCUSED)
1268 {
1269 info.m_stateMask |= wxLIST_STATE_FOCUSED ;
1270 if ( lvItem.state & LVIS_FOCUSED )
1271 info.m_state |= wxLIST_STATE_FOCUSED ;
1272 }
1273 if ( lvItem.stateMask & LVIS_SELECTED)
1274 {
1275 info.m_stateMask |= wxLIST_STATE_SELECTED ;
1276 if ( lvItem.state & LVIS_SELECTED )
1277 info.m_state |= wxLIST_STATE_SELECTED ;
1278 }
1279 }
1280
1281 if ( lvItem.mask & LVIF_TEXT )
1282 {
1283 info.m_mask |= wxLIST_MASK_TEXT;
1284 info.m_text = lvItem.pszText;
1285 }
1286 if ( lvItem.mask & LVIF_IMAGE )
1287 {
1288 info.m_mask |= wxLIST_MASK_IMAGE;
1289 info.m_image = lvItem.iImage;
1290 }
1291 if ( lvItem.mask & LVIF_PARAM )
1292 info.m_mask |= wxLIST_MASK_DATA;
1293 if ( lvItem.mask & LVIF_DI_SETITEM )
1294 info.m_mask |= wxLIST_SET_ITEM;
1295 info.m_col = lvItem.iSubItem;
1296
1297 if (needText)
1298 {
1299 if (lvItem.pszText)
1300 delete[] lvItem.pszText;
1301 }
1302 lvItem.mask = oldMask ;
1303}
1304
1305static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem)
1306{
1307 lvItem.iItem = (int) info.m_itemId ;
1308
1309 lvItem.iImage = info.m_image ;
1310 lvItem.lParam = info.m_data;
1311 lvItem.stateMask = 0;
1312 lvItem.state = 0;
1313 lvItem.mask = 0;
1314 lvItem.iSubItem = info.m_col;
1315
1316 if (info.m_mask & wxLIST_MASK_STATE)
1317 {
1318 lvItem.mask |= LVIF_STATE ;
1319 if (info.m_stateMask & wxLIST_STATE_CUT)
1320 {
1321 lvItem.stateMask |= LVIS_CUT ;
1322 if (info.m_state & wxLIST_STATE_CUT)
1323 lvItem.state |= LVIS_CUT;
1324 }
1325 if (info.m_stateMask & wxLIST_STATE_DROPHILITED)
1326 {
1327 lvItem.stateMask |= LVIS_DROPHILITED;
1328 if (info.m_state & wxLIST_STATE_DROPHILITED)
1329 lvItem.state |= LVIS_DROPHILITED;
1330 }
1331 if (info.m_stateMask & wxLIST_STATE_FOCUSED)
1332 {
1333 lvItem.stateMask |= LVIS_FOCUSED;
1334 if (info.m_state & wxLIST_STATE_FOCUSED)
1335 lvItem.state |= LVIS_FOCUSED;
1336 }
1337 if (info.m_stateMask & wxLIST_STATE_SELECTED)
1338 {
1339 lvItem.stateMask |= LVIS_SELECTED;
1340 if (info.m_state & wxLIST_STATE_SELECTED)
1341 lvItem.state |= LVIS_SELECTED;
1342 }
1343 }
1344
1345 if (info.m_mask & wxLIST_MASK_TEXT)
1346 {
1347 lvItem.mask |= LVIF_TEXT ;
1348 if ( ctrl->GetWindowStyleFlag() & wxLC_USER_TEXT )
1349 {
1350 lvItem.pszText = LPSTR_TEXTCALLBACK;
1351 }
1352 else
1353 {
1354 lvItem.pszText = (char *) (const char *)info.m_text ;
1355 if ( lvItem.pszText )
1356 lvItem.cchTextMax = info.m_text.Length();
1357 else
1358 lvItem.cchTextMax = 0;
1359 }
1360 }
1361 if (info.m_mask & wxLIST_MASK_IMAGE)
1362 lvItem.mask |= LVIF_IMAGE ;
1363 if (info.m_mask & wxLIST_MASK_DATA)
1364 lvItem.mask |= LVIF_PARAM ;
1365}
1366
1367// List event
1368IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxCommandEvent)
1369
1370wxListEvent::wxListEvent(WXTYPE commandType, int id):
1371 wxCommandEvent(commandType, id)
1372{
1373 m_code = 0;
1374 m_itemIndex = 0;
1375 m_col = 0;
1376 m_cancelled = FALSE;
1377}
1378
1379#endif
1380