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