1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "listctrl.h"
22 #pragma implementation "listctrlbase.h"
25 // For compilers that support precompilation, includes "wx.h".
26 #include "wx/wxprec.h"
38 #include "wx/listctrl.h"
41 #include "wx/msw/private.h"
43 #ifdef __GNUWIN32_OLD__
44 #include "wx/msw/gnuwin32/extra.h"
51 (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)
54 #ifndef LVM_SETEXTENDEDLISTVIEWSTYLE
55 #define LVM_SETEXTENDEDLISTVIEWSTYLE (0x1000 + 54)
58 #ifndef LVS_EX_FULLROWSELECT
59 #define LVS_EX_FULLROWSELECT 0x00000020
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 static void wxConvertToMSWListItem(const wxListCtrl
*ctrl
, wxListItem
& info
, LV_ITEM
& tvItem
);
67 static void wxConvertFromMSWListItem(const wxListCtrl
*ctrl
, wxListItem
& info
, LV_ITEM
& tvItem
, HWND getFullInfo
= 0);
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
74 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
76 // ============================================================================
78 // ============================================================================
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 void wxListEvent::CopyObject(wxObject
& object_dest
) const
86 wxListEvent
*obj
= (wxListEvent
*)&object_dest
;
88 wxNotifyEvent::CopyObject(object_dest
);
91 obj
->m_itemIndex
= m_itemIndex
;
92 obj
->m_oldItemIndex
= m_oldItemIndex
;
94 obj
->m_cancelled
= m_cancelled
;
95 obj
->m_pointDrag
= m_pointDrag
;
96 obj
->m_item
.m_mask
= m_item
.m_mask
;
97 obj
->m_item
.m_itemId
= m_item
.m_itemId
;
98 obj
->m_item
.m_col
= m_item
.m_col
;
99 obj
->m_item
.m_state
= m_item
.m_state
;
100 obj
->m_item
.m_stateMask
= m_item
.m_stateMask
;
101 obj
->m_item
.m_text
= m_item
.m_text
;
102 obj
->m_item
.m_image
= m_item
.m_image
;
103 obj
->m_item
.m_data
= m_item
.m_data
;
104 obj
->m_item
.m_format
= m_item
.m_format
;
105 obj
->m_item
.m_width
= m_item
.m_width
;
107 if ( m_item
.HasAttributes() )
109 obj
->m_item
.SetTextColour(m_item
.GetTextColour());
110 obj
->m_item
.SetBackgroundColour(m_item
.GetBackgroundColour());
111 obj
->m_item
.SetFont(m_item
.GetFont());
115 // ----------------------------------------------------------------------------
116 // wxListCtrl construction
117 // ----------------------------------------------------------------------------
119 void wxListCtrl::Init()
121 m_imageListNormal
= NULL
;
122 m_imageListSmall
= NULL
;
123 m_imageListState
= NULL
;
127 m_hasAnyAttr
= FALSE
;
130 bool wxListCtrl::Create(wxWindow
*parent
,
135 const wxValidator
& validator
,
136 const wxString
& name
)
139 SetValidator(validator
);
140 #endif // wxUSE_VALIDATORS
149 m_windowStyle
= style
;
162 m_windowId
= (id
== -1) ? NewControlId() : id
;
164 DWORD wstyle
= WS_VISIBLE
| WS_CHILD
| WS_TABSTOP
|
165 LVS_SHAREIMAGELISTS
| LVS_SHOWSELALWAYS
;
166 if ( wxStyleHasBorder(m_windowStyle
) )
168 m_baseStyle
= wstyle
;
170 if ( !DoCreateControl(x
, y
, width
, height
) )
174 parent
->AddChild(this);
179 bool wxListCtrl::DoCreateControl(int x
, int y
, int w
, int h
)
181 DWORD wstyle
= m_baseStyle
;
184 WXDWORD exStyle
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
);
186 // Even with extended styles, need to combine with WS_BORDER
187 // for them to look right.
191 long oldStyle
= 0; // Dummy
192 wstyle
|= ConvertToMSWStyle(oldStyle
, m_windowStyle
);
194 // Create the ListView control.
195 m_hWnd
= (WXHWND
)CreateWindowEx(exStyle
,
200 GetWinHwnd(GetParent()),
207 wxLogError(_("Can't create list control window, check "
208 "that comctl32.dll is installed."));
213 // for comctl32.dll v 4.70+ we want to have this attribute because it's
214 // prettier (and also because wxGTK does it like this)
215 if ( (wstyle
& LVS_REPORT
) && wxTheApp
->GetComCtl32Version() >= 470 )
217 ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE
,
218 0, LVS_EX_FULLROWSELECT
);
221 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
));
222 SetForegroundColour(GetParent()->GetForegroundColour());
229 void wxListCtrl::UpdateStyle()
233 // The new window view style
235 DWORD dwStyleNew
= ConvertToMSWStyle(dummy
, m_windowStyle
);
236 dwStyleNew
|= m_baseStyle
;
238 // Get the current window style.
239 DWORD dwStyleOld
= ::GetWindowLong(GetHwnd(), GWL_STYLE
);
241 // Only set the window style if the view bits have changed.
242 if ( dwStyleOld
!= dwStyleNew
)
244 ::SetWindowLong(GetHwnd(), GWL_STYLE
, dwStyleNew
);
249 void wxListCtrl::FreeAllAttrs(bool dontRecreate
)
253 for ( wxNode
*node
= m_attrs
.Next(); node
; node
= m_attrs
.Next() )
255 delete (wxListItemAttr
*)node
->Data();
261 m_attrs
.Create(wxKEY_INTEGER
, 1000); // just as def ctor
264 m_hasAnyAttr
= FALSE
;
268 wxListCtrl::~wxListCtrl()
270 FreeAllAttrs(TRUE
/* no need to recreate hash any more */);
274 m_textCtrl
->UnsubclassWin();
275 m_textCtrl
->SetHWND(0);
281 // ----------------------------------------------------------------------------
282 // set/get/change style
283 // ----------------------------------------------------------------------------
285 // Add or remove a single window style
286 void wxListCtrl::SetSingleStyle(long style
, bool add
)
288 long flag
= GetWindowStyleFlag();
290 // Get rid of conflicting styles
293 if ( style
& wxLC_MASK_TYPE
)
294 flag
= flag
& ~wxLC_MASK_TYPE
;
295 if ( style
& wxLC_MASK_ALIGN
)
296 flag
= flag
& ~wxLC_MASK_ALIGN
;
297 if ( style
& wxLC_MASK_SORT
)
298 flag
= flag
& ~wxLC_MASK_SORT
;
314 m_windowStyle
= flag
;
319 // Set the whole window style
320 void wxListCtrl::SetWindowStyleFlag(long flag
)
322 m_windowStyle
= flag
;
327 // Can be just a single style, or a bitlist
328 long wxListCtrl::ConvertToMSWStyle(long& oldStyle
, long style
) const
331 if ( style
& wxLC_ICON
)
333 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_SMALLICON
)
334 oldStyle
-= LVS_SMALLICON
;
335 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_REPORT
)
336 oldStyle
-= LVS_REPORT
;
337 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_LIST
)
338 oldStyle
-= LVS_LIST
;
342 if ( style
& wxLC_SMALL_ICON
)
344 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_ICON
)
345 oldStyle
-= LVS_ICON
;
346 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_REPORT
)
347 oldStyle
-= LVS_REPORT
;
348 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_LIST
)
349 oldStyle
-= LVS_LIST
;
350 wstyle
|= LVS_SMALLICON
;
353 if ( style
& wxLC_LIST
)
355 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_ICON
)
356 oldStyle
-= LVS_ICON
;
357 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_REPORT
)
358 oldStyle
-= LVS_REPORT
;
359 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_SMALLICON
)
360 oldStyle
-= LVS_SMALLICON
;
364 if ( style
& wxLC_REPORT
)
366 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_ICON
)
367 oldStyle
-= LVS_ICON
;
368 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_LIST
)
369 oldStyle
-= LVS_LIST
;
370 if ( (oldStyle
& LVS_TYPEMASK
) == LVS_SMALLICON
)
371 oldStyle
-= LVS_SMALLICON
;
373 wstyle
|= LVS_REPORT
;
376 if ( style
& wxLC_ALIGN_LEFT
)
378 if ( oldStyle
& LVS_ALIGNTOP
)
379 oldStyle
-= LVS_ALIGNTOP
;
380 wstyle
|= LVS_ALIGNLEFT
;
383 if ( style
& wxLC_ALIGN_TOP
)
385 if ( oldStyle
& LVS_ALIGNLEFT
)
386 oldStyle
-= LVS_ALIGNLEFT
;
387 wstyle
|= LVS_ALIGNTOP
;
390 if ( style
& wxLC_AUTOARRANGE
)
391 wstyle
|= LVS_AUTOARRANGE
;
393 // Apparently, no such style (documentation wrong?)
395 if ( style & wxLC_BUTTON )
396 wstyle |= LVS_BUTTON;
399 if ( style
& wxLC_NO_SORT_HEADER
)
400 wstyle
|= LVS_NOSORTHEADER
;
402 if ( style
& wxLC_NO_HEADER
)
403 wstyle
|= LVS_NOCOLUMNHEADER
;
405 if ( style
& wxLC_EDIT_LABELS
)
406 wstyle
|= LVS_EDITLABELS
;
408 if ( style
& wxLC_SINGLE_SEL
)
409 wstyle
|= LVS_SINGLESEL
;
411 if ( style
& wxLC_SORT_ASCENDING
)
413 if ( oldStyle
& LVS_SORTDESCENDING
)
414 oldStyle
-= LVS_SORTDESCENDING
;
415 wstyle
|= LVS_SORTASCENDING
;
418 if ( style
& wxLC_SORT_DESCENDING
)
420 if ( oldStyle
& LVS_SORTASCENDING
)
421 oldStyle
-= LVS_SORTASCENDING
;
422 wstyle
|= LVS_SORTDESCENDING
;
428 // ----------------------------------------------------------------------------
430 // ----------------------------------------------------------------------------
432 // Sets the foreground, i.e. text, colour
433 bool wxListCtrl::SetForegroundColour(const wxColour
& col
)
435 if ( !wxWindow::SetForegroundColour(col
) )
438 ListView_SetTextColor(GetHwnd(), wxColourToRGB(col
));
443 // Sets the background colour
444 bool wxListCtrl::SetBackgroundColour(const wxColour
& col
)
446 if ( !wxWindow::SetBackgroundColour(col
) )
449 // we set the same colour for both the "empty" background and the items
451 COLORREF color
= wxColourToRGB(col
);
452 ListView_SetBkColor(GetHwnd(), color
);
453 ListView_SetTextBkColor(GetHwnd(), color
);
458 // Gets information about this column
459 bool wxListCtrl::GetColumn(int col
, wxListItem
& item
) const
464 lvCol
.pszText
= NULL
;
466 if ( item
.m_mask
& wxLIST_MASK_TEXT
)
468 lvCol
.mask
|= LVCF_TEXT
;
469 lvCol
.pszText
= new wxChar
[513];
470 lvCol
.cchTextMax
= 512;
473 bool success
= (ListView_GetColumn(GetHwnd(), col
, & lvCol
) != 0);
475 // item.m_subItem = lvCol.iSubItem;
476 item
.m_width
= lvCol
.cx
;
478 if ( (item
.m_mask
& wxLIST_MASK_TEXT
) && lvCol
.pszText
)
480 item
.m_text
= lvCol
.pszText
;
481 delete[] lvCol
.pszText
;
484 if ( item
.m_mask
& wxLIST_MASK_FORMAT
)
486 if (lvCol
.fmt
== LVCFMT_LEFT
)
487 item
.m_format
= wxLIST_FORMAT_LEFT
;
488 else if (lvCol
.fmt
== LVCFMT_RIGHT
)
489 item
.m_format
= wxLIST_FORMAT_RIGHT
;
490 else if (lvCol
.fmt
== LVCFMT_CENTER
)
491 item
.m_format
= wxLIST_FORMAT_CENTRE
;
497 // Sets information about this column
498 bool wxListCtrl::SetColumn(int col
, wxListItem
& item
)
503 lvCol
.pszText
= NULL
;
505 if ( item
.m_mask
& wxLIST_MASK_TEXT
)
507 lvCol
.mask
|= LVCF_TEXT
;
508 lvCol
.pszText
= WXSTRINGCAST item
.m_text
;
509 lvCol
.cchTextMax
= 0; // Ignored
511 if ( item
.m_mask
& wxLIST_MASK_FORMAT
)
513 lvCol
.mask
|= LVCF_FMT
;
515 if ( item
.m_format
== wxLIST_FORMAT_LEFT
)
516 lvCol
.fmt
= LVCFMT_LEFT
;
517 if ( item
.m_format
== wxLIST_FORMAT_RIGHT
)
518 lvCol
.fmt
= LVCFMT_RIGHT
;
519 if ( item
.m_format
== wxLIST_FORMAT_CENTRE
)
520 lvCol
.fmt
= LVCFMT_CENTER
;
523 if ( item
.m_mask
& wxLIST_MASK_WIDTH
)
525 lvCol
.mask
|= LVCF_WIDTH
;
526 lvCol
.cx
= item
.m_width
;
528 if ( lvCol
.cx
== wxLIST_AUTOSIZE
)
529 lvCol
.cx
= LVSCW_AUTOSIZE
;
530 else if ( lvCol
.cx
== wxLIST_AUTOSIZE_USEHEADER
)
531 lvCol
.cx
= LVSCW_AUTOSIZE_USEHEADER
;
533 lvCol
.mask
|= LVCF_SUBITEM
;
534 lvCol
.iSubItem
= col
;
535 return (ListView_SetColumn(GetHwnd(), col
, & lvCol
) != 0);
538 // Gets the column width
539 int wxListCtrl::GetColumnWidth(int col
) const
541 return ListView_GetColumnWidth(GetHwnd(), col
);
544 // Sets the column width
545 bool wxListCtrl::SetColumnWidth(int col
, int width
)
548 if ( m_windowStyle
& wxLC_LIST
)
552 if ( width2
== wxLIST_AUTOSIZE
)
553 width2
= LVSCW_AUTOSIZE
;
554 else if ( width2
== wxLIST_AUTOSIZE_USEHEADER
)
555 width2
= LVSCW_AUTOSIZE_USEHEADER
;
557 return (ListView_SetColumnWidth(GetHwnd(), col2
, width2
) != 0);
560 // Gets the number of items that can fit vertically in the
561 // visible area of the list control (list or report view)
562 // or the total number of items in the list control (icon
563 // or small icon view)
564 int wxListCtrl::GetCountPerPage() const
566 return ListView_GetCountPerPage(GetHwnd());
569 // Gets the edit control for editing labels.
570 wxTextCtrl
* wxListCtrl::GetEditControl() const
575 // Gets information about the item
576 bool wxListCtrl::GetItem(wxListItem
& info
) const
579 wxZeroMemory(lvItem
);
581 lvItem
.iItem
= info
.m_itemId
;
582 lvItem
.iSubItem
= info
.m_col
;
584 if ( info
.m_mask
& wxLIST_MASK_TEXT
)
586 lvItem
.mask
|= LVIF_TEXT
;
587 lvItem
.pszText
= new wxChar
[513];
588 lvItem
.cchTextMax
= 512;
592 lvItem
.pszText
= NULL
;
595 if (info
.m_mask
& wxLIST_MASK_DATA
)
596 lvItem
.mask
|= LVIF_PARAM
;
598 if ( info
.m_mask
& wxLIST_MASK_STATE
)
600 lvItem
.mask
|= LVIF_STATE
;
601 // the other bits are hardly interesting anyhow
602 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
605 bool success
= ListView_GetItem((HWND
)GetHWND(), &lvItem
) != 0;
608 wxLogError(_("Couldn't retrieve information about list control item %d."),
613 wxConvertFromMSWListItem(this, info
, lvItem
);
617 delete[] lvItem
.pszText
;
622 // Sets information about the item
623 bool wxListCtrl::SetItem(wxListItem
& info
)
626 wxConvertToMSWListItem(this, info
, item
);
628 // check whether it has any custom attributes
629 if ( info
.HasAttributes() )
631 m_attrs
.Put(item
.iItem
, (wxObject
*)new wxListItemAttr(*info
.GetAttributes()));
637 bool ok
= ListView_SetItem(GetHwnd(), &item
) != 0;
638 if ( ok
&& (info
.m_mask
& wxLIST_MASK_IMAGE
) )
640 // make the change visible
641 ListView_Update(GetHwnd(), item
.iItem
);
647 long wxListCtrl::SetItem(long index
, int col
, const wxString
& label
, int imageId
)
651 info
.m_mask
= wxLIST_MASK_TEXT
;
652 info
.m_itemId
= index
;
656 info
.m_image
= imageId
;
657 info
.m_mask
|= wxLIST_MASK_IMAGE
;
659 return SetItem(info
);
663 // Gets the item state
664 int wxListCtrl::GetItemState(long item
, long stateMask
) const
668 info
.m_mask
= wxLIST_MASK_STATE
;
669 info
.m_stateMask
= stateMask
;
670 info
.m_itemId
= item
;
678 // Sets the item state
679 bool wxListCtrl::SetItemState(long item
, long state
, long stateMask
)
683 info
.m_mask
= wxLIST_MASK_STATE
;
684 info
.m_state
= state
;
685 info
.m_stateMask
= stateMask
;
686 info
.m_itemId
= item
;
688 return SetItem(info
);
691 // Sets the item image
692 bool wxListCtrl::SetItemImage(long item
, int image
, int selImage
)
696 info
.m_mask
= wxLIST_MASK_IMAGE
;
697 info
.m_image
= image
;
698 info
.m_itemId
= item
;
700 return SetItem(info
);
703 // Gets the item text
704 wxString
wxListCtrl::GetItemText(long item
) const
708 info
.m_mask
= wxLIST_MASK_TEXT
;
709 info
.m_itemId
= item
;
716 // Sets the item text
717 void wxListCtrl::SetItemText(long item
, const wxString
& str
)
721 info
.m_mask
= wxLIST_MASK_TEXT
;
722 info
.m_itemId
= item
;
728 // Gets the item data
729 long wxListCtrl::GetItemData(long item
) const
733 info
.m_mask
= wxLIST_MASK_DATA
;
734 info
.m_itemId
= item
;
741 // Sets the item data
742 bool wxListCtrl::SetItemData(long item
, long data
)
746 info
.m_mask
= wxLIST_MASK_DATA
;
747 info
.m_itemId
= item
;
750 return SetItem(info
);
753 // Gets the item rectangle
754 bool wxListCtrl::GetItemRect(long item
, wxRect
& rect
, int code
) const
758 int code2
= LVIR_BOUNDS
;
759 if ( code
== wxLIST_RECT_BOUNDS
)
761 else if ( code
== wxLIST_RECT_ICON
)
763 else if ( code
== wxLIST_RECT_LABEL
)
767 bool success
= (ListView_GetItemRect(GetHwnd(), (int) item
, &rect2
) != 0);
769 bool success
= (ListView_GetItemRect(GetHwnd(), (int) item
, &rect2
, code2
) != 0);
774 rect
.width
= rect2
.right
- rect2
.left
;
775 rect
.height
= rect2
.bottom
- rect2
.left
;
779 // Gets the item position
780 bool wxListCtrl::GetItemPosition(long item
, wxPoint
& pos
) const
784 bool success
= (ListView_GetItemPosition(GetHwnd(), (int) item
, &pt
) != 0);
786 pos
.x
= pt
.x
; pos
.y
= pt
.y
;
790 // Sets the item position.
791 bool wxListCtrl::SetItemPosition(long item
, const wxPoint
& pos
)
793 return (ListView_SetItemPosition(GetHwnd(), (int) item
, pos
.x
, pos
.y
) != 0);
796 // Gets the number of items in the list control
797 int wxListCtrl::GetItemCount() const
799 return ListView_GetItemCount(GetHwnd());
802 // Retrieves the spacing between icons in pixels.
803 // If small is TRUE, gets the spacing for the small icon
804 // view, otherwise the large icon view.
805 int wxListCtrl::GetItemSpacing(bool isSmall
) const
807 return ListView_GetItemSpacing(GetHwnd(), (BOOL
) isSmall
);
810 // Gets the number of selected items in the list control
811 int wxListCtrl::GetSelectedItemCount() const
813 return ListView_GetSelectedCount(GetHwnd());
816 // Gets the text colour of the listview
817 wxColour
wxListCtrl::GetTextColour() const
819 COLORREF ref
= ListView_GetTextColor(GetHwnd());
820 wxColour
col(GetRValue(ref
), GetGValue(ref
), GetBValue(ref
));
824 // Sets the text colour of the listview
825 void wxListCtrl::SetTextColour(const wxColour
& col
)
827 ListView_SetTextColor(GetHwnd(), PALETTERGB(col
.Red(), col
.Green(), col
.Blue()));
830 // Gets the index of the topmost visible item when in
831 // list or report view
832 long wxListCtrl::GetTopItem() const
834 return (long) ListView_GetTopIndex(GetHwnd());
837 // Searches for an item, starting from 'item'.
838 // 'geometry' is one of
839 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
840 // 'state' is a state bit flag, one or more of
841 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
842 // item can be -1 to find the first item that matches the
844 // Returns the item or -1 if unsuccessful.
845 long wxListCtrl::GetNextItem(long item
, int geom
, int state
) const
849 if ( geom
== wxLIST_NEXT_ABOVE
)
851 if ( geom
== wxLIST_NEXT_ALL
)
853 if ( geom
== wxLIST_NEXT_BELOW
)
855 if ( geom
== wxLIST_NEXT_LEFT
)
856 flags
|= LVNI_TOLEFT
;
857 if ( geom
== wxLIST_NEXT_RIGHT
)
858 flags
|= LVNI_TORIGHT
;
860 if ( state
& wxLIST_STATE_CUT
)
862 if ( state
& wxLIST_STATE_DROPHILITED
)
863 flags
|= LVNI_DROPHILITED
;
864 if ( state
& wxLIST_STATE_FOCUSED
)
865 flags
|= LVNI_FOCUSED
;
866 if ( state
& wxLIST_STATE_SELECTED
)
867 flags
|= LVNI_SELECTED
;
869 return (long) ListView_GetNextItem(GetHwnd(), item
, flags
);
873 wxImageList
*wxListCtrl::GetImageList(int which
) const
875 if ( which
== wxIMAGE_LIST_NORMAL
)
877 return m_imageListNormal
;
879 else if ( which
== wxIMAGE_LIST_SMALL
)
881 return m_imageListSmall
;
883 else if ( which
== wxIMAGE_LIST_STATE
)
885 return m_imageListState
;
890 void wxListCtrl::SetImageList(wxImageList
*imageList
, int which
)
893 if ( which
== wxIMAGE_LIST_NORMAL
)
895 flags
= LVSIL_NORMAL
;
896 m_imageListNormal
= imageList
;
898 else if ( which
== wxIMAGE_LIST_SMALL
)
901 m_imageListSmall
= imageList
;
903 else if ( which
== wxIMAGE_LIST_STATE
)
906 m_imageListState
= imageList
;
908 ListView_SetImageList(GetHwnd(), (HIMAGELIST
) imageList
? imageList
->GetHIMAGELIST() : 0, flags
);
911 // ----------------------------------------------------------------------------
913 // ----------------------------------------------------------------------------
915 // Arranges the items
916 bool wxListCtrl::Arrange(int flag
)
919 if ( flag
== wxLIST_ALIGN_LEFT
)
920 code
= LVA_ALIGNLEFT
;
921 else if ( flag
== wxLIST_ALIGN_TOP
)
923 else if ( flag
== wxLIST_ALIGN_DEFAULT
)
925 else if ( flag
== wxLIST_ALIGN_SNAP_TO_GRID
)
926 code
= LVA_SNAPTOGRID
;
928 return (ListView_Arrange(GetHwnd(), code
) != 0);
932 bool wxListCtrl::DeleteItem(long item
)
934 return (ListView_DeleteItem(GetHwnd(), (int) item
) != 0);
938 bool wxListCtrl::DeleteAllItems()
940 return (ListView_DeleteAllItems(GetHwnd()) != 0);
944 bool wxListCtrl::DeleteAllColumns()
946 while ( m_colCount
> 0 )
948 if ( ListView_DeleteColumn(GetHwnd(), 0) == 0 )
950 wxLogLastError("ListView_DeleteColumn");
958 wxASSERT_MSG( m_colCount
== 0, wxT("no columns should be left") );
964 bool wxListCtrl::DeleteColumn(int col
)
966 bool success
= (ListView_DeleteColumn(GetHwnd(), col
) != 0);
968 if ( success
&& (m_colCount
> 0) )
973 // Clears items, and columns if there are any.
974 void wxListCtrl::ClearAll()
977 if ( m_colCount
> 0 )
981 wxTextCtrl
* wxListCtrl::EditLabel(long item
, wxClassInfo
* textControlClass
)
983 wxASSERT( (textControlClass
->IsKindOf(CLASSINFO(wxTextCtrl
))) );
985 HWND hWnd
= (HWND
) ListView_EditLabel(GetHwnd(), item
);
989 m_textCtrl
->UnsubclassWin();
990 m_textCtrl
->SetHWND(0);
995 m_textCtrl
= (wxTextCtrl
*) textControlClass
->CreateObject();
996 m_textCtrl
->SetHWND((WXHWND
) hWnd
);
997 m_textCtrl
->SubclassWin((WXHWND
) hWnd
);
1002 // End label editing, optionally cancelling the edit
1003 bool wxListCtrl::EndEditLabel(bool cancel
)
1007 /* I don't know how to implement this: there's no such macro as ListView_EndEditLabelNow.
1009 bool success = (ListView_EndEditLabelNow(GetHwnd(), cancel) != 0);
1013 m_textCtrl->UnsubclassWin();
1014 m_textCtrl->SetHWND(0);
1024 // Ensures this item is visible
1025 bool wxListCtrl::EnsureVisible(long item
)
1027 return (ListView_EnsureVisible(GetHwnd(), (int) item
, FALSE
) != 0);
1030 // Find an item whose label matches this string, starting from the item after 'start'
1031 // or the beginning if 'start' is -1.
1032 long wxListCtrl::FindItem(long start
, const wxString
& str
, bool partial
)
1034 LV_FINDINFO findInfo
;
1036 findInfo
.flags
= LVFI_STRING
;
1038 findInfo
.flags
|= LVFI_STRING
;
1039 findInfo
.psz
= WXSTRINGCAST str
;
1041 return ListView_FindItem(GetHwnd(), (int) start
, & findInfo
);
1044 // Find an item whose data matches this data, starting from the item after 'start'
1045 // or the beginning if 'start' is -1.
1046 long wxListCtrl::FindItem(long start
, long data
)
1048 LV_FINDINFO findInfo
;
1050 findInfo
.flags
= LVFI_PARAM
;
1051 findInfo
.lParam
= data
;
1053 return ListView_FindItem(GetHwnd(), (int) start
, & findInfo
);
1056 // Find an item nearest this position in the specified direction, starting from
1057 // the item after 'start' or the beginning if 'start' is -1.
1058 long wxListCtrl::FindItem(long start
, const wxPoint
& pt
, int direction
)
1060 LV_FINDINFO findInfo
;
1062 findInfo
.flags
= LVFI_NEARESTXY
;
1063 findInfo
.pt
.x
= pt
.x
;
1064 findInfo
.pt
.y
= pt
.y
;
1065 findInfo
.vkDirection
= VK_RIGHT
;
1067 if ( direction
== wxLIST_FIND_UP
)
1068 findInfo
.vkDirection
= VK_UP
;
1069 else if ( direction
== wxLIST_FIND_DOWN
)
1070 findInfo
.vkDirection
= VK_DOWN
;
1071 else if ( direction
== wxLIST_FIND_LEFT
)
1072 findInfo
.vkDirection
= VK_LEFT
;
1073 else if ( direction
== wxLIST_FIND_RIGHT
)
1074 findInfo
.vkDirection
= VK_RIGHT
;
1076 return ListView_FindItem(GetHwnd(), (int) start
, & findInfo
);
1079 // Determines which item (if any) is at the specified point,
1080 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
1081 long wxListCtrl::HitTest(const wxPoint
& point
, int& flags
)
1083 LV_HITTESTINFO hitTestInfo
;
1084 hitTestInfo
.pt
.x
= (int) point
.x
;
1085 hitTestInfo
.pt
.y
= (int) point
.y
;
1087 ListView_HitTest(GetHwnd(), & hitTestInfo
);
1090 if ( hitTestInfo
.flags
& LVHT_ABOVE
)
1091 flags
|= wxLIST_HITTEST_ABOVE
;
1092 if ( hitTestInfo
.flags
& LVHT_BELOW
)
1093 flags
|= wxLIST_HITTEST_BELOW
;
1094 if ( hitTestInfo
.flags
& LVHT_NOWHERE
)
1095 flags
|= wxLIST_HITTEST_NOWHERE
;
1096 if ( hitTestInfo
.flags
& LVHT_ONITEMICON
)
1097 flags
|= wxLIST_HITTEST_ONITEMICON
;
1098 if ( hitTestInfo
.flags
& LVHT_ONITEMLABEL
)
1099 flags
|= wxLIST_HITTEST_ONITEMLABEL
;
1100 if ( hitTestInfo
.flags
& LVHT_ONITEMSTATEICON
)
1101 flags
|= wxLIST_HITTEST_ONITEMSTATEICON
;
1102 if ( hitTestInfo
.flags
& LVHT_TOLEFT
)
1103 flags
|= wxLIST_HITTEST_TOLEFT
;
1104 if ( hitTestInfo
.flags
& LVHT_TORIGHT
)
1105 flags
|= wxLIST_HITTEST_TORIGHT
;
1107 return (long) hitTestInfo
.iItem
;
1110 // Inserts an item, returning the index of the new item if successful,
1112 long wxListCtrl::InsertItem(wxListItem
& info
)
1115 wxConvertToMSWListItem(this, info
, item
);
1117 // check whether it has any custom attributes
1118 if ( info
.HasAttributes() )
1120 m_attrs
.Put(item
.iItem
, (wxObject
*)new wxListItemAttr(*info
.GetAttributes()));
1122 m_hasAnyAttr
= TRUE
;
1125 return (long) ListView_InsertItem(GetHwnd(), & item
);
1128 long wxListCtrl::InsertItem(long index
, const wxString
& label
)
1131 info
.m_text
= label
;
1132 info
.m_mask
= wxLIST_MASK_TEXT
;
1133 info
.m_itemId
= index
;
1134 return InsertItem(info
);
1137 // Inserts an image item
1138 long wxListCtrl::InsertItem(long index
, int imageIndex
)
1141 info
.m_image
= imageIndex
;
1142 info
.m_mask
= wxLIST_MASK_IMAGE
;
1143 info
.m_itemId
= index
;
1144 return InsertItem(info
);
1147 // Inserts an image/string item
1148 long wxListCtrl::InsertItem(long index
, const wxString
& label
, int imageIndex
)
1151 info
.m_image
= imageIndex
;
1152 info
.m_text
= label
;
1153 info
.m_mask
= wxLIST_MASK_IMAGE
| wxLIST_MASK_TEXT
;
1154 info
.m_itemId
= index
;
1155 return InsertItem(info
);
1158 // For list view mode (only), inserts a column.
1159 long wxListCtrl::InsertColumn(long col
, wxListItem
& item
)
1164 lvCol
.pszText
= NULL
;
1166 if ( item
.m_mask
& wxLIST_MASK_TEXT
)
1168 lvCol
.mask
|= LVCF_TEXT
;
1169 lvCol
.pszText
= WXSTRINGCAST item
.m_text
;
1170 lvCol
.cchTextMax
= 0; // Ignored
1172 if ( item
.m_mask
& wxLIST_MASK_FORMAT
)
1174 lvCol
.mask
|= LVCF_FMT
;
1176 if ( item
.m_format
== wxLIST_FORMAT_LEFT
)
1177 lvCol
.fmt
= LVCFMT_LEFT
;
1178 if ( item
.m_format
== wxLIST_FORMAT_RIGHT
)
1179 lvCol
.fmt
= LVCFMT_RIGHT
;
1180 if ( item
.m_format
== wxLIST_FORMAT_CENTRE
)
1181 lvCol
.fmt
= LVCFMT_CENTER
;
1184 lvCol
.mask
|= LVCF_WIDTH
;
1185 if ( item
.m_mask
& wxLIST_MASK_WIDTH
)
1187 if ( item
.m_width
== wxLIST_AUTOSIZE
)
1188 lvCol
.cx
= LVSCW_AUTOSIZE
;
1189 else if ( item
.m_width
== wxLIST_AUTOSIZE_USEHEADER
)
1190 lvCol
.cx
= LVSCW_AUTOSIZE_USEHEADER
;
1192 lvCol
.cx
= item
.m_width
;
1196 // always give some width to the new column: this one is compatible
1201 lvCol
.mask
|= LVCF_SUBITEM
;
1202 lvCol
.iSubItem
= col
;
1204 bool success
= ListView_InsertColumn(GetHwnd(), col
, & lvCol
) != -1;
1211 wxLogDebug(wxT("Failed to insert the column '%s' into listview!"),
1218 long wxListCtrl::InsertColumn(long col
,
1219 const wxString
& heading
,
1224 item
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
1225 item
.m_text
= heading
;
1228 item
.m_mask
|= wxLIST_MASK_WIDTH
;
1229 item
.m_width
= width
;
1231 item
.m_format
= format
;
1233 return InsertColumn(col
, item
);
1236 // Scrolls the list control. If in icon, small icon or report view mode,
1237 // x specifies the number of pixels to scroll. If in list view mode, x
1238 // specifies the number of columns to scroll.
1239 // If in icon, small icon or list view mode, y specifies the number of pixels
1240 // to scroll. If in report view mode, y specifies the number of lines to scroll.
1241 bool wxListCtrl::ScrollList(int dx
, int dy
)
1243 return (ListView_Scroll(GetHwnd(), dx
, dy
) != 0);
1248 // fn is a function which takes 3 long arguments: item1, item2, data.
1249 // item1 is the long data associated with a first item (NOT the index).
1250 // item2 is the long data associated with a second item (NOT the index).
1251 // data is the same value as passed to SortItems.
1252 // The return value is a negative number if the first item should precede the second
1253 // item, a positive number of the second item should precede the first,
1254 // or zero if the two items are equivalent.
1256 // data is arbitrary data to be passed to the sort function.
1257 bool wxListCtrl::SortItems(wxListCtrlCompare fn
, long data
)
1259 return (ListView_SortItems(GetHwnd(), (PFNLVCOMPARE
) fn
, data
) != 0);
1262 // ----------------------------------------------------------------------------
1263 // message processing
1264 // ----------------------------------------------------------------------------
1266 bool wxListCtrl::MSWCommand(WXUINT cmd
, WXWORD id
)
1268 if (cmd
== EN_UPDATE
)
1270 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, id
);
1271 event
.SetEventObject( this );
1272 ProcessCommand(event
);
1275 else if (cmd
== EN_KILLFOCUS
)
1277 wxCommandEvent
event(wxEVT_KILL_FOCUS
, id
);
1278 event
.SetEventObject( this );
1279 ProcessCommand(event
);
1286 bool wxListCtrl::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM
*result
)
1288 // prepare the event
1289 // -----------------
1291 wxListEvent
event(wxEVT_NULL
, m_windowId
);
1292 wxEventType eventType
= wxEVT_NULL
;
1294 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
1296 // almost all messages use NM_LISTVIEW
1297 NM_LISTVIEW
*nmLV
= (NM_LISTVIEW
*)nmhdr
;
1299 // this is true for almost all events
1300 event
.m_item
.m_data
= nmLV
->lParam
;
1302 switch ( nmhdr
->code
)
1304 case LVN_BEGINRDRAG
:
1305 eventType
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
;
1309 if ( eventType
== wxEVT_NULL
)
1311 eventType
= wxEVT_COMMAND_LIST_BEGIN_DRAG
;
1314 event
.m_itemIndex
= nmLV
->iItem
;
1315 event
.m_pointDrag
.x
= nmLV
->ptAction
.x
;
1316 event
.m_pointDrag
.y
= nmLV
->ptAction
.y
;
1319 case LVN_BEGINLABELEDIT
:
1321 eventType
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
;
1322 LV_DISPINFO
*info
= (LV_DISPINFO
*)lParam
;
1323 wxConvertFromMSWListItem(this, event
.m_item
, info
->item
, GetHwnd());
1327 case LVN_COLUMNCLICK
:
1328 eventType
= wxEVT_COMMAND_LIST_COL_CLICK
;
1329 event
.m_itemIndex
= -1;
1330 event
.m_col
= nmLV
->iSubItem
;
1333 case LVN_DELETEALLITEMS
:
1334 eventType
= wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
;
1335 event
.m_itemIndex
= -1;
1341 case LVN_DELETEITEM
:
1342 eventType
= wxEVT_COMMAND_LIST_DELETE_ITEM
;
1343 event
.m_itemIndex
= nmLV
->iItem
;
1347 delete (wxListItemAttr
*)m_attrs
.Delete(nmLV
->iItem
);
1351 case LVN_ENDLABELEDIT
:
1353 eventType
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
;
1354 LV_DISPINFO
*info
= (LV_DISPINFO
*)lParam
;
1355 wxConvertFromMSWListItem(this, event
.m_item
, info
->item
);
1356 if ( info
->item
.pszText
== NULL
|| info
->item
.iItem
== -1 )
1361 case LVN_SETDISPINFO
:
1363 eventType
= wxEVT_COMMAND_LIST_SET_INFO
;
1364 LV_DISPINFO
*info
= (LV_DISPINFO
*)lParam
;
1365 wxConvertFromMSWListItem(this, event
.m_item
, info
->item
, GetHwnd());
1369 case LVN_GETDISPINFO
:
1370 // this provokes stack overflow: indeed, wxConvertFromMSWListItem()
1371 // sends us WM_NOTIFY! As it doesn't do anything for now, just leave
1375 // TODO: some text buffering here, I think
1376 // TODO: API for getting Windows to retrieve values
1378 eventType
= wxEVT_COMMAND_LIST_GET_INFO
;
1379 LV_DISPINFO
*info
= (LV_DISPINFO
*)lParam
;
1380 wxConvertFromMSWListItem(this, event
.m_item
, info
->item
, GetHwnd());
1387 case LVN_INSERTITEM
:
1388 eventType
= wxEVT_COMMAND_LIST_INSERT_ITEM
;
1389 event
.m_itemIndex
= nmLV
->iItem
;
1392 case LVN_ITEMCHANGED
:
1393 // This needs to be sent to wxListCtrl as a rather more concrete
1394 // event. For now, just detect a selection or deselection.
1395 if ( (nmLV
->uNewState
& LVIS_SELECTED
) && !(nmLV
->uOldState
& LVIS_SELECTED
) )
1397 eventType
= wxEVT_COMMAND_LIST_ITEM_SELECTED
;
1398 event
.m_itemIndex
= nmLV
->iItem
;
1400 else if ( !(nmLV
->uNewState
& LVIS_SELECTED
) && (nmLV
->uOldState
& LVIS_SELECTED
) )
1402 eventType
= wxEVT_COMMAND_LIST_ITEM_DESELECTED
;
1403 event
.m_itemIndex
= nmLV
->iItem
;
1413 LV_KEYDOWN
*info
= (LV_KEYDOWN
*)lParam
;
1414 WORD wVKey
= info
->wVKey
;
1416 // get the current selection
1417 long lItem
= GetNextItem(-1,
1419 wxLIST_STATE_SELECTED
);
1421 // <Enter> or <Space> activate the selected item if any
1422 if ( lItem
!= -1 && (wVKey
== VK_RETURN
|| wVKey
== VK_SPACE
) )
1424 // TODO this behaviour probably should be optional
1425 eventType
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
;
1426 event
.m_itemIndex
= lItem
;
1430 eventType
= wxEVT_COMMAND_LIST_KEY_DOWN
;
1431 event
.m_code
= wxCharCodeMSWToWX(wVKey
);
1434 event
.m_item
.m_data
= GetItemData(lItem
);
1439 // if the user processes it in wxEVT_COMMAND_LEFT_CLICK(), don't do
1441 if ( wxControl::MSWOnNotify(idCtrl
, lParam
, result
) )
1446 // else translate it into wxEVT_COMMAND_LIST_ITEM_ACTIVATED event
1447 // if it happened on an item (and not on empty place)
1448 if ( nmLV
->iItem
== -1 )
1454 eventType
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
;
1455 event
.m_itemIndex
= nmLV
->iItem
;
1456 event
.m_item
.m_data
= GetItemData(nmLV
->iItem
);
1460 /* TECH NOTE: NM_RCLICK isn't really good enough here. We want to
1461 subclass and check for the actual WM_RBUTTONDOWN message,
1462 because NM_RCLICK waits for the WM_RBUTTONUP message as well
1463 before firing off. We want to have notify events for both down
1466 // if the user processes it in wxEVT_COMMAND_RIGHT_CLICK(),
1467 // don't do anything else
1468 if ( wxControl::MSWOnNotify(idCtrl
, lParam
, result
) )
1473 // else translate it into wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK event
1474 LV_HITTESTINFO lvhti
;
1475 wxZeroMemory(lvhti
);
1477 ::GetCursorPos(&(lvhti
.pt
));
1478 ::ScreenToClient(GetHwnd(),&(lvhti
.pt
));
1479 if ( ListView_HitTest(GetHwnd(),&lvhti
) != -1 )
1481 if ( lvhti
.flags
& LVHT_ONITEM
)
1483 eventType
= wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
;
1484 event
.m_itemIndex
= lvhti
.iItem
;
1491 case NM_MCLICK
: // ***** THERE IS NO NM_MCLICK. Subclass anyone? ******
1493 // if the user processes it in wxEVT_COMMAND_MIDDLE_CLICK(), don't do
1495 if ( wxControl::MSWOnNotify(idCtrl
, lParam
, result
) )
1500 // else translate it into wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK event
1501 eventType
= wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
;
1502 NMITEMACTIVATE
* hdr
= (NMITEMACTIVATE
*)lParam
;
1503 event
.m_itemIndex
= hdr
->iItem
;
1508 #if defined(_WIN32_IE) && _WIN32_IE >= 0x300
1511 LPNMLVCUSTOMDRAW lplvcd
= (LPNMLVCUSTOMDRAW
)lParam
;
1512 NMCUSTOMDRAW
& nmcd
= lplvcd
->nmcd
;
1513 switch( nmcd
.dwDrawStage
)
1516 // if we've got any items with non standard attributes,
1517 // notify us before painting each item
1518 *result
= m_hasAnyAttr
? CDRF_NOTIFYITEMDRAW
1522 case CDDS_ITEMPREPAINT
:
1524 wxListItemAttr
*attr
=
1525 (wxListItemAttr
*)m_attrs
.Get(nmcd
.dwItemSpec
);
1529 // nothing to do for this item
1530 return CDRF_DODEFAULT
;
1534 wxColour colText
, colBack
;
1535 if ( attr
->HasFont() )
1537 wxFont font
= attr
->GetFont();
1538 hFont
= (HFONT
)font
.GetResourceHandle();
1545 if ( attr
->HasTextColour() )
1547 colText
= attr
->GetTextColour();
1551 colText
= GetTextColour();
1554 if ( attr
->HasBackgroundColour() )
1556 colBack
= attr
->GetBackgroundColour();
1560 colBack
= GetBackgroundColour();
1563 // note that if we wanted to set colours for
1564 // individual columns (subitems), we would have
1565 // returned CDRF_NOTIFYSUBITEMREDRAW from here
1568 ::SelectObject(nmcd
.hdc
, hFont
);
1570 *result
= CDRF_NEWFONT
;
1574 *result
= CDRF_DODEFAULT
;
1577 lplvcd
->clrText
= wxColourToRGB(colText
);
1578 lplvcd
->clrTextBk
= wxColourToRGB(colBack
);
1584 *result
= CDRF_DODEFAULT
;
1589 #endif // _WIN32_IE >= 0x300
1592 return wxControl::MSWOnNotify(idCtrl
, lParam
, result
);
1595 // process the event
1596 // -----------------
1598 event
.SetEventObject( this );
1599 event
.SetEventType(eventType
);
1601 if ( !GetEventHandler()->ProcessEvent(event
) )
1607 switch ( nmhdr
->code
)
1609 case LVN_DELETEALLITEMS
:
1610 // always return TRUE to suppress all additional LVN_DELETEITEM
1611 // notifications - this makes deleting all items from a list ctrl
1617 case LVN_GETDISPINFO
:
1619 LV_DISPINFO
*info
= (LV_DISPINFO
*)lParam
;
1620 if ( info
->item
.mask
& LVIF_TEXT
)
1622 if ( !event
.m_item
.m_text
.IsNull() )
1624 info
->item
.pszText
= AddPool(event
.m_item
.m_text
);
1625 info
->item
.cchTextMax
= wxStrlen(info
->item
.pszText
) + 1;
1628 // wxConvertToMSWListItem(this, event.m_item, info->item);
1631 case LVN_ENDLABELEDIT
:
1633 *result
= event
.IsAllowed();
1638 *result
= !event
.IsAllowed();
1643 wxChar
*wxListCtrl::AddPool(const wxString
& str
)
1645 // Remove the first element if 3 strings exist
1646 if ( m_stringPool
.Number() == 3 )
1648 wxNode
*node
= m_stringPool
.First();
1649 delete[] (char *)node
->Data();
1652 wxNode
*node
= m_stringPool
.Add(WXSTRINGCAST str
);
1653 return (wxChar
*)node
->Data();
1656 // ----------------------------------------------------------------------------
1658 // ----------------------------------------------------------------------------
1660 // List item structure
1661 wxListItem::wxListItem()
1671 m_format
= wxLIST_FORMAT_CENTRE
;
1677 void wxListItem::Clear()
1686 m_format
= wxLIST_FORMAT_CENTRE
;
1688 m_text
= wxEmptyString
;
1690 if (m_attr
) delete m_attr
;
1694 void wxListItem::ClearAttributes()
1696 if (m_attr
) delete m_attr
;
1700 static void wxConvertFromMSWListItem(const wxListCtrl
*ctrl
, wxListItem
& info
, LV_ITEM
& lvItem
, HWND getFullInfo
)
1702 info
.m_data
= lvItem
.lParam
;
1705 info
.m_stateMask
= 0;
1706 info
.m_itemId
= lvItem
.iItem
;
1708 long oldMask
= lvItem
.mask
;
1710 bool needText
= FALSE
;
1711 if (getFullInfo
!= 0)
1713 if ( lvItem
.mask
& LVIF_TEXT
)
1720 lvItem
.pszText
= new wxChar
[513];
1721 lvItem
.cchTextMax
= 512;
1723 // lvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
1724 lvItem
.mask
|= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
;
1725 ::SendMessage(getFullInfo
, LVM_GETITEM
, 0, (LPARAM
)& lvItem
);
1728 if ( lvItem
.mask
& LVIF_STATE
)
1730 info
.m_mask
|= wxLIST_MASK_STATE
;
1732 if ( lvItem
.stateMask
& LVIS_CUT
)
1734 info
.m_stateMask
|= wxLIST_STATE_CUT
;
1735 if ( lvItem
.state
& LVIS_CUT
)
1736 info
.m_state
|= wxLIST_STATE_CUT
;
1738 if ( lvItem
.stateMask
& LVIS_DROPHILITED
)
1740 info
.m_stateMask
|= wxLIST_STATE_DROPHILITED
;
1741 if ( lvItem
.state
& LVIS_DROPHILITED
)
1742 info
.m_state
|= wxLIST_STATE_DROPHILITED
;
1744 if ( lvItem
.stateMask
& LVIS_FOCUSED
)
1746 info
.m_stateMask
|= wxLIST_STATE_FOCUSED
;
1747 if ( lvItem
.state
& LVIS_FOCUSED
)
1748 info
.m_state
|= wxLIST_STATE_FOCUSED
;
1750 if ( lvItem
.stateMask
& LVIS_SELECTED
)
1752 info
.m_stateMask
|= wxLIST_STATE_SELECTED
;
1753 if ( lvItem
.state
& LVIS_SELECTED
)
1754 info
.m_state
|= wxLIST_STATE_SELECTED
;
1758 if ( lvItem
.mask
& LVIF_TEXT
)
1760 info
.m_mask
|= wxLIST_MASK_TEXT
;
1761 info
.m_text
= lvItem
.pszText
;
1763 if ( lvItem
.mask
& LVIF_IMAGE
)
1765 info
.m_mask
|= wxLIST_MASK_IMAGE
;
1766 info
.m_image
= lvItem
.iImage
;
1768 if ( lvItem
.mask
& LVIF_PARAM
)
1769 info
.m_mask
|= wxLIST_MASK_DATA
;
1770 if ( lvItem
.mask
& LVIF_DI_SETITEM
)
1771 info
.m_mask
|= wxLIST_SET_ITEM
;
1772 info
.m_col
= lvItem
.iSubItem
;
1777 delete[] lvItem
.pszText
;
1779 lvItem
.mask
= oldMask
;
1782 static void wxConvertToMSWListItem(const wxListCtrl
*ctrl
, wxListItem
& info
, LV_ITEM
& lvItem
)
1784 lvItem
.iItem
= (int) info
.m_itemId
;
1786 lvItem
.iImage
= info
.m_image
;
1787 lvItem
.lParam
= info
.m_data
;
1788 lvItem
.stateMask
= 0;
1791 lvItem
.iSubItem
= info
.m_col
;
1793 if (info
.m_mask
& wxLIST_MASK_STATE
)
1795 lvItem
.mask
|= LVIF_STATE
;
1796 if (info
.m_stateMask
& wxLIST_STATE_CUT
)
1798 lvItem
.stateMask
|= LVIS_CUT
;
1799 if (info
.m_state
& wxLIST_STATE_CUT
)
1800 lvItem
.state
|= LVIS_CUT
;
1802 if (info
.m_stateMask
& wxLIST_STATE_DROPHILITED
)
1804 lvItem
.stateMask
|= LVIS_DROPHILITED
;
1805 if (info
.m_state
& wxLIST_STATE_DROPHILITED
)
1806 lvItem
.state
|= LVIS_DROPHILITED
;
1808 if (info
.m_stateMask
& wxLIST_STATE_FOCUSED
)
1810 lvItem
.stateMask
|= LVIS_FOCUSED
;
1811 if (info
.m_state
& wxLIST_STATE_FOCUSED
)
1812 lvItem
.state
|= LVIS_FOCUSED
;
1814 if (info
.m_stateMask
& wxLIST_STATE_SELECTED
)
1816 lvItem
.stateMask
|= LVIS_SELECTED
;
1817 if (info
.m_state
& wxLIST_STATE_SELECTED
)
1818 lvItem
.state
|= LVIS_SELECTED
;
1822 if (info
.m_mask
& wxLIST_MASK_TEXT
)
1824 lvItem
.mask
|= LVIF_TEXT
;
1825 if ( ctrl
->GetWindowStyleFlag() & wxLC_USER_TEXT
)
1827 lvItem
.pszText
= LPSTR_TEXTCALLBACK
;
1831 lvItem
.pszText
= WXSTRINGCAST info
.m_text
;
1832 if ( lvItem
.pszText
)
1833 lvItem
.cchTextMax
= info
.m_text
.Length();
1835 lvItem
.cchTextMax
= 0;
1838 if (info
.m_mask
& wxLIST_MASK_IMAGE
)
1839 lvItem
.mask
|= LVIF_IMAGE
;
1840 if (info
.m_mask
& wxLIST_MASK_DATA
)
1841 lvItem
.mask
|= LVIF_PARAM
;
1844 // ----------------------------------------------------------------------------
1846 // ----------------------------------------------------------------------------
1848 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
1850 wxListEvent::wxListEvent(wxEventType commandType
, int id
)
1851 : wxNotifyEvent(commandType
, id
)
1857 m_cancelled
= FALSE
;