]> git.saurik.com Git - wxWidgets.git/blame - src/os2/listbox.cpp
Blind fix for bug #1209944, wxFileConfig constructor corrupts the stack
[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
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
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
ec157c8f 131 SetBackgroundColour(vSettings.GetColour(wxSYS_COLOUR_WINDOW));
49dc8caa 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 {
ec157c8f 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 196 //
77ffb593 197 // Set standard wxWidgets colors for Listbox items and highlighting
5d44b24e
DW
198 //
199 wxColour vColour;
200
0fba44b4 201 vColour.Set(wxString(wxT("WHITE")));
5d44b24e
DW
202
203 LONG lColor = (LONG)vColour.GetPixel();
204
205 ::WinSetPresParam( m_hWnd
206 ,PP_HILITEFOREGROUNDCOLOR
207 ,sizeof(LONG)
208 ,(PVOID)&lColor
209 );
0fba44b4 210 vColour.Set(wxString(wxT("NAVY")));
5d44b24e
DW
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;
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
49dc8caa
DW
369int wxListBox::FindString(
370 const wxString& rsString
371) const
372{
373 int nPos;
374 LONG lTextLength;
375 PSZ zStr;
dcd307ee 376
0e320a79 377
49dc8caa
DW
378 for (nPos = 0; nPos < m_nNumItems; nPos++)
379 {
380 lTextLength = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0));
381 zStr = new char[lTextLength + 1];
382 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT(nPos, (SHORT)lTextLength), (MPARAM)zStr);
0fba44b4 383 if (rsString == (wxChar*)zStr)
49dc8caa
DW
384 {
385 delete [] zStr;
386 break;
387 }
388 delete [] zStr;
389 }
390 return nPos;
391} // end of wxListBox::FindString
0e320a79
DW
392
393void wxListBox::Clear()
394{
fb9010ed 395#if wxUSE_OWNER_DRAWN
49dc8caa
DW
396 size_t lUiCount = m_aItems.Count();
397
398 while (lUiCount-- != 0)
399 {
400 delete m_aItems[lUiCount];
fb9010ed
DW
401 }
402
403 m_aItems.Clear();
dcd307ee 404#else // !wxUSE_OWNER_DRAWN
49dc8caa 405 if (HasClientObjectData())
dcd307ee 406 {
49dc8caa 407 for (size_t n = 0; n < (size_t)m_lNumItems; n++)
dcd307ee
DW
408 {
409 delete GetClientObject(n);
410 }
411 }
412#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
49dc8caa 413 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
dcd307ee 414
49dc8caa
DW
415 m_nNumItems = 0;
416} // end of wxListBox::Clear
fb9010ed 417
c6179a84 418void wxListBox::DoSetSelection(
49dc8caa
DW
419 int N
420, bool bSelect
421)
0e320a79 422{
49dc8caa 423 wxCHECK_RET( N >= 0 && N < m_nNumItems,
fb9010ed 424 wxT("invalid index in wxListBox::SetSelection") );
49dc8caa
DW
425 ::WinSendMsg( GetHwnd()
426 ,LM_SELECTITEM
427 ,MPFROMLONG(N)
428 ,(MPARAM)bSelect
429 );
1de4baa3
DW
430 if(m_windowStyle & wxLB_OWNERDRAW)
431 Refresh();
49dc8caa
DW
432} // end of wxListBox::SetSelection
433
434bool wxListBox::IsSelected(
435 int N
436) const
437{
ec157c8f 438 wxCHECK_MSG( N >= 0 && N < m_nNumItems, false,
fb9010ed
DW
439 wxT("invalid index in wxListBox::Selected") );
440
49dc8caa 441 LONG lItem;
0e320a79 442
70a2c656
DW
443 if (GetWindowStyleFlag() & wxLB_EXTENDED)
444 {
445 if (N == 0)
446 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
447 else
448 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)(N - 1), (MPARAM)0));
449 }
450 else
451 {
452 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
453 }
454 return (lItem == (LONG)N && lItem != LIT_NONE);
49dc8caa
DW
455} // end of wxListBox::IsSelected
456
457wxClientData* wxListBox::DoGetItemClientObject(
458 int n
459) const
0e320a79 460{
dcd307ee 461 return (wxClientData *)DoGetItemClientData(n);
0e320a79
DW
462}
463
49dc8caa
DW
464void* wxListBox::DoGetItemClientData(
465 int n
466) const
0e320a79 467{
49dc8caa 468 wxCHECK_MSG( n >= 0 && n < m_nNumItems, NULL,
fb9010ed
DW
469 wxT("invalid index in wxListBox::GetClientData") );
470
49dc8caa
DW
471 return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
472} // end of wxListBox::DoGetItemClientData
0e320a79 473
49dc8caa
DW
474void wxListBox::DoSetItemClientObject(
475 int n
476, wxClientData* pClientData
477)
0e320a79 478{
49dc8caa
DW
479 DoSetItemClientData( n
480 ,pClientData
481 );
482} // end of wxListBox::DoSetItemClientObject
dcd307ee 483
49dc8caa
DW
484void wxListBox::DoSetItemClientData(
485 int n
486, void* pClientData
487)
dcd307ee 488{
49dc8caa 489 wxCHECK_RET( n >= 0 && n < m_nNumItems,
fb9010ed
DW
490 wxT("invalid index in wxListBox::SetClientData") );
491
dcd307ee
DW
492#if wxUSE_OWNER_DRAWN
493 if ( m_windowStyle & wxLB_OWNERDRAW )
494 {
49dc8caa
DW
495 //
496 // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
dcd307ee 497 // in OnMeasure/OnDraw.
49dc8caa 498 //
dcd307ee
DW
499 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
500 }
501#endif // wxUSE_OWNER_DRAWN
502
49dc8caa
DW
503 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
504} // end of wxListBox::DoSetItemClientData
dcd307ee
DW
505
506bool wxListBox::HasMultipleSelection() const
507{
508 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
49dc8caa 509} // end of wxListBox::HasMultipleSelection
0e320a79 510
49dc8caa
DW
511int wxListBox::GetSelections(
512 wxArrayInt& raSelections
513) const
0e320a79 514{
49dc8caa
DW
515 int nCount = 0;
516 LONG lItem;
0e320a79 517
fb9010ed 518
49dc8caa
DW
519 raSelections.Empty();
520 if (HasMultipleSelection())
521 {
522 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
523 ,LM_QUERYSELECTION
524 ,(MPARAM)LIT_FIRST
525 ,(MPARAM)0
526 )
527 );
528 if (lItem != LIT_NONE)
529 {
530 nCount++;
531 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
532 ,LM_QUERYSELECTION
533 ,(MPARAM)lItem
534 ,(MPARAM)0
535 )
536 )) != LIT_NONE)
537 {
538 nCount++;
539 }
540 raSelections.Alloc(nCount);
541 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
542 ,LM_QUERYSELECTION
543 ,(MPARAM)LIT_FIRST
544 ,(MPARAM)0
545 )
546 );
547
548 raSelections.Add((int)lItem);
549 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
550 ,LM_QUERYSELECTION
551 ,(MPARAM)lItem
552 ,(MPARAM)0
553 )
554 )) != LIT_NONE)
555 {
556 raSelections.Add((int)lItem);
557 }
558 return nCount;
fb9010ed 559 }
49dc8caa 560 return 0;
0e320a79
DW
561 }
562 else // single-selection listbox
563 {
49dc8caa
DW
564 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
565 ,LM_QUERYSELECTION
566 ,(MPARAM)LIT_FIRST
567 ,(MPARAM)0
568 )
569 );
570 raSelections.Add((int)lItem);
0e320a79
DW
571 return 1;
572 }
dcd307ee 573 return 0;
49dc8caa 574} // end of wxListBox::GetSelections
0e320a79 575
0e320a79
DW
576int wxListBox::GetSelection() const
577{
dcd307ee 578 wxCHECK_MSG( !HasMultipleSelection(),
fb9010ed
DW
579 -1,
580 wxT("GetSelection() can't be used with multiple-selection "
581 "listboxes, use GetSelections() instead.") );
582
49dc8caa
DW
583 return(LONGFROMMR(::WinSendMsg( GetHwnd()
584 ,LM_QUERYSELECTION
585 ,(MPARAM)LIT_FIRST
586 ,(MPARAM)0
587 )
588 ));
589} // end of wxListBox::GetSelection
0e320a79 590
49dc8caa
DW
591wxString wxListBox::GetString(
592 int N
593) const
0e320a79 594{
49dc8caa 595 LONG lLen = 0;
0fba44b4 596 wxChar* zBuf;
49dc8caa 597 wxString sResult;
fb9010ed 598
0fba44b4 599 wxCHECK_MSG( N >= 0 && N < m_nNumItems, wxEmptyString,
49dc8caa 600 wxT("invalid index in wxListBox::GetClientData") );
0e320a79 601
49dc8caa 602 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0));
0fba44b4 603 zBuf = new wxChar[lLen + 1];
49dc8caa
DW
604 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)N, (SHORT)lLen), (MPARAM)zBuf);
605 zBuf[lLen] = '\0';
606 sResult = zBuf;
607 delete [] zBuf;
608 return sResult;
609} // end of wxListBox::GetString
610
611void wxListBox::DoInsertItems(
612 const wxArrayString& asItems
613, int nPos
614)
615{
616 wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
dcd307ee
DW
617 wxT("invalid index in wxListBox::InsertItems") );
618
49dc8caa 619 int nItems = asItems.GetCount();
dcd307ee 620
49dc8caa 621 for (int i = 0; i < nItems; i++)
3437f881
DW
622 {
623 int nIndex = (int)::WinSendMsg( GetHwnd()
624 ,LM_INSERTITEM
625 ,MPFROMLONG((LONG)(i + nPos))
626 ,(MPARAM)asItems[i].c_str()
627 );
628
629 wxOwnerDrawn* pNewItem = CreateItem(nIndex);
630
631 pNewItem->SetName(asItems[i]);
632 pNewItem->SetFont(GetFont());
633 m_aItems.Insert(pNewItem, nIndex);
634 ::WinSendMsg( GetHwnd()
635 ,LM_SETITEMHANDLE
9923c37d 636 ,(MPARAM)((LONG)nIndex)
3437f881
DW
637 ,MPFROMP(pNewItem)
638 );
639 m_nNumItems += nItems;
640 }
49dc8caa 641} // end of wxListBox::DoInsertItems
dcd307ee 642
49dc8caa
DW
643void wxListBox::SetString(
644 int N
645, const wxString& rsString
646)
dcd307ee 647{
49dc8caa 648 wxCHECK_RET( N >= 0 && N < m_nNumItems,
dcd307ee
DW
649 wxT("invalid index in wxListBox::SetString") );
650
49dc8caa
DW
651 //
652 // Remember the state of the item
653 //
654 bool bWasSelected = IsSelected(N);
655 void* pOldData = NULL;
656 wxClientData* pOldObjData = NULL;
657
658 if (m_clientDataItemsType == wxClientData_Void)
659 pOldData = GetClientData(N);
660 else if (m_clientDataItemsType == wxClientData_Object)
661 pOldObjData = GetClientObject(N);
662
663 //
664 // Delete and recreate it
665 //
666 ::WinSendMsg( GetHwnd()
667 ,LM_DELETEITEM
668 ,(MPARAM)N
669 ,(MPARAM)0
670 );
671
672 int nNewN = N;
673
674 if (N == m_nNumItems - 1)
675 nNewN = -1;
676
677 ::WinSendMsg( GetHwnd()
678 ,LM_INSERTITEM
679 ,(MPARAM)nNewN
680 ,(MPARAM)rsString.c_str()
681 );
682
683 //
684 // Restore the client data
685 //
686 if (pOldData)
687 SetClientData( N
688 ,pOldData
689 );
690 else if (pOldObjData)
691 SetClientObject( N
692 ,pOldObjData
693 );
694
695 //
696 // We may have lost the selection
697 //
698 if (bWasSelected)
dcd307ee
DW
699 Select(N);
700
701#if wxUSE_OWNER_DRAWN
49dc8caa
DW
702 if (m_windowStyle & wxLB_OWNERDRAW)
703 //
704 // Update item's text
705 //
706 m_aItems[N]->SetName(rsString);
dcd307ee 707#endif //USE_OWNER_DRAWN
49dc8caa 708} // end of wxListBox::SetString
dcd307ee
DW
709
710int wxListBox::GetCount() const
711{
49dc8caa 712 return m_nNumItems;
dcd307ee
DW
713}
714
715// ----------------------------------------------------------------------------
716// helpers
717// ----------------------------------------------------------------------------
718
e78c4d50 719wxSize wxListBox::DoGetBestSize() const
fb9010ed 720{
49dc8caa
DW
721 //
722 // Find the widest string
723 //
724 int nLine;
725 int nListbox = 0;
726 int nCx;
727 int nCy;
0d598bae 728 wxFont vFont = (wxFont)GetFont();
49dc8caa
DW
729
730 for (int i = 0; i < m_nNumItems; i++)
fb9010ed 731 {
49dc8caa
DW
732 wxString vStr(GetString(i));
733
734 GetTextExtent( vStr
735 ,&nLine
736 ,NULL
737 );
738 if (nLine > nListbox)
739 nListbox = nLine;
fb9010ed
DW
740 }
741
49dc8caa
DW
742 //
743 // Give it some reasonable default value if there are no strings in the
744 // list.
745 //
746 if (nListbox == 0)
747 nListbox = 100;
748
749 //
750 // The listbox should be slightly larger than the widest string
751 //
752 wxGetCharSize( GetHWND()
753 ,&nCx
754 ,&nCy
0d598bae 755 ,&vFont
49dc8caa
DW
756 );
757 nListbox += 3 * nCx;
758
759 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
760
761 return wxSize( nListbox
762 ,hListbox
763 );
764} // end of wxListBox::DoGetBestSize
fb9010ed 765
dcd307ee
DW
766// ----------------------------------------------------------------------------
767// callbacks
768// ----------------------------------------------------------------------------
769
49dc8caa
DW
770bool wxListBox::OS2Command(
771 WXUINT uParam
772, WXWORD WXUNUSED(wId))
0e320a79 773{
49dc8caa 774 wxEventType eEvtType;
dcd307ee 775
49dc8caa
DW
776 if (uParam == LN_SELECT)
777 {
778 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
dcd307ee 779 }
49dc8caa 780 if (uParam == LN_ENTER)
0e320a79 781 {
49dc8caa 782 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
0e320a79 783 }
fb9010ed 784 else
49dc8caa
DW
785 {
786 //
787 // Some event we're not interested in
788 //
ec157c8f 789 return false;
49dc8caa
DW
790 }
791 wxCommandEvent vEvent( eEvtType
792 ,m_windowId
793 );
fb9010ed 794
49dc8caa 795 vEvent.SetEventObject(this);
fb9010ed 796
49dc8caa
DW
797 wxArrayInt aSelections;
798 int n;
799 int nCount = GetSelections(aSelections);
fb9010ed 800
49dc8caa
DW
801 if (nCount > 0)
802 {
803 n = aSelections[0];
804 if (HasClientObjectData())
805 vEvent.SetClientObject(GetClientObject(n));
806 else if ( HasClientUntypedData() )
807 vEvent.SetClientData(GetClientData(n));
808 vEvent.SetString(GetString(n));
809 }
810 else
811 {
812 n = -1;
813 }
687706f5 814 vEvent.SetInt(n);
49dc8caa
DW
815 return GetEventHandler()->ProcessEvent(vEvent);
816} // end of wxListBox::OS2Command
fb9010ed 817
dcd307ee
DW
818// ----------------------------------------------------------------------------
819// wxCheckListBox support
820// ----------------------------------------------------------------------------
fb9010ed
DW
821
822#if wxUSE_OWNER_DRAWN
823
49dc8caa
DW
824//
825// Drawing
fb9010ed 826// -------
49dc8caa 827//
fb9010ed
DW
828#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
829
f5ea767e 830long wxListBox::OS2OnMeasure(
1de4baa3
DW
831 WXMEASUREITEMSTRUCT* pItem
832)
fb9010ed 833{
1de4baa3
DW
834 if (!pItem)
835 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
836
837 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
838 wxScreenDC vDc;
839
49dc8caa 840 //
1de4baa3 841 // Only owner-drawn control should receive this message
49dc8caa 842 //
1de4baa3
DW
843 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
844
845 vDc.SetFont(GetFont());
846
847 wxCoord vHeight;
f5ea767e
DW
848 wxCoord vWidth;
849
850 GetSize( &vWidth
851 ,NULL
852 );
1de4baa3 853
f5ea767e 854 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
1de4baa3
DW
855 pMeasureStruct->rclItem.xLeft = 0;
856 pMeasureStruct->rclItem.yTop = 0;
857 pMeasureStruct->rclItem.yBottom = 0;
858
9923c37d 859 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
f5ea767e 860 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
1de4baa3 861
f5ea767e 862 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
1de4baa3 863} // end of wxListBox::OS2OnMeasure
fb9010ed 864
1de4baa3
DW
865bool wxListBox::OS2OnDraw (
866 WXDRAWITEMSTRUCT* pItem
867)
fb9010ed 868{
1de4baa3
DW
869 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
870 LONG lItemID = pDrawStruct->idItem;
871 int eAction = 0;
872 int eStatus = 0;
873
49dc8caa 874 //
1de4baa3 875 // Only owner-drawn control should receive this message
49dc8caa 876 //
ec157c8f 877 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), false);
1de4baa3
DW
878
879
880 //
881 // The item may be -1 for an empty listbox
882 //
883 if (lItemID == -1L)
ec157c8f 884 return false;
1de4baa3
DW
885
886 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
887 ,LM_QUERYITEMHANDLE
888 ,MPFROMLONG(pDrawStruct->idItem)
889 ,(MPARAM)0
890 )
891 );
892
ec157c8f 893 wxCHECK(pData, false );
1de4baa3
DW
894
895 wxDC vDc;
896 wxRect vRect( wxPoint( pDrawStruct->rclItem.xLeft
897 ,pDrawStruct->rclItem.yTop
898 )
899 ,wxPoint( pDrawStruct->rclItem.xRight
900 ,pDrawStruct->rclItem.yBottom
901 )
902 );
903
904 vDc.SetHPS(pDrawStruct->hps);
905
906 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
907 {
908 //
909 // Entire Item needs to be redrawn (either it has reappeared from
910 // behind another window or is being displayed for the first time
911 //
912 eAction = wxOwnerDrawn::wxODDrawAll;
913
914 if (pDrawStruct->fsAttribute & MIA_HILITED)
915 {
916 //
917 // If it is currently selected we let the system handle it
918 //
919 eStatus |= wxOwnerDrawn::wxODSelected;
920 }
921 if (pDrawStruct->fsAttribute & MIA_CHECKED)
922 {
923 //
924 // If it is currently checked we draw our own
925 //
926 eStatus |= wxOwnerDrawn::wxODChecked;
927 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
928 }
929 if (pDrawStruct->fsAttribute & MIA_DISABLED)
930 {
931 //
932 // If it is currently disabled we let the system handle it
933 //
934 eStatus |= wxOwnerDrawn::wxODDisabled;
935 }
936 //
937 // Don't really care about framed (indicationg focus) or NoDismiss
938 //
939 }
940 else
941 {
942 if (pDrawStruct->fsAttribute & MIA_HILITED)
943 {
944 eAction = wxOwnerDrawn::wxODDrawAll;
945 eStatus |= wxOwnerDrawn::wxODSelected;
946 //
947 // Keep the system from trying to highlight with its bogus colors
948 //
949 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
950 }
951 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
952 {
953 eAction = wxOwnerDrawn::wxODDrawAll;
954 eStatus = 0;
955 //
956 // Keep the system from trying to highlight with its bogus colors
957 //
958 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
959 }
960 else
961 {
962 //
963 // For now we don't care about anything else
964 // just ignore the entire message!
965 //
ec157c8f 966 return true;
1de4baa3
DW
967 }
968 }
969 return pData->OnDrawItem( vDc
970 ,vRect
971 ,(wxOwnerDrawn::wxODAction)eAction
972 ,(wxOwnerDrawn::wxODStatus)eStatus
973 );
974} // end of wxListBox::OS2OnDraw
975
49dc8caa
DW
976#endif // ndef for wxUSE_OWNER_DRAWN
977
978#endif // ndef for wxUSE_LISTBOX
7e99520b 979