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