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