]> git.saurik.com Git - wxWidgets.git/blame - src/os2/listbox.cpp
expand . into cwd
[wxWidgets.git] / src / os2 / listbox.cpp
CommitLineData
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
47class wxListBoxItem : public wxOwnerDrawn
48{
49public:
49dc8caa 50 wxListBoxItem(const wxString& rsStr = "");
fb9010ed
DW
51};
52
49dc8caa
DW
53wxListBoxItem::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
66wxOwnerDrawn* 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
80wxListBox::wxListBox()
81{
49dc8caa
DW
82 m_nNumItems = 0;
83 m_nSelected = 0;
84} // end of wxListBox::wxListBox
85
86bool 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
213wxListBox::~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
225void 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
235void 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
245void 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
266int 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
294void 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
360int 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
384void 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
409void 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
423bool 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
436wxClientData* wxListBox::DoGetItemClientObject(
437 int n
438) const
0e320a79 439{
dcd307ee 440 return (wxClientData *)DoGetItemClientData(n);
0e320a79
DW
441}
442
49dc8caa
DW
443void* 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
453void 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
463void 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
485bool wxListBox::HasMultipleSelection() const
486{
487 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
49dc8caa 488} // end of wxListBox::HasMultipleSelection
0e320a79 489
49dc8caa
DW
490int 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
555int 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
570wxString 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
590void 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
605void 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
672int wxListBox::GetCount() const
673{
49dc8caa 674 return m_nNumItems;
dcd307ee
DW
675}
676
677// ----------------------------------------------------------------------------
678// helpers
679// ----------------------------------------------------------------------------
680
e78c4d50 681wxSize 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
731bool 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
791bool wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT *item)
792{
49dc8caa
DW
793 //
794 // TODO: Get to this eventually
795 //
fb9010ed
DW
796 return TRUE;
797}
798
fb9010ed
DW
799bool 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