1 /////////////////////////////////////////////////////////////////////////////// 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  15 #include "wx/window.h" 
  16 #include "wx/os2/private.h" 
  19 #include "wx/listbox.h" 
  20 #include "wx/settings.h" 
  24 #include "wx/dcscreen.h" 
  26 #include "wx/scrolwin.h" 
  32 #include "wx/dynarray.h" 
  38     #include  "wx/ownerdrw.h" 
  41   IMPLEMENT_DYNAMIC_CLASS(wxListBox
, wxControl
) 
  43 // ============================================================================ 
  44 // list box item declaration and implementation 
  45 // ============================================================================ 
  49 class wxListBoxItem 
: public wxOwnerDrawn
 
  52     wxListBoxItem(const wxString
& rsStr 
= ""); 
  55 wxListBoxItem::wxListBoxItem( 
  63     // No bitmaps/checkmarks 
  66 } // end of wxListBoxItem::wxListBoxItem 
  68 wxOwnerDrawn
* wxListBox::CreateItem( 
  72     return new wxListBoxItem(); 
  73 } // end of wxListBox::CreateItem 
  75 #endif  //USE_OWNER_DRAWN 
  77 // ============================================================================ 
  78 // list box control implementation 
  79 // ============================================================================ 
  82 wxListBox::wxListBox() 
  86 } // end of wxListBox::wxListBox 
  88 bool wxListBox::Create( 
  93 , const wxArrayString
&              asChoices
 
  95 , const wxValidator
&                rValidator
 
  96 , const wxString
&                   rsName
 
  99     wxCArrayString 
chs(asChoices
); 
 101     return Create(pParent
, vId
, rPos
, rSize
, chs
.GetCount(), chs
.GetStrings(), 
 102                   lStyle
, rValidator
, rsName
); 
 105 bool wxListBox::Create( 
 108 , const wxPoint
&                    rPos
 
 109 , const wxSize
&                     rSize
 
 111 , const wxString                    asChoices
[] 
 113 , const wxValidator
&                rValidator
 
 114 , const wxString
&                   rsName
 
 123     SetValidator(rValidator
); 
 127         pParent
->AddChild(this); 
 129     wxSystemSettings                vSettings
; 
 131     SetBackgroundColour(vSettings
.GetSystemColour(wxSYS_COLOUR_WINDOW
)); 
 132     SetForegroundColour(pParent
->GetForegroundColour()); 
 134     m_windowId 
= (vId 
== -1) ? (int)NewControlId() : vId
; 
 138     int                             nWidth  
= rSize
.x
; 
 139     int                             nHeight 
= rSize
.y
; 
 141     m_windowStyle 
= lStyle
; 
 145     if (m_windowStyle 
& wxCLIP_SIBLINGS 
) 
 146         lStyle 
|= WS_CLIPSIBLINGS
; 
 147     if (m_windowStyle 
& wxLB_MULTIPLE
) 
 148         lStyle 
|= LS_MULTIPLESEL
; 
 149     else if (m_windowStyle 
& wxLB_EXTENDED
) 
 150         lStyle 
|= LS_EXTENDEDSEL
; 
 151     if (m_windowStyle 
& wxLB_HSCROLL
) 
 152         lStyle 
|= LS_HORZSCROLL
; 
 153     if (m_windowStyle 
& wxLB_OWNERDRAW
) 
 154         lStyle 
|= LS_OWNERDRAW
; 
 157     // Without this style, you get unexpected heights, so e.g. constraint layout 
 158     // doesn't work properly 
 160     lStyle 
|= LS_NOADJUSTPOS
; 
 162     m_hWnd 
= (WXHWND
)::WinCreateWindow( GetWinHwnd(pParent
) // Parent 
 163                                        ,WC_LISTBOX          
// Default Listbox class 
 164                                        ,"LISTBOX"           // Control's name 
 165                                        ,lStyle              
// Initial Style 
 166                                        ,0, 0, 0, 0          // Position and size 
 167                                        ,GetWinHwnd(pParent
) // Owner 
 169                                        ,(HMENU
)m_windowId   
// Id 
 170                                        ,NULL                
// Control Data 
 171                                        ,NULL                
// Presentation Parameters 
 179     // Subclass again for purposes of dialog editing mode 
 185     for (lUi 
= 0; lUi 
< (LONG
)n
; lUi
++) 
 187         Append(asChoices
[lUi
]); 
 189     wxFont
*                          pTextFont 
= new wxFont( 10 
 197     // Set standard wxWidgets colors for Listbox items and highlighting 
 201     vColour
.Set(wxString("WHITE")); 
 203     LONG                            lColor 
= (LONG
)vColour
.GetPixel(); 
 205     ::WinSetPresParam( m_hWnd
 
 206                       ,PP_HILITEFOREGROUNDCOLOR
 
 210     vColour
.Set(wxString("NAVY")); 
 211     lColor 
= (LONG
)vColour
.GetPixel(); 
 212     ::WinSetPresParam( m_hWnd
 
 213                       ,PP_HILITEBACKGROUNDCOLOR
 
 225 } // end of wxListBox::Create 
 227 wxListBox::~wxListBox() 
 229 #if wxUSE_OWNER_DRAWN 
 230     size_t                          lUiCount 
= m_aItems
.Count(); 
 232     while (lUiCount
-- != 0) 
 234         delete m_aItems
[lUiCount
]; 
 236 #endif // wxUSE_OWNER_DRAWN 
 237 } // end of wxListBox::~wxListBox 
 239 void wxListBox::SetupColours() 
 241     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 242     SetForegroundColour(GetParent()->GetForegroundColour()); 
 243 } // end of wxListBox::SetupColours 
 245 // ---------------------------------------------------------------------------- 
 246 // implementation of wxListBoxBase methods 
 247 // ---------------------------------------------------------------------------- 
 249 void wxListBox::DoSetFirstItem( 
 253     wxCHECK_RET( N 
>= 0 && N 
< m_nNumItems
, 
 254                  wxT("invalid index in wxListBox::SetFirstItem") ); 
 256     ::WinSendMsg(GetHwnd(), LM_SETTOPINDEX
, MPFROMLONG(N
), (MPARAM
)0); 
 257 } // end of wxListBox::DoSetFirstItem 
 259 void wxListBox::Delete( 
 263     wxCHECK_RET( N 
>= 0 && N 
< m_nNumItems
, 
 264                  wxT("invalid index in wxListBox::Delete") ); 
 266 #if wxUSE_OWNER_DRAWN 
 268     m_aItems
.RemoveAt(N
); 
 269 #else // !wxUSE_OWNER_DRAWN 
 270     if (HasClientObjectData()) 
 272         delete GetClientObject(N
); 
 274 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN 
 276     ::WinSendMsg(GetHwnd(), LM_DELETEITEM
, (MPARAM
)N
, (MPARAM
)0); 
 278 } // end of wxListBox::DoSetFirstItem 
 280 int wxListBox::DoAppend( 
 281   const wxString
&                   rsItem
 
 287     if (m_windowStyle 
& wxLB_SORT
) 
 288         lIndexType 
= LIT_SORTASCENDING
; 
 290         lIndexType 
= LIT_END
; 
 291     lIndex 
= (long)::WinSendMsg(GetHwnd(), LM_INSERTITEM
, (MPARAM
)lIndexType
, (MPARAM
)rsItem
.c_str()); 
 294 #if wxUSE_OWNER_DRAWN 
 295     if (m_windowStyle 
& wxLB_OWNERDRAW
) 
 297         wxOwnerDrawn
*               pNewItem 
= CreateItem(lIndex
); // dummy argument 
 301         pNewItem
->SetName(rsItem
); 
 302         m_aItems
.Insert(pNewItem
, lIndex
); 
 303         ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE
, (MPARAM
)lIndex
, MPFROMP(pNewItem
)); 
 304         pNewItem
->SetFont(GetFont()); 
 308 } // end of wxListBox::DoAppend 
 310 void wxListBox::DoSetItems( 
 311   const wxArrayString
&              raChoices
 
 312 , void**                            ppClientData
 
 315     BOOL                            bHideAndShow 
= IsShown(); 
 321         ::WinShowWindow(GetHwnd(), FALSE
); 
 323     ::WinSendMsg(GetHwnd(), LM_DELETEALL
, (MPARAM
)0, (MPARAM
)0); 
 324     m_nNumItems 
= raChoices
.GetCount(); 
 325     for (i 
= 0; i 
< m_nNumItems
; i
++) 
 328         if (m_windowStyle 
& wxLB_SORT
) 
 329             lIndexType 
= LIT_SORTASCENDING
; 
 331             lIndexType 
= LIT_END
; 
 332         ::WinSendMsg(GetHwnd(), LM_INSERTITEM
, (MPARAM
)lIndexType
, (MPARAM
)raChoices
[i
].c_str()); 
 336 #if wxUSE_OWNER_DRAWN 
 337             wxASSERT_MSG(ppClientData
[i
] == NULL
, 
 338                          wxT("Can't use client data with owner-drawn listboxes")); 
 339 #else // !wxUSE_OWNER_DRAWN 
 340             ::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE
, MPFROMLONG(lCount
), MPFROMP(ppClientData
[i
])); 
 341 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN 
 345 #if wxUSE_OWNER_DRAWN 
 346     if ( m_windowStyle 
& wxLB_OWNERDRAW 
) 
 349         // First delete old items 
 351         WX_CLEAR_ARRAY(m_aItems
); 
 354         // Then create new ones 
 356         for (size_t ui 
= 0; ui 
< (size_t)m_nNumItems
; ui
++) 
 358             wxOwnerDrawn
*           pNewItem 
= CreateItem(ui
); 
 360             pNewItem
->SetName(raChoices
[ui
]); 
 361             m_aItems
.Add(pNewItem
); 
 362             ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE
, MPFROMLONG(ui
), MPFROMP(pNewItem
)); 
 365 #endif // wxUSE_OWNER_DRAWN 
 366     ::WinShowWindow(GetHwnd(), TRUE
); 
 367 } // end of wxListBox::DoSetItems 
 369 int wxListBox::FindString( 
 370   const wxString
&                   rsString
 
 378     for (nPos 
= 0; nPos 
< m_nNumItems
; nPos
++) 
 380         lTextLength 
= LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH
, (MPARAM
)nPos
, (MPARAM
)0)); 
 381         zStr 
= new char[lTextLength 
+ 1]; 
 382         ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT
, MPFROM2SHORT(nPos
, (SHORT
)lTextLength
), (MPARAM
)zStr
); 
 383         if (rsString 
== (char*)zStr
) 
 391 } // end of wxListBox::FindString 
 393 void wxListBox::Clear() 
 395 #if wxUSE_OWNER_DRAWN 
 396     size_t                          lUiCount 
= m_aItems
.Count(); 
 398     while (lUiCount
-- != 0) 
 400         delete m_aItems
[lUiCount
]; 
 404 #else // !wxUSE_OWNER_DRAWN 
 405     if (HasClientObjectData()) 
 407         for (size_t n 
= 0; n 
< (size_t)m_lNumItems
; n
++) 
 409             delete GetClientObject(n
); 
 412 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN 
 413     ::WinSendMsg(GetHwnd(), LM_DELETEALL
, (MPARAM
)0, (MPARAM
)0); 
 416 } // end of wxListBox::Clear 
 418 void wxListBox::SetSelection( 
 423     wxCHECK_RET( N 
>= 0 && N 
< m_nNumItems
, 
 424                  wxT("invalid index in wxListBox::SetSelection") ); 
 425     ::WinSendMsg( GetHwnd() 
 430     if(m_windowStyle 
& wxLB_OWNERDRAW
) 
 432 } // end of wxListBox::SetSelection 
 434 bool wxListBox::IsSelected( 
 438     wxCHECK_MSG( N 
>= 0 && N 
< m_nNumItems
, FALSE
, 
 439                  wxT("invalid index in wxListBox::Selected") ); 
 443     if (GetWindowStyleFlag() & wxLB_EXTENDED
) 
 446             lItem 
= LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION
, (MPARAM
)LIT_FIRST
, (MPARAM
)0)); 
 448             lItem 
= LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION
, (MPARAM
)(N 
- 1), (MPARAM
)0)); 
 452         lItem 
= LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION
, (MPARAM
)LIT_FIRST
, (MPARAM
)0)); 
 454     return (lItem 
== (LONG
)N 
&& lItem 
!= LIT_NONE
); 
 455 } // end of wxListBox::IsSelected 
 457 wxClientData
* wxListBox::DoGetItemClientObject( 
 461     return (wxClientData 
*)DoGetItemClientData(n
); 
 464 void* wxListBox::DoGetItemClientData( 
 468     wxCHECK_MSG( n 
>= 0 && n 
< m_nNumItems
, NULL
, 
 469                  wxT("invalid index in wxListBox::GetClientData") ); 
 471     return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE
, MPFROMLONG(n
), (MPARAM
)0)); 
 472 } // end of wxListBox::DoGetItemClientData 
 474 void wxListBox::DoSetItemClientObject( 
 476 , wxClientData
*                     pClientData
 
 479     DoSetItemClientData( n
 
 482 } // end of wxListBox::DoSetItemClientObject 
 484 void wxListBox::DoSetItemClientData( 
 489     wxCHECK_RET( n 
>= 0 && n 
< m_nNumItems
, 
 490                  wxT("invalid index in wxListBox::SetClientData") ); 
 492 #if wxUSE_OWNER_DRAWN 
 493     if ( m_windowStyle 
& wxLB_OWNERDRAW 
) 
 496         // Client data must be pointer to wxOwnerDrawn, otherwise we would crash 
 497         // in OnMeasure/OnDraw. 
 499         wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes")); 
 501 #endif // wxUSE_OWNER_DRAWN 
 503     ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE
, MPFROMLONG(n
), MPFROMP(pClientData
)); 
 504 } // end of wxListBox::DoSetItemClientData 
 506 bool wxListBox::HasMultipleSelection() const 
 508     return (m_windowStyle 
& wxLB_MULTIPLE
) || (m_windowStyle 
& wxLB_EXTENDED
); 
 509 } // end of wxListBox::HasMultipleSelection 
 511 int wxListBox::GetSelections( 
 512   wxArrayInt
&                       raSelections
 
 519     raSelections
.Empty(); 
 520     if (HasMultipleSelection()) 
 522         lItem 
= LONGFROMMR(::WinSendMsg( GetHwnd() 
 528         if (lItem 
!= LIT_NONE
) 
 531             while ((lItem 
= LONGFROMMR(::WinSendMsg( GetHwnd() 
 540             raSelections
.Alloc(nCount
); 
 541             lItem 
= LONGFROMMR(::WinSendMsg( GetHwnd() 
 548             raSelections
.Add((int)lItem
); 
 549             while ((lItem 
= LONGFROMMR(::WinSendMsg( GetHwnd() 
 556                 raSelections
.Add((int)lItem
); 
 562     else  // single-selection listbox 
 564         lItem 
= LONGFROMMR(::WinSendMsg( GetHwnd() 
 570         raSelections
.Add((int)lItem
); 
 574 } // end of wxListBox::GetSelections 
 576 int wxListBox::GetSelection() const 
 578     wxCHECK_MSG( !HasMultipleSelection(), 
 580                  wxT("GetSelection() can't be used with multiple-selection " 
 581                     "listboxes, use GetSelections() instead.") ); 
 583     return(LONGFROMMR(::WinSendMsg( GetHwnd() 
 589 } // end of wxListBox::GetSelection 
 591 wxString 
wxListBox::GetString( 
 599     wxCHECK_MSG( N 
>= 0 && N 
< m_nNumItems
, "", 
 600                  wxT("invalid index in wxListBox::GetClientData") ); 
 602     lLen 
= LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH
, (MPARAM
)N
, (MPARAM
)0)); 
 603     zBuf 
= new char[lLen 
+ 1]; 
 604     ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT
, MPFROM2SHORT((SHORT
)N
, (SHORT
)lLen
), (MPARAM
)zBuf
); 
 609 } // end of wxListBox::GetString 
 611 void wxListBox::DoInsertItems( 
 612   const wxArrayString
&              asItems
 
 616     wxCHECK_RET( nPos 
>= 0 && nPos 
<= m_nNumItems
, 
 617                  wxT("invalid index in wxListBox::InsertItems") ); 
 619     int                             nItems 
= asItems
.GetCount(); 
 621     for (int i 
= 0; i 
< nItems
; i
++) 
 623         int                         nIndex 
= (int)::WinSendMsg( GetHwnd() 
 625                                                                ,MPFROMLONG((LONG
)(i 
+ nPos
)) 
 626                                                                ,(MPARAM
)asItems
[i
].c_str() 
 629         wxOwnerDrawn
*               pNewItem 
= CreateItem(nIndex
); 
 631         pNewItem
->SetName(asItems
[i
]); 
 632         pNewItem
->SetFont(GetFont()); 
 633         m_aItems
.Insert(pNewItem
, nIndex
); 
 634         ::WinSendMsg( GetHwnd() 
 636                      ,(MPARAM
)((LONG
)nIndex
) 
 639         m_nNumItems 
+= nItems
; 
 641 } // end of wxListBox::DoInsertItems 
 643 void wxListBox::SetString( 
 645 , const wxString
&                   rsString
 
 648     wxCHECK_RET( N 
>= 0 && N 
< m_nNumItems
, 
 649                  wxT("invalid index in wxListBox::SetString") ); 
 652     // Remember the state of the item 
 654     bool                            bWasSelected 
= IsSelected(N
); 
 655     void*                           pOldData 
= NULL
; 
 656     wxClientData
*                   pOldObjData 
= NULL
; 
 658     if (m_clientDataItemsType 
== wxClientData_Void
) 
 659         pOldData 
= GetClientData(N
); 
 660     else if (m_clientDataItemsType 
== wxClientData_Object
) 
 661         pOldObjData 
= GetClientObject(N
); 
 664     // Delete and recreate it 
 666     ::WinSendMsg( GetHwnd() 
 674     if (N 
== m_nNumItems 
- 1) 
 677     ::WinSendMsg( GetHwnd() 
 680                  ,(MPARAM
)rsString
.c_str() 
 684     // Restore the client data 
 690     else if (pOldObjData
) 
 696     // We may have lost the selection 
 701 #if wxUSE_OWNER_DRAWN 
 702     if (m_windowStyle 
& wxLB_OWNERDRAW
) 
 704         // Update item's text 
 706         m_aItems
[N
]->SetName(rsString
); 
 707 #endif  //USE_OWNER_DRAWN 
 708 } // end of wxListBox::SetString 
 710 int wxListBox::GetCount() const 
 715 // ---------------------------------------------------------------------------- 
 717 // ---------------------------------------------------------------------------- 
 719 wxSize 
wxListBox::DoGetBestSize() const 
 722     // Find the widest string 
 729     for (int i 
= 0; i 
< m_nNumItems
; i
++) 
 731         wxString                    
vStr(GetString(i
)); 
 737         if (nLine 
> nListbox
) 
 742     // Give it some reasonable default value if there are no strings in the 
 749     // The listbox should be slightly larger than the widest string 
 751     wxGetCharSize( GetHWND() 
 758     int                             hListbox 
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy
) * (wxMax(m_nNumItems
, 7)); 
 760     return wxSize( nListbox
 
 763 } // end of wxListBox::DoGetBestSize 
 765 // ---------------------------------------------------------------------------- 
 767 // ---------------------------------------------------------------------------- 
 769 bool wxListBox::OS2Command( 
 771 , WXWORD                            
WXUNUSED(wId
)) 
 773     wxEventType                     eEvtType
; 
 775     if (uParam 
== LN_SELECT
) 
 777         eEvtType 
= wxEVT_COMMAND_LISTBOX_SELECTED
; 
 779     if (uParam 
== LN_ENTER
) 
 781         eEvtType 
= wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
; 
 786         // Some event we're not interested in 
 790     wxCommandEvent                  
vEvent( eEvtType
 
 794     vEvent
.SetEventObject(this); 
 796     wxArrayInt                      aSelections
; 
 798     int                             nCount 
= GetSelections(aSelections
); 
 803         if (HasClientObjectData()) 
 804             vEvent
.SetClientObject(GetClientObject(n
)); 
 805         else if ( HasClientUntypedData() ) 
 806             vEvent
.SetClientData(GetClientData(n
)); 
 807         vEvent
.SetString(GetString(n
)); 
 813     vEvent
.m_commandInt 
= n
; 
 814     return GetEventHandler()->ProcessEvent(vEvent
); 
 815 } // end of wxListBox::OS2Command 
 817 // ---------------------------------------------------------------------------- 
 818 // wxCheckListBox support 
 819 // ---------------------------------------------------------------------------- 
 821 #if wxUSE_OWNER_DRAWN 
 827 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE    (1) 
 829 long wxListBox::OS2OnMeasure( 
 830   WXMEASUREITEMSTRUCT
*              pItem
 
 834         pItem 
= (WXMEASUREITEMSTRUCT
*)new OWNERITEM
; 
 836     POWNERITEM                      pMeasureStruct 
= (POWNERITEM
)pItem
; 
 840     // Only owner-drawn control should receive this message 
 842     wxCHECK( ((m_windowStyle 
& wxLB_OWNERDRAW
) == wxLB_OWNERDRAW
), FALSE 
); 
 844     vDc
.SetFont(GetFont()); 
 853     pMeasureStruct
->rclItem
.xRight 
= (USHORT
)vWidth
; 
 854     pMeasureStruct
->rclItem
.xLeft  
= 0; 
 855     pMeasureStruct
->rclItem
.yTop   
= 0; 
 856     pMeasureStruct
->rclItem
.yBottom 
= 0; 
 858     vHeight 
= (wxCoord
)(vDc
.GetCharHeight() * 2.5); 
 859     pMeasureStruct
->rclItem
.yTop  
= (USHORT
)vHeight
; 
 861     return long(MRFROM2SHORT((USHORT
)vHeight
, (USHORT
)vWidth
)); 
 862 } // end of wxListBox::OS2OnMeasure 
 864 bool wxListBox::OS2OnDraw ( 
 865   WXDRAWITEMSTRUCT
*                 pItem
 
 868     POWNERITEM                      pDrawStruct 
= (POWNERITEM
)pItem
; 
 869     LONG                            lItemID 
= pDrawStruct
->idItem
; 
 874     // Only owner-drawn control should receive this message 
 876     wxCHECK(((m_windowStyle 
& wxLB_OWNERDRAW
) == wxLB_OWNERDRAW
), FALSE
); 
 880     // The item may be -1 for an empty listbox 
 885     wxListBoxItem
*                   pData 
= (wxListBoxItem
*)PVOIDFROMMR( ::WinSendMsg( GetHwnd() 
 887                                                                                        ,MPFROMLONG(pDrawStruct
->idItem
) 
 892     wxCHECK(pData
, FALSE 
); 
 895     wxRect                            
vRect( wxPoint( pDrawStruct
->rclItem
.xLeft
 
 896                                                      ,pDrawStruct
->rclItem
.yTop
 
 898                                             ,wxPoint( pDrawStruct
->rclItem
.xRight
 
 899                                                      ,pDrawStruct
->rclItem
.yBottom
 
 903     vDc
.SetHPS(pDrawStruct
->hps
); 
 905     if (pDrawStruct
->fsAttribute 
== pDrawStruct
->fsAttributeOld
) 
 908         // Entire Item needs to be redrawn (either it has reappeared from 
 909         // behind another window or is being displayed for the first time 
 911         eAction 
= wxOwnerDrawn::wxODDrawAll
; 
 913         if (pDrawStruct
->fsAttribute 
& MIA_HILITED
) 
 916             // If it is currently selected we let the system handle it 
 918             eStatus 
|= wxOwnerDrawn::wxODSelected
; 
 920         if (pDrawStruct
->fsAttribute 
& MIA_CHECKED
) 
 923             // If it is currently checked we draw our own 
 925             eStatus 
|= wxOwnerDrawn::wxODChecked
; 
 926             pDrawStruct
->fsAttributeOld 
= pDrawStruct
->fsAttribute 
&= ~MIA_CHECKED
; 
 928         if (pDrawStruct
->fsAttribute 
& MIA_DISABLED
) 
 931             // If it is currently disabled we let the system handle it 
 933             eStatus 
|= wxOwnerDrawn::wxODDisabled
; 
 936         // Don't really care about framed (indicationg focus) or NoDismiss 
 941         if (pDrawStruct
->fsAttribute 
& MIA_HILITED
) 
 943             eAction 
= wxOwnerDrawn::wxODDrawAll
; 
 944             eStatus 
|= wxOwnerDrawn::wxODSelected
; 
 946             // Keep the system from trying to highlight with its bogus colors 
 948             pDrawStruct
->fsAttributeOld 
= pDrawStruct
->fsAttribute 
&= ~MIA_HILITED
; 
 950         else if (!(pDrawStruct
->fsAttribute 
& MIA_HILITED
)) 
 952             eAction 
= wxOwnerDrawn::wxODDrawAll
; 
 955             // Keep the system from trying to highlight with its bogus colors 
 957             pDrawStruct
->fsAttribute 
= pDrawStruct
->fsAttributeOld 
&= ~MIA_HILITED
; 
 962             // For now we don't care about anything else 
 963             // just ignore the entire message! 
 968     return pData
->OnDrawItem( vDc
 
 970                              ,(wxOwnerDrawn::wxODAction
)eAction
 
 971                              ,(wxOwnerDrawn::wxODStatus
)eStatus
 
 973 } // end of wxListBox::OS2OnDraw 
 975 #endif // ndef for wxUSE_OWNER_DRAWN 
 977 #endif // ndef for wxUSE_LISTBOX