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