1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/wince/checklst.cpp
3 // Purpose: implementation of wxCheckListBox class
4 // Author: Wlodzimierz ABX Skiba
8 // Copyright: (c) Wlodzimierz Skiba
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #if wxUSE_CHECKLISTBOX
32 #include "wx/checklst.h"
34 // include <commctrl.h> "properly"
35 #include "wx/msw/wrapcctl.h"
37 // ============================================================================
39 // ============================================================================
41 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxControl
)
43 // ----------------------------------------------------------------------------
44 // implementation of wxCheckListBox class
45 // ----------------------------------------------------------------------------
49 BEGIN_EVENT_TABLE(wxCheckListBox
, wxControl
)
50 EVT_SIZE(wxCheckListBox::OnSize
)
56 // def ctor: use Create() to really create the control
57 wxCheckListBox::wxCheckListBox()
61 // ctor which creates the associated control
62 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
63 const wxPoint
& pos
, const wxSize
& size
,
64 int nStrings
, const wxString choices
[],
65 long style
, const wxValidator
& val
,
68 Create(parent
, id
, pos
, size
, nStrings
, choices
, style
, val
, name
);
71 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
72 const wxPoint
& pos
, const wxSize
& size
,
73 const wxArrayString
& choices
,
74 long style
, const wxValidator
& val
,
77 Create(parent
, id
, pos
, size
, choices
, style
, val
, name
);
80 wxCheckListBox::~wxCheckListBox()
82 m_itemsClientData
.Clear();
85 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
86 const wxPoint
& pos
, const wxSize
& size
,
87 int n
, const wxString choices
[],
89 const wxValidator
& validator
, const wxString
& name
)
91 // initialize base class fields
92 if ( !CreateControl(parent
, id
, pos
, size
, style
, validator
, name
) )
95 // create the native control
96 if ( !MSWCreateControl(WC_LISTVIEW
, wxEmptyString
, pos
, size
) )
98 // control creation failed
102 ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE
, 0,
103 LVS_EX_CHECKBOXES
| LVS_EX_FULLROWSELECT
);
105 // insert single column with checkboxes and labels
108 ListView_InsertColumn(GetHwnd(), 0, &col
);
110 ListView_SetItemCount( GetHwnd(), n
);
112 // initialize the contents
113 for ( int i
= 0; i
< n
; i
++ )
118 m_itemsClientData
.SetCount(n
);
120 // now we can compute our best size correctly, so do it if necessary
126 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
127 const wxPoint
& pos
, const wxSize
& size
,
128 const wxArrayString
& choices
,
130 const wxValidator
& validator
, const wxString
& name
)
132 wxCArrayString
chs(choices
);
133 return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
134 style
, validator
, name
);
137 WXDWORD
wxCheckListBox::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
139 WXDWORD wstyle
= wxControl::MSWGetStyle(style
, exstyle
);
141 wstyle
|= LVS_REPORT
| LVS_NOCOLUMNHEADER
| LVS_NOSORTHEADER
;
146 void wxCheckListBox::OnSize(wxSizeEvent
& event
)
148 // set width of the column we use to the width of list client area
150 int w
= GetClientSize().x
;
151 ListView_SetColumnWidth( GetHwnd(), 0, w
);
154 // misc overloaded methods
155 // -----------------------
157 void wxCheckListBox::Delete(unsigned int n
)
159 wxCHECK_RET( IsValid( n
), _T("invalid index in wxCheckListBox::Delete") );
161 if ( !ListView_DeleteItem(GetHwnd(), n
) )
163 wxLogLastError(_T("ListView_DeleteItem"));
165 m_itemsClientData
.RemoveAt(n
);
171 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const
173 wxCHECK_MSG( IsValid( uiIndex
), false,
174 _T("invalid index in wxCheckListBox::IsChecked") );
176 return (ListView_GetCheckState(((HWND
)GetHWND()), uiIndex
) != 0);
179 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
)
181 wxCHECK_RET( IsValid( uiIndex
),
182 _T("invalid index in wxCheckListBox::Check") );
184 ListView_SetCheckState(((HWND
)GetHWND()), uiIndex
, bCheck
)
187 // interface derived from wxListBox and lower classes
188 // --------------------------------------------------
190 void wxCheckListBox::Clear()
192 unsigned int n
= GetCount();
200 m_itemsClientData
.Clear();
202 wxCHECK_RET( n
== GetCount(),
203 _T("broken wxCheckListBox::Clear()") );
206 unsigned int wxCheckListBox::GetCount() const
208 return (unsigned int)ListView_GetItemCount( (HWND
)GetHWND() );
211 int wxCheckListBox::GetSelection() const
214 for (i
= 0; (unsigned int)i
< GetCount(); i
++)
216 int selState
= ListView_GetItemState(GetHwnd(), i
, LVIS_SELECTED
);
217 if (selState
== LVIS_SELECTED
)
224 int wxCheckListBox::GetSelections(wxArrayInt
& aSelections
) const
227 for (i
= 0; (unsigned int)i
< GetCount(); i
++)
229 int selState
= ListView_GetItemState(GetHwnd(), i
, LVIS_SELECTED
);
230 if (selState
== LVIS_SELECTED
)
234 return aSelections
.GetCount();
237 wxString
wxCheckListBox::GetString(unsigned int n
) const
239 const int bufSize
= 513;
241 ListView_GetItemText( (HWND
)GetHWND(), n
, 0, buf
, bufSize
- 1 );
242 buf
[bufSize
-1] = _T('\0');
247 bool wxCheckListBox::IsSelected(int n
) const
249 int selState
= ListView_GetItemState(GetHwnd(), n
, LVIS_SELECTED
);
250 return (selState
== LVIS_SELECTED
);
253 void wxCheckListBox::SetString(unsigned int n
, const wxString
& s
)
255 wxCHECK_RET( IsValid( n
),
256 _T("invalid index in wxCheckListBox::SetString") );
257 wxChar
*buf
= new wxChar
[s
.length()+1];
258 wxStrcpy(buf
, s
.c_str());
259 ListView_SetItemText( (HWND
)GetHWND(), n
, 0, buf
);
263 int wxCheckListBox::DoAppend(const wxString
& item
)
265 int n
= (int)GetCount();
267 wxZeroMemory(newItem
);
269 int ret
= ListView_InsertItem( (HWND
)GetHWND(), & newItem
);
270 wxCHECK_MSG( n
== ret
, -1, _T("Item not added") );
271 SetString( ret
, item
);
272 m_itemsClientData
.Insert(NULL
, ret
);
276 void* wxCheckListBox::DoGetItemClientData(unsigned int n
) const
278 return m_itemsClientData
.Item(n
);
281 wxClientData
* wxCheckListBox::DoGetItemClientObject(unsigned int n
) const
283 return (wxClientData
*)DoGetItemClientData(n
);
286 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, unsigned int pos
)
288 wxCHECK_RET( IsValidInsert( pos
),
289 wxT("invalid index in wxListBox::InsertItems") );
291 for( unsigned int i
= 0; i
< items
.GetCount(); i
++ )
294 wxZeroMemory(newItem
);
295 newItem
.iItem
= i
+pos
;
296 int ret
= ListView_InsertItem( (HWND
)GetHWND(), & newItem
);
297 wxASSERT_MSG( int(i
+pos
) == ret
, _T("Item not added") );
298 SetString( ret
, items
[i
] );
299 m_itemsClientData
.Insert(NULL
, ret
);
303 void wxCheckListBox::DoSetFirstItem(int n
)
305 int pos
= ListView_GetTopIndex( (HWND
)GetHWND() );
308 BOOL ret
= ListView_GetItemPosition( (HWND
)GetHWND(), n
, &ppt
);
309 wxCHECK_RET( ret
== TRUE
, _T("Broken DoSetFirstItem") );
310 ListView_Scroll( (HWND
)GetHWND(), 0, 0 );
311 ListView_Scroll( (HWND
)GetHWND(), 0, ppt
.y
);
314 void wxCheckListBox::DoSetItemClientData(unsigned int n
, void* clientData
)
316 m_itemsClientData
.Item(n
) = clientData
;
319 void wxCheckListBox::DoSetItemClientObject(unsigned int n
, wxClientData
* clientData
)
321 DoSetItemClientData(n
, clientData
);
324 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
326 ListView_SetItemCount( GetHwnd(), GetCount() + items
.GetCount() );
328 for( unsigned int i
= 0; i
< items
.GetCount(); i
++ )
330 int pos
= Append(items
[i
]);
331 if( pos
>= 0 && clientData
)
332 DoSetItemClientData(pos
, clientData
[i
]);
336 void wxCheckListBox::DoSetSelection(int n
, bool select
)
338 ListView_SetItemState(GetHwnd(), n
, select
? LVIS_SELECTED
: 0, LVIS_SELECTED
);
341 bool wxCheckListBox::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM
*result
)
346 wxCommandEvent
event(wxEVT_NULL
, m_windowId
);
347 event
.SetEventObject(this);
349 wxEventType eventType
= wxEVT_NULL
;
351 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
353 if ( nmhdr
->hwndFrom
== GetHwnd() )
355 // almost all messages use NM_LISTVIEW
356 NM_LISTVIEW
*nmLV
= (NM_LISTVIEW
*)nmhdr
;
358 const int iItem
= nmLV
->iItem
;
360 bool processed
= true;
361 switch ( nmhdr
->code
)
363 case LVN_ITEMCHANGED
:
364 // we translate this catch all message into more interesting
365 // (and more easy to process) wxWidgets events
367 // first of all, we deal with the state change events only and
368 // only for valid items (item == -1 for the virtual list
370 if ( nmLV
->uChanged
& LVIF_STATE
&& iItem
!= -1 )
372 // temp vars for readability
373 const UINT stOld
= nmLV
->uOldState
;
374 const UINT stNew
= nmLV
->uNewState
;
376 // Check image changed
377 if ((stOld
& LVIS_STATEIMAGEMASK
) != (stNew
& LVIS_STATEIMAGEMASK
))
379 event
.SetEventType(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
);
380 event
.SetInt(IsChecked(iItem
));
381 (void) GetEventHandler()->ProcessEvent(event
);
384 if ( (stNew
& LVIS_SELECTED
) != (stOld
& LVIS_SELECTED
) )
386 eventType
= wxEVT_COMMAND_LISTBOX_SELECTED
;
388 event
.SetExtraLong( (stNew
& LVIS_SELECTED
) != 0 ); // is a selection
393 if ( eventType
== wxEVT_NULL
)
395 // not an interesting event for us
406 return wxControl::MSWOnNotify(idCtrl
, lParam
, result
);
410 // where did this one come from?
417 event
.SetEventType(eventType
);
419 bool processed
= GetEventHandler()->ProcessEvent(event
);