]> git.saurik.com Git - wxWidgets.git/blob - src/os2/listbox.cpp
Add wxCairoLibrary (not yet built)
[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/listbox.h"
18
19 #ifndef WX_PRECOMP
20     #include "wx/dynarray.h"
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"
28     #include "wx/log.h"
29     #include "wx/window.h"
30 #endif
31
32 #include "wx/os2/private.h"
33
34 #define INCL_M
35 #include <os2.h>
36
37 #if wxUSE_OWNER_DRAWN
38     #include  "wx/ownerdrw.h"
39 #endif
40
41 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControlWithItems)
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::DoDeleteOneItem(unsigned 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 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
264
265     ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
266     m_nNumItems--;
267 } // end of wxListBox::DoSetFirstItem
268
269 int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items,
270                              unsigned int pos,
271                              void **clientData,
272                              wxClientDataType type)
273 {
274     long lIndex = 0;
275     LONG lIndexType = 0;
276     bool incrementPos = false;
277
278     if (IsSorted())
279         lIndexType = LIT_SORTASCENDING;
280     else if (pos == GetCount())
281         lIndexType = LIT_END;
282     else
283     {
284         lIndexType = (LONG)pos;
285         incrementPos = true;
286     }
287
288     int n = wxNOT_FOUND;
289
290     unsigned int count = items.GetCount();
291     for (unsigned int i = 0; i < count; i++)
292     {
293         n = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)items[i].wx_str());
294         if (n < 0)
295         {
296             wxLogLastError(_T("WinSendMsg(LM_INSERTITEM)"));
297             n = wxNOT_FOUND;
298             break;
299         }
300         ++m_nNumItems;
301
302 #if wxUSE_OWNER_DRAWN
303         if (HasFlag(wxLB_OWNERDRAW))
304         {
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());
312         }
313 #endif
314         AssignNewItemClientData(n, clientData, i, type);
315
316         if (incrementPos)
317             ++lIndexType;
318     }
319
320     return n;
321 } // end of wxListBox::DoInsertAppendItemsWithData
322
323 void wxListBox::DoClear()
324 {
325 #if wxUSE_OWNER_DRAWN
326     unsigned int lUiCount = m_aItems.Count();
327
328     while (lUiCount-- != 0)
329     {
330         delete m_aItems[lUiCount];
331     }
332
333     m_aItems.Clear();
334 #endif // wxUSE_OWNER_DRAWN
335     ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
336
337     m_nNumItems = 0;
338 } // end of wxListBox::Clear
339
340 void wxListBox::DoSetSelection( int N, bool bSelect)
341 {
342     wxCHECK_RET( IsValid(N),
343                  wxT("invalid index in wxListBox::SetSelection") );
344     ::WinSendMsg( GetHwnd()
345                  ,LM_SELECTITEM
346                  ,MPFROMLONG(N)
347                  ,(MPARAM)bSelect
348                 );
349     if(m_windowStyle & wxLB_OWNERDRAW)
350         Refresh();
351 } // end of wxListBox::SetSelection
352
353 bool wxListBox::IsSelected( int N ) const
354 {
355     wxCHECK_MSG( IsValid(N), false,
356                  wxT("invalid index in wxListBox::Selected") );
357
358     LONG                            lItem;
359
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);
372 } // end of wxListBox::IsSelected
373
374 void* wxListBox::DoGetItemClientData(unsigned int n) const
375 {
376     wxCHECK_MSG( IsValid(n), NULL,
377                  wxT("invalid index in wxListBox::GetClientData") );
378
379     return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
380 } // end of wxListBox::DoGetItemClientData
381
382 void wxListBox::DoSetItemClientData(unsigned int n, void* pClientData)
383 {
384     wxCHECK_RET( IsValid(n),
385                  wxT("invalid index in wxListBox::SetClientData") );
386
387 #if wxUSE_OWNER_DRAWN
388     if ( m_windowStyle & wxLB_OWNERDRAW )
389     {
390         //
391         // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
392         // in OnMeasure/OnDraw.
393         //
394         wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
395     }
396 #endif // wxUSE_OWNER_DRAWN
397
398     ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
399 } // end of wxListBox::DoSetItemClientData
400
401 bool wxListBox::HasMultipleSelection() const
402 {
403     return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
404 } // end of wxListBox::HasMultipleSelection
405
406 int wxListBox::GetSelections( wxArrayInt& raSelections ) const
407 {
408     int  nCount = 0;
409     LONG lItem;
410
411
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;
452         }
453     }
454     else  // single-selection listbox
455     {
456         lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
457                                         ,LM_QUERYSELECTION
458                                         ,(MPARAM)LIT_FIRST
459                                         ,(MPARAM)0
460                                        )
461                           );
462         raSelections.Add((int)lItem);
463         return 1;
464     }
465     return 0;
466 } // end of wxListBox::GetSelections
467
468 int wxListBox::GetSelection() const
469 {
470     wxCHECK_MSG( !HasMultipleSelection(),
471                  -1,
472                  wxT("GetSelection() can't be used with multiple-selection "
473                     "listboxes, use GetSelections() instead.") );
474
475     return(LONGFROMMR(::WinSendMsg( GetHwnd()
476                                    ,LM_QUERYSELECTION
477                                    ,(MPARAM)LIT_FIRST
478                                    ,(MPARAM)0
479                                   )
480                      ));
481 } // end of wxListBox::GetSelection
482
483 wxString wxListBox::GetString(unsigned int n) const
484 {
485     LONG     lLen = 0;
486     wxChar*  zBuf;
487     wxString sResult;
488
489     wxCHECK_MSG( IsValid(n), wxEmptyString,
490                  wxT("invalid index in wxListBox::GetClientData") );
491
492     lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
493     zBuf = new wxChar[lLen + 1];
494     ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)n, (SHORT)lLen), (MPARAM)zBuf);
495     zBuf[lLen] = '\0';
496     sResult = zBuf;
497     delete [] zBuf;
498     return sResult;
499 } // end of wxListBox::GetString
500
501 void wxListBox::SetString(unsigned int n, const wxString& rsString)
502 {
503     wxCHECK_RET( IsValid(n),
504                  wxT("invalid index in wxListBox::SetString") );
505
506     //
507     // Remember the state of the item
508     //
509     bool           bWasSelected = IsSelected(n);
510     void*          pOldData = NULL;
511     wxClientData*  pOldObjData = NULL;
512
513     if (m_clientDataItemsType == wxClientData_Void)
514         pOldData = GetClientData(n);
515     else if (m_clientDataItemsType == wxClientData_Object)
516         pOldObjData = GetClientObject(n);
517
518     //
519     // Delete and recreate it
520     //
521     ::WinSendMsg( GetHwnd()
522                  ,LM_DELETEITEM
523                  ,(MPARAM)n
524                  ,(MPARAM)0
525                 );
526
527     int nNewN = n;
528
529     if (n == (m_nNumItems - 1))
530         nNewN = -1;
531
532     ::WinSendMsg( GetHwnd()
533                  ,LM_INSERTITEM
534                  ,(MPARAM)nNewN
535                  ,(MPARAM)rsString.wx_str()
536                 );
537
538     //
539     // Restore the client data
540     //
541     if (pOldData)
542         SetClientData(n, pOldData);
543     else if (pOldObjData)
544         SetClientObject(n, pOldObjData);
545
546     //
547     // We may have lost the selection
548     //
549     if (bWasSelected)
550         Select(n);
551
552 #if wxUSE_OWNER_DRAWN
553     if (m_windowStyle & wxLB_OWNERDRAW)
554         //
555         // Update item's text
556         //
557         m_aItems[n]->SetName(rsString);
558 #endif  //USE_OWNER_DRAWN
559 } // end of wxListBox::SetString
560
561 unsigned int wxListBox::GetCount() const
562 {
563     return m_nNumItems;
564 }
565
566 // ----------------------------------------------------------------------------
567 // helpers
568 // ----------------------------------------------------------------------------
569
570 wxSize wxListBox::DoGetBestSize() const
571 {
572     //
573     // Find the widest string
574     //
575     int        nLine;
576     int        nListbox = 0;
577     int        nCx;
578     int        nCy;
579     wxFont     vFont = (wxFont)GetFont();
580
581     for (unsigned int i = 0; i < m_nNumItems; i++)
582     {
583         wxString vStr(GetString(i));
584
585         GetTextExtent( vStr, &nLine, NULL );
586         if (nLine > nListbox)
587             nListbox = nLine;
588     }
589
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
603                   ,&vFont
604                  );
605     nListbox += 3 * nCx;
606
607     int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
608
609     return wxSize( nListbox
610                   ,hListbox
611                  );
612 } // end of wxListBox::DoGetBestSize
613
614 // ----------------------------------------------------------------------------
615 // callbacks
616 // ----------------------------------------------------------------------------
617
618 bool wxListBox::OS2Command(
619   WXUINT                            uParam
620 , WXWORD                            WXUNUSED(wId))
621 {
622     wxEventType                     eEvtType;
623
624     if (uParam == LN_SELECT)
625     {
626         eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
627     }
628     else if (uParam == LN_ENTER)
629     {
630         eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
631     }
632     else
633     {
634         //
635         // Some event we're not interested in
636         //
637         return false;
638     }
639     wxCommandEvent                  vEvent( eEvtType
640                                            ,m_windowId
641                                           );
642
643     vEvent.SetEventObject(this);
644
645     wxArrayInt aSelections;
646     int        n;
647     int        nCount = GetSelections(aSelections);
648
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     }
662     vEvent.SetInt(n);
663     return GetEventHandler()->ProcessEvent(vEvent);
664 } // end of wxListBox::OS2Command
665
666 // ----------------------------------------------------------------------------
667 // wxCheckListBox support
668 // ----------------------------------------------------------------------------
669
670 #if wxUSE_OWNER_DRAWN
671
672 //
673 // Drawing
674 // -------
675 //
676 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE    (1)
677
678 long wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT* pItem)
679 {
680     if (!pItem)
681         pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
682
683     POWNERITEM                      pMeasureStruct = (POWNERITEM)pItem;
684     wxScreenDC                      vDc;
685
686     //
687     // Only owner-drawn control should receive this message
688     //
689     wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
690
691     vDc.SetFont(GetFont());
692
693     wxCoord                         vHeight;
694     wxCoord                         vWidth;
695
696     GetSize( &vWidth
697             ,NULL
698            );
699
700     pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
701     pMeasureStruct->rclItem.xLeft  = 0;
702     pMeasureStruct->rclItem.yTop   = 0;
703     pMeasureStruct->rclItem.yBottom = 0;
704
705     vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
706     pMeasureStruct->rclItem.yTop  = (USHORT)vHeight;
707
708     return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
709 } // end of wxListBox::OS2OnMeasure
710
711 bool wxListBox::OS2OnDraw (
712   WXDRAWITEMSTRUCT*                 pItem
713 )
714 {
715     POWNERITEM                      pDrawStruct = (POWNERITEM)pItem;
716     LONG                            lItemID = pDrawStruct->idItem;
717     int                             eAction = 0;
718     int                             eStatus = 0;
719
720     //
721     // Only owner-drawn control should receive this message
722     //
723     wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), false);
724
725
726     //
727     // The item may be -1 for an empty listbox
728     //
729     if (lItemID == -1L)
730         return false;
731
732     wxListBoxItem*                   pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
733                                                                                        ,LM_QUERYITEMHANDLE
734                                                                                        ,MPFROMLONG(pDrawStruct->idItem)
735                                                                                        ,(MPARAM)0
736                                                                                       )
737                                                                         );
738
739     wxCHECK(pData, false );
740
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 );
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             //
808             return true;
809         }
810     }
811     return pData->OnDrawItem( vDc
812                              ,vRect
813                              ,(wxOwnerDrawn::wxODAction)eAction
814                              ,(wxOwnerDrawn::wxODStatus)eStatus
815                             );
816 } // end of wxListBox::OS2OnDraw
817
818 #endif // ndef for wxUSE_OWNER_DRAWN
819
820 #endif // wxUSE_LISTBOX