1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/wince/checklst.cpp
3 // Purpose: implementation of wxCheckListBox class
4 // Author: Wlodzimierz ABX Skiba
7 // Copyright: (c) Wlodzimierz Skiba
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #if wxUSE_CHECKLISTBOX
28 #include "wx/checklst.h"
31 #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
34 // ============================================================================
36 // ============================================================================
38 // ----------------------------------------------------------------------------
39 // implementation of wxCheckListBox class
40 // ----------------------------------------------------------------------------
44 BEGIN_EVENT_TABLE(wxCheckListBox
, wxControl
)
45 EVT_SIZE(wxCheckListBox::OnSize
)
51 // def ctor: use Create() to really create the control
52 wxCheckListBox::wxCheckListBox()
56 // ctor which creates the associated control
57 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
58 const wxPoint
& pos
, const wxSize
& size
,
59 int nStrings
, const wxString choices
[],
60 long style
, const wxValidator
& val
,
63 Create(parent
, id
, pos
, size
, nStrings
, choices
, style
, val
, name
);
66 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
67 const wxPoint
& pos
, const wxSize
& size
,
68 const wxArrayString
& choices
,
69 long style
, const wxValidator
& val
,
72 Create(parent
, id
, pos
, size
, choices
, style
, val
, name
);
75 wxCheckListBox::~wxCheckListBox()
77 m_itemsClientData
.Clear();
80 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
81 const wxPoint
& pos
, const wxSize
& size
,
82 int n
, const wxString choices
[],
84 const wxValidator
& validator
, const wxString
& name
)
86 // initialize base class fields
87 if ( !CreateControl(parent
, id
, pos
, size
, style
, validator
, name
) )
90 // create the native control
91 if ( !MSWCreateControl(WC_LISTVIEW
, wxEmptyString
, pos
, size
) )
93 // control creation failed
97 ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE
, 0,
98 LVS_EX_CHECKBOXES
| LVS_EX_FULLROWSELECT
);
100 // insert single column with checkboxes and labels
103 ListView_InsertColumn(GetHwnd(), 0, &col
);
105 ListView_SetItemCount( GetHwnd(), n
);
107 // initialize the contents
108 for ( int i
= 0; i
< n
; i
++ )
113 m_itemsClientData
.SetCount(n
);
115 // now we can compute our best size correctly, so do it if necessary
116 SetInitialSize(size
);
121 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
122 const wxPoint
& pos
, const wxSize
& size
,
123 const wxArrayString
& choices
,
125 const wxValidator
& validator
, const wxString
& name
)
127 wxCArrayString
chs(choices
);
128 return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
129 style
, validator
, name
);
132 WXDWORD
wxCheckListBox::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
134 WXDWORD wstyle
= wxControl::MSWGetStyle(style
, exstyle
);
136 wstyle
|= LVS_REPORT
| LVS_NOCOLUMNHEADER
| LVS_NOSORTHEADER
;
141 void wxCheckListBox::OnSize(wxSizeEvent
& event
)
143 // set width of the column we use to the width of list client area
145 int w
= GetClientSize().x
;
146 ListView_SetColumnWidth( GetHwnd(), 0, w
);
149 // misc overloaded methods
150 // -----------------------
152 void wxCheckListBox::DoDeleteOneItem(unsigned int n
)
154 wxCHECK_RET( IsValid( n
), wxT("invalid index in wxCheckListBox::Delete") );
156 if ( !ListView_DeleteItem(GetHwnd(), n
) )
158 wxLogLastError(wxT("ListView_DeleteItem"));
160 m_itemsClientData
.RemoveAt(n
);
166 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const
168 wxCHECK_MSG( IsValid( uiIndex
), false,
169 wxT("invalid index in wxCheckListBox::IsChecked") );
171 return (ListView_GetCheckState(((HWND
)GetHWND()), uiIndex
) != 0);
174 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
)
176 wxCHECK_RET( IsValid( uiIndex
),
177 wxT("invalid index in wxCheckListBox::Check") );
179 ListView_SetCheckState(((HWND
)GetHWND()), uiIndex
, bCheck
)
182 // interface derived from wxListBox and lower classes
183 // --------------------------------------------------
185 void wxCheckListBox::DoClear()
187 unsigned int n
= GetCount();
195 wxASSERT_MSG( IsEmpty(), wxT("logic error in DoClear()") );
198 unsigned int wxCheckListBox::GetCount() const
200 return (unsigned int)ListView_GetItemCount( (HWND
)GetHWND() );
203 int wxCheckListBox::GetSelection() const
206 for (i
= 0; (unsigned int)i
< GetCount(); i
++)
208 int selState
= ListView_GetItemState(GetHwnd(), i
, LVIS_SELECTED
);
209 if (selState
== LVIS_SELECTED
)
216 int wxCheckListBox::GetSelections(wxArrayInt
& aSelections
) const
219 for (i
= 0; (unsigned int)i
< GetCount(); i
++)
221 int selState
= ListView_GetItemState(GetHwnd(), i
, LVIS_SELECTED
);
222 if (selState
== LVIS_SELECTED
)
226 return aSelections
.GetCount();
229 wxString
wxCheckListBox::GetString(unsigned int n
) const
231 const int bufSize
= 513;
233 ListView_GetItemText( (HWND
)GetHWND(), n
, 0, buf
, bufSize
- 1 );
234 buf
[bufSize
-1] = wxT('\0');
239 bool wxCheckListBox::IsSelected(int n
) const
241 int selState
= ListView_GetItemState(GetHwnd(), n
, LVIS_SELECTED
);
242 return (selState
== LVIS_SELECTED
);
245 void wxCheckListBox::SetString(unsigned int n
, const wxString
& s
)
247 wxCHECK_RET( IsValid( n
),
248 wxT("invalid index in wxCheckListBox::SetString") );
249 wxChar
*buf
= new wxChar
[s
.length()+1];
250 wxStrcpy(buf
, s
.c_str());
251 ListView_SetItemText( (HWND
)GetHWND(), n
, 0, buf
);
255 void* wxCheckListBox::DoGetItemClientData(unsigned int n
) const
257 return m_itemsClientData
.Item(n
);
260 int wxCheckListBox::DoInsertItems(const wxArrayStringsAdapter
& items
,
262 void **clientData
, wxClientDataType type
)
264 const unsigned int count
= items
.GetCount();
266 ListView_SetItemCount( GetHwnd(), GetCount() + count
);
270 for( unsigned int i
= 0; i
< count
; i
++ )
273 wxZeroMemory(newItem
);
274 newItem
.iItem
= pos
+ i
;
275 n
= ListView_InsertItem( (HWND
)GetHWND(), & newItem
);
276 wxCHECK_MSG( n
!= -1, -1, wxT("Item not added") );
277 SetString( n
, items
[i
] );
278 m_itemsClientData
.Insert(NULL
, n
);
280 AssignNewItemClientData(n
, clientData
, i
, type
);
286 void wxCheckListBox::DoSetFirstItem(int n
)
288 int pos
= ListView_GetTopIndex( (HWND
)GetHWND() );
291 BOOL ret
= ListView_GetItemPosition( (HWND
)GetHWND(), n
, &ppt
);
292 wxCHECK_RET( ret
== TRUE
, wxT("Broken DoSetFirstItem") );
293 ListView_Scroll( (HWND
)GetHWND(), 0, 0 );
294 ListView_Scroll( (HWND
)GetHWND(), 0, ppt
.y
);
297 void wxCheckListBox::DoSetItemClientData(unsigned int n
, void* clientData
)
299 m_itemsClientData
.Item(n
) = clientData
;
302 void wxCheckListBox::DoSetSelection(int n
, bool select
)
304 ListView_SetItemState(GetHwnd(), n
, select
? LVIS_SELECTED
: 0, LVIS_SELECTED
);
307 bool wxCheckListBox::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM
*result
)
312 wxCommandEvent
event(wxEVT_NULL
, m_windowId
);
313 event
.SetEventObject(this);
315 wxEventType eventType
= wxEVT_NULL
;
317 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
319 if ( nmhdr
->hwndFrom
== GetHwnd() )
321 // almost all messages use NM_LISTVIEW
322 NM_LISTVIEW
*nmLV
= (NM_LISTVIEW
*)nmhdr
;
324 const int iItem
= nmLV
->iItem
;
326 bool processed
= true;
327 switch ( nmhdr
->code
)
329 case LVN_ITEMCHANGED
:
330 // we translate this catch all message into more interesting
331 // (and more easy to process) wxWidgets events
333 // first of all, we deal with the state change events only and
334 // only for valid items (item == -1 for the virtual list
336 if ( nmLV
->uChanged
& LVIF_STATE
&& iItem
!= -1 )
338 // temp vars for readability
339 const UINT stOld
= nmLV
->uOldState
;
340 const UINT stNew
= nmLV
->uNewState
;
342 // Check image changed
343 if ((stOld
& LVIS_STATEIMAGEMASK
) != (stNew
& LVIS_STATEIMAGEMASK
))
345 event
.SetEventType(wxEVT_CHECKLISTBOX
);
346 event
.SetInt(IsChecked(iItem
));
347 (void) GetEventHandler()->ProcessEvent(event
);
350 if ( (stNew
& LVIS_SELECTED
) != (stOld
& LVIS_SELECTED
) )
352 eventType
= wxEVT_LISTBOX
;
354 event
.SetExtraLong( (stNew
& LVIS_SELECTED
) != 0 ); // is a selection
359 if ( eventType
== wxEVT_NULL
)
361 // not an interesting event for us
372 return wxControl::MSWOnNotify(idCtrl
, lParam
, result
);
376 // where did this one come from?
383 event
.SetEventType(eventType
);
385 bool processed
= GetEventHandler()->ProcessEvent(event
);