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