]> git.saurik.com Git - wxWidgets.git/blame - src/os2/listbox.cpp
fixed debug assert in VC 7.1 CRT due to calling isalnum() with 8bit chars
[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{
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);
383 if (rsString == (char*)zStr)
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
49dc8caa
DW
418void wxListBox::SetSelection(
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{
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
DW
595 LONG lLen = 0;
596 char* zBuf;
597 wxString sResult;
fb9010ed 598
49dc8caa
DW
599 wxCHECK_MSG( N >= 0 && N < m_nNumItems, "",
600 wxT("invalid index in wxListBox::GetClientData") );
0e320a79 601
49dc8caa
DW
602 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0));
603 zBuf = new char[lLen + 1];
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;
728
729 for (int i = 0; i < m_nNumItems; i++)
fb9010ed 730 {
49dc8caa
DW
731 wxString vStr(GetString(i));
732
733 GetTextExtent( vStr
734 ,&nLine
735 ,NULL
736 );
737 if (nLine > nListbox)
738 nListbox = nLine;
fb9010ed
DW
739 }
740
49dc8caa
DW
741 //
742 // Give it some reasonable default value if there are no strings in the
743 // list.
744 //
745 if (nListbox == 0)
746 nListbox = 100;
747
748 //
749 // The listbox should be slightly larger than the widest string
750 //
751 wxGetCharSize( GetHWND()
752 ,&nCx
753 ,&nCy
754 ,(wxFont*)&GetFont()
755 );
756 nListbox += 3 * nCx;
757
758 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
759
760 return wxSize( nListbox
761 ,hListbox
762 );
763} // end of wxListBox::DoGetBestSize
fb9010ed 764
dcd307ee
DW
765// ----------------------------------------------------------------------------
766// callbacks
767// ----------------------------------------------------------------------------
768
49dc8caa
DW
769bool wxListBox::OS2Command(
770 WXUINT uParam
771, WXWORD WXUNUSED(wId))
0e320a79 772{
49dc8caa 773 wxEventType eEvtType;
dcd307ee 774
49dc8caa
DW
775 if (uParam == LN_SELECT)
776 {
777 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
dcd307ee 778 }
49dc8caa 779 if (uParam == LN_ENTER)
0e320a79 780 {
49dc8caa 781 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
0e320a79 782 }
fb9010ed 783 else
49dc8caa
DW
784 {
785 //
786 // Some event we're not interested in
787 //
788 return FALSE;
789 }
790 wxCommandEvent vEvent( eEvtType
791 ,m_windowId
792 );
fb9010ed 793
49dc8caa 794 vEvent.SetEventObject(this);
fb9010ed 795
49dc8caa
DW
796 wxArrayInt aSelections;
797 int n;
798 int nCount = GetSelections(aSelections);
fb9010ed 799
49dc8caa
DW
800 if (nCount > 0)
801 {
802 n = aSelections[0];
803 if (HasClientObjectData())
804 vEvent.SetClientObject(GetClientObject(n));
805 else if ( HasClientUntypedData() )
806 vEvent.SetClientData(GetClientData(n));
807 vEvent.SetString(GetString(n));
808 }
809 else
810 {
811 n = -1;
812 }
813 vEvent.m_commandInt = n;
814 return GetEventHandler()->ProcessEvent(vEvent);
815} // end of wxListBox::OS2Command
fb9010ed 816
dcd307ee
DW
817// ----------------------------------------------------------------------------
818// wxCheckListBox support
819// ----------------------------------------------------------------------------
fb9010ed
DW
820
821#if wxUSE_OWNER_DRAWN
822
49dc8caa
DW
823//
824// Drawing
fb9010ed 825// -------
49dc8caa 826//
fb9010ed
DW
827#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
828
f5ea767e 829long wxListBox::OS2OnMeasure(
1de4baa3
DW
830 WXMEASUREITEMSTRUCT* pItem
831)
fb9010ed 832{
1de4baa3
DW
833 if (!pItem)
834 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
835
836 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
837 wxScreenDC vDc;
838
49dc8caa 839 //
1de4baa3 840 // Only owner-drawn control should receive this message
49dc8caa 841 //
1de4baa3
DW
842 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
843
844 vDc.SetFont(GetFont());
845
846 wxCoord vHeight;
f5ea767e
DW
847 wxCoord vWidth;
848
849 GetSize( &vWidth
850 ,NULL
851 );
1de4baa3 852
f5ea767e 853 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
1de4baa3
DW
854 pMeasureStruct->rclItem.xLeft = 0;
855 pMeasureStruct->rclItem.yTop = 0;
856 pMeasureStruct->rclItem.yBottom = 0;
857
9923c37d 858 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
f5ea767e 859 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
1de4baa3 860
f5ea767e 861 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
1de4baa3 862} // end of wxListBox::OS2OnMeasure
fb9010ed 863
1de4baa3
DW
864bool wxListBox::OS2OnDraw (
865 WXDRAWITEMSTRUCT* pItem
866)
fb9010ed 867{
1de4baa3
DW
868 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
869 LONG lItemID = pDrawStruct->idItem;
870 int eAction = 0;
871 int eStatus = 0;
872
49dc8caa 873 //
1de4baa3 874 // Only owner-drawn control should receive this message
49dc8caa 875 //
1de4baa3
DW
876 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE);
877
878
879 //
880 // The item may be -1 for an empty listbox
881 //
882 if (lItemID == -1L)
883 return FALSE;
884
885 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
886 ,LM_QUERYITEMHANDLE
887 ,MPFROMLONG(pDrawStruct->idItem)
888 ,(MPARAM)0
889 )
890 );
891
892 wxCHECK(pData, FALSE );
893
894 wxDC vDc;
895 wxRect vRect( wxPoint( pDrawStruct->rclItem.xLeft
896 ,pDrawStruct->rclItem.yTop
897 )
898 ,wxPoint( pDrawStruct->rclItem.xRight
899 ,pDrawStruct->rclItem.yBottom
900 )
901 );
902
903 vDc.SetHPS(pDrawStruct->hps);
904
905 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
906 {
907 //
908 // Entire Item needs to be redrawn (either it has reappeared from
909 // behind another window or is being displayed for the first time
910 //
911 eAction = wxOwnerDrawn::wxODDrawAll;
912
913 if (pDrawStruct->fsAttribute & MIA_HILITED)
914 {
915 //
916 // If it is currently selected we let the system handle it
917 //
918 eStatus |= wxOwnerDrawn::wxODSelected;
919 }
920 if (pDrawStruct->fsAttribute & MIA_CHECKED)
921 {
922 //
923 // If it is currently checked we draw our own
924 //
925 eStatus |= wxOwnerDrawn::wxODChecked;
926 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
927 }
928 if (pDrawStruct->fsAttribute & MIA_DISABLED)
929 {
930 //
931 // If it is currently disabled we let the system handle it
932 //
933 eStatus |= wxOwnerDrawn::wxODDisabled;
934 }
935 //
936 // Don't really care about framed (indicationg focus) or NoDismiss
937 //
938 }
939 else
940 {
941 if (pDrawStruct->fsAttribute & MIA_HILITED)
942 {
943 eAction = wxOwnerDrawn::wxODDrawAll;
944 eStatus |= wxOwnerDrawn::wxODSelected;
945 //
946 // Keep the system from trying to highlight with its bogus colors
947 //
948 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
949 }
950 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
951 {
952 eAction = wxOwnerDrawn::wxODDrawAll;
953 eStatus = 0;
954 //
955 // Keep the system from trying to highlight with its bogus colors
956 //
957 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
958 }
959 else
960 {
961 //
962 // For now we don't care about anything else
963 // just ignore the entire message!
964 //
965 return TRUE;
966 }
967 }
968 return pData->OnDrawItem( vDc
969 ,vRect
970 ,(wxOwnerDrawn::wxODAction)eAction
971 ,(wxOwnerDrawn::wxODStatus)eStatus
972 );
973} // end of wxListBox::OS2OnDraw
974
49dc8caa
DW
975#endif // ndef for wxUSE_OWNER_DRAWN
976
977#endif // ndef for wxUSE_LISTBOX
7e99520b 978