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