]> git.saurik.com Git - wxWidgets.git/blame - src/os2/listbox.cpp
fixed memory leak in RestoreState
[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
b1294ada 41IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControlWithItems)
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
a236aa20 255void wxListBox::DoDeleteOneItem(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
DW
263#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
264
aa61d352 265 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
49dc8caa
DW
266 m_nNumItems--;
267} // end of wxListBox::DoSetFirstItem
0e320a79 268
a236aa20
VZ
269int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items,
270 unsigned int pos,
271 void **clientData,
272 wxClientDataType type)
0e320a79 273{
8228b893
WS
274 long lIndex = 0;
275 LONG lIndexType = 0;
a236aa20 276 bool incrementPos = false;
49dc8caa 277
a236aa20 278 if (IsSorted())
9923c37d 279 lIndexType = LIT_SORTASCENDING;
a236aa20 280 else if (pos == GetCount())
9923c37d 281 lIndexType = LIT_END;
a236aa20 282 else
49dc8caa 283 {
a236aa20
VZ
284 lIndexType = (LONG)pos;
285 incrementPos = true;
fb9010ed 286 }
0e320a79 287
a236aa20 288 int n = wxNOT_FOUND;
0e320a79 289
a236aa20
VZ
290 unsigned int count = items.GetCount();
291 for (unsigned int i = 0; i < count; i++)
fb9010ed 292 {
a236aa20
VZ
293 n = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)items[i].wx_str());
294 if (n < 0)
dcd307ee 295 {
a236aa20
VZ
296 wxLogLastError(_T("WinSendMsg(LM_INSERTITEM)"));
297 n = wxNOT_FOUND;
298 break;
dcd307ee 299 }
a236aa20 300 ++m_nNumItems;
fb9010ed
DW
301
302#if wxUSE_OWNER_DRAWN
a236aa20 303 if (HasFlag(wxLB_OWNERDRAW))
49dc8caa 304 {
a236aa20
VZ
305 wxOwnerDrawn* pNewItem = CreateItem(n); // dummy argument
306 wxScreenDC vDc; // FIXME: is it really needed here?
307
308 pNewItem->SetName(items[i]);
309 m_aItems.Insert(pNewItem, n);
310 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pNewItem));
311 pNewItem->SetFont(GetFont());
fb9010ed 312 }
a236aa20
VZ
313#endif
314 AssignNewItemClientData(n, clientData, i, type);
315
316 if (incrementPos)
317 ++lIndexType;
fb9010ed 318 }
0e320a79 319
a236aa20
VZ
320 return n;
321} // end of wxListBox::DoInsertAppendItemsWithData
322
323void wxListBox::DoClear()
0e320a79 324{
fb9010ed 325#if wxUSE_OWNER_DRAWN
aa61d352 326 unsigned int lUiCount = m_aItems.Count();
49dc8caa
DW
327
328 while (lUiCount-- != 0)
329 {
330 delete m_aItems[lUiCount];
fb9010ed
DW
331 }
332
333 m_aItems.Clear();
a236aa20 334#endif // wxUSE_OWNER_DRAWN
49dc8caa 335 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
dcd307ee 336
49dc8caa
DW
337 m_nNumItems = 0;
338} // end of wxListBox::Clear
fb9010ed 339
8228b893 340void wxListBox::DoSetSelection( int N, bool bSelect)
0e320a79 341{
8228b893 342 wxCHECK_RET( IsValid(N),
fb9010ed 343 wxT("invalid index in wxListBox::SetSelection") );
49dc8caa
DW
344 ::WinSendMsg( GetHwnd()
345 ,LM_SELECTITEM
346 ,MPFROMLONG(N)
347 ,(MPARAM)bSelect
348 );
1de4baa3
DW
349 if(m_windowStyle & wxLB_OWNERDRAW)
350 Refresh();
49dc8caa
DW
351} // end of wxListBox::SetSelection
352
8228b893 353bool wxListBox::IsSelected( int N ) const
49dc8caa 354{
8228b893 355 wxCHECK_MSG( IsValid(N), false,
fb9010ed
DW
356 wxT("invalid index in wxListBox::Selected") );
357
49dc8caa 358 LONG lItem;
0e320a79 359
70a2c656
DW
360 if (GetWindowStyleFlag() & wxLB_EXTENDED)
361 {
362 if (N == 0)
363 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
364 else
365 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)(N - 1), (MPARAM)0));
366 }
367 else
368 {
369 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
370 }
371 return (lItem == (LONG)N && lItem != LIT_NONE);
49dc8caa
DW
372} // end of wxListBox::IsSelected
373
aa61d352 374void* wxListBox::DoGetItemClientData(unsigned int n) const
0e320a79 375{
8228b893 376 wxCHECK_MSG( IsValid(n), NULL,
fb9010ed
DW
377 wxT("invalid index in wxListBox::GetClientData") );
378
49dc8caa
DW
379 return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
380} // end of wxListBox::DoGetItemClientData
0e320a79 381
aa61d352 382void wxListBox::DoSetItemClientData(unsigned int n, void* pClientData)
dcd307ee 383{
8228b893 384 wxCHECK_RET( IsValid(n),
fb9010ed
DW
385 wxT("invalid index in wxListBox::SetClientData") );
386
dcd307ee
DW
387#if wxUSE_OWNER_DRAWN
388 if ( m_windowStyle & wxLB_OWNERDRAW )
389 {
49dc8caa
DW
390 //
391 // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
dcd307ee 392 // in OnMeasure/OnDraw.
49dc8caa 393 //
dcd307ee
DW
394 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
395 }
396#endif // wxUSE_OWNER_DRAWN
397
49dc8caa
DW
398 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
399} // end of wxListBox::DoSetItemClientData
dcd307ee
DW
400
401bool wxListBox::HasMultipleSelection() const
402{
403 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
49dc8caa 404} // end of wxListBox::HasMultipleSelection
0e320a79 405
6670f564 406int wxListBox::GetSelections( wxArrayInt& raSelections ) const
0e320a79 407{
8228b893
WS
408 int nCount = 0;
409 LONG lItem;
0e320a79 410
fb9010ed 411
49dc8caa
DW
412 raSelections.Empty();
413 if (HasMultipleSelection())
414 {
415 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
416 ,LM_QUERYSELECTION
417 ,(MPARAM)LIT_FIRST
418 ,(MPARAM)0
419 )
420 );
421 if (lItem != LIT_NONE)
422 {
423 nCount++;
424 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
425 ,LM_QUERYSELECTION
426 ,(MPARAM)lItem
427 ,(MPARAM)0
428 )
429 )) != LIT_NONE)
430 {
431 nCount++;
432 }
433 raSelections.Alloc(nCount);
434 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
435 ,LM_QUERYSELECTION
436 ,(MPARAM)LIT_FIRST
437 ,(MPARAM)0
438 )
439 );
440
441 raSelections.Add((int)lItem);
442 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
443 ,LM_QUERYSELECTION
444 ,(MPARAM)lItem
445 ,(MPARAM)0
446 )
447 )) != LIT_NONE)
448 {
449 raSelections.Add((int)lItem);
450 }
451 return nCount;
fb9010ed 452 }
0e320a79
DW
453 }
454 else // single-selection listbox
455 {
49dc8caa
DW
456 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
457 ,LM_QUERYSELECTION
458 ,(MPARAM)LIT_FIRST
459 ,(MPARAM)0
460 )
461 );
462 raSelections.Add((int)lItem);
0e320a79
DW
463 return 1;
464 }
dcd307ee 465 return 0;
49dc8caa 466} // end of wxListBox::GetSelections
0e320a79 467
0e320a79
DW
468int wxListBox::GetSelection() const
469{
dcd307ee 470 wxCHECK_MSG( !HasMultipleSelection(),
fb9010ed
DW
471 -1,
472 wxT("GetSelection() can't be used with multiple-selection "
473 "listboxes, use GetSelections() instead.") );
474
49dc8caa
DW
475 return(LONGFROMMR(::WinSendMsg( GetHwnd()
476 ,LM_QUERYSELECTION
477 ,(MPARAM)LIT_FIRST
478 ,(MPARAM)0
479 )
480 ));
481} // end of wxListBox::GetSelection
0e320a79 482
aa61d352 483wxString wxListBox::GetString(unsigned int n) const
0e320a79 484{
8228b893
WS
485 LONG lLen = 0;
486 wxChar* zBuf;
487 wxString sResult;
fb9010ed 488
aa61d352 489 wxCHECK_MSG( IsValid(n), wxEmptyString,
49dc8caa 490 wxT("invalid index in wxListBox::GetClientData") );
0e320a79 491
aa61d352 492 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
0fba44b4 493 zBuf = new wxChar[lLen + 1];
aa61d352 494 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)n, (SHORT)lLen), (MPARAM)zBuf);
49dc8caa
DW
495 zBuf[lLen] = '\0';
496 sResult = zBuf;
497 delete [] zBuf;
498 return sResult;
499} // end of wxListBox::GetString
500
aa61d352 501void wxListBox::SetString(unsigned int n, const wxString& rsString)
dcd307ee 502{
aa61d352 503 wxCHECK_RET( IsValid(n),
dcd307ee
DW
504 wxT("invalid index in wxListBox::SetString") );
505
49dc8caa
DW
506 //
507 // Remember the state of the item
508 //
aa61d352 509 bool bWasSelected = IsSelected(n);
8228b893
WS
510 void* pOldData = NULL;
511 wxClientData* pOldObjData = NULL;
49dc8caa
DW
512
513 if (m_clientDataItemsType == wxClientData_Void)
aa61d352 514 pOldData = GetClientData(n);
49dc8caa 515 else if (m_clientDataItemsType == wxClientData_Object)
aa61d352 516 pOldObjData = GetClientObject(n);
49dc8caa
DW
517
518 //
519 // Delete and recreate it
520 //
521 ::WinSendMsg( GetHwnd()
522 ,LM_DELETEITEM
aa61d352 523 ,(MPARAM)n
49dc8caa
DW
524 ,(MPARAM)0
525 );
526
aa61d352 527 int nNewN = n;
49dc8caa 528
020e385d 529 if (n == (m_nNumItems - 1))
49dc8caa
DW
530 nNewN = -1;
531
532 ::WinSendMsg( GetHwnd()
533 ,LM_INSERTITEM
534 ,(MPARAM)nNewN
404aba09 535 ,(MPARAM)rsString.wx_str()
49dc8caa
DW
536 );
537
538 //
539 // Restore the client data
540 //
541 if (pOldData)
aa61d352 542 SetClientData(n, pOldData);
49dc8caa 543 else if (pOldObjData)
aa61d352 544 SetClientObject(n, pOldObjData);
49dc8caa
DW
545
546 //
547 // We may have lost the selection
548 //
549 if (bWasSelected)
aa61d352 550 Select(n);
dcd307ee
DW
551
552#if wxUSE_OWNER_DRAWN
49dc8caa
DW
553 if (m_windowStyle & wxLB_OWNERDRAW)
554 //
555 // Update item's text
556 //
aa61d352 557 m_aItems[n]->SetName(rsString);
dcd307ee 558#endif //USE_OWNER_DRAWN
49dc8caa 559} // end of wxListBox::SetString
dcd307ee 560
aa61d352 561unsigned int wxListBox::GetCount() const
dcd307ee 562{
49dc8caa 563 return m_nNumItems;
dcd307ee
DW
564}
565
566// ----------------------------------------------------------------------------
567// helpers
568// ----------------------------------------------------------------------------
569
e78c4d50 570wxSize wxListBox::DoGetBestSize() const
fb9010ed 571{
49dc8caa
DW
572 //
573 // Find the widest string
574 //
8228b893
WS
575 int nLine;
576 int nListbox = 0;
577 int nCx;
578 int nCy;
579 wxFont vFont = (wxFont)GetFont();
49dc8caa 580
aa61d352 581 for (unsigned int i = 0; i < m_nNumItems; i++)
fb9010ed 582 {
8228b893 583 wxString vStr(GetString(i));
49dc8caa 584
8228b893 585 GetTextExtent( vStr, &nLine, NULL );
49dc8caa
DW
586 if (nLine > nListbox)
587 nListbox = nLine;
fb9010ed
DW
588 }
589
49dc8caa
DW
590 //
591 // Give it some reasonable default value if there are no strings in the
592 // list.
593 //
594 if (nListbox == 0)
595 nListbox = 100;
596
597 //
598 // The listbox should be slightly larger than the widest string
599 //
600 wxGetCharSize( GetHWND()
601 ,&nCx
602 ,&nCy
0d598bae 603 ,&vFont
49dc8caa
DW
604 );
605 nListbox += 3 * nCx;
606
8228b893 607 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
49dc8caa
DW
608
609 return wxSize( nListbox
610 ,hListbox
611 );
612} // end of wxListBox::DoGetBestSize
fb9010ed 613
dcd307ee
DW
614// ----------------------------------------------------------------------------
615// callbacks
616// ----------------------------------------------------------------------------
617
49dc8caa
DW
618bool wxListBox::OS2Command(
619 WXUINT uParam
620, WXWORD WXUNUSED(wId))
0e320a79 621{
49dc8caa 622 wxEventType eEvtType;
dcd307ee 623
49dc8caa
DW
624 if (uParam == LN_SELECT)
625 {
626 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
dcd307ee 627 }
d6701f32 628 else if (uParam == LN_ENTER)
0e320a79 629 {
49dc8caa 630 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
0e320a79 631 }
fb9010ed 632 else
49dc8caa
DW
633 {
634 //
635 // Some event we're not interested in
636 //
ec157c8f 637 return false;
49dc8caa
DW
638 }
639 wxCommandEvent vEvent( eEvtType
640 ,m_windowId
641 );
fb9010ed 642
49dc8caa 643 vEvent.SetEventObject(this);
fb9010ed 644
8228b893
WS
645 wxArrayInt aSelections;
646 int n;
647 int nCount = GetSelections(aSelections);
fb9010ed 648
49dc8caa
DW
649 if (nCount > 0)
650 {
651 n = aSelections[0];
652 if (HasClientObjectData())
653 vEvent.SetClientObject(GetClientObject(n));
654 else if ( HasClientUntypedData() )
655 vEvent.SetClientData(GetClientData(n));
656 vEvent.SetString(GetString(n));
657 }
658 else
659 {
660 n = -1;
661 }
687706f5 662 vEvent.SetInt(n);
49dc8caa
DW
663 return GetEventHandler()->ProcessEvent(vEvent);
664} // end of wxListBox::OS2Command
fb9010ed 665
dcd307ee
DW
666// ----------------------------------------------------------------------------
667// wxCheckListBox support
668// ----------------------------------------------------------------------------
fb9010ed
DW
669
670#if wxUSE_OWNER_DRAWN
671
49dc8caa
DW
672//
673// Drawing
fb9010ed 674// -------
49dc8caa 675//
fb9010ed
DW
676#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
677
8228b893 678long wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT* pItem)
fb9010ed 679{
1de4baa3
DW
680 if (!pItem)
681 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
682
683 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
684 wxScreenDC vDc;
685
49dc8caa 686 //
1de4baa3 687 // Only owner-drawn control should receive this message
49dc8caa 688 //
1de4baa3
DW
689 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
690
691 vDc.SetFont(GetFont());
692
693 wxCoord vHeight;
f5ea767e
DW
694 wxCoord vWidth;
695
696 GetSize( &vWidth
697 ,NULL
698 );
1de4baa3 699
f5ea767e 700 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
1de4baa3
DW
701 pMeasureStruct->rclItem.xLeft = 0;
702 pMeasureStruct->rclItem.yTop = 0;
703 pMeasureStruct->rclItem.yBottom = 0;
704
9923c37d 705 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
f5ea767e 706 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
1de4baa3 707
f5ea767e 708 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
1de4baa3 709} // end of wxListBox::OS2OnMeasure
fb9010ed 710
1de4baa3
DW
711bool wxListBox::OS2OnDraw (
712 WXDRAWITEMSTRUCT* pItem
713)
fb9010ed 714{
1de4baa3
DW
715 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
716 LONG lItemID = pDrawStruct->idItem;
717 int eAction = 0;
718 int eStatus = 0;
719
49dc8caa 720 //
1de4baa3 721 // Only owner-drawn control should receive this message
49dc8caa 722 //
ec157c8f 723 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), false);
1de4baa3
DW
724
725
726 //
727 // The item may be -1 for an empty listbox
728 //
729 if (lItemID == -1L)
ec157c8f 730 return false;
1de4baa3
DW
731
732 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
733 ,LM_QUERYITEMHANDLE
734 ,MPFROMLONG(pDrawStruct->idItem)
735 ,(MPARAM)0
736 )
737 );
738
ec157c8f 739 wxCHECK(pData, false );
1de4baa3 740
6670f564
WS
741 wxDC vDc;
742 wxPoint pt1( pDrawStruct->rclItem.xLeft, pDrawStruct->rclItem.yTop );
743 wxPoint pt2( pDrawStruct->rclItem.xRight, pDrawStruct->rclItem.yBottom );
744 wxRect vRect( pt1, pt2 );
1de4baa3
DW
745
746 vDc.SetHPS(pDrawStruct->hps);
747
748 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
749 {
750 //
751 // Entire Item needs to be redrawn (either it has reappeared from
752 // behind another window or is being displayed for the first time
753 //
754 eAction = wxOwnerDrawn::wxODDrawAll;
755
756 if (pDrawStruct->fsAttribute & MIA_HILITED)
757 {
758 //
759 // If it is currently selected we let the system handle it
760 //
761 eStatus |= wxOwnerDrawn::wxODSelected;
762 }
763 if (pDrawStruct->fsAttribute & MIA_CHECKED)
764 {
765 //
766 // If it is currently checked we draw our own
767 //
768 eStatus |= wxOwnerDrawn::wxODChecked;
769 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
770 }
771 if (pDrawStruct->fsAttribute & MIA_DISABLED)
772 {
773 //
774 // If it is currently disabled we let the system handle it
775 //
776 eStatus |= wxOwnerDrawn::wxODDisabled;
777 }
778 //
779 // Don't really care about framed (indicationg focus) or NoDismiss
780 //
781 }
782 else
783 {
784 if (pDrawStruct->fsAttribute & MIA_HILITED)
785 {
786 eAction = wxOwnerDrawn::wxODDrawAll;
787 eStatus |= wxOwnerDrawn::wxODSelected;
788 //
789 // Keep the system from trying to highlight with its bogus colors
790 //
791 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
792 }
793 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
794 {
795 eAction = wxOwnerDrawn::wxODDrawAll;
796 eStatus = 0;
797 //
798 // Keep the system from trying to highlight with its bogus colors
799 //
800 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
801 }
802 else
803 {
804 //
805 // For now we don't care about anything else
806 // just ignore the entire message!
807 //
ec157c8f 808 return true;
1de4baa3
DW
809 }
810 }
811 return pData->OnDrawItem( vDc
812 ,vRect
813 ,(wxOwnerDrawn::wxODAction)eAction
814 ,(wxOwnerDrawn::wxODStatus)eStatus
815 );
816} // end of wxListBox::OS2OnDraw
817
49dc8caa
DW
818#endif // ndef for wxUSE_OWNER_DRAWN
819
8228b893 820#endif // wxUSE_LISTBOX