1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/listctrl.cpp 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  33     #include "wx/settings.h" 
  34     #include "wx/dcclient.h" 
  35     #include "wx/textctrl.h" 
  38 #include "wx/imaglist.h" 
  39 #include "wx/listctrl.h" 
  41 #include "wx/os2/private.h" 
  44 // FIELDOFFSET in DETAIL view as defined in the OS2TK45 simply doesn't work 
  45 // We use this, which does! 
  48 #define FIELDOFFSET(type, field)    ((ULONG)&(((type *)0)->field)) 
  50 // ---------------------------------------------------------------------------- 
  51 // private helper classes 
  52 // ---------------------------------------------------------------------------- 
  54 ///////////////////////////////////////////////////////////////////////////// 
  56 //   Under OS/2 we have to use our own RECORDCORE based struct if we have 
  57 //   user data to store in a PM Container Control (and wxListCtrl is a PM 
  58 //   Container in ICON, NAME, TEXT or DETAIL view). m_ulUserData is a four 
  59 //   byte value containing a pointer to our CListIntemInternalData class 
  62 //   And now for the big time OS/2 Kludge.  In traditional OS/2 PM 
  63 //   applications using containers, programmers determine BEFORE creation 
  64 //   how many records the view will have, initially, and how many columns 
  65 //   the detail view of the container will have, as the container represents 
  66 //   a known data block.  Thus the OS/2 PM CV_DETAIL view, i.e. 
  67 //   the wxWidgets wxLC_REPORT view, relies on STATIC structure for its 
  68 //   columnar data.  It gets the data to display by telling it the specific 
  69 //   offset of the field in the struct containing the displayable data.  That 
  70 //   data has be of OS/2 Types, PSZ (char string), CDATE or CTIME format. 
  71 //   wxWidgets is dynamic in nature, however.  We insert columns, one at a 
  72 //   time and do not know how many until the app is done inserting them. So 
  73 //   for OS/2 I have to set a max allowable since they are fixed.  We return 
  74 //   an error to the app if they include more than we can handle. 
  76 //   For example to display the data "Col 4 of Item 6" in a report view, I'd 
  78 //   pRecord->m_pzColumn4 = "Col 4 of Item 6"; 
  79 //   pField->offStruct = FIELDOFFSET(MYRECORD, m_pzColumn4); 
  80 //   and then call the PM API to set it. 
  82 //   This really stinks but I can't use a pointer to another struct as the 
  83 //   FIELDOFFSET call could only tell OS/2 the four byte value offset of 
  84 //   pointer field and it would display giberish in the column. 
  85 ///////////////////////////////////////////////////////////////////////////// 
  86 typedef struct _MYRECORD
 
  89     unsigned long                   m_ulItemId
; 
  90     unsigned long                   m_ulUserData
; //actually a pointer value to real data (a CListItemInternalData class instance) 
 101 } MYRECORD
, *PMYRECORD
; 
 103 ///////////////////////////////////////////////////////////////////////////// 
 104 // CLASS CListItemInternalData 
 107 //  The MSW version had problems with SetTextColour() et al as the 
 108 //  CListItemAttr's were stored keyed on the item index. If a item was 
 109 //  inserted anywhere but the end of the list the the text attributes 
 110 //  (colour etc) for the following items were out of sync. 
 113 //  Under MSW the only way to associate data with a 
 114 //  List item independent of its position in the list is to store a pointer 
 115 //  to it in its lParam attribute. However user programs are already using 
 116 //  this (via the SetItemData() GetItemData() calls). 
 118 //  However what we can do is store a pointer to a structure which contains 
 119 //  the attributes we want *and* a lParam for the users data, e.g. 
 121 //  class CListItemInternalData 
 124 //       GuiAdvCtrl_CListItemAttr* pAttr; 
 125 //       long                      lParam; // user data 
 128 //  To conserve memory, a CListItemInternalData is only allocated for a 
 129 //  LV_ITEM if text attributes or user data(lparam) are being set. 
 131 //  For OS/2, the lParam value points to whatever actual data we have 
 132 ///////////////////////////////////////////////////////////////////////////// 
 133 class CListItemInternalData
 
 137     CListItemInternalData(): m_pAttr(NULL
) 
 141     ~CListItemInternalData() 
 147     wxListItemAttr
*                 m_pAttr
; 
 148     WXLPARAM                        m_lParam
; // user data 
 149     PMYRECORD                       m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted 
 150 }; // end of CLASS CListItemInternalData 
 152 ///////////////////////////////////////////////////////////////////////////// 
 153 // STRUCT SInternalDataSort 
 157 // fn is a function which takes 3 long arguments: item1, item2, data. 
 158 // item1 is the long data associated with a first item (NOT the index). 
 159 // item2 is the long data associated with a second item (NOT the index). 
 160 // data is the same value as passed to SortItems. 
 162 // The return value is a negative number if the first item should precede the 
 163 // second item, a positive number of the second item should precede the first, 
 164 // or zero if the two items are equivalent. 
 166 // data is arbitrary data to be passed to the sort function. 
 168 // Internal structures for proxying the user compare function 
 169 // so that we can pass it the *real* user data 
 170 ///////////////////////////////////////////////////////////////////////////// 
 171 typedef struct internalDataSort
 
 173     wxListCtrlCompare               m_fnUser
; 
 175 } SInternalDataSort
; // end of STRUCT SInternalDataSort 
 177 // ---------------------------------------------------------------------------- 
 178 // private helper functions 
 179 // ---------------------------------------------------------------------------- 
 181 ///////////////////////////////////////////////////////////////////////////// 
 183 // FindOS2ListFieldByColNum 
 185 //  There is no way, under OS/2 to get a field in a container by index, 
 186 //  directly, so you must get the first one, then cycle through the list 
 187 //  until you get to where you want to be. 
 190 //  hWnd   -- window handle of container to search 
 191 //  lIndex -- index to set 
 194 //  pointer to the FIELDINFO struct at the index in the container record 
 196 ///////////////////////////////////////////////////////////////////////////// 
 197 PFIELDINFO 
FindOS2ListFieldByColNum ( 
 202     PFIELDINFO                      pFieldInfo 
= NULL
; 
 206     if (!::WinSendMsg( hWnd
 
 209                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 212     for (i 
= 0; i 
< vCnrInfo
.cFields
; i
++) 
 215             pFieldInfo 
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 216                                                               ,CM_QUERYDETAILFIELDINFO
 
 221             pFieldInfo 
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 222                                                               ,CM_QUERYDETAILFIELDINFO
 
 228         if (i 
== (ULONG
)lIndex
) 
 234 } // end of FindOS2ListFieldByColNum 
 236 ///////////////////////////////////////////////////////////////////////////// 
 238 // FindOS2ListRecordByID 
 240 //  There is no way, under OS/2 to get a record in a container by index, 
 241 //  directly, so you must get the first one, then cycle through the list 
 242 //  until you get to where you want to be. 
 245 //  hWnd    -- window handle of container to search 
 246 //  lItemId -- index to set 
 249 //  pointer to the internal RECORDCORE struct at the index in the container 
 251 ///////////////////////////////////////////////////////////////////////////// 
 252 PMYRECORD 
FindOS2ListRecordByID ( 
 257     PMYRECORD                       pRecord 
= NULL
; 
 261     if (!::WinSendMsg( hWnd
 
 264                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 267     for (i 
= 0; i 
< vCnrInfo
.cRecords
; i
++) 
 270             pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 273                                                           ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
 276             pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 279                                                           ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
 283         if (pRecord
->m_ulItemId 
== (ULONG
)lItemId
) 
 287 } // end of FindOS2ListRecordByID 
 289 ///////////////////////////////////////////////////////////////////////////// 
 293 //  Since OS/2 does not keep native record id's but wx insists on inserting 
 294 //  and selecting via ID's, when we insert a record in the middle we need 
 295 //  to bump the id's of each record after the one we just inserted. 
 298 //  hWnd    -- window handle of container to search 
 299 //  pRecord -- record after which we starting bumping id's 
 304 ///////////////////////////////////////////////////////////////////////////// 
 312         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 315                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
 318             pRecord
->m_ulItemId
++; 
 320 } // end of BumpRecordIds 
 322 ///////////////////////////////////////////////////////////////////////////// 
 326 //  Get the internal data given a handle and an id 
 329 //  hWnd    -- window handle to the control in which item is located 
 330 //  lItemId -- ID to get 
 333 //  pointer to the internal data 
 336 //  Under OS/2 PM a container item cannot be obtained via a simple index or 
 337 //  id retrieval.  We have to walk the record list if we are looking for 
 338 //  a record at a specific index location 
 339 ///////////////////////////////////////////////////////////////////////////// 
 340 CListItemInternalData
* GetInternalData ( 
 345     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( hWnd
 
 349     // Internal user data is stored AFTER the last field of the RECORDCORE 
 353     return((CListItemInternalData 
*)(pRecord
->m_ulUserData
)); 
 354 } // end of GetInternalData 
 356 ///////////////////////////////////////////////////////////////////////////// 
 360 //  Get the internal data given a pointer to a list control and an id 
 363 //  pCtl    -- pointer to control inwhich item is located 
 364 //  lItemId -- ID to get 
 367 //  pointer to the internal data 
 369 ///////////////////////////////////////////////////////////////////////////// 
 370 CListItemInternalData
* GetInternalData ( 
 375     return(GetInternalData( (HWND
)pCtl
->GetHWND() 
 378 } // end of GetInternalData 
 380 ///////////////////////////////////////////////////////////////////////////// 
 382 // DeleteInternalData 
 384 //  Delete the internal data for a record 
 387 //  pCtl    -- pointer to the list control containing the record 
 388 //  lItemId -- the record index to delete the internal data from 
 391 //  pointer to the internal data attribute 
 393 ///////////////////////////////////////////////////////////////////////////// 
 394 void DeleteInternalData ( 
 399     CListItemInternalData
*          pData 
= GetInternalData( pCtl
 
 404         if (pData
->m_pMyRecord
) 
 405             pData
->m_pMyRecord
->m_ulUserData 
= 0; 
 408 } // end of DeleteInternalData 
 410 // #pragma page   "GetInternalDataAttr" 
 411 ///////////////////////////////////////////////////////////////////////////// 
 413 // GetInternalDataAttr 
 415 //  Get the internal data item attribute given a pointer to a list control 
 419 //  pCtl    -- pointer to control to set 
 420 //  lItemId -- ID to set 
 423 //  pointer to the internal data attribute 
 425 ///////////////////////////////////////////////////////////////////////////// 
 426 wxListItemAttr
* GetInternalDataAttr ( 
 431     CListItemInternalData
*          pData 
= GetInternalData( pCtl
 
 436         return(pData
->m_pAttr
); 
 439 } // end of GetInternalDataAttr 
 441 ///////////////////////////////////////////////////////////////////////////// 
 443 // InternalDataCompareFunc 
 445 //  This is compare function we pass to PM.  It wraps the real compare 
 446 //  function in SInternalDataSort 
 449 //  p1       -- is the first record structure to compare 
 450 //  p2       -- is the second record structure to compare 
 451 //  lStorage -- is the same value as passed to SortItems. 
 454 //  pointer to the internal data attribute 
 456 ///////////////////////////////////////////////////////////////////////////// 
 457 SHORT EXPENTRY 
InternalDataCompareFunc ( 
 463     SInternalDataSort
*              pInternalData 
= (SInternalDataSort 
*)pStorage
; 
 464     CListItemInternalData
*          pData1 
= (CListItemInternalData 
*)p1
->m_ulUserData
; 
 465     CListItemInternalData
*          pData2 
= (CListItemInternalData 
*)p2
->m_ulUserData
; 
 466     long                            lD1 
= (pData1 
== NULL 
? 0 : (long)pData1
->m_lParam
); 
 467     long                            lD2 
= (pData2 
== NULL 
? 0 : (long)pData2
->m_lParam
); 
 469     return(pInternalData
->m_fnUser( lD1
 
 471                                    ,pInternalData
->m_lData
 
 473 } // end of InternalDataCompareFunc 
 475 ///////////////////////////////////////////////////////////////////////////// 
 477 // ConvertFromOS2ListItem 
 479 //  Convert from an internal PM List item to a Toolkit List item 
 482 //  hWndListCtrl -- the control's windows handle 
 483 //  rInfo        -- the library list control to convert to 
 484 //  pRecord      -- the OS list control to convert from 
 489 ///////////////////////////////////////////////////////////////////////////// 
 490 void ConvertFromOS2ListItem ( HWND hWndListCtrl
, 
 494     CListItemInternalData
* pInternaldata 
= (CListItemInternalData 
*)pRecord
->m_ulUserData
; 
 495     bool bNeedText 
= false; 
 498         rInfo
.SetData(pInternaldata
->m_lParam
); 
 502     rInfo
.SetStateMask(0); 
 503     rInfo
.SetId((long)pRecord
->m_ulItemId
); 
 504     if (hWndListCtrl 
!= 0) 
 506         pRecord 
= FindOS2ListRecordByID( hWndListCtrl
 
 512     // The wxListItem class is really set up to handle the WIN32 list item 
 513     // and OS/2 are not as complicated.  Just set both state members to the 
 514     // same thing under OS/2 
 516     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_DROPONABLE
) 
 518         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_DROPHILITED
); 
 519         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_DROPHILITED
); 
 521     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_SELECTED
) 
 523         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_SELECTED
); 
 524         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_SELECTED
); 
 526     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_DISABLED
) 
 528         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_DISABLED
); 
 529         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_DISABLED
); 
 531     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_FILTERED
) 
 533         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_FILTERED
); 
 534         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_FILTERED
); 
 536     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_INUSE
) 
 538         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_INUSE
); 
 539         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_INUSE
); 
 541     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_PICKED
) 
 543         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_PICKED
); 
 544         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_PICKED
); 
 546     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_SOURCE
) 
 548         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_SOURCE
); 
 549         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_SOURCE
); 
 552     if (pRecord
->m_vRecord
.pszText 
!= (PSZ
)NULL
) 
 554         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
); 
 555         rInfo
.SetText(pRecord
->m_vRecord
.pszText
); 
 557     if (pRecord
->m_vRecord
.pszIcon 
!= (PSZ
)NULL 
|| 
 558         pRecord
->m_vRecord
.pszName 
!= (PSZ
)NULL
) 
 560         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
); 
 561         rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
); 
 563     if (pRecord
->m_ulUserData
) 
 564         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
); 
 565 } // end of ConvertFromOS2ListItem 
 567 ///////////////////////////////////////////////////////////////////////////// 
 571 //  Convert from an library states to OS states 
 574 //  lState       -- the state 
 575 //  pRecord      -- the OS list control to use 
 580 ///////////////////////////////////////////////////////////////////////////// 
 581 void ConvertToOS2Flags ( 
 586     if (lState 
& wxLIST_STATE_DROPHILITED
) 
 587         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_DROPONABLE
; 
 588     if (lState 
& wxLIST_STATE_SELECTED
) 
 589         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_SELECTED
; 
 590     if (lState 
& wxLIST_STATE_DISABLED
) 
 591         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_DISABLED
; 
 592     if (lState 
& wxLIST_STATE_FILTERED
) 
 593         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_FILTERED
; 
 594     if (lState 
& wxLIST_STATE_INUSE
) 
 595         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_INUSE
; 
 596     if (lState 
& wxLIST_STATE_PICKED
) 
 597         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_PICKED
; 
 598     if (lState 
& wxLIST_STATE_SOURCE
) 
 599         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_SOURCE
; 
 600 } // end of ConvertToOS2Flags 
 602 ///////////////////////////////////////////////////////////////////////////// 
 604 // ConvertToOS2ListItem 
 606 //  Convert from a library List item to an internal OS2 List item. We set 
 607 //  only the fields we need to set.  Some of them are set by the API when 
 608 //  they are added to the container. 
 611 //  pCtrl      -- the control to use 
 612 //  rInfo      -- the item to convert 
 613 //  pRecord    -- the OS list control to use, should be zeroed out 
 614 //  pFieldinfo -- a field struct that may contain columnar data for detail view 
 619 ///////////////////////////////////////////////////////////////////////////// 
 620 void ConvertToOS2ListItem ( 
 621   const wxListCtrl
*                 pCtrl
 
 622 , const wxListItem
&                 rInfo
 
 624 , PFIELDINFO                        pFieldInfo
 
 627     pRecord
->m_ulItemId    
= (ULONG
)rInfo
.GetId(); 
 628     pRecord
->m_vRecord
.cb 
= sizeof(RECORDCORE
); 
 629     if (rInfo
.GetMask() & wxLIST_MASK_STATE
) 
 631         ConvertToOS2Flags( rInfo
.m_state
 
 635     if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON 
|| 
 636         pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
) 
 638         pRecord
->m_vRecord
.pszIcon 
= (char*)rInfo
.GetText().c_str(); 
 640     if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view 
 642         pRecord
->m_vRecord
.pszText 
= (char*)rInfo
.GetText().c_str(); 
 645     // In the case of a report view the text will be the data in the lead column 
 646     // ???? Don't know why, but that is how it works in other ports. 
 648     if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
) 
 652             switch(rInfo
.GetColumn()) 
 655                     pRecord
->m_pzColumn1 
= (char*)rInfo
.GetText().c_str(); 
 656                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn1
); 
 660                     pRecord
->m_pzColumn2 
= (char*)rInfo
.GetText().c_str(); 
 661                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn2
); 
 665                     pRecord
->m_pzColumn3 
= (char*)rInfo
.GetText().c_str(); 
 666                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn3
); 
 670                     pRecord
->m_pzColumn4 
= (char*)rInfo
.GetText().c_str(); 
 671                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn4
); 
 675                     pRecord
->m_pzColumn5 
= (char*)rInfo
.GetText().c_str(); 
 676                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn5
); 
 680                     pRecord
->m_pzColumn6 
= (char*)rInfo
.GetText().c_str(); 
 681                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn6
); 
 685                     pRecord
->m_pzColumn7 
= (char*)rInfo
.GetText().c_str(); 
 686                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn7
); 
 690                     pRecord
->m_pzColumn8 
= (char*)rInfo
.GetText().c_str(); 
 691                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn8
); 
 695                     pRecord
->m_pzColumn9 
= (char*)rInfo
.GetText().c_str(); 
 696                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn9
); 
 700                     pRecord
->m_pzColumn10 
= (char*)rInfo
.GetText().c_str(); 
 701                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn10
); 
 705                     wxFAIL_MSG( wxT("wxOS2 does not support more than 10 columns in REPORT view") ); 
 710     if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) 
 712         pRecord
->m_vRecord
.hptrIcon      
= (HPOINTER
)rInfo
.GetImage(); 
 713         pRecord
->m_vRecord
.hptrMiniIcon  
= (HPOINTER
)rInfo
.m_miniImage
; 
 715 } // end of ConvertToOS2ListItem 
 717 ///////////////////////////////////////////////////////////////////////////// 
 719 // ConvertToOS2ListCol 
 721 //  Convert from a library List column to an internal PM List column 
 724 //  lCol   -- the columnd to convert 
 725 //  rItem  -- the item to convert 
 726 //  pField -- the OS list column to use 
 731 ///////////////////////////////////////////////////////////////////////////// 
 732 void ConvertToOS2ListCol ( 
 734 , const wxListItem
&                 rItem
 
 738     memset(pField
, '\0', sizeof(FIELDINFO
)); 
 739     pField
->cb 
= sizeof(FIELDINFO
); 
 742     // Default some settings 
 744     pField
->flData  
= CFA_HORZSEPARATOR 
| CFA_SEPARATOR
; 
 745     pField
->flTitle 
= CFA_CENTER
; 
 747     if (rItem
.GetMask() & wxLIST_MASK_TEXT
) 
 749         pField
->flData 
|= CFA_STRING
; 
 750         pField
->pTitleData 
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data 
 752     if (rItem
.GetMask() & wxLIST_MASK_FORMAT
) 
 754         if (rItem
.m_format 
== wxLIST_FORMAT_LEFT
) 
 755             pField
->flData 
|= CFA_LEFT
; 
 756         else if (rItem
.m_format 
== wxLIST_FORMAT_RIGHT
) 
 757             pField
->flData 
|= CFA_RIGHT
; 
 758         else if (rItem
.m_format 
== wxLIST_FORMAT_CENTRE
) 
 759             pField
->flData 
|= CFA_CENTER
; 
 762         pField
->flData 
|= CFA_CENTER
;  // Just ensure the default is centered 
 763     if (rItem
.GetMask() & wxLIST_MASK_WIDTH
) 
 765         if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE 
|| 
 766              rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
)) 
 767             pField
->cxWidth 
= rItem
.GetWidth(); 
 768         // else: OS/2 automatically sets the width if created with the approppriate style 
 772     // Still need to set the actual data 
 774     pField
->offStruct 
= 0; 
 775 } // end of ConvertToOS2ListCol 
 778 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
) 
 779 IMPLEMENT_DYNAMIC_CLASS(wxListView
, wxListCtrl
) 
 780 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
) 
 782 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
) 
 784 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
) 
 785     EVT_PAINT(wxListCtrl::OnPaint
) 
 788 // ============================================================================ 
 790 // ============================================================================ 
 792 // ---------------------------------------------------------------------------- 
 793 // wxListCtrl construction 
 794 // ---------------------------------------------------------------------------- 
 796 void wxListCtrl::Init () 
 798     m_pImageListNormal     
= NULL
; 
 799     m_pImageListSmall      
= NULL
; 
 800     m_pImageListState      
= NULL
; 
 801     m_bOwnsImageListNormal 
= false; 
 802     m_bOwnsImageListSmall  
= false; 
 803     m_bOwnsImageListState  
= false; 
 807     m_bAnyInternalData     
= false; 
 808     m_bHasAnyAttr          
= false; 
 809 } // end of wxListCtrl::Init 
 811 bool wxListCtrl::Create ( wxWindow
* pParent
, 
 816                           const wxValidator
& rValidator
, 
 817                           const wxString
& rsName 
) 
 821     int nWidth 
= rSize
.x
; 
 822     int nHeight 
= rSize
.y
; 
 825     SetValidator(rValidator
); 
 826 #endif // wxUSE_VALIDATORS 
 829     SetWindowStyleFlag(lStyle
); 
 840     m_windowId 
= (vId 
== -1) ? NewControlId() : vId
; 
 842     long lSstyle 
= WS_VISIBLE 
| WS_TABSTOP
; 
 844     if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
) 
 845         lSstyle 
|= WS_CLIPSIBLINGS
; 
 846     m_lBaseStyle 
= lSstyle
; 
 847     if (!DoCreateControl( nX
 
 854         pParent
->AddChild(this); 
 856 } // end of wxListCtrl::Create 
 858 bool wxListCtrl::DoCreateControl ( int nX
, int nY
, 
 859                                    int nWidth
, int nHeight 
) 
 861     DWORD lWstyle 
= m_lBaseStyle
; 
 862     long lOldStyle 
= 0; // Dummy 
 866     lWstyle 
|= ConvertToOS2Style( lOldStyle
 
 867                                  ,GetWindowStyleFlag() 
 870     m_hWnd 
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND() 
 875                                        ,GetParent()->GetHWND() 
 887     // Now set the display attributes of the container 
 889     if (!::WinSendMsg( GetHWND() 
 892                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 895     lWstyle 
= ConvertViewToOS2Style(GetWindowStyleFlag()); 
 896     vCnrInfo
.flWindowAttr 
|= lWstyle
; 
 897     if (!::WinSendMsg( GetHWND() 
 900                       ,(MPARAM
)CMA_FLWINDOWATTR
 
 905     // And now set needed arrangement flags 
 907     lWstyle 
= ConvertArrangeToOS2Style(GetWindowStyleFlag()); 
 908     if (!::WinSendMsg( GetHWND() 
 910                       ,(MPARAM
)CMA_ARRANGEGRID
 
 914     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 915     SetForegroundColour(GetParent()->GetForegroundColour()); 
 917     SetFont(*wxSMALL_FONT
); 
 920     SetSize( nX
, nY
, nWidth
, nHeight 
); 
 922 } // end of wxListCtrl::DoCreateControl 
 924 void wxListCtrl::UpdateStyle () 
 929         DWORD dwStyleNew 
= ConvertToOS2Style( lDummy
, GetWindowStyleFlag() ); 
 931         dwStyleNew 
|= m_lBaseStyle
; 
 934         // Get the current window style. 
 936         ULONG dwStyleOld 
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
); 
 939         // Only set the window style if the view bits have changed. 
 941         if (dwStyleOld 
!= dwStyleNew
) 
 943             ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
); 
 946 } // end of wxListCtrl::UpdateStyle 
 948 void wxListCtrl::FreeAllInternalData () 
 950     if (m_bAnyInternalData
) 
 952         int n 
= GetItemCount(); 
 955         for (i 
= 0; i 
< n
; i
++) 
 956             DeleteInternalData(this, (long)i
); 
 957         m_bAnyInternalData 
= false; 
 959 } // end of wxListCtrl::FreeAllInternalData 
 961 wxListCtrl::~wxListCtrl () 
 963     FreeAllInternalData(); 
 966         m_pTextCtrl
->SetHWND(0); 
 967         m_pTextCtrl
->UnsubclassWin(); 
 972     if (m_bOwnsImageListNormal
) 
 973         delete m_pImageListNormal
; 
 974     if (m_bOwnsImageListSmall
) 
 975         delete m_pImageListSmall
; 
 976     if (m_bOwnsImageListState
) 
 977         delete m_pImageListState
; 
 978 } // end of wxListCtrl::~wxListCtrl 
 980 // ---------------------------------------------------------------------------- 
 981 // set/get/change style 
 982 // ---------------------------------------------------------------------------- 
 984 // Add or remove a single window style 
 985 void wxListCtrl::SetSingleStyle ( 
 990     long                            lFlag 
= GetWindowStyleFlag(); 
 993     // Get rid of conflicting styles 
 997         if (lStyle 
& wxLC_MASK_TYPE
) 
 998             lFlag 
= lFlag 
& ~wxLC_MASK_TYPE
; 
 999         if (lStyle 
& wxLC_MASK_ALIGN 
) 
1000             lFlag 
= lFlag 
& ~wxLC_MASK_ALIGN
; 
1001         if (lStyle 
& wxLC_MASK_SORT 
) 
1002             lFlag 
= lFlag 
& ~wxLC_MASK_SORT
; 
1016     m_windowStyle 
= lFlag
; 
1018 } // end of wxListCtrl::SetSingleStyle 
1020 // Set the whole window style 
1021 void wxListCtrl::SetWindowStyleFlag ( 
1025     m_windowStyle 
= lFlag
; 
1027 } // end of wxListCtrl::SetWindowStyleFlag 
1029 long wxListCtrl::ConvertToOS2Style ( 
1037     // The only styles OS2 uses on creation are auto arrange, read only, and 
1038     // and selection styles.  This lib does not support OS/2 MINIRECORDCORE 
1039     // or VERIFYPOINTER styles 
1041     if (lStyle 
& wxLC_AUTOARRANGE
) 
1042         lWstyle 
|= CCS_AUTOPOSITION
; 
1043     if (lStyle 
& wxLC_SINGLE_SEL
) 
1044         lWstyle 
|= CCS_SINGLESEL
; 
1046         lWstyle 
|= CCS_EXTENDSEL
; 
1047     if (!(lStyle 
& wxLC_EDIT_LABELS
)) 
1048         lWstyle 
|= CCS_READONLY
; 
1050 } // end of wxListCtrl::ConvertToOS2Style 
1052 long wxListCtrl::ConvertArrangeToOS2Style ( 
1058     if (lStyle 
& wxLC_ALIGN_LEFT
) 
1060         lWstyle 
|= CMA_LEFT
; 
1063     if (lStyle 
& wxLC_ALIGN_TOP
) 
1068 } // end of wxListCtrl::ConvertArrangeToOS2Style 
1070 long wxListCtrl::ConvertViewToOS2Style ( 
1074     long                            lWstyle 
= CA_DRAWICON
; // we will only use icons 
1076     if (lStyle 
& wxLC_ICON
) 
1080     if (lStyle 
& wxLC_SMALL_ICON
) 
1082         lWstyle 
|= (CV_ICON 
| CV_MINI
); 
1084     if (lStyle 
& wxLC_LIST
) 
1088     if (lStyle 
& wxLC_REPORT
) 
1090         lWstyle 
|= CV_DETAIL
; 
1092     if (lStyle 
& wxLC_VIRTUAL
) 
1094         lWstyle 
|= CA_OWNERDRAW
; 
1096     if (lStyle 
& wxLC_AUTOARRANGE
) 
1100     if (!(lStyle 
& wxLC_NO_HEADER
)) 
1102         lWstyle 
|= CA_DETAILSVIEWTITLES
; 
1105 } // end of wxListCtrl::ConvertViewToOS2Style 
1107 // ---------------------------------------------------------------------------- 
1109 // ---------------------------------------------------------------------------- 
1111 // Sets the foreground, i.e. text, colour 
1112 bool wxListCtrl::SetForegroundColour (const wxColour
& rCol
) 
1114     ULONG ulColor 
= wxColourToRGB(rCol
); 
1116     if (!wxWindow::SetForegroundColour(rCol
)) 
1119     ::WinSetPresParam( GetHWND() 
1125 } // end of wxListCtrl::SetForegroundColour 
1127 // Sets the background colour 
1128 bool wxListCtrl::SetBackgroundColour ( const wxColour
& rCol 
) 
1130     if (!wxWindow::SetBackgroundColour(rCol
)) 
1134     // We set the same colour for both the "empty" background and the items 
1137     ULONG ulColor 
= wxColourToRGB(rCol
); 
1139     ::WinSetPresParam( GetHWND() 
1145 } // end of wxListCtrl::SetBackgroundColour 
1147 // Gets information about this column 
1148 bool wxListCtrl::GetColumn ( int nCol
, wxListItem
& rItem 
) const 
1150     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND(), nCol 
); 
1154     rItem
.SetWidth(pFieldInfo
->cxWidth
); 
1155     if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) && 
1156         (pFieldInfo
->flData 
& CFA_STRING
) && 
1157         (pFieldInfo
->pUserData 
!= NULL
)) 
1159         rItem
.SetText((char*)pFieldInfo
->pUserData
); 
1161     if (rItem
.GetMask() & wxLIST_MASK_FORMAT 
) 
1163         if (pFieldInfo
->flData 
& CFA_LEFT
) 
1164             rItem
.m_format 
= wxLIST_FORMAT_LEFT
; 
1165         else if (pFieldInfo
->flData 
& CFA_RIGHT
) 
1166             rItem
.m_format 
= wxLIST_FORMAT_RIGHT
; 
1167         else if (pFieldInfo
->flData 
& CFA_CENTER
) 
1168             rItem
.m_format 
= wxLIST_FORMAT_CENTRE
; 
1171 } // end of wxListCtrl::GetColumn 
1173 // Sets information about this column 
1174 bool wxListCtrl::SetColumn ( int nCol
, wxListItem
& rItem 
) 
1176     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum( GetHWND(), nCol 
); 
1177     ConvertToOS2ListCol( nCol
, rItem
, pFieldInfo 
); 
1179     // Since we changed the field pointed to, we invalidate to see the result 
1181     ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
); 
1183 } // end of wxListCtrl::SetColumn 
1185 // Gets the column width 
1186 int wxListCtrl::GetColumnWidth ( int nCol 
) const 
1188     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND(), nCol 
); 
1192     return((int)pFieldInfo
->cxWidth
); 
1193 } // end of wxListCtrl::GetColumnWidth 
1195 // Sets the column width 
1196 bool wxListCtrl::SetColumnWidth ( int nCol
, int nWidth 
) 
1199     int nWidth2 
= nWidth
; 
1201     if (GetWindowStyleFlag() & wxLC_LIST
) 
1204     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum( GetHWND(), nCol 
); 
1205     pFieldInfo
->cxWidth 
= nWidth
; 
1206     ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
); 
1208 } // end of wxListCtrl::SetColumnWidth 
1210 // Gets the number of items that can fit vertically in the 
1211 // visible area of the list control (list or report view) 
1212 // or the total number of items in the list control (icon 
1213 // or small icon view) 
1214 int wxListCtrl::GetCountPerPage () const 
1216     QUERYRECORDRECT                 vQueryRect
; 
1222     if (!::WinSendMsg( GetHWND() 
1225                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1228     memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
)); 
1229     vQueryRect
.cb 
= sizeof(QUERYRECORDRECT
); 
1230     if (vCnrInfo
.flWindowAttr 
& CV_ICON
) 
1231         vQueryRect
.fsExtent 
= CMA_ICON 
| CMA_TEXT
; 
1232     else if (vCnrInfo
.flWindowAttr 
& CV_NAME
) 
1233         vQueryRect
.fsExtent 
= CMA_ICON 
| CMA_TEXT
; 
1234     else if (vCnrInfo
.flWindowAttr 
& CV_TEXT
) 
1235         vQueryRect
.fsExtent 
= CMA_TEXT
; 
1236     else if (vCnrInfo
.flWindowAttr 
& CV_DETAIL
) 
1237         vQueryRect
.fsExtent 
= CMA_TEXT
; 
1238     if (!::WinSendMsg( GetHWND() 
1240                       ,MPFROMP(&vRectRecord
) 
1241                       ,MPFROMP(&vQueryRect
) 
1244     if (!::WinSendMsg( GetHWND() 
1245                       ,CM_QUERYVIEWPORTRECT
 
1246                       ,MPFROMP(&vRectControl
) 
1247                       ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
) 
1250     nCount 
= (int)((int)((vRectControl
.xRight 
- vRectControl
.xLeft
) / (vRectRecord
.xRight 
- vRectRecord
.xLeft
)) * 
1251                    (int)((vRectControl
.yTop 
- vRectControl
.yBottom
) / (vRectRecord
.yTop 
- vRectRecord
.yBottom
)) 
1253     if (nCount 
> (int)vCnrInfo
.cFields
) 
1254         nCount 
= (int)vCnrInfo
.cFields
; 
1256 } // end of wxListCtrl::GetCountPerPage 
1258 // Gets the edit control for editing labels. 
1259 wxTextCtrl
* wxListCtrl::GetEditControl() const 
1264 // Gets information about the item 
1265 bool wxListCtrl::GetItem ( wxListItem
& rInfo 
) const 
1267     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() ); 
1270     // Give NULL as hwnd as we already have everything we need 
1272     ConvertFromOS2ListItem( NULL
, rInfo
, pRecord 
); 
1274 } // end of wxListCtrl::GetItem 
1276 // Sets information about the item 
1277 bool wxListCtrl::SetItem ( wxListItem
& rInfo 
) 
1279     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND(), rInfo
.GetColumn() ); 
1280     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() ); 
1282     ConvertToOS2ListItem( this 
1289     // Check if setting attributes or lParam 
1291     if (rInfo
.HasAttributes() || (rInfo
.GetMask()  & wxLIST_MASK_DATA
)) 
1294         // Get internal item data 
1295         // perhaps a cache here ? 
1297         CListItemInternalData
*      pData 
= GetInternalData( this 
1306             m_bAnyInternalData    
= true; 
1307             pData                 
= new CListItemInternalData(); 
1308             pRecord
->m_ulUserData 
= (unsigned long)pData
; 
1314         if (rInfo
.GetMask()  & wxLIST_MASK_DATA
) 
1315             pData
->m_lParam 
= (WXLPARAM
)rInfo
.GetData(); 
1318         if (rInfo
.HasAttributes()) 
1321                 *pData
->m_pAttr 
= *rInfo
.GetAttributes(); 
1323                 pData
->m_pAttr 
= new wxListItemAttr(*rInfo
.GetAttributes()); 
1325         pData
->m_pMyRecord 
= pRecord
;  // they point to each other 
1329     // We need to update the item immediately to show the new image 
1331     bool bUpdateNow 
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0; 
1334     // Check whether it has any custom attributes 
1336     if (rInfo
.HasAttributes()) 
1338         m_bHasAnyAttr 
= true; 
1341         // If the colour has changed, we must redraw the item 
1345     if (::WinIsWindowVisible(GetHWND())) 
1347         ::WinSendMsg( GetHWND() 
1348                      ,CM_INVALIDATERECORD
 
1350                      ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1352         RefreshItem(pRecord
->m_ulItemId
); 
1354     ::WinSendMsg( GetHWND() 
1355                  ,CM_INVALIDATEDETAILFIELDINFO
 
1360 } // end of wxListCtrl::SetItem 
1362 long wxListCtrl::SetItem ( 
1365 , const wxString
&                   rsLabel
 
1371     vInfo
.m_text   
= rsLabel
; 
1372     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1373     vInfo
.m_itemId 
= lIndex
; 
1377         vInfo
.m_image 
= nImageId
; 
1378         vInfo
.m_mask 
|= wxLIST_MASK_IMAGE
; 
1380     return SetItem(vInfo
); 
1381 } // end of wxListCtrl::SetItem 
1383 // Gets the item state 
1384 int wxListCtrl::GetItemState ( 
1391     vInfo
.m_mask      
= wxLIST_MASK_STATE
; 
1392     vInfo
.m_stateMask 
= lStateMask
; 
1393     vInfo
.m_itemId    
= lItem
; 
1395     if (!GetItem(vInfo
)) 
1397     return vInfo
.m_state
; 
1398 } // end of wxListCtrl::GetItemState 
1400 // Sets the item state 
1401 bool wxListCtrl::SetItemState ( long lItem
, long lState
, long lStateMask 
) 
1403     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
1406     // Don't use SetItem() here as it doesn't work with the virtual list 
1409     ConvertToOS2Flags( lState
, pRecord 
); 
1412     // for the virtual list controls we need to refresh the previously focused 
1413     // item manually when changing focus without changing selection 
1414     // programmatically because otherwise it keeps its focus rectangle until 
1415     // next repaint (yet another comctl32 bug) 
1420         (lStateMask 
& wxLIST_STATE_FOCUSED
) && 
1421          (lState 
& wxLIST_STATE_FOCUSED
) ) 
1423         lFocusOld 
= GetNextItem( -1 
1425                                 ,wxLIST_STATE_FOCUSED
 
1432     ::WinSendMsg( GetHWND() 
1433                  ,CM_INVALIDATERECORD
 
1435                  ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1438     if (lFocusOld 
!= -1) 
1441         // No need to refresh the item if it was previously selected, it would 
1442         // only result in annoying flicker 
1444         if (!(GetItemState( lFocusOld
 
1445                            ,wxLIST_STATE_SELECTED
 
1446                           ) & wxLIST_STATE_SELECTED
)) 
1448             RefreshItem(lFocusOld
); 
1452 } // end of wxListCtrl::SetItemState 
1454 // Sets the item image 
1455 bool wxListCtrl::SetItemImage ( 
1458 , int                               WXUNUSED(nSelImage
)) 
1460     return SetItemColumnInfo(lItem
, 0, nImage
); 
1461 } // end of wxListCtrl::SetItemImage 
1463 // Sets the item image 
1464 bool wxListCtrl::SetItemColumnImage ( 
1471     vInfo
.m_mask   
= wxLIST_MASK_IMAGE
; 
1472     vInfo
.m_image  
= nImage
; 
1473     vInfo
.m_itemId 
= lItem
; 
1474     vInfo
.m_col    
= lColumn
; 
1475     return SetItem(vInfo
); 
1476 } // end of wxListCtrl::SetItemColumnImage 
1478 // Gets the item text 
1479 wxString 
wxListCtrl::GetItemText ( 
1485     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1486     vInfo
.m_itemId 
= lItem
; 
1488     if (!GetItem(vInfo
)) 
1489         return wxEmptyString
; 
1490     return vInfo
.m_text
; 
1491 } // end of wxListCtrl::GetItemText 
1493 // Sets the item text 
1494 void wxListCtrl::SetItemText ( 
1496 , const wxString
&                   rsStr
 
1501     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1502     vInfo
.m_itemId 
= lItem
; 
1503     vInfo
.m_text   
= rsStr
; 
1505 } // end of wxListCtrl::SetItemText 
1507 // Gets the item data 
1508 long wxListCtrl::GetItemData ( 
1514     vInfo
.m_mask   
= wxLIST_MASK_DATA
; 
1515     vInfo
.m_itemId 
= lItem
; 
1516     if (!GetItem(vInfo
)) 
1518     return vInfo
.m_data
; 
1519 } // end of wxListCtrl::GetItemData 
1521 // Sets the item data 
1522 bool wxListCtrl::SetItemPtrData ( 
1529     vInfo
.m_mask   
= wxLIST_MASK_DATA
; 
1530     vInfo
.m_itemId 
= lItem
; 
1531     vInfo
.m_data   
= lData
; 
1532     return SetItem(vInfo
); 
1533 } // end of wxListCtrl::SetItemPtrData 
1535 // Gets the item rectangle 
1536 bool wxListCtrl::GetItemRect ( long lItem
, 
1541     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
1542     QUERYRECORDRECT vQueryRect
; 
1548     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
1549     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
1550     vQueryRect
.fRightSplitWindow 
= TRUE
; 
1551     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
1552     ::WinSendMsg( GetHWND() 
1555                  ,MPFROMP(&vQueryRect
) 
1558     // remember OS/2 is backwards 
1560     GetClientSize( NULL
, &nHeight 
); 
1561     rRect
.x      
= vRect
.xLeft
; 
1562     rRect
.y      
= nHeight 
- vRect
.yTop
; 
1563     rRect
.width  
= vRect
.xRight
; 
1564     rRect
.height 
= nHeight 
- vRect
.yBottom
; 
1567 } // end of wxListCtrl::GetItemRect 
1569 // Gets the item position 
1570 bool wxListCtrl::GetItemPosition ( long lItem
, wxPoint
& rPos 
) const 
1573     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND() , lItem 
); 
1574     QUERYRECORDRECT vQueryRect
; 
1580     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
1581     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
1582     vQueryRect
.fRightSplitWindow 
= TRUE
; 
1583     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
1584     ::WinSendMsg( GetHWND() 
1587                  ,MPFROMP(&vQueryRect
) 
1590     // remember OS/2 is backwards 
1592     GetClientSize( NULL
, &nHeight 
); 
1593     rPos
.x   
= vRect
.xLeft
; 
1594     rPos
.y   
= nHeight 
- vRect
.yTop
; 
1597 } // end of wxListCtrl::GetItemPosition 
1599 // Sets the item position. 
1600 bool wxListCtrl::SetItemPosition ( long lItem
, const wxPoint
& rPos 
) 
1603     // Items cannot be positioned in X/Y coord in OS/2 
1606 } // end of wxListCtrl::SetItemPosition 
1608 // Gets the number of items in the list control 
1609 int wxListCtrl::GetItemCount () const 
1613     if (!::WinSendMsg( GetHWND() 
1616                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1619     return vCnrInfo
.cRecords
; 
1620 } // end of wxListCtrl::GetItemCount 
1622 // Retrieves the spacing between icons in pixels. 
1623 // If bIsSmall is true, gets the spacing for the small icon 
1624 // view, otherwise the large icon view. 
1625 int wxListCtrl::GetItemSpacing ( bool bIsSmall 
) const 
1629     if (!::WinSendMsg( GetHWND() 
1632                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1635     return vCnrInfo
.cyLineSpacing
; 
1636 } // end of wxListCtrl::GetItemSpacing 
1638 void wxListCtrl::SetItemTextColour ( 
1640 , const wxColour
&                   rCol
 
1645     vInfo
.m_itemId 
= lItem
; 
1646     vInfo
.SetTextColour(rCol
); 
1648 } // end of wxListCtrl::SetItemTextColour 
1650 wxColour 
wxListCtrl::GetItemTextColour ( 
1656     vInfo
.m_itemId 
= lItem
; 
1658     return vInfo
.GetTextColour(); 
1659 } // end of wxListCtrl::GetItemTextColour 
1661 void wxListCtrl::SetItemBackgroundColour ( 
1663 , const wxColour
&                   rCol
 
1668     vInfo
.m_itemId 
= lItem
; 
1669     vInfo
.SetBackgroundColour(rCol
); 
1671 } // end of wxListCtrl::SetItemBackgroundColour 
1673 wxColour 
wxListCtrl::GetItemBackgroundColour ( 
1679     vInfo
.m_itemId 
= lItem
; 
1681     return vInfo
.GetBackgroundColour(); 
1682 } // end of wxListCtrl::GetItemBackgroundColour 
1684 // Gets the number of selected items in the list control 
1685 int wxListCtrl::GetSelectedItemCount () const 
1687     PMYRECORD                       pRecord 
= NULL
; 
1689     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1690                                                   ,CM_QUERYRECORDEMPHASIS
 
1692                                                   ,(MPARAM
)CRA_SELECTED
 
1700         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1701                                                       ,CM_QUERYRECORDEMPHASIS
 
1703                                                       ,(MPARAM
)CRA_SELECTED
 
1709 } // end of wxListCtrl::GetSelectedItemCount 
1711 // Gets the text colour of the listview 
1712 wxColour 
wxListCtrl::GetTextColour () const 
1717     ::WinQueryPresParam( GetHWND() 
1727 } // end of wxListCtrl::GetTextColour 
1729 // Sets the text colour of the listview 
1730 void wxListCtrl::SetTextColour ( 
1731   const wxColour
&                   rCol
 
1734     ULONG                           ulColor 
= wxColourToRGB(rCol
); 
1736     ::WinSetPresParam( GetHWND() 
1741 } // end of wxListCtrl::SetTextColour 
1743 // Gets the index of the topmost visible item when in 
1744 // list or report view 
1745 long wxListCtrl::GetTopItem () const 
1747     PMYRECORD                       pRecord 
= NULL
; 
1748     QUERYRECFROMRECT                vQueryRect
; 
1751     ::WinSendMsg( GetHWND() 
1752                  ,CM_QUERYVIEWPORTRECT
 
1754                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
1756     vQueryRect
.cb        
= sizeof(QUERYRECFROMRECT
); 
1757     vQueryRect
.rect      
= vRect
; 
1758     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
1760     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1761                                       ,CM_QUERYRECORDFROMRECT
 
1763                                       ,MPFROMP(&vQueryRect
) 
1768     return (long)pRecord
->m_ulItemId
; 
1769 } // end of wxListCtrl::GetTopItem 
1771 // Searches for an item, starting from 'item'. 
1772 // 'geometry' is one of 
1773 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT. 
1774 // 'state' is a state bit flag, one or more of 
1775 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT. 
1776 // item can be -1 to find the first item that matches the 
1778 // Returns the item or -1 if unsuccessful. 
1779 long wxListCtrl::GetNextItem ( 
1781 , int                               WXUNUSED(nGeom
) 
1782 , int                               WXUNUSED(nState
) 
1785     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1789     pRecord 
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
; 
1791         return((long)pRecord
->m_ulItemId
); 
1793 } // end of wxListCtrl::GetNextItem 
1795 wxImageList
* wxListCtrl::GetImageList ( 
1799     if (nWhich 
== wxIMAGE_LIST_NORMAL 
) 
1801         return m_pImageListNormal
; 
1803     else if (nWhich 
== wxIMAGE_LIST_SMALL 
) 
1805         return m_pImageListSmall
; 
1807     else if (nWhich 
== wxIMAGE_LIST_STATE 
) 
1809         return m_pImageListState
; 
1812 } // end of wxListCtrl::GetImageList 
1814 void wxListCtrl::SetImageList ( wxImageList
* pImageList
, 
1817     if (nWhich 
== wxIMAGE_LIST_NORMAL
) 
1819         if (m_bOwnsImageListNormal
) 
1820             delete m_pImageListNormal
; 
1821         m_pImageListNormal     
= pImageList
; 
1822         m_bOwnsImageListNormal 
= false; 
1824     else if (nWhich 
== wxIMAGE_LIST_SMALL
) 
1826         if (m_bOwnsImageListSmall
) 
1827             delete m_pImageListSmall
; 
1828         m_pImageListSmall    
= pImageList
; 
1829         m_bOwnsImageListSmall 
= false; 
1831     else if (nWhich 
== wxIMAGE_LIST_STATE
) 
1833         if (m_bOwnsImageListState
) 
1834             delete m_pImageListState
; 
1835         m_pImageListState     
= pImageList
; 
1836         m_bOwnsImageListState 
= false; 
1838 } // end of wxListCtrl::SetImageList 
1840 void wxListCtrl::AssignImageList ( wxImageList
* pImageList
, int nWhich 
) 
1842     SetImageList( pImageList
, nWhich 
); 
1844     if (nWhich 
== wxIMAGE_LIST_NORMAL 
) 
1845         m_bOwnsImageListNormal 
= true; 
1846     else if (nWhich 
== wxIMAGE_LIST_SMALL 
) 
1847         m_bOwnsImageListSmall 
= true; 
1848     else if (nWhich 
== wxIMAGE_LIST_STATE 
) 
1849         m_bOwnsImageListState 
= true; 
1850 } // end of wxListCtrl::AssignImageList 
1852 // ---------------------------------------------------------------------------- 
1854 // ---------------------------------------------------------------------------- 
1856 // Arranges the items 
1857 bool wxListCtrl::Arrange ( int nFlag 
) 
1862     if (nFlag 
== wxLIST_ALIGN_SNAP_TO_GRID
) 
1864         ulType 
= CMA_ARRANGEGRID
; 
1865         if (nFlag 
== wxLIST_ALIGN_LEFT
) 
1866             ulFlags 
|= CMA_LEFT
; 
1867         else if (nFlag 
== wxLIST_ALIGN_TOP
) 
1869         else if (nFlag 
== wxLIST_ALIGN_DEFAULT
) 
1870             ulFlags 
|= CMA_LEFT
; 
1873         ulType 
= CMA_ARRANGESTANDARD
; 
1874     ::WinSendMsg( GetHWND() 
1880     // We do not support CMA_ARRANGESELECTED 
1883 } // end of wxListCtrl::Arrange 
1886 bool wxListCtrl::DeleteItem ( long lItem 
) 
1888     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
1889     if (LONGFROMMR(::WinSendMsg( GetHWND() 
1892                                 ,MPFROM2SHORT(1, CMA_FREE
) 
1899     // The virtual list control doesn't refresh itself correctly, help it 
1904         // We need to refresh all the lines below the one which was deleted 
1908         if (lItem 
> 0 && GetItemCount()) 
1910             GetItemRect( lItem 
- 1 
1916             vRectItem
.y 
= vRectItem
.height 
= 0; 
1918         wxRect                      vRectWin 
= GetRect(); 
1920         vRectWin
.height 
= vRectWin
.GetBottom() - vRectItem
.GetBottom(); 
1921         vRectWin
.y      
= vRectItem
.GetBottom(); 
1922         RefreshRect(vRectWin
); 
1925 } // end of wxListCtrl::DeleteItem 
1927 // Deletes all items 
1928 bool wxListCtrl::DeleteAllItems () 
1930     return((LONG
)::WinSendMsg( GetHWND() 
1933                               ,MPFROM2SHORT(0, CMA_FREE
) 
1935 } // end of wxListCtrl::DeleteAllItems 
1937 // Deletes all items 
1938 bool wxListCtrl::DeleteAllColumns () 
1940     while (m_nColCount 
> 0) 
1942         DeleteColumn(m_nColCount 
- 1); 
1946     wxASSERT_MSG(m_nColCount 
== 0, wxT("no columns should be left")); 
1948 } // end of wxListCtrl::DeleteAllColumns 
1951 bool wxListCtrl::DeleteColumn ( int nCol 
) 
1953     bool bSuccess 
= false; 
1954     PFIELDINFO pField 
= FindOS2ListFieldByColNum( GetHWND(), nCol 
); 
1955     bSuccess 
= ((LONG
)::WinSendMsg( GetHWND() 
1956                                    ,CM_REMOVEDETAILFIELDINFO
 
1958                                    ,MPFROM2SHORT((SHORT
)1, CMA_FREE
) 
1960     if (bSuccess 
&& (m_nColCount 
> 0)) 
1963 } // end of wxListCtrl::DeleteColumn 
1965 // Clears items, and columns if there are any. 
1966 void wxListCtrl::ClearAll () 
1969     if (m_nColCount 
> 0) 
1971 } // end of wxListCtrl::ClearAll 
1974 // OS/2 does not use a text control for its container labels.  You merely 
1975 // "open" a record for editting. 
1977 wxTextCtrl
* wxListCtrl::EditLabel ( 
1979 , wxClassInfo
*                      WXUNUSED(pTextControlClass
) 
1983     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1987     vEdit
.cb         
= sizeof(CNREDITDATA
); 
1988     vEdit
.hwndCnr    
= GetHWND(); 
1989     vEdit
.pRecord    
= &pRecord
->m_vRecord
; 
1990     vEdit
.pFieldInfo 
= NULL
; 
1991     vEdit
.ppszText   
= NULL
; 
1995     ::WinSendMsg( GetHWND() 
2001 } // end of wxListCtrl::EditLabel 
2003 // End label editing, optionally cancelling the edit.  Under OS/2 you close 
2004 // the record for editting 
2005 bool wxListCtrl::EndEditLabel ( bool WXUNUSED(bCancel
) ) 
2007     ::WinSendMsg( GetHWND() 
2013 } // end of wxListCtrl::EndEditLabel 
2015 // Ensures this item is visible 
2016 bool wxListCtrl::EnsureVisible ( long lItem 
) 
2018     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
2019     ::WinSendMsg( GetHWND() 
2020                  ,CM_INVALIDATERECORD
 
2022                  ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
) 
2025 } // end of wxListCtrl::EnsureVisible 
2027 // Find an item whose label matches this string, starting from the item after 'start' 
2028 // or the beginning if 'start' is -1. 
2029 long wxListCtrl::FindItem ( 
2031 , const wxString
&                   rsStr
 
2036     SEARCHSTRING                    vSearch
; 
2037     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2043     if (!::WinSendMsg( GetHWND() 
2046                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
2050     if (vCnrInfo
.flWindowAttr 
& CV_ICON
) 
2052     if (vCnrInfo
.flWindowAttr 
& CV_NAME
) 
2054     if (vCnrInfo
.flWindowAttr 
& CV_TEXT
) 
2056     if (vCnrInfo
.flWindowAttr 
& CV_DETAIL
) 
2059         ulFlag 
|= CV_EXACTLENGTH
; 
2061     vSearch
.cb              
= sizeof(SEARCHSTRING
); 
2062     vSearch
.pszSearch       
= (char*)rsStr
.c_str(); 
2063     vSearch
.fsPrefix        
= TRUE
; 
2064     vSearch
.fsCaseSensitive 
= TRUE
; 
2065     vSearch
.usView          
= ulFlag
; 
2069         pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2077         pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2085     return pRecord
->m_ulItemId
; 
2086 } // end of wxListCtrl::FindItem 
2088 // Find an item whose data matches this data, starting from the item after 'start' 
2089 // or the beginning if 'start' is -1. 
2090 long wxListCtrl::FindItem ( 
2095     long                            lIdx 
= lStart 
+ 1; 
2096     long                            lCount 
= GetItemCount(); 
2098     while (lIdx 
< lCount
) 
2100         if (GetItemData(lIdx
) == lData
) 
2105 } // end of wxListCtrl::FindItem 
2107 // Find an item nearest this position in the specified direction, starting from 
2108 // the item after 'start' or the beginning if 'start' is -1. 
2109 long wxListCtrl::FindItem ( 
2111 , const wxPoint
&                    rPoint
 
2116     QUERYRECORDRECT                 vQueryRect
; 
2117     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2124     if (!::WinSendMsg( GetHWND() 
2127                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
2131     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
2132     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
2133     vQueryRect
.fRightSplitWindow 
= TRUE
; 
2134     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
2136     ::WinSendMsg( GetHWND() 
2139                  ,MPFROMP(&vQueryRect
) 
2141     vLibRect
.SetLeft(vRect
.xLeft
); 
2142     vLibRect
.SetTop(vRect
.yTop
); 
2143     vLibRect
.SetRight(vRect
.xRight
); 
2144     vLibRect
.SetBottom(vRect
.yBottom
); 
2145     if (vLibRect
.Contains(rPoint
)) 
2146         return pRecord
->m_ulItemId
; 
2148     for (i 
= lStart 
+ 1; i 
< vCnrInfo
.cRecords
; i
++) 
2150         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
2153                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
2155         vQueryRect
.pRecord 
= (PRECORDCORE
)pRecord
; 
2156         ::WinSendMsg( GetHWND() 
2159                      ,MPFROMP(&vQueryRect
) 
2161         vLibRect
.SetLeft(vRect
.xLeft
); 
2162         vLibRect
.SetTop(vRect
.yTop
); 
2163         vLibRect
.SetRight(vRect
.xRight
); 
2164         vLibRect
.SetBottom(vRect
.yBottom
); 
2165         if (vLibRect
.Contains(rPoint
)) 
2166             return pRecord
->m_ulItemId
; 
2169 } // end of wxListCtrl::FindItem 
2171 // Determines which item (if any) is at the specified point, 
2172 // giving details in 'flags' (see wxLIST_HITTEST_... flags above) 
2173 long wxListCtrl::HitTest ( 
2174   const wxPoint
&                    rPoint
 
2175 , int&                              WXUNUSED(rFlags
) 
2178     PMYRECORD                       pRecord 
= NULL
; 
2179     QUERYRECFROMRECT                vQueryRect
; 
2184     // Get height for OS/2 point conversion 
2186     ::WinSendMsg( GetHWND() 
2187                  ,CM_QUERYVIEWPORTRECT
 
2189                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
2191     lHeight 
= vRect
.yTop 
- vRect
.yBottom
; 
2194     // For now just try and get a record in the general vicinity and forget 
2197     vRect
.xLeft   
= rPoint
.x 
- 2; 
2198     vRect
.xRight  
= rPoint
.x 
+ 2; 
2199     vRect
.yTop    
= (lHeight 
- rPoint
.y
) + 2; 
2200     vRect
.yBottom 
= (lHeight 
- rPoint
.y
) - 2; 
2202     vQueryRect
.cb 
= sizeof(QUERYRECFROMRECT
); 
2203     vQueryRect
.rect 
= vRect
; 
2204     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
2206     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2207                                       ,CM_QUERYRECORDFROMRECT
 
2209                                       ,MPFROMP(&vQueryRect
) 
2214     return pRecord
->m_ulItemId
; 
2215 } // end of wxListCtrl::HitTest 
2217 // Inserts an item, returning the index of the new item if successful, 
2219 long wxListCtrl::InsertItem ( 
2223     wxASSERT_MSG( !IsVirtual(), wxT("can't be used with virtual controls") ); 
2225     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND() 
2228     PMYRECORD                       pRecordAfter 
= NULL
; 
2229     PMYRECORD                       pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2231                                                                       ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
)) 
2235     ConvertToOS2ListItem( this 
2241     if (rInfo
.GetId() > 0) 
2242         pRecordAfter 
= FindOS2ListRecordByID( GetHWND() 
2246     RECORDINSERT                    vInsert
; 
2248     vInsert
.cb                
= sizeof(RECORDINSERT
); 
2249     vInsert
.pRecordParent     
= NULL
; 
2251         vInsert
.pRecordOrder  
= (PRECORDCORE
)CMA_FIRST
; 
2253         vInsert
.pRecordOrder  
= (PRECORDCORE
)pRecordAfter
; 
2254     vInsert
.zOrder            
= CMA_TOP
; 
2255     vInsert
.cRecordsInsert    
= 1; 
2256     vInsert
.fInvalidateRecord 
= TRUE
; 
2259     // Check wether we need to allocate our internal data 
2261     bool                            bNeedInternalData 
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) || 
2262                                                           rInfo
.HasAttributes() 
2264     if (bNeedInternalData
) 
2266         m_bAnyInternalData 
= true; 
2269         // Internal stucture that manages data 
2271         CListItemInternalData
*      pData 
= new CListItemInternalData(); 
2273         pRecord
->m_ulUserData 
= (unsigned long)pData
; 
2274         if (rInfo
.GetMask() & wxLIST_MASK_DATA
) 
2275             pData
->m_lParam 
= (WXLPARAM
)rInfo
.GetData(); 
2278         // Check whether it has any custom attributes 
2280         if (rInfo
.HasAttributes()) 
2283             // Take copy of attributes 
2285             pData
->m_pAttr 
= new wxListItemAttr(*rInfo
.GetAttributes()); 
2288     if (!::WinSendMsg( GetHWND() 
2295     // OS/2 must mannually bump the index's of following records 
2297     BumpRecordIds( GetHWND() 
2300     ::WinSendMsg( GetHWND() 
2301                  ,CM_INVALIDATEDETAILFIELDINFO
 
2305     return pRecord
->m_ulItemId
; 
2306 } // end of wxListCtrl::InsertItem 
2308 long wxListCtrl::InsertItem ( 
2310 , const wxString
&                   rsLabel
 
2315     memset(&vInfo
, '\0', sizeof(wxListItem
)); 
2316     vInfo
.m_text   
= rsLabel
; 
2317     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
2318     vInfo
.m_itemId 
= lIndex
; 
2319     return InsertItem(vInfo
); 
2320 } // end of wxListCtrl::InsertItem 
2322 // Inserts an image item 
2323 long wxListCtrl::InsertItem ( 
2330     vInfo
.m_image  
= nImageIndex
; 
2331     vInfo
.m_mask   
= wxLIST_MASK_IMAGE
; 
2332     vInfo
.m_itemId 
= lIndex
; 
2333     return InsertItem(vInfo
); 
2334 } // end of wxListCtrl::InsertItem 
2336 // Inserts an image/string item 
2337 long wxListCtrl::InsertItem ( 
2339 , const wxString
&                   rsLabel
 
2345     vInfo
.m_image  
= nImageIndex
; 
2346     vInfo
.m_text   
= rsLabel
; 
2347     vInfo
.m_mask   
= wxLIST_MASK_IMAGE 
| wxLIST_MASK_TEXT
; 
2348     vInfo
.m_itemId 
= lIndex
; 
2349     return InsertItem(vInfo
); 
2350 } // end of wxListCtrl::InsertItem 
2352 // For details view mode (only), inserts a column. 
2353 long wxListCtrl::InsertColumn ( 
2359     PFIELDINFO                      pField 
= (PFIELDINFO
)::WinSendMsg( GetHWND() 
2360                                                                       ,CM_ALLOCDETAILFIELDINFO
 
2364     PFIELDINFO                      pFieldAfter 
= FindOS2ListFieldByColNum ( GetHWND() 
2367     FIELDINFOINSERT                 vInsert
; 
2369     ConvertToOS2ListCol ( lCol
 
2374     vInsert
.cb                   
= sizeof(FIELDINFOINSERT
); 
2375     vInsert
.pFieldInfoOrder      
= pFieldAfter
; 
2376     vInsert
.fInvalidateFieldInfo 
= TRUE
; 
2377     vInsert
.cFieldInfoInsert     
= 1; 
2379     bSuccess 
= ::WinSendMsg( GetHWND() 
2380                             ,CM_INSERTDETAILFIELDINFO
 
2385 } // end of wxListCtrl::InsertColumn 
2387 long wxListCtrl::InsertColumn ( 
2389 , const wxString
&                   rsHeading
 
2396     vItem
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_FORMAT
; 
2397     vItem
.m_text 
= rsHeading
; 
2400         vItem
.m_mask 
|= wxLIST_MASK_WIDTH
; 
2401         vItem
.m_width 
= nWidth
; 
2403     vItem
.m_format 
= nFormat
; 
2405     return InsertColumn( lCol
 
2408 } // end of wxListCtrl::InsertColumn 
2410 // scroll the control by the given number of pixels (exception: in list view, 
2411 // dx is interpreted as number of columns) 
2412 bool wxListCtrl::ScrollList ( int nDx
, int nDy 
) 
2415         ::WinSendMsg( GetHWND() 
2417                      ,(MPARAM
)CMA_HORIZONTAL
 
2421         ::WinSendMsg( GetHWND() 
2423                      ,(MPARAM
)CMA_VERTICAL
 
2427 } // end of wxListCtrl::ScrollList 
2429 bool wxListCtrl::SortItems ( wxListCtrlCompare fn
, long lData 
) 
2431     SInternalDataSort vInternalData
; 
2433     vInternalData
.m_fnUser 
= fn
; 
2434     vInternalData
.m_lData  
= lData
; 
2436     // WPARAM cast is needed for mingw/cygwin 
2437     if (!::WinSendMsg( GetHWND() 
2439                       ,(PFN
)InternalDataCompareFunc
 
2440                       ,(PVOID
)&vInternalData
 
2443         wxLogDebug(wxT("CM_SORTRECORD failed")); 
2447 } // end of wxListCtrl::SortItems 
2449 // ---------------------------------------------------------------------------- 
2450 // message processing 
2451 // ---------------------------------------------------------------------------- 
2453 bool wxListCtrl::OS2Command ( WXUINT uCmd
, WXWORD wId 
) 
2455     if (uCmd 
== CN_ENDEDIT
) 
2457         wxCommandEvent 
vEvent( wxEVT_COMMAND_TEXT_UPDATED
, wId 
); 
2459         vEvent
.SetEventObject( this ); 
2460         ProcessCommand(vEvent
); 
2463     else if (uCmd 
== CN_KILLFOCUS
) 
2465         wxCommandEvent 
vEvent( wxEVT_KILL_FOCUS
, wId 
); 
2466         vEvent
.SetEventObject( this ); 
2467         ProcessCommand(vEvent
); 
2472 } // end of wxListCtrl::OS2Command 
2474 // Necessary for drawing hrules and vrules, if specified 
2475 void wxListCtrl::OnPaint ( wxPaintEvent
& rEvent 
) 
2477     wxPaintDC                       
vDc(this); 
2478     wxPen                           
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
) 
2482     wxSize                          vClientSize 
= GetClientSize(); 
2484     int                             nItemCount 
= GetItemCount(); 
2487     bool                            bDrawHRules 
= ((GetWindowStyle() & wxLC_HRULES
) != 0); 
2488     bool                            bDrawVRules 
= ((GetWindowStyle() & wxLC_VRULES
) != 0); 
2490     wxControl::OnPaint(rEvent
); 
2493     // Reset the device origin since it may have been set 
2495     vDc
.SetDeviceOrigin(0, 0); 
2496     if (!bDrawHRules 
&& !bDrawVRules
) 
2498     if ((GetWindowStyle() & wxLC_REPORT
) == 0) 
2501     vDc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
2505         long                        lTop 
= GetTopItem(); 
2507         for (i 
= lTop
; i 
< lTop 
+ GetCountPerPage() + 1; i
++) 
2513                 nCy 
= vItemRect
.GetTop(); 
2514                 if (i 
!= 0) // Don't draw the first one 
2523                 if (i 
== nItemCount 
- 1) 
2525                     nCy 
= vItemRect
.GetBottom(); 
2536     if (bDrawVRules 
&& (i 
> -1)) 
2538         wxRect                      vFirstItemRect
; 
2548             int                     nX 
= vItemRect
.GetX(); 
2550             for (nCol 
= 0; nCol 
< GetColumnCount(); nCol
++) 
2552                 int                 nColWidth 
= GetColumnWidth(nCol
); 
2555                 vDc
.DrawLine( nX 
- 1 
2556                              ,vFirstItemRect
.GetY() - 2 
2558                              ,vItemRect
.GetBottom() 
2563 } // end of wxListCtrl::OnPaint 
2565 // ---------------------------------------------------------------------------- 
2566 // virtual list controls 
2567 // ---------------------------------------------------------------------------- 
2569 wxString 
wxListCtrl::OnGetItemText ( 
2570   long                              WXUNUSED(lItem
) 
2571 , long                              WXUNUSED(lCol
) 
2574     // this is a pure virtual function, in fact - which is not really pure 
2575     // because the controls which are not virtual don't need to implement it 
2576     wxFAIL_MSG( wxT("not supposed to be called") ); 
2577     return wxEmptyString
; 
2578 } // end of wxListCtrl::OnGetItemText 
2580 int wxListCtrl::OnGetItemImage ( 
2581   long                              WXUNUSED(lItem
) 
2585     wxFAIL_MSG( wxT("not supposed to be called") ); 
2587 } // end of wxListCtrl::OnGetItemImage 
2589 int wxListCtrl::OnGetItemColumnImage ( 
2595         return OnGetItemImage(lItem
); 
2598 } // end of wxListCtrl::OnGetItemColumnImage 
2600 wxListItemAttr
* wxListCtrl::OnGetItemAttr ( 
2601   long                              WXUNUSED_UNLESS_DEBUG(lItem
) 
2604     wxASSERT_MSG( lItem 
>= 0 && lItem 
< GetItemCount(), 
2605                   wxT("invalid item index in OnGetItemAttr()") ); 
2608     // No attributes by default 
2611 } // end of wxListCtrl::OnGetItemAttr 
2613 void wxListCtrl::SetItemCount ( 
2617     wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") ); 
2620     // Cannot explicitly set the record count in OS/2 
2622 } // end of wxListCtrl::SetItemCount 
2624 void wxListCtrl::RefreshItem ( 
2634 } // end of wxListCtrl::RefreshItem 
2636 void wxListCtrl::RefreshItems ( long lItemFrom
, long lItemTo 
) 
2641     GetItemRect( lItemFrom 
, vRect1 
); 
2642     GetItemRect( lItemTo 
, vRect2 
); 
2644     wxRect vRect 
= vRect1
; 
2646     vRect
.height 
= vRect2
.GetBottom() - vRect1
.GetTop(); 
2648 } // end of wxListCtrl::RefreshItems 
2650 MRESULT 
wxListCtrl::OS2WindowProc( WXUINT uMsg
, 
2654     bool                            bProcessed 
= false; 
2656     wxListEvent                     
vEvent( wxEVT_NULL
 
2659     wxEventType                     vEventType 
= wxEVT_NULL
; 
2660     PCNRDRAGINIT                    pDragInit 
= NULL
; 
2661     PCNREDITDATA                    pEditData 
= NULL
; 
2662     PNOTIFYRECORDENTER              pNotifyEnter 
= NULL
; 
2664     vEvent
.SetEventObject(this); 
2669             // First off let's set some internal data 
2671             switch(SHORT2FROMMP(wParam
)) 
2677                         CListItemInternalData
*  pInternaldata 
= (CListItemInternalData 
*)lParam
; 
2681                             wxListItem
*     pItem 
= (wxListItem
*)&vEvent
.GetItem(); 
2683                             pItem
->SetData((long)pInternaldata
->m_lParam
); 
2689             // Now let's go through the codes we're interested in 
2691             switch(SHORT2FROMMP(wParam
)) 
2694                     pDragInit 
= (PCNRDRAGINIT
)lParam
; 
2697                         PMYRECORD       pRecord 
= (PMYRECORD
)pDragInit
->pRecord
; 
2699                         vEventType 
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
; 
2700                         vEvent
.m_itemIndex   
= pRecord
->m_ulItemId
; 
2701                         vEvent
.m_pointDrag
.x 
= pDragInit
->x
; 
2702                         vEvent
.m_pointDrag
.y 
= pDragInit
->y
; 
2707                     pEditData 
= (PCNREDITDATA
)lParam
; 
2710                         vEventType 
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
; 
2711                         ConvertFromOS2ListItem( GetHWND() 
2712                                                ,(wxListItem 
&)vEvent
.GetItem() 
2713                                                ,(PMYRECORD
)pEditData
->pRecord
 
2715                         vEvent
.m_itemIndex 
= vEvent
.GetItem().GetId(); 
2720                     pEditData 
= (PCNREDITDATA
)lParam
; 
2723                         vEventType 
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
; 
2724                         ConvertFromOS2ListItem( GetHWND() 
2725                                                ,(wxListItem 
&)vEvent
.GetItem() 
2726                                                ,(PMYRECORD
)pEditData
->pRecord
 
2728                         if (pEditData
->cbText 
== 0) 
2729                             return (MRESULT
)FALSE
; 
2730                         vEvent
.m_itemIndex 
= vEvent
.GetItem().GetId(); 
2735                     pNotifyEnter 
= (PNOTIFYRECORDENTER
)lParam
; 
2738                         wxListItem
*     pItem 
= (wxListItem
*)&vEvent
.GetItem(); 
2739                         PMYRECORD       pMyRecord 
= (PMYRECORD
)pNotifyEnter
->pRecord
; 
2741                         vEventType             
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
; 
2742                         vEvent
.m_itemIndex 
= pMyRecord
->m_ulItemId
; 
2743                         pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
)); 
2744                         pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
)); 
2749                     // Add the CN_DROP messages for Direct Manipulation 
2752             vEvent
.SetEventType(vEventType
); 
2753             bProcessed 
= HandleWindowEvent(vEvent
); 
2757         lRc 
= wxControl::OS2WindowProc( uMsg
 
2762 } // end of wxListCtrl::WindowProc 
2764 #endif // wxUSE_LISTCTRL