]> git.saurik.com Git - wxWidgets.git/blame - src/os2/listbox.cpp
don't refresh the current cell in SetCellHighlightROPenWidth() if it's invalid (...
[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
38400bb4 32#include "wx/os2/dcclient.h"
ad9835c9
WS
33#include "wx/os2/private.h"
34
fb9010ed
DW
35#define INCL_M
36#include <os2.h>
37
fb9010ed
DW
38#if wxUSE_OWNER_DRAWN
39 #include "wx/ownerdrw.h"
40#endif
41
b1294ada 42IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControlWithItems)
0e320a79 43
fb9010ed
DW
44// ============================================================================
45// list box item declaration and implementation
46// ============================================================================
47
48#if wxUSE_OWNER_DRAWN
49
50class wxListBoxItem : public wxOwnerDrawn
51{
52public:
0fba44b4 53 wxListBoxItem(const wxString& rsStr = wxEmptyString);
fb9010ed
DW
54};
55
49dc8caa
DW
56wxListBoxItem::wxListBoxItem(
57 const wxString& rsStr
58)
59: wxOwnerDrawn( rsStr
ec157c8f 60 ,false
49dc8caa 61 )
fb9010ed 62{
49dc8caa
DW
63 //
64 // No bitmaps/checkmarks
65 //
fb9010ed 66 SetMarginWidth(0);
49dc8caa 67} // end of wxListBoxItem::wxListBoxItem
fb9010ed 68
6670f564 69wxOwnerDrawn* wxListBox::CreateItem( size_t WXUNUSED(n) )
fb9010ed
DW
70{
71 return new wxListBoxItem();
49dc8caa 72} // end of wxListBox::CreateItem
fb9010ed
DW
73
74#endif //USE_OWNER_DRAWN
75
0e320a79
DW
76// ============================================================================
77// list box control implementation
78// ============================================================================
79
80// Listbox item
81wxListBox::wxListBox()
82{
49dc8caa
DW
83 m_nNumItems = 0;
84 m_nSelected = 0;
85} // end of wxListBox::wxListBox
86
584ad2a3
MB
87bool wxListBox::Create(
88 wxWindow* pParent
89, wxWindowID vId
90, const wxPoint& rPos
91, const wxSize& rSize
92, const wxArrayString& asChoices
93, long lStyle
94, const wxValidator& rValidator
95, const wxString& rsName
96)
97{
98 wxCArrayString chs(asChoices);
99
100 return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
101 lStyle, rValidator, rsName);
102}
103
8228b893
WS
104bool wxListBox::Create( wxWindow* pParent,
105 wxWindowID vId,
106 const wxPoint& rPos,
107 const wxSize& rSize,
108 int n,
109 const wxString asChoices[],
110 long lStyle,
111 const wxValidator& rValidator,
112 const wxString& rsName )
0e320a79 113{
49dc8caa
DW
114 m_nNumItems = 0;
115 m_hWnd = 0;
116 m_nSelected = 0;
0e320a79 117
49dc8caa 118 SetName(rsName);
5d4b632b 119#if wxUSE_VALIDATORS
49dc8caa 120 SetValidator(rValidator);
5d4b632b 121#endif
0e320a79 122
49dc8caa
DW
123 if (pParent)
124 pParent->AddChild(this);
125
126 wxSystemSettings vSettings;
127
ec157c8f 128 SetBackgroundColour(vSettings.GetColour(wxSYS_COLOUR_WINDOW));
49dc8caa 129 SetForegroundColour(pParent->GetForegroundColour());
0e320a79 130
49dc8caa 131 m_windowId = (vId == -1) ? (int)NewControlId() : vId;
0e320a79 132
49dc8caa
DW
133 int nX = rPos.x;
134 int nY = rPos.y;
135 int nWidth = rSize.x;
136 int nHeight = rSize.y;
0e320a79 137
49dc8caa 138 m_windowStyle = lStyle;
fb9010ed 139
49dc8caa
DW
140 lStyle = WS_VISIBLE;
141
142 if (m_windowStyle & wxCLIP_SIBLINGS )
143 lStyle |= WS_CLIPSIBLINGS;
fb9010ed 144 if (m_windowStyle & wxLB_MULTIPLE)
49dc8caa 145 lStyle |= LS_MULTIPLESEL;
fb9010ed 146 else if (m_windowStyle & wxLB_EXTENDED)
49dc8caa 147 lStyle |= LS_EXTENDEDSEL;
fb9010ed 148 if (m_windowStyle & wxLB_HSCROLL)
49dc8caa
DW
149 lStyle |= LS_HORZSCROLL;
150 if (m_windowStyle & wxLB_OWNERDRAW)
151 lStyle |= LS_OWNERDRAW;
fb9010ed 152
49dc8caa 153 //
fb9010ed
DW
154 // Without this style, you get unexpected heights, so e.g. constraint layout
155 // doesn't work properly
49dc8caa
DW
156 //
157 lStyle |= LS_NOADJUSTPOS;
158
159 m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent) // Parent
160 ,WC_LISTBOX // Default Listbox class
161 ,"LISTBOX" // Control's name
162 ,lStyle // Initial Style
163 ,0, 0, 0, 0 // Position and size
164 ,GetWinHwnd(pParent) // Owner
165 ,HWND_TOP // Z-Order
166 ,(HMENU)m_windowId // Id
167 ,NULL // Control Data
168 ,NULL // Presentation Parameters
169 );
170 if (m_hWnd == 0)
fb9010ed 171 {
ec157c8f 172 return false;
fb9010ed
DW
173 }
174
49dc8caa
DW
175 //
176 // Subclass again for purposes of dialog editing mode
177 //
fb9010ed
DW
178 SubclassWin(m_hWnd);
179
49dc8caa 180 LONG lUi;
0e320a79 181
49dc8caa
DW
182 for (lUi = 0; lUi < (LONG)n; lUi++)
183 {
184 Append(asChoices[lUi]);
185 }
b3260bce
DW
186 wxFont* pTextFont = new wxFont( 10
187 ,wxMODERN
188 ,wxNORMAL
189 ,wxNORMAL
190 );
191 SetFont(*pTextFont);
e58dab20 192
5d44b24e 193 //
ad4e3f7b 194 // Set OS/2 system colours for Listbox items and highlighting
5d44b24e
DW
195 //
196 wxColour vColour;
197
ad4e3f7b 198 vColour = wxSystemSettingsNative::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
5d44b24e
DW
199
200 LONG lColor = (LONG)vColour.GetPixel();
201
202 ::WinSetPresParam( m_hWnd
203 ,PP_HILITEFOREGROUNDCOLOR
204 ,sizeof(LONG)
205 ,(PVOID)&lColor
206 );
ad4e3f7b 207 vColour = wxSystemSettingsNative::GetColour(wxSYS_COLOUR_HIGHLIGHT);
5d44b24e
DW
208 lColor = (LONG)vColour.GetPixel();
209 ::WinSetPresParam( m_hWnd
210 ,PP_HILITEBACKGROUNDCOLOR
211 ,sizeof(LONG)
212 ,(PVOID)&lColor
213 );
214
ad4e3f7b
SN
215 SetXComp(0);
216 SetYComp(0);
49dc8caa
DW
217 SetSize( nX
218 ,nY
219 ,nWidth
220 ,nHeight
221 );
b3260bce 222 delete pTextFont;
ec157c8f 223 return true;
49dc8caa 224} // end of wxListBox::Create
0e320a79
DW
225
226wxListBox::~wxListBox()
227{
fb9010ed 228#if wxUSE_OWNER_DRAWN
8228b893 229 size_t lUiCount = m_aItems.Count();
49dc8caa
DW
230
231 while (lUiCount-- != 0)
232 {
233 delete m_aItems[lUiCount];
fb9010ed
DW
234 }
235#endif // wxUSE_OWNER_DRAWN
49dc8caa 236} // end of wxListBox::~wxListBox
fb9010ed
DW
237
238void wxListBox::SetupColours()
239{
a756f210 240 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
fb9010ed 241 SetForegroundColour(GetParent()->GetForegroundColour());
49dc8caa 242} // end of wxListBox::SetupColours
0e320a79 243
dcd307ee
DW
244// ----------------------------------------------------------------------------
245// implementation of wxListBoxBase methods
246// ----------------------------------------------------------------------------
247
8228b893 248void wxListBox::DoSetFirstItem(int N)
0e320a79 249{
8228b893 250 wxCHECK_RET( IsValid(N),
fb9010ed
DW
251 wxT("invalid index in wxListBox::SetFirstItem") );
252
49dc8caa
DW
253 ::WinSendMsg(GetHwnd(), LM_SETTOPINDEX, MPFROMLONG(N), (MPARAM)0);
254} // end of wxListBox::DoSetFirstItem
0e320a79 255
a236aa20 256void wxListBox::DoDeleteOneItem(unsigned int n)
0e320a79 257{
aa61d352 258 wxCHECK_RET( IsValid(n),
fb9010ed
DW
259 wxT("invalid index in wxListBox::Delete") );
260
dcd307ee 261#if wxUSE_OWNER_DRAWN
aa61d352
VZ
262 delete m_aItems[n];
263 m_aItems.RemoveAt(n);
dcd307ee
DW
264#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
265
aa61d352 266 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
49dc8caa
DW
267 m_nNumItems--;
268} // end of wxListBox::DoSetFirstItem
0e320a79 269
a236aa20
VZ
270int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items,
271 unsigned int pos,
272 void **clientData,
273 wxClientDataType type)
0e320a79 274{
8228b893
WS
275 long lIndex = 0;
276 LONG lIndexType = 0;
a236aa20 277 bool incrementPos = false;
49dc8caa 278
a236aa20 279 if (IsSorted())
9923c37d 280 lIndexType = LIT_SORTASCENDING;
a236aa20 281 else if (pos == GetCount())
9923c37d 282 lIndexType = LIT_END;
a236aa20 283 else
49dc8caa 284 {
a236aa20
VZ
285 lIndexType = (LONG)pos;
286 incrementPos = true;
fb9010ed 287 }
0e320a79 288
a236aa20 289 int n = wxNOT_FOUND;
0e320a79 290
a236aa20
VZ
291 unsigned int count = items.GetCount();
292 for (unsigned int i = 0; i < count; i++)
fb9010ed 293 {
a236aa20
VZ
294 n = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)items[i].wx_str());
295 if (n < 0)
dcd307ee 296 {
a236aa20
VZ
297 wxLogLastError(_T("WinSendMsg(LM_INSERTITEM)"));
298 n = wxNOT_FOUND;
299 break;
dcd307ee 300 }
a236aa20 301 ++m_nNumItems;
fb9010ed
DW
302
303#if wxUSE_OWNER_DRAWN
a236aa20 304 if (HasFlag(wxLB_OWNERDRAW))
49dc8caa 305 {
a236aa20
VZ
306 wxOwnerDrawn* pNewItem = CreateItem(n); // dummy argument
307 wxScreenDC vDc; // FIXME: is it really needed here?
308
309 pNewItem->SetName(items[i]);
310 m_aItems.Insert(pNewItem, n);
311 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pNewItem));
312 pNewItem->SetFont(GetFont());
fb9010ed 313 }
a236aa20
VZ
314#endif
315 AssignNewItemClientData(n, clientData, i, type);
316
317 if (incrementPos)
318 ++lIndexType;
fb9010ed 319 }
0e320a79 320
a236aa20
VZ
321 return n;
322} // end of wxListBox::DoInsertAppendItemsWithData
323
324void wxListBox::DoClear()
0e320a79 325{
fb9010ed 326#if wxUSE_OWNER_DRAWN
aa61d352 327 unsigned int lUiCount = m_aItems.Count();
49dc8caa
DW
328
329 while (lUiCount-- != 0)
330 {
331 delete m_aItems[lUiCount];
fb9010ed
DW
332 }
333
334 m_aItems.Clear();
a236aa20 335#endif // wxUSE_OWNER_DRAWN
49dc8caa 336 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
dcd307ee 337
49dc8caa
DW
338 m_nNumItems = 0;
339} // end of wxListBox::Clear
fb9010ed 340
8228b893 341void wxListBox::DoSetSelection( int N, bool bSelect)
0e320a79 342{
8228b893 343 wxCHECK_RET( IsValid(N),
fb9010ed 344 wxT("invalid index in wxListBox::SetSelection") );
49dc8caa
DW
345 ::WinSendMsg( GetHwnd()
346 ,LM_SELECTITEM
347 ,MPFROMLONG(N)
348 ,(MPARAM)bSelect
349 );
1de4baa3
DW
350 if(m_windowStyle & wxLB_OWNERDRAW)
351 Refresh();
49dc8caa
DW
352} // end of wxListBox::SetSelection
353
8228b893 354bool wxListBox::IsSelected( int N ) const
49dc8caa 355{
8228b893 356 wxCHECK_MSG( IsValid(N), false,
fb9010ed
DW
357 wxT("invalid index in wxListBox::Selected") );
358
49dc8caa 359 LONG lItem;
0e320a79 360
70a2c656
DW
361 if (GetWindowStyleFlag() & wxLB_EXTENDED)
362 {
363 if (N == 0)
364 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
365 else
366 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)(N - 1), (MPARAM)0));
367 }
368 else
369 {
370 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
371 }
372 return (lItem == (LONG)N && lItem != LIT_NONE);
49dc8caa
DW
373} // end of wxListBox::IsSelected
374
aa61d352 375void* wxListBox::DoGetItemClientData(unsigned int n) const
0e320a79 376{
8228b893 377 wxCHECK_MSG( IsValid(n), NULL,
fb9010ed
DW
378 wxT("invalid index in wxListBox::GetClientData") );
379
49dc8caa
DW
380 return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
381} // end of wxListBox::DoGetItemClientData
0e320a79 382
aa61d352 383void wxListBox::DoSetItemClientData(unsigned int n, void* pClientData)
dcd307ee 384{
8228b893 385 wxCHECK_RET( IsValid(n),
fb9010ed
DW
386 wxT("invalid index in wxListBox::SetClientData") );
387
dcd307ee
DW
388#if wxUSE_OWNER_DRAWN
389 if ( m_windowStyle & wxLB_OWNERDRAW )
390 {
49dc8caa
DW
391 //
392 // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
dcd307ee 393 // in OnMeasure/OnDraw.
49dc8caa 394 //
dcd307ee
DW
395 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
396 }
397#endif // wxUSE_OWNER_DRAWN
398
49dc8caa
DW
399 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
400} // end of wxListBox::DoSetItemClientData
dcd307ee
DW
401
402bool wxListBox::HasMultipleSelection() const
403{
404 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
49dc8caa 405} // end of wxListBox::HasMultipleSelection
0e320a79 406
6670f564 407int wxListBox::GetSelections( wxArrayInt& raSelections ) const
0e320a79 408{
8228b893
WS
409 int nCount = 0;
410 LONG lItem;
0e320a79 411
fb9010ed 412
49dc8caa
DW
413 raSelections.Empty();
414 if (HasMultipleSelection())
415 {
416 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
417 ,LM_QUERYSELECTION
418 ,(MPARAM)LIT_FIRST
419 ,(MPARAM)0
420 )
421 );
422 if (lItem != LIT_NONE)
423 {
424 nCount++;
425 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
426 ,LM_QUERYSELECTION
427 ,(MPARAM)lItem
428 ,(MPARAM)0
429 )
430 )) != LIT_NONE)
431 {
432 nCount++;
433 }
434 raSelections.Alloc(nCount);
435 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
436 ,LM_QUERYSELECTION
437 ,(MPARAM)LIT_FIRST
438 ,(MPARAM)0
439 )
440 );
441
442 raSelections.Add((int)lItem);
443 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
444 ,LM_QUERYSELECTION
445 ,(MPARAM)lItem
446 ,(MPARAM)0
447 )
448 )) != LIT_NONE)
449 {
450 raSelections.Add((int)lItem);
451 }
452 return nCount;
fb9010ed 453 }
0e320a79
DW
454 }
455 else // single-selection listbox
456 {
49dc8caa
DW
457 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
458 ,LM_QUERYSELECTION
459 ,(MPARAM)LIT_FIRST
460 ,(MPARAM)0
461 )
462 );
463 raSelections.Add((int)lItem);
0e320a79
DW
464 return 1;
465 }
dcd307ee 466 return 0;
49dc8caa 467} // end of wxListBox::GetSelections
0e320a79 468
0e320a79
DW
469int wxListBox::GetSelection() const
470{
dcd307ee 471 wxCHECK_MSG( !HasMultipleSelection(),
fb9010ed
DW
472 -1,
473 wxT("GetSelection() can't be used with multiple-selection "
474 "listboxes, use GetSelections() instead.") );
475
49dc8caa
DW
476 return(LONGFROMMR(::WinSendMsg( GetHwnd()
477 ,LM_QUERYSELECTION
478 ,(MPARAM)LIT_FIRST
479 ,(MPARAM)0
480 )
481 ));
482} // end of wxListBox::GetSelection
0e320a79 483
aa61d352 484wxString wxListBox::GetString(unsigned int n) const
0e320a79 485{
8228b893
WS
486 LONG lLen = 0;
487 wxChar* zBuf;
488 wxString sResult;
fb9010ed 489
aa61d352 490 wxCHECK_MSG( IsValid(n), wxEmptyString,
49dc8caa 491 wxT("invalid index in wxListBox::GetClientData") );
0e320a79 492
aa61d352 493 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
0fba44b4 494 zBuf = new wxChar[lLen + 1];
aa61d352 495 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)n, (SHORT)lLen), (MPARAM)zBuf);
49dc8caa
DW
496 zBuf[lLen] = '\0';
497 sResult = zBuf;
498 delete [] zBuf;
499 return sResult;
500} // end of wxListBox::GetString
501
aa61d352 502void wxListBox::SetString(unsigned int n, const wxString& rsString)
dcd307ee 503{
aa61d352 504 wxCHECK_RET( IsValid(n),
dcd307ee
DW
505 wxT("invalid index in wxListBox::SetString") );
506
49dc8caa
DW
507 //
508 // Remember the state of the item
509 //
aa61d352 510 bool bWasSelected = IsSelected(n);
8228b893
WS
511 void* pOldData = NULL;
512 wxClientData* pOldObjData = NULL;
49dc8caa 513
6d8eb95b 514 if ( HasClientUntypedData() )
aa61d352 515 pOldData = GetClientData(n);
6d8eb95b 516 else if ( HasClientObjectData() )
aa61d352 517 pOldObjData = GetClientObject(n);
49dc8caa
DW
518
519 //
520 // Delete and recreate it
521 //
522 ::WinSendMsg( GetHwnd()
523 ,LM_DELETEITEM
aa61d352 524 ,(MPARAM)n
49dc8caa
DW
525 ,(MPARAM)0
526 );
527
aa61d352 528 int nNewN = n;
49dc8caa 529
020e385d 530 if (n == (m_nNumItems - 1))
49dc8caa
DW
531 nNewN = -1;
532
533 ::WinSendMsg( GetHwnd()
534 ,LM_INSERTITEM
535 ,(MPARAM)nNewN
404aba09 536 ,(MPARAM)rsString.wx_str()
49dc8caa
DW
537 );
538
539 //
540 // Restore the client data
541 //
542 if (pOldData)
aa61d352 543 SetClientData(n, pOldData);
49dc8caa 544 else if (pOldObjData)
aa61d352 545 SetClientObject(n, pOldObjData);
49dc8caa
DW
546
547 //
548 // We may have lost the selection
549 //
550 if (bWasSelected)
aa61d352 551 Select(n);
dcd307ee
DW
552
553#if wxUSE_OWNER_DRAWN
49dc8caa
DW
554 if (m_windowStyle & wxLB_OWNERDRAW)
555 //
556 // Update item's text
557 //
aa61d352 558 m_aItems[n]->SetName(rsString);
dcd307ee 559#endif //USE_OWNER_DRAWN
49dc8caa 560} // end of wxListBox::SetString
dcd307ee 561
aa61d352 562unsigned int wxListBox::GetCount() const
dcd307ee 563{
49dc8caa 564 return m_nNumItems;
dcd307ee
DW
565}
566
567// ----------------------------------------------------------------------------
568// helpers
569// ----------------------------------------------------------------------------
570
e78c4d50 571wxSize wxListBox::DoGetBestSize() const
fb9010ed 572{
49dc8caa
DW
573 //
574 // Find the widest string
575 //
8228b893
WS
576 int nLine;
577 int nListbox = 0;
578 int nCx;
579 int nCy;
580 wxFont vFont = (wxFont)GetFont();
49dc8caa 581
aa61d352 582 for (unsigned int i = 0; i < m_nNumItems; i++)
fb9010ed 583 {
8228b893 584 wxString vStr(GetString(i));
49dc8caa 585
8228b893 586 GetTextExtent( vStr, &nLine, NULL );
49dc8caa
DW
587 if (nLine > nListbox)
588 nListbox = nLine;
fb9010ed
DW
589 }
590
49dc8caa
DW
591 //
592 // Give it some reasonable default value if there are no strings in the
593 // list.
594 //
595 if (nListbox == 0)
596 nListbox = 100;
597
598 //
599 // The listbox should be slightly larger than the widest string
600 //
601 wxGetCharSize( GetHWND()
602 ,&nCx
603 ,&nCy
0d598bae 604 ,&vFont
49dc8caa
DW
605 );
606 nListbox += 3 * nCx;
607
8228b893 608 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
49dc8caa
DW
609
610 return wxSize( nListbox
611 ,hListbox
612 );
613} // end of wxListBox::DoGetBestSize
fb9010ed 614
dcd307ee
DW
615// ----------------------------------------------------------------------------
616// callbacks
617// ----------------------------------------------------------------------------
618
49dc8caa
DW
619bool wxListBox::OS2Command(
620 WXUINT uParam
621, WXWORD WXUNUSED(wId))
0e320a79 622{
49dc8caa 623 wxEventType eEvtType;
dcd307ee 624
49dc8caa
DW
625 if (uParam == LN_SELECT)
626 {
627 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
dcd307ee 628 }
d6701f32 629 else if (uParam == LN_ENTER)
0e320a79 630 {
49dc8caa 631 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
0e320a79 632 }
fb9010ed 633 else
49dc8caa
DW
634 {
635 //
636 // Some event we're not interested in
637 //
ec157c8f 638 return false;
49dc8caa
DW
639 }
640 wxCommandEvent vEvent( eEvtType
641 ,m_windowId
642 );
fb9010ed 643
49dc8caa 644 vEvent.SetEventObject(this);
fb9010ed 645
8228b893
WS
646 wxArrayInt aSelections;
647 int n;
648 int nCount = GetSelections(aSelections);
fb9010ed 649
49dc8caa
DW
650 if (nCount > 0)
651 {
652 n = aSelections[0];
653 if (HasClientObjectData())
654 vEvent.SetClientObject(GetClientObject(n));
655 else if ( HasClientUntypedData() )
656 vEvent.SetClientData(GetClientData(n));
657 vEvent.SetString(GetString(n));
658 }
659 else
660 {
661 n = -1;
662 }
687706f5 663 vEvent.SetInt(n);
937013e0 664 return HandleWindowEvent(vEvent);
49dc8caa 665} // end of wxListBox::OS2Command
fb9010ed 666
dcd307ee
DW
667// ----------------------------------------------------------------------------
668// wxCheckListBox support
669// ----------------------------------------------------------------------------
fb9010ed
DW
670
671#if wxUSE_OWNER_DRAWN
672
49dc8caa
DW
673//
674// Drawing
fb9010ed 675// -------
49dc8caa 676//
fb9010ed
DW
677#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
678
8228b893 679long wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT* pItem)
fb9010ed 680{
1de4baa3
DW
681 if (!pItem)
682 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
683
684 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
685 wxScreenDC vDc;
686
49dc8caa 687 //
1de4baa3 688 // Only owner-drawn control should receive this message
49dc8caa 689 //
1de4baa3
DW
690 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
691
692 vDc.SetFont(GetFont());
693
694 wxCoord vHeight;
f5ea767e
DW
695 wxCoord vWidth;
696
697 GetSize( &vWidth
698 ,NULL
699 );
1de4baa3 700
f5ea767e 701 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
1de4baa3
DW
702 pMeasureStruct->rclItem.xLeft = 0;
703 pMeasureStruct->rclItem.yTop = 0;
704 pMeasureStruct->rclItem.yBottom = 0;
705
9923c37d 706 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
f5ea767e 707 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
1de4baa3 708
f5ea767e 709 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
1de4baa3 710} // end of wxListBox::OS2OnMeasure
fb9010ed 711
1de4baa3
DW
712bool wxListBox::OS2OnDraw (
713 WXDRAWITEMSTRUCT* pItem
714)
fb9010ed 715{
1de4baa3
DW
716 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
717 LONG lItemID = pDrawStruct->idItem;
718 int eAction = 0;
719 int eStatus = 0;
720
49dc8caa 721 //
1de4baa3 722 // Only owner-drawn control should receive this message
49dc8caa 723 //
ec157c8f 724 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), false);
1de4baa3
DW
725
726
727 //
728 // The item may be -1 for an empty listbox
729 //
730 if (lItemID == -1L)
ec157c8f 731 return false;
1de4baa3
DW
732
733 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
734 ,LM_QUERYITEMHANDLE
735 ,MPFROMLONG(pDrawStruct->idItem)
736 ,(MPARAM)0
737 )
738 );
739
ec157c8f 740 wxCHECK(pData, false );
1de4baa3 741
38400bb4
SN
742 wxClientDC vDc(this);
743 wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl();
6670f564
WS
744 wxPoint pt1( pDrawStruct->rclItem.xLeft, pDrawStruct->rclItem.yTop );
745 wxPoint pt2( pDrawStruct->rclItem.xRight, pDrawStruct->rclItem.yBottom );
746 wxRect vRect( pt1, pt2 );
1de4baa3 747
38400bb4 748 impl->SetHPS(pDrawStruct->hps);
1de4baa3
DW
749
750 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
751 {
752 //
753 // Entire Item needs to be redrawn (either it has reappeared from
754 // behind another window or is being displayed for the first time
755 //
756 eAction = wxOwnerDrawn::wxODDrawAll;
757
758 if (pDrawStruct->fsAttribute & MIA_HILITED)
759 {
760 //
761 // If it is currently selected we let the system handle it
762 //
763 eStatus |= wxOwnerDrawn::wxODSelected;
764 }
765 if (pDrawStruct->fsAttribute & MIA_CHECKED)
766 {
767 //
768 // If it is currently checked we draw our own
769 //
770 eStatus |= wxOwnerDrawn::wxODChecked;
771 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
772 }
773 if (pDrawStruct->fsAttribute & MIA_DISABLED)
774 {
775 //
776 // If it is currently disabled we let the system handle it
777 //
778 eStatus |= wxOwnerDrawn::wxODDisabled;
779 }
780 //
781 // Don't really care about framed (indicationg focus) or NoDismiss
782 //
783 }
784 else
785 {
786 if (pDrawStruct->fsAttribute & MIA_HILITED)
787 {
788 eAction = wxOwnerDrawn::wxODDrawAll;
789 eStatus |= wxOwnerDrawn::wxODSelected;
790 //
791 // Keep the system from trying to highlight with its bogus colors
792 //
793 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
794 }
795 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
796 {
797 eAction = wxOwnerDrawn::wxODDrawAll;
798 eStatus = 0;
799 //
800 // Keep the system from trying to highlight with its bogus colors
801 //
802 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
803 }
804 else
805 {
806 //
807 // For now we don't care about anything else
808 // just ignore the entire message!
809 //
ec157c8f 810 return true;
1de4baa3
DW
811 }
812 }
813 return pData->OnDrawItem( vDc
814 ,vRect
815 ,(wxOwnerDrawn::wxODAction)eAction
816 ,(wxOwnerDrawn::wxODStatus)eStatus
817 );
818} // end of wxListBox::OS2OnDraw
819
49dc8caa
DW
820#endif // ndef for wxUSE_OWNER_DRAWN
821
8228b893 822#endif // wxUSE_LISTBOX