]> git.saurik.com Git - wxWidgets.git/blame - src/os2/listbox.cpp
Some doc corrections
[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"
1a75e76f 24#include "wx/dcscreen.h"
fb9010ed 25#include "wx/utils.h"
a4a16252 26#include "wx/scrolwin.h"
fb9010ed
DW
27#endif
28
29#define INCL_M
30#include <os2.h>
31
0e320a79
DW
32#include "wx/dynarray.h"
33#include "wx/log.h"
34
7e99520b
DW
35#if wxUSE_LISTBOX
36
fb9010ed
DW
37#if wxUSE_OWNER_DRAWN
38 #include "wx/ownerdrw.h"
39#endif
40
0e320a79 41 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
0e320a79 42
fb9010ed
DW
43// ============================================================================
44// list box item declaration and implementation
45// ============================================================================
46
47#if wxUSE_OWNER_DRAWN
48
49class wxListBoxItem : public wxOwnerDrawn
50{
51public:
49dc8caa 52 wxListBoxItem(const wxString& rsStr = "");
fb9010ed
DW
53};
54
49dc8caa
DW
55wxListBoxItem::wxListBoxItem(
56 const wxString& rsStr
57)
58: wxOwnerDrawn( rsStr
59 ,FALSE
60 )
fb9010ed 61{
49dc8caa
DW
62 //
63 // No bitmaps/checkmarks
64 //
fb9010ed 65 SetMarginWidth(0);
49dc8caa 66} // end of wxListBoxItem::wxListBoxItem
fb9010ed 67
49dc8caa
DW
68wxOwnerDrawn* wxListBox::CreateItem(
69 size_t n
70)
fb9010ed
DW
71{
72 return new wxListBoxItem();
49dc8caa 73} // end of wxListBox::CreateItem
fb9010ed
DW
74
75#endif //USE_OWNER_DRAWN
76
0e320a79
DW
77// ============================================================================
78// list box control implementation
79// ============================================================================
80
81// Listbox item
82wxListBox::wxListBox()
83{
49dc8caa
DW
84 m_nNumItems = 0;
85 m_nSelected = 0;
86} // end of wxListBox::wxListBox
87
584ad2a3
MB
88bool wxListBox::Create(
89 wxWindow* pParent
90, wxWindowID vId
91, const wxPoint& rPos
92, const wxSize& rSize
93, const wxArrayString& asChoices
94, long lStyle
95, const wxValidator& rValidator
96, const wxString& rsName
97)
98{
99 wxCArrayString chs(asChoices);
100
101 return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
102 lStyle, rValidator, rsName);
103}
104
49dc8caa
DW
105bool wxListBox::Create(
106 wxWindow* pParent
107, wxWindowID vId
108, const wxPoint& rPos
109, const wxSize& rSize
110, int n
111, const wxString asChoices[]
112, long lStyle
49dc8caa 113, const wxValidator& rValidator
49dc8caa
DW
114, const wxString& rsName
115)
0e320a79 116{
49dc8caa
DW
117 m_nNumItems = 0;
118 m_hWnd = 0;
119 m_nSelected = 0;
0e320a79 120
49dc8caa 121 SetName(rsName);
5d4b632b 122#if wxUSE_VALIDATORS
49dc8caa 123 SetValidator(rValidator);
5d4b632b 124#endif
0e320a79 125
49dc8caa
DW
126 if (pParent)
127 pParent->AddChild(this);
128
129 wxSystemSettings vSettings;
130
131 SetBackgroundColour(vSettings.GetSystemColour(wxSYS_COLOUR_WINDOW));
132 SetForegroundColour(pParent->GetForegroundColour());
0e320a79 133
49dc8caa 134 m_windowId = (vId == -1) ? (int)NewControlId() : vId;
0e320a79 135
49dc8caa
DW
136 int nX = rPos.x;
137 int nY = rPos.y;
138 int nWidth = rSize.x;
139 int nHeight = rSize.y;
0e320a79 140
49dc8caa 141 m_windowStyle = lStyle;
fb9010ed 142
49dc8caa
DW
143 lStyle = WS_VISIBLE;
144
145 if (m_windowStyle & wxCLIP_SIBLINGS )
146 lStyle |= WS_CLIPSIBLINGS;
fb9010ed 147 if (m_windowStyle & wxLB_MULTIPLE)
49dc8caa 148 lStyle |= LS_MULTIPLESEL;
fb9010ed 149 else if (m_windowStyle & wxLB_EXTENDED)
49dc8caa 150 lStyle |= LS_EXTENDEDSEL;
fb9010ed 151 if (m_windowStyle & wxLB_HSCROLL)
49dc8caa
DW
152 lStyle |= LS_HORZSCROLL;
153 if (m_windowStyle & wxLB_OWNERDRAW)
154 lStyle |= LS_OWNERDRAW;
fb9010ed 155
49dc8caa 156 //
fb9010ed
DW
157 // Without this style, you get unexpected heights, so e.g. constraint layout
158 // doesn't work properly
49dc8caa
DW
159 //
160 lStyle |= LS_NOADJUSTPOS;
161
162 m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent) // Parent
163 ,WC_LISTBOX // Default Listbox class
164 ,"LISTBOX" // Control's name
165 ,lStyle // Initial Style
166 ,0, 0, 0, 0 // Position and size
167 ,GetWinHwnd(pParent) // Owner
168 ,HWND_TOP // Z-Order
169 ,(HMENU)m_windowId // Id
170 ,NULL // Control Data
171 ,NULL // Presentation Parameters
172 );
173 if (m_hWnd == 0)
fb9010ed 174 {
49dc8caa 175 return FALSE;
fb9010ed
DW
176 }
177
49dc8caa
DW
178 //
179 // Subclass again for purposes of dialog editing mode
180 //
fb9010ed
DW
181 SubclassWin(m_hWnd);
182
49dc8caa 183 LONG lUi;
0e320a79 184
49dc8caa
DW
185 for (lUi = 0; lUi < (LONG)n; lUi++)
186 {
187 Append(asChoices[lUi]);
188 }
b3260bce
DW
189 wxFont* pTextFont = new wxFont( 10
190 ,wxMODERN
191 ,wxNORMAL
192 ,wxNORMAL
193 );
194 SetFont(*pTextFont);
e58dab20 195
5d44b24e
DW
196 //
197 // Set standard wxWindows colors for Listbox items and highlighting
198 //
199 wxColour vColour;
200
201 vColour.Set(wxString("WHITE"));
202
203 LONG lColor = (LONG)vColour.GetPixel();
204
205 ::WinSetPresParam( m_hWnd
206 ,PP_HILITEFOREGROUNDCOLOR
207 ,sizeof(LONG)
208 ,(PVOID)&lColor
209 );
210 vColour.Set(wxString("NAVY"));
211 lColor = (LONG)vColour.GetPixel();
212 ::WinSetPresParam( m_hWnd
213 ,PP_HILITEBACKGROUNDCOLOR
214 ,sizeof(LONG)
215 ,(PVOID)&lColor
216 );
217
49dc8caa
DW
218 SetSize( nX
219 ,nY
220 ,nWidth
221 ,nHeight
222 );
b3260bce 223 delete pTextFont;
dcd307ee 224 return TRUE;
49dc8caa 225} // end of wxListBox::Create
0e320a79
DW
226
227wxListBox::~wxListBox()
228{
fb9010ed 229#if wxUSE_OWNER_DRAWN
49dc8caa
DW
230 size_t lUiCount = m_aItems.Count();
231
232 while (lUiCount-- != 0)
233 {
234 delete m_aItems[lUiCount];
fb9010ed
DW
235 }
236#endif // wxUSE_OWNER_DRAWN
49dc8caa 237} // end of wxListBox::~wxListBox
fb9010ed
DW
238
239void wxListBox::SetupColours()
240{
a756f210 241 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
fb9010ed 242 SetForegroundColour(GetParent()->GetForegroundColour());
49dc8caa 243} // end of wxListBox::SetupColours
0e320a79 244
dcd307ee
DW
245// ----------------------------------------------------------------------------
246// implementation of wxListBoxBase methods
247// ----------------------------------------------------------------------------
248
49dc8caa
DW
249void wxListBox::DoSetFirstItem(
250 int N
251)
0e320a79 252{
49dc8caa 253 wxCHECK_RET( N >= 0 && N < m_nNumItems,
fb9010ed
DW
254 wxT("invalid index in wxListBox::SetFirstItem") );
255
49dc8caa
DW
256 ::WinSendMsg(GetHwnd(), LM_SETTOPINDEX, MPFROMLONG(N), (MPARAM)0);
257} // end of wxListBox::DoSetFirstItem
0e320a79 258
49dc8caa
DW
259void wxListBox::Delete(
260 int N
261)
0e320a79 262{
49dc8caa 263 wxCHECK_RET( N >= 0 && N < m_nNumItems,
fb9010ed
DW
264 wxT("invalid index in wxListBox::Delete") );
265
dcd307ee
DW
266#if wxUSE_OWNER_DRAWN
267 delete m_aItems[N];
893758d5 268 m_aItems.RemoveAt(N);
dcd307ee 269#else // !wxUSE_OWNER_DRAWN
49dc8caa 270 if (HasClientObjectData())
dcd307ee
DW
271 {
272 delete GetClientObject(N);
273 }
274#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
275
49dc8caa
DW
276 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)N, (MPARAM)0);
277 m_nNumItems--;
278} // end of wxListBox::DoSetFirstItem
0e320a79 279
49dc8caa
DW
280int wxListBox::DoAppend(
281 const wxString& rsItem
282)
0e320a79 283{
49dc8caa
DW
284 int nIndex = 0;
285 SHORT nIndexType = 0;
286
287 if (m_windowStyle & wxLB_SORT)
288 nIndexType = LIT_SORTASCENDING;
289 else
290 nIndexType = LIT_END;
291 nIndex = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)rsItem.c_str());
292 m_nNumItems++;
fb9010ed
DW
293
294#if wxUSE_OWNER_DRAWN
49dc8caa
DW
295 if (m_windowStyle & wxLB_OWNERDRAW)
296 {
297 wxOwnerDrawn* pNewItem = CreateItem(nIndex); // dummy argument
f5ea767e
DW
298 wxScreenDC vDc;
299 wxCoord vHeight;
300
49dc8caa
DW
301
302 pNewItem->SetName(rsItem);
3437f881 303 m_aItems.Insert(pNewItem, nIndex);
49dc8caa
DW
304 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)((SHORT)nIndex), MPFROMP(pNewItem));
305 pNewItem->SetFont(GetFont());
fb9010ed
DW
306 }
307#endif
49dc8caa
DW
308 return nIndex;
309} // end of wxListBox::DoAppend
0e320a79 310
49dc8caa
DW
311void wxListBox::DoSetItems(
312 const wxArrayString& raChoices
313, void** ppClientData
314)
0e320a79 315{
49dc8caa
DW
316 BOOL bHideAndShow = IsShown();
317 int nCount = 0;
318 int i;
319 SHORT nIndexType = 0;
0e320a79 320
49dc8caa 321 if (bHideAndShow)
fb9010ed 322 {
49dc8caa
DW
323 ::WinShowWindow(GetHwnd(), FALSE);
324 }
325 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
326 m_nNumItems = raChoices.GetCount();
327 for (i = 0; i < m_nNumItems; i++)
328 {
329
330 if (m_windowStyle & wxLB_SORT)
331 nIndexType = LIT_SORTASCENDING;
332 else
333 nIndexType = LIT_END;
334 ::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)raChoices[i].c_str());
335
336 if (ppClientData)
dcd307ee
DW
337 {
338#if wxUSE_OWNER_DRAWN
49dc8caa 339 wxASSERT_MSG(ppClientData[i] == NULL,
dcd307ee
DW
340 wxT("Can't use client data with owner-drawn listboxes"));
341#else // !wxUSE_OWNER_DRAWN
49dc8caa 342 ::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lCount), MPFROMP(ppClientData[i]));
dcd307ee
DW
343#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
344 }
fb9010ed 345 }
fb9010ed
DW
346
347#if wxUSE_OWNER_DRAWN
49dc8caa
DW
348 if ( m_windowStyle & wxLB_OWNERDRAW )
349 {
350 //
351 // First delete old items
352 //
3437f881 353 WX_CLEAR_ARRAY(m_aItems);
fb9010ed 354
49dc8caa
DW
355 //
356 // Then create new ones
357 //
3437f881 358 for (size_t ui = 0; ui < (size_t)m_nNumItems; ui++)
49dc8caa 359 {
3437f881 360 wxOwnerDrawn* pNewItem = CreateItem(ui);
49dc8caa 361
3437f881 362 pNewItem->SetName(raChoices[ui]);
fb9010ed 363 m_aItems.Add(pNewItem);
3437f881 364 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(ui), MPFROMP(pNewItem));
fb9010ed
DW
365 }
366 }
dcd307ee 367#endif // wxUSE_OWNER_DRAWN
49dc8caa
DW
368 ::WinShowWindow(GetHwnd(), TRUE);
369} // end of wxListBox::DoSetItems
0e320a79 370
49dc8caa
DW
371int wxListBox::FindString(
372 const wxString& rsString
373) const
374{
375 int nPos;
376 LONG lTextLength;
377 PSZ zStr;
dcd307ee 378
0e320a79 379
49dc8caa
DW
380 for (nPos = 0; nPos < m_nNumItems; nPos++)
381 {
382 lTextLength = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0));
383 zStr = new char[lTextLength + 1];
384 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT(nPos, (SHORT)lTextLength), (MPARAM)zStr);
385 if (rsString == (char*)zStr)
386 {
387 delete [] zStr;
388 break;
389 }
390 delete [] zStr;
391 }
392 return nPos;
393} // end of wxListBox::FindString
0e320a79
DW
394
395void wxListBox::Clear()
396{
fb9010ed 397#if wxUSE_OWNER_DRAWN
49dc8caa
DW
398 size_t lUiCount = m_aItems.Count();
399
400 while (lUiCount-- != 0)
401 {
402 delete m_aItems[lUiCount];
fb9010ed
DW
403 }
404
405 m_aItems.Clear();
dcd307ee 406#else // !wxUSE_OWNER_DRAWN
49dc8caa 407 if (HasClientObjectData())
dcd307ee 408 {
49dc8caa 409 for (size_t n = 0; n < (size_t)m_lNumItems; n++)
dcd307ee
DW
410 {
411 delete GetClientObject(n);
412 }
413 }
414#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
49dc8caa 415 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
dcd307ee 416
49dc8caa
DW
417 m_nNumItems = 0;
418} // end of wxListBox::Clear
fb9010ed 419
49dc8caa
DW
420void wxListBox::SetSelection(
421 int N
422, bool bSelect
423)
0e320a79 424{
49dc8caa 425 wxCHECK_RET( N >= 0 && N < m_nNumItems,
fb9010ed 426 wxT("invalid index in wxListBox::SetSelection") );
49dc8caa
DW
427 ::WinSendMsg( GetHwnd()
428 ,LM_SELECTITEM
429 ,MPFROMLONG(N)
430 ,(MPARAM)bSelect
431 );
1de4baa3
DW
432 if(m_windowStyle & wxLB_OWNERDRAW)
433 Refresh();
49dc8caa
DW
434} // end of wxListBox::SetSelection
435
436bool wxListBox::IsSelected(
437 int N
438) const
439{
440 wxCHECK_MSG( N >= 0 && N < m_nNumItems, FALSE,
fb9010ed
DW
441 wxT("invalid index in wxListBox::Selected") );
442
49dc8caa 443 LONG lItem;
0e320a79 444
70a2c656
DW
445 if (GetWindowStyleFlag() & wxLB_EXTENDED)
446 {
447 if (N == 0)
448 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
449 else
450 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)(N - 1), (MPARAM)0));
451 }
452 else
453 {
454 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
455 }
456 return (lItem == (LONG)N && lItem != LIT_NONE);
49dc8caa
DW
457} // end of wxListBox::IsSelected
458
459wxClientData* wxListBox::DoGetItemClientObject(
460 int n
461) const
0e320a79 462{
dcd307ee 463 return (wxClientData *)DoGetItemClientData(n);
0e320a79
DW
464}
465
49dc8caa
DW
466void* wxListBox::DoGetItemClientData(
467 int n
468) const
0e320a79 469{
49dc8caa 470 wxCHECK_MSG( n >= 0 && n < m_nNumItems, NULL,
fb9010ed
DW
471 wxT("invalid index in wxListBox::GetClientData") );
472
49dc8caa
DW
473 return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
474} // end of wxListBox::DoGetItemClientData
0e320a79 475
49dc8caa
DW
476void wxListBox::DoSetItemClientObject(
477 int n
478, wxClientData* pClientData
479)
0e320a79 480{
49dc8caa
DW
481 DoSetItemClientData( n
482 ,pClientData
483 );
484} // end of wxListBox::DoSetItemClientObject
dcd307ee 485
49dc8caa
DW
486void wxListBox::DoSetItemClientData(
487 int n
488, void* pClientData
489)
dcd307ee 490{
49dc8caa 491 wxCHECK_RET( n >= 0 && n < m_nNumItems,
fb9010ed
DW
492 wxT("invalid index in wxListBox::SetClientData") );
493
dcd307ee
DW
494#if wxUSE_OWNER_DRAWN
495 if ( m_windowStyle & wxLB_OWNERDRAW )
496 {
49dc8caa
DW
497 //
498 // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
dcd307ee 499 // in OnMeasure/OnDraw.
49dc8caa 500 //
dcd307ee
DW
501 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
502 }
503#endif // wxUSE_OWNER_DRAWN
504
49dc8caa
DW
505 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
506} // end of wxListBox::DoSetItemClientData
dcd307ee
DW
507
508bool wxListBox::HasMultipleSelection() const
509{
510 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
49dc8caa 511} // end of wxListBox::HasMultipleSelection
0e320a79 512
49dc8caa
DW
513int wxListBox::GetSelections(
514 wxArrayInt& raSelections
515) const
0e320a79 516{
49dc8caa
DW
517 int nCount = 0;
518 LONG lItem;
0e320a79 519
fb9010ed 520
49dc8caa
DW
521 raSelections.Empty();
522 if (HasMultipleSelection())
523 {
524 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
525 ,LM_QUERYSELECTION
526 ,(MPARAM)LIT_FIRST
527 ,(MPARAM)0
528 )
529 );
530 if (lItem != LIT_NONE)
531 {
532 nCount++;
533 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
534 ,LM_QUERYSELECTION
535 ,(MPARAM)lItem
536 ,(MPARAM)0
537 )
538 )) != LIT_NONE)
539 {
540 nCount++;
541 }
542 raSelections.Alloc(nCount);
543 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
544 ,LM_QUERYSELECTION
545 ,(MPARAM)LIT_FIRST
546 ,(MPARAM)0
547 )
548 );
549
550 raSelections.Add((int)lItem);
551 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
552 ,LM_QUERYSELECTION
553 ,(MPARAM)lItem
554 ,(MPARAM)0
555 )
556 )) != LIT_NONE)
557 {
558 raSelections.Add((int)lItem);
559 }
560 return nCount;
fb9010ed 561 }
49dc8caa 562 return 0;
0e320a79
DW
563 }
564 else // single-selection listbox
565 {
49dc8caa
DW
566 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
567 ,LM_QUERYSELECTION
568 ,(MPARAM)LIT_FIRST
569 ,(MPARAM)0
570 )
571 );
572 raSelections.Add((int)lItem);
0e320a79
DW
573 return 1;
574 }
dcd307ee 575 return 0;
49dc8caa 576} // end of wxListBox::GetSelections
0e320a79 577
0e320a79
DW
578int wxListBox::GetSelection() const
579{
dcd307ee 580 wxCHECK_MSG( !HasMultipleSelection(),
fb9010ed
DW
581 -1,
582 wxT("GetSelection() can't be used with multiple-selection "
583 "listboxes, use GetSelections() instead.") );
584
49dc8caa
DW
585 return(LONGFROMMR(::WinSendMsg( GetHwnd()
586 ,LM_QUERYSELECTION
587 ,(MPARAM)LIT_FIRST
588 ,(MPARAM)0
589 )
590 ));
591} // end of wxListBox::GetSelection
0e320a79 592
49dc8caa
DW
593wxString wxListBox::GetString(
594 int N
595) const
0e320a79 596{
49dc8caa
DW
597 LONG lLen = 0;
598 char* zBuf;
599 wxString sResult;
fb9010ed 600
49dc8caa
DW
601 wxCHECK_MSG( N >= 0 && N < m_nNumItems, "",
602 wxT("invalid index in wxListBox::GetClientData") );
0e320a79 603
49dc8caa
DW
604 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0));
605 zBuf = new char[lLen + 1];
606 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)N, (SHORT)lLen), (MPARAM)zBuf);
607 zBuf[lLen] = '\0';
608 sResult = zBuf;
609 delete [] zBuf;
610 return sResult;
611} // end of wxListBox::GetString
612
613void wxListBox::DoInsertItems(
614 const wxArrayString& asItems
615, int nPos
616)
617{
618 wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
dcd307ee
DW
619 wxT("invalid index in wxListBox::InsertItems") );
620
49dc8caa 621 int nItems = asItems.GetCount();
dcd307ee 622
49dc8caa 623 for (int i = 0; i < nItems; i++)
3437f881
DW
624 {
625 int nIndex = (int)::WinSendMsg( GetHwnd()
626 ,LM_INSERTITEM
627 ,MPFROMLONG((LONG)(i + nPos))
628 ,(MPARAM)asItems[i].c_str()
629 );
630
631 wxOwnerDrawn* pNewItem = CreateItem(nIndex);
632
633 pNewItem->SetName(asItems[i]);
634 pNewItem->SetFont(GetFont());
635 m_aItems.Insert(pNewItem, nIndex);
636 ::WinSendMsg( GetHwnd()
637 ,LM_SETITEMHANDLE
638 ,(MPARAM)((SHORT)nIndex)
639 ,MPFROMP(pNewItem)
640 );
641 m_nNumItems += nItems;
642 }
49dc8caa 643} // end of wxListBox::DoInsertItems
dcd307ee 644
49dc8caa
DW
645void wxListBox::SetString(
646 int N
647, const wxString& rsString
648)
dcd307ee 649{
49dc8caa 650 wxCHECK_RET( N >= 0 && N < m_nNumItems,
dcd307ee
DW
651 wxT("invalid index in wxListBox::SetString") );
652
49dc8caa
DW
653 //
654 // Remember the state of the item
655 //
656 bool bWasSelected = IsSelected(N);
657 void* pOldData = NULL;
658 wxClientData* pOldObjData = NULL;
659
660 if (m_clientDataItemsType == wxClientData_Void)
661 pOldData = GetClientData(N);
662 else if (m_clientDataItemsType == wxClientData_Object)
663 pOldObjData = GetClientObject(N);
664
665 //
666 // Delete and recreate it
667 //
668 ::WinSendMsg( GetHwnd()
669 ,LM_DELETEITEM
670 ,(MPARAM)N
671 ,(MPARAM)0
672 );
673
674 int nNewN = N;
675
676 if (N == m_nNumItems - 1)
677 nNewN = -1;
678
679 ::WinSendMsg( GetHwnd()
680 ,LM_INSERTITEM
681 ,(MPARAM)nNewN
682 ,(MPARAM)rsString.c_str()
683 );
684
685 //
686 // Restore the client data
687 //
688 if (pOldData)
689 SetClientData( N
690 ,pOldData
691 );
692 else if (pOldObjData)
693 SetClientObject( N
694 ,pOldObjData
695 );
696
697 //
698 // We may have lost the selection
699 //
700 if (bWasSelected)
dcd307ee
DW
701 Select(N);
702
703#if wxUSE_OWNER_DRAWN
49dc8caa
DW
704 if (m_windowStyle & wxLB_OWNERDRAW)
705 //
706 // Update item's text
707 //
708 m_aItems[N]->SetName(rsString);
dcd307ee 709#endif //USE_OWNER_DRAWN
49dc8caa 710} // end of wxListBox::SetString
dcd307ee
DW
711
712int wxListBox::GetCount() const
713{
49dc8caa 714 return m_nNumItems;
dcd307ee
DW
715}
716
717// ----------------------------------------------------------------------------
718// helpers
719// ----------------------------------------------------------------------------
720
e78c4d50 721wxSize wxListBox::DoGetBestSize() const
fb9010ed 722{
49dc8caa
DW
723 //
724 // Find the widest string
725 //
726 int nLine;
727 int nListbox = 0;
728 int nCx;
729 int nCy;
730
731 for (int i = 0; i < m_nNumItems; i++)
fb9010ed 732 {
49dc8caa
DW
733 wxString vStr(GetString(i));
734
735 GetTextExtent( vStr
736 ,&nLine
737 ,NULL
738 );
739 if (nLine > nListbox)
740 nListbox = nLine;
fb9010ed
DW
741 }
742
49dc8caa
DW
743 //
744 // Give it some reasonable default value if there are no strings in the
745 // list.
746 //
747 if (nListbox == 0)
748 nListbox = 100;
749
750 //
751 // The listbox should be slightly larger than the widest string
752 //
753 wxGetCharSize( GetHWND()
754 ,&nCx
755 ,&nCy
756 ,(wxFont*)&GetFont()
757 );
758 nListbox += 3 * nCx;
759
760 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
761
762 return wxSize( nListbox
763 ,hListbox
764 );
765} // end of wxListBox::DoGetBestSize
fb9010ed 766
dcd307ee
DW
767// ----------------------------------------------------------------------------
768// callbacks
769// ----------------------------------------------------------------------------
770
49dc8caa
DW
771bool wxListBox::OS2Command(
772 WXUINT uParam
773, WXWORD WXUNUSED(wId))
0e320a79 774{
49dc8caa 775 wxEventType eEvtType;
dcd307ee 776
49dc8caa
DW
777 if (uParam == LN_SELECT)
778 {
779 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
dcd307ee 780 }
49dc8caa 781 if (uParam == LN_ENTER)
0e320a79 782 {
49dc8caa 783 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
0e320a79 784 }
fb9010ed 785 else
49dc8caa
DW
786 {
787 //
788 // Some event we're not interested in
789 //
790 return FALSE;
791 }
792 wxCommandEvent vEvent( eEvtType
793 ,m_windowId
794 );
fb9010ed 795
49dc8caa 796 vEvent.SetEventObject(this);
fb9010ed 797
49dc8caa
DW
798 wxArrayInt aSelections;
799 int n;
800 int nCount = GetSelections(aSelections);
fb9010ed 801
49dc8caa
DW
802 if (nCount > 0)
803 {
804 n = aSelections[0];
805 if (HasClientObjectData())
806 vEvent.SetClientObject(GetClientObject(n));
807 else if ( HasClientUntypedData() )
808 vEvent.SetClientData(GetClientData(n));
809 vEvent.SetString(GetString(n));
810 }
811 else
812 {
813 n = -1;
814 }
815 vEvent.m_commandInt = n;
816 return GetEventHandler()->ProcessEvent(vEvent);
817} // end of wxListBox::OS2Command
fb9010ed 818
dcd307ee
DW
819// ----------------------------------------------------------------------------
820// wxCheckListBox support
821// ----------------------------------------------------------------------------
fb9010ed
DW
822
823#if wxUSE_OWNER_DRAWN
824
49dc8caa
DW
825//
826// Drawing
fb9010ed 827// -------
49dc8caa 828//
fb9010ed
DW
829#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
830
f5ea767e 831long wxListBox::OS2OnMeasure(
1de4baa3
DW
832 WXMEASUREITEMSTRUCT* pItem
833)
fb9010ed 834{
1de4baa3
DW
835 if (!pItem)
836 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
837
838 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
839 wxScreenDC vDc;
840
49dc8caa 841 //
1de4baa3 842 // Only owner-drawn control should receive this message
49dc8caa 843 //
1de4baa3
DW
844 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
845
846 vDc.SetFont(GetFont());
847
848 wxCoord vHeight;
f5ea767e
DW
849 wxCoord vWidth;
850
851 GetSize( &vWidth
852 ,NULL
853 );
1de4baa3 854
f5ea767e 855 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
1de4baa3
DW
856 pMeasureStruct->rclItem.xLeft = 0;
857 pMeasureStruct->rclItem.yTop = 0;
858 pMeasureStruct->rclItem.yBottom = 0;
859
860 vHeight = vDc.GetCharHeight() * 2.5;
f5ea767e 861 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
1de4baa3 862
f5ea767e 863 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
1de4baa3 864} // end of wxListBox::OS2OnMeasure
fb9010ed 865
1de4baa3
DW
866bool wxListBox::OS2OnDraw (
867 WXDRAWITEMSTRUCT* pItem
868)
fb9010ed 869{
1de4baa3
DW
870 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
871 LONG lItemID = pDrawStruct->idItem;
872 int eAction = 0;
873 int eStatus = 0;
874
49dc8caa 875 //
1de4baa3 876 // Only owner-drawn control should receive this message
49dc8caa 877 //
1de4baa3
DW
878 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE);
879
880
881 //
882 // The item may be -1 for an empty listbox
883 //
884 if (lItemID == -1L)
885 return FALSE;
886
887 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
888 ,LM_QUERYITEMHANDLE
889 ,MPFROMLONG(pDrawStruct->idItem)
890 ,(MPARAM)0
891 )
892 );
893
894 wxCHECK(pData, FALSE );
895
896 wxDC vDc;
897 wxRect vRect( wxPoint( pDrawStruct->rclItem.xLeft
898 ,pDrawStruct->rclItem.yTop
899 )
900 ,wxPoint( pDrawStruct->rclItem.xRight
901 ,pDrawStruct->rclItem.yBottom
902 )
903 );
904
905 vDc.SetHPS(pDrawStruct->hps);
906
907 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
908 {
909 //
910 // Entire Item needs to be redrawn (either it has reappeared from
911 // behind another window or is being displayed for the first time
912 //
913 eAction = wxOwnerDrawn::wxODDrawAll;
914
915 if (pDrawStruct->fsAttribute & MIA_HILITED)
916 {
917 //
918 // If it is currently selected we let the system handle it
919 //
920 eStatus |= wxOwnerDrawn::wxODSelected;
921 }
922 if (pDrawStruct->fsAttribute & MIA_CHECKED)
923 {
924 //
925 // If it is currently checked we draw our own
926 //
927 eStatus |= wxOwnerDrawn::wxODChecked;
928 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
929 }
930 if (pDrawStruct->fsAttribute & MIA_DISABLED)
931 {
932 //
933 // If it is currently disabled we let the system handle it
934 //
935 eStatus |= wxOwnerDrawn::wxODDisabled;
936 }
937 //
938 // Don't really care about framed (indicationg focus) or NoDismiss
939 //
940 }
941 else
942 {
943 if (pDrawStruct->fsAttribute & MIA_HILITED)
944 {
945 eAction = wxOwnerDrawn::wxODDrawAll;
946 eStatus |= wxOwnerDrawn::wxODSelected;
947 //
948 // Keep the system from trying to highlight with its bogus colors
949 //
950 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
951 }
952 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
953 {
954 eAction = wxOwnerDrawn::wxODDrawAll;
955 eStatus = 0;
956 //
957 // Keep the system from trying to highlight with its bogus colors
958 //
959 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
960 }
961 else
962 {
963 //
964 // For now we don't care about anything else
965 // just ignore the entire message!
966 //
967 return TRUE;
968 }
969 }
970 return pData->OnDrawItem( vDc
971 ,vRect
972 ,(wxOwnerDrawn::wxODAction)eAction
973 ,(wxOwnerDrawn::wxODStatus)eStatus
974 );
975} // end of wxListBox::OS2OnDraw
976
49dc8caa
DW
977#endif // ndef for wxUSE_OWNER_DRAWN
978
979#endif // ndef for wxUSE_LISTBOX
7e99520b 980