]>
Commit | Line | Data |
---|---|---|
0e320a79 DW |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: listbox.cpp | |
3 | // Purpose: wxListBox | |
fb9010ed | 4 | // Author: David Webster |
0e320a79 | 5 | // Modified by: |
fb9010ed | 6 | // Created: 10/09/99 |
0e320a79 | 7 | // RCS-ID: $Id$ |
fb9010ed | 8 | // Copyright: (c) David Webster |
0e320a79 DW |
9 | // Licence: wxWindows licence |
10 | /////////////////////////////////////////////////////////////////////////////// | |
11 | ||
fb9010ed DW |
12 | // For compilers that support precompilation, includes "wx.h". |
13 | #include "wx/wxprec.h" | |
14 | ||
15 | #include "wx/window.h" | |
16 | #include "wx/os2/private.h" | |
0e320a79 | 17 | |
fb9010ed | 18 | #ifndef WX_PRECOMP |
0e320a79 DW |
19 | #include "wx/listbox.h" |
20 | #include "wx/settings.h" | |
fb9010ed DW |
21 | #include "wx/brush.h" |
22 | #include "wx/font.h" | |
23 | #include "wx/dc.h" | |
24 | #include "wx/utils.h" | |
25 | #endif | |
26 | ||
27 | #define INCL_M | |
28 | #include <os2.h> | |
29 | ||
0e320a79 DW |
30 | #include "wx/dynarray.h" |
31 | #include "wx/log.h" | |
32 | ||
7e99520b DW |
33 | #if wxUSE_LISTBOX |
34 | ||
fb9010ed DW |
35 | #if wxUSE_OWNER_DRAWN |
36 | #include "wx/ownerdrw.h" | |
37 | #endif | |
38 | ||
0e320a79 | 39 | IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl) |
0e320a79 | 40 | |
fb9010ed DW |
41 | // ============================================================================ |
42 | // list box item declaration and implementation | |
43 | // ============================================================================ | |
44 | ||
45 | #if wxUSE_OWNER_DRAWN | |
46 | ||
47 | class wxListBoxItem : public wxOwnerDrawn | |
48 | { | |
49 | public: | |
49dc8caa | 50 | wxListBoxItem(const wxString& rsStr = ""); |
fb9010ed DW |
51 | }; |
52 | ||
49dc8caa DW |
53 | wxListBoxItem::wxListBoxItem( |
54 | const wxString& rsStr | |
55 | ) | |
56 | : wxOwnerDrawn( rsStr | |
57 | ,FALSE | |
58 | ) | |
fb9010ed | 59 | { |
49dc8caa DW |
60 | // |
61 | // No bitmaps/checkmarks | |
62 | // | |
fb9010ed | 63 | SetMarginWidth(0); |
49dc8caa | 64 | } // end of wxListBoxItem::wxListBoxItem |
fb9010ed | 65 | |
49dc8caa DW |
66 | wxOwnerDrawn* wxListBox::CreateItem( |
67 | size_t n | |
68 | ) | |
fb9010ed DW |
69 | { |
70 | return new wxListBoxItem(); | |
49dc8caa | 71 | } // end of wxListBox::CreateItem |
fb9010ed DW |
72 | |
73 | #endif //USE_OWNER_DRAWN | |
74 | ||
0e320a79 DW |
75 | // ============================================================================ |
76 | // list box control implementation | |
77 | // ============================================================================ | |
78 | ||
79 | // Listbox item | |
80 | wxListBox::wxListBox() | |
81 | { | |
49dc8caa DW |
82 | m_nNumItems = 0; |
83 | m_nSelected = 0; | |
84 | } // end of wxListBox::wxListBox | |
85 | ||
86 | bool wxListBox::Create( | |
87 | wxWindow* pParent | |
88 | , wxWindowID vId | |
89 | , const wxPoint& rPos | |
90 | , const wxSize& rSize | |
91 | , int n | |
92 | , const wxString asChoices[] | |
93 | , long lStyle | |
5d4b632b | 94 | #if wxUSE_VALIDATORS |
49dc8caa | 95 | , const wxValidator& rValidator |
5d4b632b | 96 | #endif |
49dc8caa DW |
97 | , const wxString& rsName |
98 | ) | |
0e320a79 | 99 | { |
49dc8caa DW |
100 | m_nNumItems = 0; |
101 | m_hWnd = 0; | |
102 | m_nSelected = 0; | |
0e320a79 | 103 | |
49dc8caa | 104 | SetName(rsName); |
5d4b632b | 105 | #if wxUSE_VALIDATORS |
49dc8caa | 106 | SetValidator(rValidator); |
5d4b632b | 107 | #endif |
0e320a79 | 108 | |
49dc8caa DW |
109 | if (pParent) |
110 | pParent->AddChild(this); | |
111 | ||
112 | wxSystemSettings vSettings; | |
113 | ||
114 | SetBackgroundColour(vSettings.GetSystemColour(wxSYS_COLOUR_WINDOW)); | |
115 | SetForegroundColour(pParent->GetForegroundColour()); | |
0e320a79 | 116 | |
49dc8caa | 117 | m_windowId = (vId == -1) ? (int)NewControlId() : vId; |
0e320a79 | 118 | |
49dc8caa DW |
119 | int nX = rPos.x; |
120 | int nY = rPos.y; | |
121 | int nWidth = rSize.x; | |
122 | int nHeight = rSize.y; | |
0e320a79 | 123 | |
49dc8caa | 124 | m_windowStyle = lStyle; |
fb9010ed | 125 | |
49dc8caa DW |
126 | lStyle = WS_VISIBLE; |
127 | ||
128 | if (m_windowStyle & wxCLIP_SIBLINGS ) | |
129 | lStyle |= WS_CLIPSIBLINGS; | |
fb9010ed | 130 | if (m_windowStyle & wxLB_MULTIPLE) |
49dc8caa | 131 | lStyle |= LS_MULTIPLESEL; |
fb9010ed | 132 | else if (m_windowStyle & wxLB_EXTENDED) |
49dc8caa | 133 | lStyle |= LS_EXTENDEDSEL; |
fb9010ed | 134 | if (m_windowStyle & wxLB_HSCROLL) |
49dc8caa DW |
135 | lStyle |= LS_HORZSCROLL; |
136 | if (m_windowStyle & wxLB_OWNERDRAW) | |
137 | lStyle |= LS_OWNERDRAW; | |
fb9010ed | 138 | |
49dc8caa | 139 | // |
fb9010ed DW |
140 | // Without this style, you get unexpected heights, so e.g. constraint layout |
141 | // doesn't work properly | |
49dc8caa DW |
142 | // |
143 | lStyle |= LS_NOADJUSTPOS; | |
144 | ||
5d44b24e DW |
145 | // |
146 | // If the parent is a scrolled window the controls must | |
147 | // have this style or they will overlap the scrollbars | |
148 | // | |
149 | if (pParent) | |
150 | if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) || | |
151 | pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow))) | |
152 | lStyle |= WS_CLIPSIBLINGS; | |
153 | ||
49dc8caa DW |
154 | m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent) // Parent |
155 | ,WC_LISTBOX // Default Listbox class | |
156 | ,"LISTBOX" // Control's name | |
157 | ,lStyle // Initial Style | |
158 | ,0, 0, 0, 0 // Position and size | |
159 | ,GetWinHwnd(pParent) // Owner | |
160 | ,HWND_TOP // Z-Order | |
161 | ,(HMENU)m_windowId // Id | |
162 | ,NULL // Control Data | |
163 | ,NULL // Presentation Parameters | |
164 | ); | |
165 | if (m_hWnd == 0) | |
fb9010ed | 166 | { |
49dc8caa | 167 | return FALSE; |
fb9010ed DW |
168 | } |
169 | ||
49dc8caa DW |
170 | // |
171 | // Subclass again for purposes of dialog editing mode | |
172 | // | |
fb9010ed DW |
173 | SubclassWin(m_hWnd); |
174 | ||
49dc8caa | 175 | LONG lUi; |
0e320a79 | 176 | |
49dc8caa DW |
177 | for (lUi = 0; lUi < (LONG)n; lUi++) |
178 | { | |
179 | Append(asChoices[lUi]); | |
180 | } | |
181 | SetFont(pParent->GetFont()); | |
5d44b24e DW |
182 | |
183 | // | |
184 | // Set standard wxWindows colors for Listbox items and highlighting | |
185 | // | |
186 | wxColour vColour; | |
187 | ||
188 | vColour.Set(wxString("WHITE")); | |
189 | ||
190 | LONG lColor = (LONG)vColour.GetPixel(); | |
191 | ||
192 | ::WinSetPresParam( m_hWnd | |
193 | ,PP_HILITEFOREGROUNDCOLOR | |
194 | ,sizeof(LONG) | |
195 | ,(PVOID)&lColor | |
196 | ); | |
197 | vColour.Set(wxString("NAVY")); | |
198 | lColor = (LONG)vColour.GetPixel(); | |
199 | ::WinSetPresParam( m_hWnd | |
200 | ,PP_HILITEBACKGROUNDCOLOR | |
201 | ,sizeof(LONG) | |
202 | ,(PVOID)&lColor | |
203 | ); | |
204 | ||
49dc8caa DW |
205 | SetSize( nX |
206 | ,nY | |
207 | ,nWidth | |
208 | ,nHeight | |
209 | ); | |
dcd307ee | 210 | return TRUE; |
49dc8caa | 211 | } // end of wxListBox::Create |
0e320a79 DW |
212 | |
213 | wxListBox::~wxListBox() | |
214 | { | |
fb9010ed | 215 | #if wxUSE_OWNER_DRAWN |
49dc8caa DW |
216 | size_t lUiCount = m_aItems.Count(); |
217 | ||
218 | while (lUiCount-- != 0) | |
219 | { | |
220 | delete m_aItems[lUiCount]; | |
fb9010ed DW |
221 | } |
222 | #endif // wxUSE_OWNER_DRAWN | |
49dc8caa | 223 | } // end of wxListBox::~wxListBox |
fb9010ed DW |
224 | |
225 | void wxListBox::SetupColours() | |
226 | { | |
227 | SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); | |
228 | SetForegroundColour(GetParent()->GetForegroundColour()); | |
49dc8caa | 229 | } // end of wxListBox::SetupColours |
0e320a79 | 230 | |
dcd307ee DW |
231 | // ---------------------------------------------------------------------------- |
232 | // implementation of wxListBoxBase methods | |
233 | // ---------------------------------------------------------------------------- | |
234 | ||
49dc8caa DW |
235 | void wxListBox::DoSetFirstItem( |
236 | int N | |
237 | ) | |
0e320a79 | 238 | { |
49dc8caa | 239 | wxCHECK_RET( N >= 0 && N < m_nNumItems, |
fb9010ed DW |
240 | wxT("invalid index in wxListBox::SetFirstItem") ); |
241 | ||
49dc8caa DW |
242 | ::WinSendMsg(GetHwnd(), LM_SETTOPINDEX, MPFROMLONG(N), (MPARAM)0); |
243 | } // end of wxListBox::DoSetFirstItem | |
0e320a79 | 244 | |
49dc8caa DW |
245 | void wxListBox::Delete( |
246 | int N | |
247 | ) | |
0e320a79 | 248 | { |
49dc8caa | 249 | wxCHECK_RET( N >= 0 && N < m_nNumItems, |
fb9010ed DW |
250 | wxT("invalid index in wxListBox::Delete") ); |
251 | ||
dcd307ee DW |
252 | #if wxUSE_OWNER_DRAWN |
253 | delete m_aItems[N]; | |
893758d5 | 254 | m_aItems.RemoveAt(N); |
dcd307ee | 255 | #else // !wxUSE_OWNER_DRAWN |
49dc8caa | 256 | if (HasClientObjectData()) |
dcd307ee DW |
257 | { |
258 | delete GetClientObject(N); | |
259 | } | |
260 | #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN | |
261 | ||
49dc8caa DW |
262 | ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)N, (MPARAM)0); |
263 | m_nNumItems--; | |
264 | } // end of wxListBox::DoSetFirstItem | |
0e320a79 | 265 | |
49dc8caa DW |
266 | int wxListBox::DoAppend( |
267 | const wxString& rsItem | |
268 | ) | |
0e320a79 | 269 | { |
49dc8caa DW |
270 | int nIndex = 0; |
271 | SHORT nIndexType = 0; | |
272 | ||
273 | if (m_windowStyle & wxLB_SORT) | |
274 | nIndexType = LIT_SORTASCENDING; | |
275 | else | |
276 | nIndexType = LIT_END; | |
277 | nIndex = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)rsItem.c_str()); | |
278 | m_nNumItems++; | |
fb9010ed DW |
279 | |
280 | #if wxUSE_OWNER_DRAWN | |
49dc8caa DW |
281 | if (m_windowStyle & wxLB_OWNERDRAW) |
282 | { | |
283 | wxOwnerDrawn* pNewItem = CreateItem(nIndex); // dummy argument | |
284 | ||
285 | pNewItem->SetName(rsItem); | |
fb9010ed | 286 | m_aItems.Add(pNewItem); |
49dc8caa DW |
287 | ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)((SHORT)nIndex), MPFROMP(pNewItem)); |
288 | pNewItem->SetFont(GetFont()); | |
fb9010ed DW |
289 | } |
290 | #endif | |
49dc8caa DW |
291 | return nIndex; |
292 | } // end of wxListBox::DoAppend | |
0e320a79 | 293 | |
49dc8caa DW |
294 | void wxListBox::DoSetItems( |
295 | const wxArrayString& raChoices | |
296 | , void** ppClientData | |
297 | ) | |
0e320a79 | 298 | { |
49dc8caa DW |
299 | BOOL bHideAndShow = IsShown(); |
300 | int nCount = 0; | |
301 | int i; | |
302 | SHORT nIndexType = 0; | |
0e320a79 | 303 | |
49dc8caa | 304 | if (bHideAndShow) |
fb9010ed | 305 | { |
49dc8caa DW |
306 | ::WinShowWindow(GetHwnd(), FALSE); |
307 | } | |
308 | ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); | |
309 | m_nNumItems = raChoices.GetCount(); | |
310 | for (i = 0; i < m_nNumItems; i++) | |
311 | { | |
312 | ||
313 | if (m_windowStyle & wxLB_SORT) | |
314 | nIndexType = LIT_SORTASCENDING; | |
315 | else | |
316 | nIndexType = LIT_END; | |
317 | ::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)raChoices[i].c_str()); | |
318 | ||
319 | if (ppClientData) | |
dcd307ee DW |
320 | { |
321 | #if wxUSE_OWNER_DRAWN | |
49dc8caa | 322 | wxASSERT_MSG(ppClientData[i] == NULL, |
dcd307ee DW |
323 | wxT("Can't use client data with owner-drawn listboxes")); |
324 | #else // !wxUSE_OWNER_DRAWN | |
49dc8caa | 325 | ::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lCount), MPFROMP(ppClientData[i])); |
dcd307ee DW |
326 | #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN |
327 | } | |
fb9010ed | 328 | } |
fb9010ed DW |
329 | |
330 | #if wxUSE_OWNER_DRAWN | |
49dc8caa DW |
331 | if ( m_windowStyle & wxLB_OWNERDRAW ) |
332 | { | |
333 | // | |
334 | // First delete old items | |
335 | // | |
336 | size_t lUi = m_aItems.Count(); | |
337 | ||
338 | while (lUi-- != 0) | |
339 | { | |
340 | delete m_aItems[lUi]; | |
fb9010ed DW |
341 | } |
342 | m_aItems.Empty(); | |
343 | ||
49dc8caa DW |
344 | // |
345 | // Then create new ones | |
346 | // | |
347 | for (lUi = 0; lUi < (size_t)m_nNumItems; lUi++) | |
348 | { | |
349 | wxOwnerDrawn* pNewItem = CreateItem(lUi); | |
350 | ||
351 | pNewItem->SetName(raChoices[lUi]); | |
fb9010ed | 352 | m_aItems.Add(pNewItem); |
49dc8caa | 353 | ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lUi), MPFROMP(pNewItem)); |
fb9010ed DW |
354 | } |
355 | } | |
dcd307ee | 356 | #endif // wxUSE_OWNER_DRAWN |
49dc8caa DW |
357 | ::WinShowWindow(GetHwnd(), TRUE); |
358 | } // end of wxListBox::DoSetItems | |
0e320a79 | 359 | |
49dc8caa DW |
360 | int wxListBox::FindString( |
361 | const wxString& rsString | |
362 | ) const | |
363 | { | |
364 | int nPos; | |
365 | LONG lTextLength; | |
366 | PSZ zStr; | |
dcd307ee | 367 | |
0e320a79 | 368 | |
49dc8caa DW |
369 | for (nPos = 0; nPos < m_nNumItems; nPos++) |
370 | { | |
371 | lTextLength = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0)); | |
372 | zStr = new char[lTextLength + 1]; | |
373 | ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT(nPos, (SHORT)lTextLength), (MPARAM)zStr); | |
374 | if (rsString == (char*)zStr) | |
375 | { | |
376 | delete [] zStr; | |
377 | break; | |
378 | } | |
379 | delete [] zStr; | |
380 | } | |
381 | return nPos; | |
382 | } // end of wxListBox::FindString | |
0e320a79 DW |
383 | |
384 | void wxListBox::Clear() | |
385 | { | |
fb9010ed | 386 | #if wxUSE_OWNER_DRAWN |
49dc8caa DW |
387 | size_t lUiCount = m_aItems.Count(); |
388 | ||
389 | while (lUiCount-- != 0) | |
390 | { | |
391 | delete m_aItems[lUiCount]; | |
fb9010ed DW |
392 | } |
393 | ||
394 | m_aItems.Clear(); | |
dcd307ee | 395 | #else // !wxUSE_OWNER_DRAWN |
49dc8caa | 396 | if (HasClientObjectData()) |
dcd307ee | 397 | { |
49dc8caa | 398 | for (size_t n = 0; n < (size_t)m_lNumItems; n++) |
dcd307ee DW |
399 | { |
400 | delete GetClientObject(n); | |
401 | } | |
402 | } | |
403 | #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN | |
49dc8caa | 404 | ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); |
dcd307ee | 405 | |
49dc8caa DW |
406 | m_nNumItems = 0; |
407 | } // end of wxListBox::Clear | |
fb9010ed | 408 | |
49dc8caa DW |
409 | void wxListBox::SetSelection( |
410 | int N | |
411 | , bool bSelect | |
412 | ) | |
0e320a79 | 413 | { |
49dc8caa | 414 | wxCHECK_RET( N >= 0 && N < m_nNumItems, |
fb9010ed | 415 | wxT("invalid index in wxListBox::SetSelection") ); |
49dc8caa DW |
416 | ::WinSendMsg( GetHwnd() |
417 | ,LM_SELECTITEM | |
418 | ,MPFROMLONG(N) | |
419 | ,(MPARAM)bSelect | |
420 | ); | |
421 | } // end of wxListBox::SetSelection | |
422 | ||
423 | bool wxListBox::IsSelected( | |
424 | int N | |
425 | ) const | |
426 | { | |
427 | wxCHECK_MSG( N >= 0 && N < m_nNumItems, FALSE, | |
fb9010ed DW |
428 | wxT("invalid index in wxListBox::Selected") ); |
429 | ||
49dc8caa | 430 | LONG lItem; |
0e320a79 | 431 | |
49dc8caa DW |
432 | lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)N, (MPARAM)0)); |
433 | return (lItem != LIT_NONE); | |
434 | } // end of wxListBox::IsSelected | |
435 | ||
436 | wxClientData* wxListBox::DoGetItemClientObject( | |
437 | int n | |
438 | ) const | |
0e320a79 | 439 | { |
dcd307ee | 440 | return (wxClientData *)DoGetItemClientData(n); |
0e320a79 DW |
441 | } |
442 | ||
49dc8caa DW |
443 | void* wxListBox::DoGetItemClientData( |
444 | int n | |
445 | ) const | |
0e320a79 | 446 | { |
49dc8caa | 447 | wxCHECK_MSG( n >= 0 && n < m_nNumItems, NULL, |
fb9010ed DW |
448 | wxT("invalid index in wxListBox::GetClientData") ); |
449 | ||
49dc8caa DW |
450 | return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0)); |
451 | } // end of wxListBox::DoGetItemClientData | |
0e320a79 | 452 | |
49dc8caa DW |
453 | void wxListBox::DoSetItemClientObject( |
454 | int n | |
455 | , wxClientData* pClientData | |
456 | ) | |
0e320a79 | 457 | { |
49dc8caa DW |
458 | DoSetItemClientData( n |
459 | ,pClientData | |
460 | ); | |
461 | } // end of wxListBox::DoSetItemClientObject | |
dcd307ee | 462 | |
49dc8caa DW |
463 | void wxListBox::DoSetItemClientData( |
464 | int n | |
465 | , void* pClientData | |
466 | ) | |
dcd307ee | 467 | { |
49dc8caa | 468 | wxCHECK_RET( n >= 0 && n < m_nNumItems, |
fb9010ed DW |
469 | wxT("invalid index in wxListBox::SetClientData") ); |
470 | ||
dcd307ee DW |
471 | #if wxUSE_OWNER_DRAWN |
472 | if ( m_windowStyle & wxLB_OWNERDRAW ) | |
473 | { | |
49dc8caa DW |
474 | // |
475 | // Client data must be pointer to wxOwnerDrawn, otherwise we would crash | |
dcd307ee | 476 | // in OnMeasure/OnDraw. |
49dc8caa | 477 | // |
dcd307ee DW |
478 | wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes")); |
479 | } | |
480 | #endif // wxUSE_OWNER_DRAWN | |
481 | ||
49dc8caa DW |
482 | ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData)); |
483 | } // end of wxListBox::DoSetItemClientData | |
dcd307ee DW |
484 | |
485 | bool wxListBox::HasMultipleSelection() const | |
486 | { | |
487 | return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED); | |
49dc8caa | 488 | } // end of wxListBox::HasMultipleSelection |
0e320a79 | 489 | |
49dc8caa DW |
490 | int wxListBox::GetSelections( |
491 | wxArrayInt& raSelections | |
492 | ) const | |
0e320a79 | 493 | { |
49dc8caa DW |
494 | int nCount = 0; |
495 | LONG lItem; | |
0e320a79 | 496 | |
fb9010ed | 497 | |
49dc8caa DW |
498 | raSelections.Empty(); |
499 | if (HasMultipleSelection()) | |
500 | { | |
501 | lItem = LONGFROMMR(::WinSendMsg( GetHwnd() | |
502 | ,LM_QUERYSELECTION | |
503 | ,(MPARAM)LIT_FIRST | |
504 | ,(MPARAM)0 | |
505 | ) | |
506 | ); | |
507 | if (lItem != LIT_NONE) | |
508 | { | |
509 | nCount++; | |
510 | while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd() | |
511 | ,LM_QUERYSELECTION | |
512 | ,(MPARAM)lItem | |
513 | ,(MPARAM)0 | |
514 | ) | |
515 | )) != LIT_NONE) | |
516 | { | |
517 | nCount++; | |
518 | } | |
519 | raSelections.Alloc(nCount); | |
520 | lItem = LONGFROMMR(::WinSendMsg( GetHwnd() | |
521 | ,LM_QUERYSELECTION | |
522 | ,(MPARAM)LIT_FIRST | |
523 | ,(MPARAM)0 | |
524 | ) | |
525 | ); | |
526 | ||
527 | raSelections.Add((int)lItem); | |
528 | while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd() | |
529 | ,LM_QUERYSELECTION | |
530 | ,(MPARAM)lItem | |
531 | ,(MPARAM)0 | |
532 | ) | |
533 | )) != LIT_NONE) | |
534 | { | |
535 | raSelections.Add((int)lItem); | |
536 | } | |
537 | return nCount; | |
fb9010ed | 538 | } |
49dc8caa | 539 | return 0; |
0e320a79 DW |
540 | } |
541 | else // single-selection listbox | |
542 | { | |
49dc8caa DW |
543 | lItem = LONGFROMMR(::WinSendMsg( GetHwnd() |
544 | ,LM_QUERYSELECTION | |
545 | ,(MPARAM)LIT_FIRST | |
546 | ,(MPARAM)0 | |
547 | ) | |
548 | ); | |
549 | raSelections.Add((int)lItem); | |
0e320a79 DW |
550 | return 1; |
551 | } | |
dcd307ee | 552 | return 0; |
49dc8caa | 553 | } // end of wxListBox::GetSelections |
0e320a79 | 554 | |
0e320a79 DW |
555 | int wxListBox::GetSelection() const |
556 | { | |
dcd307ee | 557 | wxCHECK_MSG( !HasMultipleSelection(), |
fb9010ed DW |
558 | -1, |
559 | wxT("GetSelection() can't be used with multiple-selection " | |
560 | "listboxes, use GetSelections() instead.") ); | |
561 | ||
49dc8caa DW |
562 | return(LONGFROMMR(::WinSendMsg( GetHwnd() |
563 | ,LM_QUERYSELECTION | |
564 | ,(MPARAM)LIT_FIRST | |
565 | ,(MPARAM)0 | |
566 | ) | |
567 | )); | |
568 | } // end of wxListBox::GetSelection | |
0e320a79 | 569 | |
49dc8caa DW |
570 | wxString wxListBox::GetString( |
571 | int N | |
572 | ) const | |
0e320a79 | 573 | { |
49dc8caa DW |
574 | LONG lLen = 0; |
575 | char* zBuf; | |
576 | wxString sResult; | |
fb9010ed | 577 | |
49dc8caa DW |
578 | wxCHECK_MSG( N >= 0 && N < m_nNumItems, "", |
579 | wxT("invalid index in wxListBox::GetClientData") ); | |
0e320a79 | 580 | |
49dc8caa DW |
581 | lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0)); |
582 | zBuf = new char[lLen + 1]; | |
583 | ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)N, (SHORT)lLen), (MPARAM)zBuf); | |
584 | zBuf[lLen] = '\0'; | |
585 | sResult = zBuf; | |
586 | delete [] zBuf; | |
587 | return sResult; | |
588 | } // end of wxListBox::GetString | |
589 | ||
590 | void wxListBox::DoInsertItems( | |
591 | const wxArrayString& asItems | |
592 | , int nPos | |
593 | ) | |
594 | { | |
595 | wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems, | |
dcd307ee DW |
596 | wxT("invalid index in wxListBox::InsertItems") ); |
597 | ||
49dc8caa | 598 | int nItems = asItems.GetCount(); |
dcd307ee | 599 | |
49dc8caa DW |
600 | for (int i = 0; i < nItems; i++) |
601 | ::WinSendMsg(GetHwnd(), LM_INSERTITEM, MPFROMLONG((LONG)(i + nPos)), (MPARAM)asItems[i].c_str()); | |
602 | m_nNumItems += nItems; | |
603 | } // end of wxListBox::DoInsertItems | |
dcd307ee | 604 | |
49dc8caa DW |
605 | void wxListBox::SetString( |
606 | int N | |
607 | , const wxString& rsString | |
608 | ) | |
dcd307ee | 609 | { |
49dc8caa | 610 | wxCHECK_RET( N >= 0 && N < m_nNumItems, |
dcd307ee DW |
611 | wxT("invalid index in wxListBox::SetString") ); |
612 | ||
49dc8caa DW |
613 | // |
614 | // Remember the state of the item | |
615 | // | |
616 | bool bWasSelected = IsSelected(N); | |
617 | void* pOldData = NULL; | |
618 | wxClientData* pOldObjData = NULL; | |
619 | ||
620 | if (m_clientDataItemsType == wxClientData_Void) | |
621 | pOldData = GetClientData(N); | |
622 | else if (m_clientDataItemsType == wxClientData_Object) | |
623 | pOldObjData = GetClientObject(N); | |
624 | ||
625 | // | |
626 | // Delete and recreate it | |
627 | // | |
628 | ::WinSendMsg( GetHwnd() | |
629 | ,LM_DELETEITEM | |
630 | ,(MPARAM)N | |
631 | ,(MPARAM)0 | |
632 | ); | |
633 | ||
634 | int nNewN = N; | |
635 | ||
636 | if (N == m_nNumItems - 1) | |
637 | nNewN = -1; | |
638 | ||
639 | ::WinSendMsg( GetHwnd() | |
640 | ,LM_INSERTITEM | |
641 | ,(MPARAM)nNewN | |
642 | ,(MPARAM)rsString.c_str() | |
643 | ); | |
644 | ||
645 | // | |
646 | // Restore the client data | |
647 | // | |
648 | if (pOldData) | |
649 | SetClientData( N | |
650 | ,pOldData | |
651 | ); | |
652 | else if (pOldObjData) | |
653 | SetClientObject( N | |
654 | ,pOldObjData | |
655 | ); | |
656 | ||
657 | // | |
658 | // We may have lost the selection | |
659 | // | |
660 | if (bWasSelected) | |
dcd307ee DW |
661 | Select(N); |
662 | ||
663 | #if wxUSE_OWNER_DRAWN | |
49dc8caa DW |
664 | if (m_windowStyle & wxLB_OWNERDRAW) |
665 | // | |
666 | // Update item's text | |
667 | // | |
668 | m_aItems[N]->SetName(rsString); | |
dcd307ee | 669 | #endif //USE_OWNER_DRAWN |
49dc8caa | 670 | } // end of wxListBox::SetString |
dcd307ee DW |
671 | |
672 | int wxListBox::GetCount() const | |
673 | { | |
49dc8caa | 674 | return m_nNumItems; |
dcd307ee DW |
675 | } |
676 | ||
677 | // ---------------------------------------------------------------------------- | |
678 | // helpers | |
679 | // ---------------------------------------------------------------------------- | |
680 | ||
e78c4d50 | 681 | wxSize wxListBox::DoGetBestSize() const |
fb9010ed | 682 | { |
49dc8caa DW |
683 | // |
684 | // Find the widest string | |
685 | // | |
686 | int nLine; | |
687 | int nListbox = 0; | |
688 | int nCx; | |
689 | int nCy; | |
690 | ||
691 | for (int i = 0; i < m_nNumItems; i++) | |
fb9010ed | 692 | { |
49dc8caa DW |
693 | wxString vStr(GetString(i)); |
694 | ||
695 | GetTextExtent( vStr | |
696 | ,&nLine | |
697 | ,NULL | |
698 | ); | |
699 | if (nLine > nListbox) | |
700 | nListbox = nLine; | |
fb9010ed DW |
701 | } |
702 | ||
49dc8caa DW |
703 | // |
704 | // Give it some reasonable default value if there are no strings in the | |
705 | // list. | |
706 | // | |
707 | if (nListbox == 0) | |
708 | nListbox = 100; | |
709 | ||
710 | // | |
711 | // The listbox should be slightly larger than the widest string | |
712 | // | |
713 | wxGetCharSize( GetHWND() | |
714 | ,&nCx | |
715 | ,&nCy | |
716 | ,(wxFont*)&GetFont() | |
717 | ); | |
718 | nListbox += 3 * nCx; | |
719 | ||
720 | int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7)); | |
721 | ||
722 | return wxSize( nListbox | |
723 | ,hListbox | |
724 | ); | |
725 | } // end of wxListBox::DoGetBestSize | |
fb9010ed | 726 | |
dcd307ee DW |
727 | // ---------------------------------------------------------------------------- |
728 | // callbacks | |
729 | // ---------------------------------------------------------------------------- | |
730 | ||
49dc8caa DW |
731 | bool wxListBox::OS2Command( |
732 | WXUINT uParam | |
733 | , WXWORD WXUNUSED(wId)) | |
0e320a79 | 734 | { |
49dc8caa | 735 | wxEventType eEvtType; |
dcd307ee | 736 | |
49dc8caa DW |
737 | if (uParam == LN_SELECT) |
738 | { | |
739 | eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED; | |
dcd307ee | 740 | } |
49dc8caa | 741 | if (uParam == LN_ENTER) |
0e320a79 | 742 | { |
49dc8caa | 743 | eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED; |
0e320a79 | 744 | } |
fb9010ed | 745 | else |
49dc8caa DW |
746 | { |
747 | // | |
748 | // Some event we're not interested in | |
749 | // | |
750 | return FALSE; | |
751 | } | |
752 | wxCommandEvent vEvent( eEvtType | |
753 | ,m_windowId | |
754 | ); | |
fb9010ed | 755 | |
49dc8caa | 756 | vEvent.SetEventObject(this); |
fb9010ed | 757 | |
49dc8caa DW |
758 | wxArrayInt aSelections; |
759 | int n; | |
760 | int nCount = GetSelections(aSelections); | |
fb9010ed | 761 | |
49dc8caa DW |
762 | if (nCount > 0) |
763 | { | |
764 | n = aSelections[0]; | |
765 | if (HasClientObjectData()) | |
766 | vEvent.SetClientObject(GetClientObject(n)); | |
767 | else if ( HasClientUntypedData() ) | |
768 | vEvent.SetClientData(GetClientData(n)); | |
769 | vEvent.SetString(GetString(n)); | |
770 | } | |
771 | else | |
772 | { | |
773 | n = -1; | |
774 | } | |
775 | vEvent.m_commandInt = n; | |
776 | return GetEventHandler()->ProcessEvent(vEvent); | |
777 | } // end of wxListBox::OS2Command | |
fb9010ed | 778 | |
dcd307ee DW |
779 | // ---------------------------------------------------------------------------- |
780 | // wxCheckListBox support | |
781 | // ---------------------------------------------------------------------------- | |
fb9010ed DW |
782 | |
783 | #if wxUSE_OWNER_DRAWN | |
784 | ||
49dc8caa DW |
785 | // |
786 | // Drawing | |
fb9010ed | 787 | // ------- |
49dc8caa | 788 | // |
fb9010ed DW |
789 | #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1) |
790 | ||
fb9010ed DW |
791 | bool wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT *item) |
792 | { | |
49dc8caa DW |
793 | // |
794 | // TODO: Get to this eventually | |
795 | // | |
fb9010ed DW |
796 | return TRUE; |
797 | } | |
798 | ||
fb9010ed DW |
799 | bool wxListBox::OS2OnDraw(WXDRAWITEMSTRUCT *item) |
800 | { | |
49dc8caa DW |
801 | // |
802 | // TODO: Get to this eventually | |
803 | // | |
dcd307ee | 804 | return FALSE; |
fb9010ed | 805 | } |
49dc8caa DW |
806 | #endif // ndef for wxUSE_OWNER_DRAWN |
807 | ||
808 | #endif // ndef for wxUSE_LISTBOX | |
7e99520b | 809 |