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 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() 
 146     wxListItemAttr
*                 m_pAttr
; 
 147     WXLPARAM                        m_lParam
; // user data 
 148     PMYRECORD                       m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted 
 149 }; // end of CLASS CListItemInternalData 
 151 ///////////////////////////////////////////////////////////////////////////// 
 152 // STRUCT SInternalDataSort 
 156 // fn is a function which takes 3 long arguments: item1, item2, data. 
 157 // item1 is the long data associated with a first item (NOT the index). 
 158 // item2 is the long data associated with a second item (NOT the index). 
 159 // data is the same value as passed to SortItems. 
 161 // The return value is a negative number if the first item should precede the 
 162 // second item, a positive number of the second item should precede the first, 
 163 // or zero if the two items are equivalent. 
 165 // data is arbitrary data to be passed to the sort function. 
 167 // Internal structures for proxying the user compare function 
 168 // so that we can pass it the *real* user data 
 169 ///////////////////////////////////////////////////////////////////////////// 
 170 typedef struct internalDataSort
 
 172     wxListCtrlCompare               m_fnUser
; 
 174 } SInternalDataSort
; // end of STRUCT SInternalDataSort 
 176 // ---------------------------------------------------------------------------- 
 177 // private helper functions 
 178 // ---------------------------------------------------------------------------- 
 180 ///////////////////////////////////////////////////////////////////////////// 
 182 // FindOS2ListFieldByColNum 
 184 //  There is no way, under OS/2 to get a field in a container by index, 
 185 //  directly, so you must get the first one, then cycle through the list 
 186 //  until you get to where you want to be. 
 189 //  hWnd   -- window handle of container to search 
 190 //  lIndex -- index to set 
 193 //  pointer to the FIELDINFO struct at the index in the container record 
 195 ///////////////////////////////////////////////////////////////////////////// 
 196 PFIELDINFO 
FindOS2ListFieldByColNum ( 
 201     PFIELDINFO                      pFieldInfo 
= NULL
; 
 205     if (!::WinSendMsg( hWnd
 
 208                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 211     for (i 
= 0; i 
< vCnrInfo
.cFields
; i
++) 
 214             pFieldInfo 
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 215                                                               ,CM_QUERYDETAILFIELDINFO
 
 220             pFieldInfo 
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 221                                                               ,CM_QUERYDETAILFIELDINFO
 
 227         if (i 
== (ULONG
)lIndex
) 
 233 } // end of FindOS2ListFieldByColNum 
 235 ///////////////////////////////////////////////////////////////////////////// 
 237 // FindOS2ListRecordByID 
 239 //  There is no way, under OS/2 to get a record in a container by index, 
 240 //  directly, so you must get the first one, then cycle through the list 
 241 //  until you get to where you want to be. 
 244 //  hWnd    -- window handle of container to search 
 245 //  lItemId -- index to set 
 248 //  pointer to the internal RECORDCORE struct at the index in the container 
 250 ///////////////////////////////////////////////////////////////////////////// 
 251 PMYRECORD 
FindOS2ListRecordByID ( 
 256     PMYRECORD                       pRecord 
= NULL
; 
 260     if (!::WinSendMsg( hWnd
 
 263                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 266     for (i 
= 0; i 
< vCnrInfo
.cRecords
; i
++) 
 269             pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 272                                                           ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
 275             pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 278                                                           ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
 282         if (pRecord
->m_ulItemId 
== (ULONG
)lItemId
) 
 286 } // end of FindOS2ListRecordByID 
 288 ///////////////////////////////////////////////////////////////////////////// 
 292 //  Since OS/2 does not keep native record id's but wx insists on inserting 
 293 //  and selecting via ID's, when we insert a record in the middle we need 
 294 //  to bump the id's of each record after the one we just inserted. 
 297 //  hWnd    -- window handle of container to search 
 298 //  pRecord -- record after which we starting bumping id's 
 303 ///////////////////////////////////////////////////////////////////////////// 
 311         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 314                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
 317             pRecord
->m_ulItemId
++; 
 319 } // end of BumpRecordIds 
 321 ///////////////////////////////////////////////////////////////////////////// 
 325 //  Get the internal data given a handle and an id 
 328 //  hWnd    -- window handle to the control in which item is located 
 329 //  lItemId -- ID to get 
 332 //  pointer to the internal data 
 335 //  Under OS/2 PM a container item cannot be obtained via a simple index or 
 336 //  id retrieval.  We have to walk the record list if we are looking for 
 337 //  a record at a specific index location 
 338 ///////////////////////////////////////////////////////////////////////////// 
 339 CListItemInternalData
* GetInternalData ( 
 344     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( hWnd
 
 348     // Internal user data is stored AFTER the last field of the RECORDCORE 
 352     return((CListItemInternalData 
*)(pRecord
->m_ulUserData
)); 
 353 } // end of GetInternalData 
 355 ///////////////////////////////////////////////////////////////////////////// 
 359 //  Get the internal data given a pointer to a list control and an id 
 362 //  pCtl    -- pointer to control inwhich item is located 
 363 //  lItemId -- ID to get 
 366 //  pointer to the internal data 
 368 ///////////////////////////////////////////////////////////////////////////// 
 369 CListItemInternalData
* GetInternalData ( 
 374     return(GetInternalData( (HWND
)pCtl
->GetHWND() 
 377 } // end of GetInternalData 
 379 ///////////////////////////////////////////////////////////////////////////// 
 381 // DeleteInternalData 
 383 //  Delete the internal data for a record 
 386 //  pCtl    -- pointer to the list control containing the record 
 387 //  lItemId -- the record index to delete the internal data from 
 390 //  pointer to the internal data attribute 
 392 ///////////////////////////////////////////////////////////////////////////// 
 393 void DeleteInternalData ( 
 398     CListItemInternalData
*          pData 
= GetInternalData( pCtl
 
 403         if (pData
->m_pMyRecord
) 
 404             pData
->m_pMyRecord
->m_ulUserData 
= 0; 
 407 } // end of DeleteInternalData 
 409 // #pragma page   "GetInternalDataAttr" 
 410 ///////////////////////////////////////////////////////////////////////////// 
 412 // GetInternalDataAttr 
 414 //  Get the internal data item attribute given a pointer to a list control 
 418 //  pCtl    -- pointer to control to set 
 419 //  lItemId -- ID to set 
 422 //  pointer to the internal data attribute 
 424 ///////////////////////////////////////////////////////////////////////////// 
 425 wxListItemAttr
* GetInternalDataAttr ( 
 430     CListItemInternalData
*          pData 
= GetInternalData( pCtl
 
 435         return(pData
->m_pAttr
); 
 438 } // end of GetInternalDataAttr 
 440 ///////////////////////////////////////////////////////////////////////////// 
 442 // InternalDataCompareFunc 
 444 //  This is compare function we pass to PM.  It wraps the real compare 
 445 //  function in SInternalDataSort 
 448 //  p1       -- is the first record structure to compare 
 449 //  p2       -- is the second record structure to compare 
 450 //  lStorage -- is the same value as passed to SortItems. 
 453 //  pointer to the internal data attribute 
 455 ///////////////////////////////////////////////////////////////////////////// 
 456 SHORT EXPENTRY 
InternalDataCompareFunc ( 
 462     SInternalDataSort
*              pInternalData 
= (SInternalDataSort 
*)pStorage
; 
 463     CListItemInternalData
*          pData1 
= (CListItemInternalData 
*)p1
->m_ulUserData
; 
 464     CListItemInternalData
*          pData2 
= (CListItemInternalData 
*)p2
->m_ulUserData
; 
 465     long                            lD1 
= (pData1 
== NULL 
? 0 : (long)pData1
->m_lParam
); 
 466     long                            lD2 
= (pData2 
== NULL 
? 0 : (long)pData2
->m_lParam
); 
 468     return(pInternalData
->m_fnUser( lD1
 
 470                                    ,pInternalData
->m_lData
 
 472 } // end of InternalDataCompareFunc 
 474 ///////////////////////////////////////////////////////////////////////////// 
 476 // ConvertFromOS2ListItem 
 478 //  Convert from an internal PM List item to a Toolkit List item 
 481 //  hWndListCtrl -- the control's windows handle 
 482 //  rInfo        -- the library list control to convert to 
 483 //  pRecord      -- the OS list control to convert from 
 488 ///////////////////////////////////////////////////////////////////////////// 
 489 void ConvertFromOS2ListItem ( HWND hWndListCtrl
, 
 493     CListItemInternalData
* pInternaldata 
= (CListItemInternalData 
*)pRecord
->m_ulUserData
; 
 494     bool bNeedText 
= false; 
 497         rInfo
.SetData(pInternaldata
->m_lParam
); 
 501     rInfo
.SetStateMask(0); 
 502     rInfo
.SetId((long)pRecord
->m_ulItemId
); 
 503     if (hWndListCtrl 
!= 0) 
 505         pRecord 
= FindOS2ListRecordByID( hWndListCtrl
 
 511     // The wxListItem class is really set up to handle the WIN32 list item 
 512     // and OS/2 are not as complicated.  Just set both state members to the 
 513     // same thing under OS/2 
 515     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_DROPONABLE
) 
 517         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_DROPHILITED
); 
 518         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_DROPHILITED
); 
 520     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_SELECTED
) 
 522         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_SELECTED
); 
 523         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_SELECTED
); 
 525     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_DISABLED
) 
 527         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_DISABLED
); 
 528         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_DISABLED
); 
 530     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_FILTERED
) 
 532         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_FILTERED
); 
 533         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_FILTERED
); 
 535     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_INUSE
) 
 537         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_INUSE
); 
 538         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_INUSE
); 
 540     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_PICKED
) 
 542         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_PICKED
); 
 543         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_PICKED
); 
 545     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_SOURCE
) 
 547         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_SOURCE
); 
 548         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_SOURCE
); 
 551     if (pRecord
->m_vRecord
.pszText 
!= (PSZ
)NULL
) 
 553         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
); 
 554         rInfo
.SetText(pRecord
->m_vRecord
.pszText
); 
 556     if (pRecord
->m_vRecord
.pszIcon 
!= (PSZ
)NULL 
|| 
 557         pRecord
->m_vRecord
.pszName 
!= (PSZ
)NULL
) 
 559         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
); 
 560         rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
); 
 562     if (pRecord
->m_ulUserData
) 
 563         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
); 
 564 } // end of ConvertFromOS2ListItem 
 566 ///////////////////////////////////////////////////////////////////////////// 
 570 //  Convert from an library states to OS states 
 573 //  lState       -- the state 
 574 //  pRecord      -- the OS list control to use 
 579 ///////////////////////////////////////////////////////////////////////////// 
 580 void ConvertToOS2Flags ( 
 585     if (lState 
& wxLIST_STATE_DROPHILITED
) 
 586         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_DROPONABLE
; 
 587     if (lState 
& wxLIST_STATE_SELECTED
) 
 588         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_SELECTED
; 
 589     if (lState 
& wxLIST_STATE_DISABLED
) 
 590         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_DISABLED
; 
 591     if (lState 
& wxLIST_STATE_FILTERED
) 
 592         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_FILTERED
; 
 593     if (lState 
& wxLIST_STATE_INUSE
) 
 594         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_INUSE
; 
 595     if (lState 
& wxLIST_STATE_PICKED
) 
 596         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_PICKED
; 
 597     if (lState 
& wxLIST_STATE_SOURCE
) 
 598         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_SOURCE
; 
 599 } // end of ConvertToOS2Flags 
 601 ///////////////////////////////////////////////////////////////////////////// 
 603 // ConvertToOS2ListItem 
 605 //  Convert from a library List item to an internal OS2 List item. We set 
 606 //  only the fields we need to set.  Some of them are set by the API when 
 607 //  they are added to the container. 
 610 //  pCtrl      -- the control to use 
 611 //  rInfo      -- the item to convert 
 612 //  pRecord    -- the OS list control to use, should be zeroed out 
 613 //  pFieldinfo -- a field struct that may contain columnar data for detail view 
 618 ///////////////////////////////////////////////////////////////////////////// 
 619 void ConvertToOS2ListItem ( 
 620   const wxListCtrl
*                 pCtrl
 
 621 , const wxListItem
&                 rInfo
 
 623 , PFIELDINFO                        pFieldInfo
 
 626     pRecord
->m_ulItemId    
= (ULONG
)rInfo
.GetId(); 
 627     pRecord
->m_vRecord
.cb 
= sizeof(RECORDCORE
); 
 628     if (rInfo
.GetMask() & wxLIST_MASK_STATE
) 
 630         ConvertToOS2Flags( rInfo
.m_state
 
 634     if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON 
|| 
 635         pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
) 
 637         pRecord
->m_vRecord
.pszIcon 
= (char*)rInfo
.GetText().c_str(); 
 639     if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view 
 641         pRecord
->m_vRecord
.pszText 
= (char*)rInfo
.GetText().c_str(); 
 644     // In the case of a report view the text will be the data in the lead column 
 645     // ???? Don't know why, but that is how it works in other ports. 
 647     if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
) 
 651             switch(rInfo
.GetColumn()) 
 654                     pRecord
->m_pzColumn1 
= (char*)rInfo
.GetText().c_str(); 
 655                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn1
); 
 659                     pRecord
->m_pzColumn2 
= (char*)rInfo
.GetText().c_str(); 
 660                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn2
); 
 664                     pRecord
->m_pzColumn3 
= (char*)rInfo
.GetText().c_str(); 
 665                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn3
); 
 669                     pRecord
->m_pzColumn4 
= (char*)rInfo
.GetText().c_str(); 
 670                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn4
); 
 674                     pRecord
->m_pzColumn5 
= (char*)rInfo
.GetText().c_str(); 
 675                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn5
); 
 679                     pRecord
->m_pzColumn6 
= (char*)rInfo
.GetText().c_str(); 
 680                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn6
); 
 684                     pRecord
->m_pzColumn7 
= (char*)rInfo
.GetText().c_str(); 
 685                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn7
); 
 689                     pRecord
->m_pzColumn8 
= (char*)rInfo
.GetText().c_str(); 
 690                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn8
); 
 694                     pRecord
->m_pzColumn9 
= (char*)rInfo
.GetText().c_str(); 
 695                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn9
); 
 699                     pRecord
->m_pzColumn10 
= (char*)rInfo
.GetText().c_str(); 
 700                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn10
); 
 704                     wxFAIL_MSG( wxT("wxOS2 does not support more than 10 columns in REPORT view") ); 
 709     if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) 
 711         pRecord
->m_vRecord
.hptrIcon      
= (HPOINTER
)rInfo
.GetImage(); 
 712         pRecord
->m_vRecord
.hptrMiniIcon  
= (HPOINTER
)rInfo
.m_miniImage
; 
 714 } // end of ConvertToOS2ListItem 
 716 ///////////////////////////////////////////////////////////////////////////// 
 718 // ConvertToOS2ListCol 
 720 //  Convert from a library List column to an internal PM List column 
 723 //  lCol   -- the columnd to convert 
 724 //  rItem  -- the item to convert 
 725 //  pField -- the OS list column to use 
 730 ///////////////////////////////////////////////////////////////////////////// 
 731 void ConvertToOS2ListCol ( 
 733 , const wxListItem
&                 rItem
 
 737     memset(pField
, '\0', sizeof(FIELDINFO
)); 
 738     pField
->cb 
= sizeof(FIELDINFO
); 
 741     // Default some settings 
 743     pField
->flData  
= CFA_HORZSEPARATOR 
| CFA_SEPARATOR
; 
 744     pField
->flTitle 
= CFA_CENTER
; 
 746     if (rItem
.GetMask() & wxLIST_MASK_TEXT
) 
 748         pField
->flData 
|= CFA_STRING
; 
 749         pField
->pTitleData 
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data 
 751     if (rItem
.GetMask() & wxLIST_MASK_FORMAT
) 
 753         if (rItem
.m_format 
== wxLIST_FORMAT_LEFT
) 
 754             pField
->flData 
|= CFA_LEFT
; 
 755         else if (rItem
.m_format 
== wxLIST_FORMAT_RIGHT
) 
 756             pField
->flData 
|= CFA_RIGHT
; 
 757         else if (rItem
.m_format 
== wxLIST_FORMAT_CENTRE
) 
 758             pField
->flData 
|= CFA_CENTER
; 
 761         pField
->flData 
|= CFA_CENTER
;  // Just ensure the default is centered 
 762     if (rItem
.GetMask() & wxLIST_MASK_WIDTH
) 
 764         if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE 
|| 
 765              rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
)) 
 766             pField
->cxWidth 
= rItem
.GetWidth(); 
 767         // else: OS/2 automatically sets the width if created with the approppriate style 
 771     // Still need to set the actual data 
 773     pField
->offStruct 
= 0; 
 774 } // end of ConvertToOS2ListCol 
 776 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
) 
 777     EVT_PAINT(wxListCtrl::OnPaint
) 
 780 // ============================================================================ 
 782 // ============================================================================ 
 784 // ---------------------------------------------------------------------------- 
 785 // wxListCtrl construction 
 786 // ---------------------------------------------------------------------------- 
 788 void wxListCtrl::Init () 
 790     m_pImageListNormal     
= NULL
; 
 791     m_pImageListSmall      
= NULL
; 
 792     m_pImageListState      
= NULL
; 
 793     m_bOwnsImageListNormal 
= false; 
 794     m_bOwnsImageListSmall  
= false; 
 795     m_bOwnsImageListState  
= false; 
 799     m_bAnyInternalData     
= false; 
 800     m_bHasAnyAttr          
= false; 
 801 } // end of wxListCtrl::Init 
 803 bool wxListCtrl::Create ( wxWindow
* pParent
, 
 808                           const wxValidator
& rValidator
, 
 809                           const wxString
& rsName 
) 
 813     int nWidth 
= rSize
.x
; 
 814     int nHeight 
= rSize
.y
; 
 817     SetValidator(rValidator
); 
 818 #endif // wxUSE_VALIDATORS 
 821     SetWindowStyleFlag(lStyle
); 
 832     m_windowId 
= (vId 
== -1) ? NewControlId() : vId
; 
 834     long lSstyle 
= WS_VISIBLE 
| WS_TABSTOP
; 
 836     if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
) 
 837         lSstyle 
|= WS_CLIPSIBLINGS
; 
 838     m_lBaseStyle 
= lSstyle
; 
 839     if (!DoCreateControl( nX
 
 846         pParent
->AddChild(this); 
 848 } // end of wxListCtrl::Create 
 850 bool wxListCtrl::DoCreateControl ( int nX
, int nY
, 
 851                                    int nWidth
, int nHeight 
) 
 853     DWORD lWstyle 
= m_lBaseStyle
; 
 854     long lOldStyle 
= 0; // Dummy 
 858     lWstyle 
|= ConvertToOS2Style( lOldStyle
 
 859                                  ,GetWindowStyleFlag() 
 862     m_hWnd 
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND() 
 867                                        ,GetParent()->GetHWND() 
 879     // Now set the display attributes of the container 
 881     if (!::WinSendMsg( GetHWND() 
 884                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 887     lWstyle 
= ConvertViewToOS2Style(GetWindowStyleFlag()); 
 888     vCnrInfo
.flWindowAttr 
|= lWstyle
; 
 889     if (!::WinSendMsg( GetHWND() 
 892                       ,(MPARAM
)CMA_FLWINDOWATTR
 
 897     // And now set needed arrangement flags 
 899     lWstyle 
= ConvertArrangeToOS2Style(GetWindowStyleFlag()); 
 900     if (!::WinSendMsg( GetHWND() 
 902                       ,(MPARAM
)CMA_ARRANGEGRID
 
 906     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 907     SetForegroundColour(GetParent()->GetForegroundColour()); 
 909     SetFont(*wxSMALL_FONT
); 
 912     SetSize( nX
, nY
, nWidth
, nHeight 
); 
 914 } // end of wxListCtrl::DoCreateControl 
 916 void wxListCtrl::UpdateStyle () 
 921         DWORD dwStyleNew 
= ConvertToOS2Style( lDummy
, GetWindowStyleFlag() ); 
 923         dwStyleNew 
|= m_lBaseStyle
; 
 926         // Get the current window style. 
 928         ULONG dwStyleOld 
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
); 
 931         // Only set the window style if the view bits have changed. 
 933         if (dwStyleOld 
!= dwStyleNew
) 
 935             ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
); 
 938 } // end of wxListCtrl::UpdateStyle 
 940 void wxListCtrl::FreeAllInternalData () 
 942     if (m_bAnyInternalData
) 
 944         int n 
= GetItemCount(); 
 947         for (i 
= 0; i 
< n
; i
++) 
 948             DeleteInternalData(this, (long)i
); 
 949         m_bAnyInternalData 
= false; 
 951 } // end of wxListCtrl::FreeAllInternalData 
 953 wxListCtrl::~wxListCtrl () 
 955     FreeAllInternalData(); 
 958         m_pTextCtrl
->SetHWND(0); 
 959         m_pTextCtrl
->UnsubclassWin(); 
 960         wxDELETE(m_pTextCtrl
); 
 963     if (m_bOwnsImageListNormal
) 
 964         delete m_pImageListNormal
; 
 965     if (m_bOwnsImageListSmall
) 
 966         delete m_pImageListSmall
; 
 967     if (m_bOwnsImageListState
) 
 968         delete m_pImageListState
; 
 969 } // end of wxListCtrl::~wxListCtrl 
 971 // ---------------------------------------------------------------------------- 
 972 // set/get/change style 
 973 // ---------------------------------------------------------------------------- 
 975 // Add or remove a single window style 
 976 void wxListCtrl::SetSingleStyle ( 
 981     long                            lFlag 
= GetWindowStyleFlag(); 
 984     // Get rid of conflicting styles 
 988         if (lStyle 
& wxLC_MASK_TYPE
) 
 989             lFlag 
= lFlag 
& ~wxLC_MASK_TYPE
; 
 990         if (lStyle 
& wxLC_MASK_ALIGN 
) 
 991             lFlag 
= lFlag 
& ~wxLC_MASK_ALIGN
; 
 992         if (lStyle 
& wxLC_MASK_SORT 
) 
 993             lFlag 
= lFlag 
& ~wxLC_MASK_SORT
; 
1007     m_windowStyle 
= lFlag
; 
1009 } // end of wxListCtrl::SetSingleStyle 
1011 // Set the whole window style 
1012 void wxListCtrl::SetWindowStyleFlag ( 
1016     m_windowStyle 
= lFlag
; 
1018 } // end of wxListCtrl::SetWindowStyleFlag 
1020 long wxListCtrl::ConvertToOS2Style ( 
1028     // The only styles OS2 uses on creation are auto arrange, read only, and 
1029     // and selection styles.  This lib does not support OS/2 MINIRECORDCORE 
1030     // or VERIFYPOINTER styles 
1032     if (lStyle 
& wxLC_AUTOARRANGE
) 
1033         lWstyle 
|= CCS_AUTOPOSITION
; 
1034     if (lStyle 
& wxLC_SINGLE_SEL
) 
1035         lWstyle 
|= CCS_SINGLESEL
; 
1037         lWstyle 
|= CCS_EXTENDSEL
; 
1038     if (!(lStyle 
& wxLC_EDIT_LABELS
)) 
1039         lWstyle 
|= CCS_READONLY
; 
1041 } // end of wxListCtrl::ConvertToOS2Style 
1043 long wxListCtrl::ConvertArrangeToOS2Style ( 
1049     if (lStyle 
& wxLC_ALIGN_LEFT
) 
1051         lWstyle 
|= CMA_LEFT
; 
1054     if (lStyle 
& wxLC_ALIGN_TOP
) 
1059 } // end of wxListCtrl::ConvertArrangeToOS2Style 
1061 long wxListCtrl::ConvertViewToOS2Style ( 
1065     long                            lWstyle 
= CA_DRAWICON
; // we will only use icons 
1067     if (lStyle 
& wxLC_ICON
) 
1071     if (lStyle 
& wxLC_SMALL_ICON
) 
1073         lWstyle 
|= (CV_ICON 
| CV_MINI
); 
1075     if (lStyle 
& wxLC_LIST
) 
1079     if (lStyle 
& wxLC_REPORT
) 
1081         lWstyle 
|= CV_DETAIL
; 
1083     if (lStyle 
& wxLC_VIRTUAL
) 
1085         lWstyle 
|= CA_OWNERDRAW
; 
1087     if (lStyle 
& wxLC_AUTOARRANGE
) 
1091     if (!(lStyle 
& wxLC_NO_HEADER
)) 
1093         lWstyle 
|= CA_DETAILSVIEWTITLES
; 
1096 } // end of wxListCtrl::ConvertViewToOS2Style 
1098 // ---------------------------------------------------------------------------- 
1100 // ---------------------------------------------------------------------------- 
1102 // Sets the foreground, i.e. text, colour 
1103 bool wxListCtrl::SetForegroundColour (const wxColour
& rCol
) 
1105     ULONG ulColor 
= wxColourToRGB(rCol
); 
1107     if (!wxWindow::SetForegroundColour(rCol
)) 
1110     ::WinSetPresParam( GetHWND() 
1116 } // end of wxListCtrl::SetForegroundColour 
1118 // Sets the background colour 
1119 bool wxListCtrl::SetBackgroundColour ( const wxColour
& rCol 
) 
1121     if (!wxWindow::SetBackgroundColour(rCol
)) 
1125     // We set the same colour for both the "empty" background and the items 
1128     ULONG ulColor 
= wxColourToRGB(rCol
); 
1130     ::WinSetPresParam( GetHWND() 
1136 } // end of wxListCtrl::SetBackgroundColour 
1138 // Gets information about this column 
1139 bool wxListCtrl::GetColumn ( int nCol
, wxListItem
& rItem 
) const 
1141     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND(), nCol 
); 
1145     rItem
.SetWidth(pFieldInfo
->cxWidth
); 
1146     if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) && 
1147         (pFieldInfo
->flData 
& CFA_STRING
) && 
1148         (pFieldInfo
->pUserData 
!= NULL
)) 
1150         rItem
.SetText((char*)pFieldInfo
->pUserData
); 
1152     if (rItem
.GetMask() & wxLIST_MASK_FORMAT 
) 
1154         if (pFieldInfo
->flData 
& CFA_LEFT
) 
1155             rItem
.m_format 
= wxLIST_FORMAT_LEFT
; 
1156         else if (pFieldInfo
->flData 
& CFA_RIGHT
) 
1157             rItem
.m_format 
= wxLIST_FORMAT_RIGHT
; 
1158         else if (pFieldInfo
->flData 
& CFA_CENTER
) 
1159             rItem
.m_format 
= wxLIST_FORMAT_CENTRE
; 
1162 } // end of wxListCtrl::GetColumn 
1164 // Sets information about this column 
1165 bool wxListCtrl::SetColumn ( int nCol
, wxListItem
& rItem 
) 
1167     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum( GetHWND(), nCol 
); 
1168     ConvertToOS2ListCol( nCol
, rItem
, pFieldInfo 
); 
1170     // Since we changed the field pointed to, we invalidate to see the result 
1172     ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
); 
1174 } // end of wxListCtrl::SetColumn 
1176 // Gets the column width 
1177 int wxListCtrl::GetColumnWidth ( int nCol 
) const 
1179     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND(), nCol 
); 
1183     return((int)pFieldInfo
->cxWidth
); 
1184 } // end of wxListCtrl::GetColumnWidth 
1186 // Sets the column width 
1187 bool wxListCtrl::SetColumnWidth ( int nCol
, int nWidth 
) 
1190     int nWidth2 
= nWidth
; 
1192     if (GetWindowStyleFlag() & wxLC_LIST
) 
1195     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum( GetHWND(), nCol 
); 
1196     pFieldInfo
->cxWidth 
= nWidth
; 
1197     ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
); 
1199 } // end of wxListCtrl::SetColumnWidth 
1201 // Gets the number of items that can fit vertically in the 
1202 // visible area of the list control (list or report view) 
1203 // or the total number of items in the list control (icon 
1204 // or small icon view) 
1205 int wxListCtrl::GetCountPerPage () const 
1207     QUERYRECORDRECT                 vQueryRect
; 
1213     if (!::WinSendMsg( GetHWND() 
1216                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1219     memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
)); 
1220     vQueryRect
.cb 
= sizeof(QUERYRECORDRECT
); 
1221     if (vCnrInfo
.flWindowAttr 
& CV_ICON
) 
1222         vQueryRect
.fsExtent 
= CMA_ICON 
| CMA_TEXT
; 
1223     else if (vCnrInfo
.flWindowAttr 
& CV_NAME
) 
1224         vQueryRect
.fsExtent 
= CMA_ICON 
| CMA_TEXT
; 
1225     else if (vCnrInfo
.flWindowAttr 
& CV_TEXT
) 
1226         vQueryRect
.fsExtent 
= CMA_TEXT
; 
1227     else if (vCnrInfo
.flWindowAttr 
& CV_DETAIL
) 
1228         vQueryRect
.fsExtent 
= CMA_TEXT
; 
1229     if (!::WinSendMsg( GetHWND() 
1231                       ,MPFROMP(&vRectRecord
) 
1232                       ,MPFROMP(&vQueryRect
) 
1235     if (!::WinSendMsg( GetHWND() 
1236                       ,CM_QUERYVIEWPORTRECT
 
1237                       ,MPFROMP(&vRectControl
) 
1238                       ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
) 
1241     nCount 
= (int)((int)((vRectControl
.xRight 
- vRectControl
.xLeft
) / (vRectRecord
.xRight 
- vRectRecord
.xLeft
)) * 
1242                    (int)((vRectControl
.yTop 
- vRectControl
.yBottom
) / (vRectRecord
.yTop 
- vRectRecord
.yBottom
)) 
1244     if (nCount 
> (int)vCnrInfo
.cFields
) 
1245         nCount 
= (int)vCnrInfo
.cFields
; 
1247 } // end of wxListCtrl::GetCountPerPage 
1249 // Gets the edit control for editing labels. 
1250 wxTextCtrl
* wxListCtrl::GetEditControl() const 
1255 // Gets information about the item 
1256 bool wxListCtrl::GetItem ( wxListItem
& rInfo 
) const 
1258     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() ); 
1261     // Give NULL as hwnd as we already have everything we need 
1263     ConvertFromOS2ListItem( NULL
, rInfo
, pRecord 
); 
1265 } // end of wxListCtrl::GetItem 
1267 // Sets information about the item 
1268 bool wxListCtrl::SetItem ( wxListItem
& rInfo 
) 
1270     PFIELDINFO pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND(), rInfo
.GetColumn() ); 
1271     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() ); 
1273     ConvertToOS2ListItem( this 
1280     // Check if setting attributes or lParam 
1282     if (rInfo
.HasAttributes() || (rInfo
.GetMask()  & wxLIST_MASK_DATA
)) 
1285         // Get internal item data 
1286         // perhaps a cache here ? 
1288         CListItemInternalData
*      pData 
= GetInternalData( this 
1297             m_bAnyInternalData    
= true; 
1298             pData                 
= new CListItemInternalData(); 
1299             pRecord
->m_ulUserData 
= (unsigned long)pData
; 
1305         if (rInfo
.GetMask()  & wxLIST_MASK_DATA
) 
1306             pData
->m_lParam 
= (WXLPARAM
)rInfo
.GetData(); 
1309         if (rInfo
.HasAttributes()) 
1312                 *pData
->m_pAttr 
= *rInfo
.GetAttributes(); 
1314                 pData
->m_pAttr 
= new wxListItemAttr(*rInfo
.GetAttributes()); 
1316         pData
->m_pMyRecord 
= pRecord
;  // they point to each other 
1320     // We need to update the item immediately to show the new image 
1322     bool bUpdateNow 
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0; 
1325     // Check whether it has any custom attributes 
1327     if (rInfo
.HasAttributes()) 
1329         m_bHasAnyAttr 
= true; 
1332         // If the colour has changed, we must redraw the item 
1336     if (::WinIsWindowVisible(GetHWND())) 
1338         ::WinSendMsg( GetHWND() 
1339                      ,CM_INVALIDATERECORD
 
1341                      ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1343         RefreshItem(pRecord
->m_ulItemId
); 
1345     ::WinSendMsg( GetHWND() 
1346                  ,CM_INVALIDATEDETAILFIELDINFO
 
1351 } // end of wxListCtrl::SetItem 
1353 long wxListCtrl::SetItem ( 
1356 , const wxString
&                   rsLabel
 
1362     vInfo
.m_text   
= rsLabel
; 
1363     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1364     vInfo
.m_itemId 
= lIndex
; 
1368         vInfo
.m_image 
= nImageId
; 
1369         vInfo
.m_mask 
|= wxLIST_MASK_IMAGE
; 
1371     return SetItem(vInfo
); 
1372 } // end of wxListCtrl::SetItem 
1374 // Gets the item state 
1375 int wxListCtrl::GetItemState ( 
1382     vInfo
.m_mask      
= wxLIST_MASK_STATE
; 
1383     vInfo
.m_stateMask 
= lStateMask
; 
1384     vInfo
.m_itemId    
= lItem
; 
1386     if (!GetItem(vInfo
)) 
1388     return vInfo
.m_state
; 
1389 } // end of wxListCtrl::GetItemState 
1391 // Sets the item state 
1392 bool wxListCtrl::SetItemState ( long lItem
, long lState
, long lStateMask 
) 
1394     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
1397     // Don't use SetItem() here as it doesn't work with the virtual list 
1400     ConvertToOS2Flags( lState
, pRecord 
); 
1403     // for the virtual list controls we need to refresh the previously focused 
1404     // item manually when changing focus without changing selection 
1405     // programmatically because otherwise it keeps its focus rectangle until 
1406     // next repaint (yet another comctl32 bug) 
1411         (lStateMask 
& wxLIST_STATE_FOCUSED
) && 
1412          (lState 
& wxLIST_STATE_FOCUSED
) ) 
1414         lFocusOld 
= GetNextItem( -1 
1416                                 ,wxLIST_STATE_FOCUSED
 
1423     ::WinSendMsg( GetHWND() 
1424                  ,CM_INVALIDATERECORD
 
1426                  ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1429     if (lFocusOld 
!= -1) 
1432         // No need to refresh the item if it was previously selected, it would 
1433         // only result in annoying flicker 
1435         if (!(GetItemState( lFocusOld
 
1436                            ,wxLIST_STATE_SELECTED
 
1437                           ) & wxLIST_STATE_SELECTED
)) 
1439             RefreshItem(lFocusOld
); 
1443 } // end of wxListCtrl::SetItemState 
1445 // Sets the item image 
1446 bool wxListCtrl::SetItemImage ( 
1449 , int                               WXUNUSED(nSelImage
)) 
1451     return SetItemColumnInfo(lItem
, 0, nImage
); 
1452 } // end of wxListCtrl::SetItemImage 
1454 // Sets the item image 
1455 bool wxListCtrl::SetItemColumnImage ( 
1462     vInfo
.m_mask   
= wxLIST_MASK_IMAGE
; 
1463     vInfo
.m_image  
= nImage
; 
1464     vInfo
.m_itemId 
= lItem
; 
1465     vInfo
.m_col    
= lColumn
; 
1466     return SetItem(vInfo
); 
1467 } // end of wxListCtrl::SetItemColumnImage 
1469 // Gets the item text 
1470 wxString 
wxListCtrl::GetItemText ( 
1476     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1477     vInfo
.m_itemId 
= lItem
; 
1479     if (!GetItem(vInfo
)) 
1480         return wxEmptyString
; 
1481     return vInfo
.m_text
; 
1482 } // end of wxListCtrl::GetItemText 
1484 // Sets the item text 
1485 void wxListCtrl::SetItemText ( 
1487 , const wxString
&                   rsStr
 
1492     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1493     vInfo
.m_itemId 
= lItem
; 
1494     vInfo
.m_text   
= rsStr
; 
1496 } // end of wxListCtrl::SetItemText 
1498 // Gets the item data 
1499 long wxListCtrl::GetItemData ( 
1505     vInfo
.m_mask   
= wxLIST_MASK_DATA
; 
1506     vInfo
.m_itemId 
= lItem
; 
1507     if (!GetItem(vInfo
)) 
1509     return vInfo
.m_data
; 
1510 } // end of wxListCtrl::GetItemData 
1512 // Sets the item data 
1513 bool wxListCtrl::SetItemPtrData ( 
1520     vInfo
.m_mask   
= wxLIST_MASK_DATA
; 
1521     vInfo
.m_itemId 
= lItem
; 
1522     vInfo
.m_data   
= lData
; 
1523     return SetItem(vInfo
); 
1524 } // end of wxListCtrl::SetItemPtrData 
1526 // Gets the item rectangle 
1527 bool wxListCtrl::GetItemRect ( long lItem
, 
1532     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
1533     QUERYRECORDRECT vQueryRect
; 
1539     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
1540     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
1541     vQueryRect
.fRightSplitWindow 
= TRUE
; 
1542     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
1543     ::WinSendMsg( GetHWND() 
1546                  ,MPFROMP(&vQueryRect
) 
1549     // remember OS/2 is backwards 
1551     GetClientSize( NULL
, &nHeight 
); 
1552     rRect
.x      
= vRect
.xLeft
; 
1553     rRect
.y      
= nHeight 
- vRect
.yTop
; 
1554     rRect
.width  
= vRect
.xRight
; 
1555     rRect
.height 
= nHeight 
- vRect
.yBottom
; 
1558 } // end of wxListCtrl::GetItemRect 
1560 // Gets the item position 
1561 bool wxListCtrl::GetItemPosition ( long lItem
, wxPoint
& rPos 
) const 
1564     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND() , lItem 
); 
1565     QUERYRECORDRECT vQueryRect
; 
1571     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
1572     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
1573     vQueryRect
.fRightSplitWindow 
= TRUE
; 
1574     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
1575     ::WinSendMsg( GetHWND() 
1578                  ,MPFROMP(&vQueryRect
) 
1581     // remember OS/2 is backwards 
1583     GetClientSize( NULL
, &nHeight 
); 
1584     rPos
.x   
= vRect
.xLeft
; 
1585     rPos
.y   
= nHeight 
- vRect
.yTop
; 
1588 } // end of wxListCtrl::GetItemPosition 
1590 // Sets the item position. 
1591 bool wxListCtrl::SetItemPosition ( long lItem
, const wxPoint
& rPos 
) 
1594     // Items cannot be positioned in X/Y coord in OS/2 
1597 } // end of wxListCtrl::SetItemPosition 
1599 // Gets the number of items in the list control 
1600 int wxListCtrl::GetItemCount () const 
1604     if (!::WinSendMsg( GetHWND() 
1607                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1610     return vCnrInfo
.cRecords
; 
1611 } // end of wxListCtrl::GetItemCount 
1613 // Retrieves the spacing between icons in pixels. 
1614 // If bIsSmall is true, gets the spacing for the small icon 
1615 // view, otherwise the large icon view. 
1616 int wxListCtrl::GetItemSpacing ( bool bIsSmall 
) const 
1620     if (!::WinSendMsg( GetHWND() 
1623                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1626     return vCnrInfo
.cyLineSpacing
; 
1627 } // end of wxListCtrl::GetItemSpacing 
1629 void wxListCtrl::SetItemTextColour ( 
1631 , const wxColour
&                   rCol
 
1636     vInfo
.m_itemId 
= lItem
; 
1637     vInfo
.SetTextColour(rCol
); 
1639 } // end of wxListCtrl::SetItemTextColour 
1641 wxColour 
wxListCtrl::GetItemTextColour ( 
1647     vInfo
.m_itemId 
= lItem
; 
1649     return vInfo
.GetTextColour(); 
1650 } // end of wxListCtrl::GetItemTextColour 
1652 void wxListCtrl::SetItemBackgroundColour ( 
1654 , const wxColour
&                   rCol
 
1659     vInfo
.m_itemId 
= lItem
; 
1660     vInfo
.SetBackgroundColour(rCol
); 
1662 } // end of wxListCtrl::SetItemBackgroundColour 
1664 wxColour 
wxListCtrl::GetItemBackgroundColour ( 
1670     vInfo
.m_itemId 
= lItem
; 
1672     return vInfo
.GetBackgroundColour(); 
1673 } // end of wxListCtrl::GetItemBackgroundColour 
1675 // Gets the number of selected items in the list control 
1676 int wxListCtrl::GetSelectedItemCount () const 
1678     PMYRECORD                       pRecord 
= NULL
; 
1680     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1681                                                   ,CM_QUERYRECORDEMPHASIS
 
1683                                                   ,(MPARAM
)CRA_SELECTED
 
1691         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1692                                                       ,CM_QUERYRECORDEMPHASIS
 
1694                                                       ,(MPARAM
)CRA_SELECTED
 
1700 } // end of wxListCtrl::GetSelectedItemCount 
1702 // Gets the text colour of the listview 
1703 wxColour 
wxListCtrl::GetTextColour () const 
1708     ::WinQueryPresParam( GetHWND() 
1718 } // end of wxListCtrl::GetTextColour 
1720 // Sets the text colour of the listview 
1721 void wxListCtrl::SetTextColour ( 
1722   const wxColour
&                   rCol
 
1725     ULONG                           ulColor 
= wxColourToRGB(rCol
); 
1727     ::WinSetPresParam( GetHWND() 
1732 } // end of wxListCtrl::SetTextColour 
1734 // Gets the index of the topmost visible item when in 
1735 // list or report view 
1736 long wxListCtrl::GetTopItem () const 
1738     PMYRECORD                       pRecord 
= NULL
; 
1739     QUERYRECFROMRECT                vQueryRect
; 
1742     ::WinSendMsg( GetHWND() 
1743                  ,CM_QUERYVIEWPORTRECT
 
1745                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
1747     vQueryRect
.cb        
= sizeof(QUERYRECFROMRECT
); 
1748     vQueryRect
.rect      
= vRect
; 
1749     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
1751     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1752                                       ,CM_QUERYRECORDFROMRECT
 
1754                                       ,MPFROMP(&vQueryRect
) 
1759     return (long)pRecord
->m_ulItemId
; 
1760 } // end of wxListCtrl::GetTopItem 
1762 // Searches for an item, starting from 'item'. 
1763 // 'geometry' is one of 
1764 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT. 
1765 // 'state' is a state bit flag, one or more of 
1766 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT. 
1767 // item can be -1 to find the first item that matches the 
1769 // Returns the item or -1 if unsuccessful. 
1770 long wxListCtrl::GetNextItem ( 
1772 , int                               WXUNUSED(nGeom
) 
1773 , int                               WXUNUSED(nState
) 
1776     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1780     pRecord 
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
; 
1782         return((long)pRecord
->m_ulItemId
); 
1784 } // end of wxListCtrl::GetNextItem 
1786 wxImageList
* wxListCtrl::GetImageList ( 
1790     if (nWhich 
== wxIMAGE_LIST_NORMAL 
) 
1792         return m_pImageListNormal
; 
1794     else if (nWhich 
== wxIMAGE_LIST_SMALL 
) 
1796         return m_pImageListSmall
; 
1798     else if (nWhich 
== wxIMAGE_LIST_STATE 
) 
1800         return m_pImageListState
; 
1803 } // end of wxListCtrl::GetImageList 
1805 void wxListCtrl::SetImageList ( wxImageList
* pImageList
, 
1808     if (nWhich 
== wxIMAGE_LIST_NORMAL
) 
1810         if (m_bOwnsImageListNormal
) 
1811             delete m_pImageListNormal
; 
1812         m_pImageListNormal     
= pImageList
; 
1813         m_bOwnsImageListNormal 
= false; 
1815     else if (nWhich 
== wxIMAGE_LIST_SMALL
) 
1817         if (m_bOwnsImageListSmall
) 
1818             delete m_pImageListSmall
; 
1819         m_pImageListSmall    
= pImageList
; 
1820         m_bOwnsImageListSmall 
= false; 
1822     else if (nWhich 
== wxIMAGE_LIST_STATE
) 
1824         if (m_bOwnsImageListState
) 
1825             delete m_pImageListState
; 
1826         m_pImageListState     
= pImageList
; 
1827         m_bOwnsImageListState 
= false; 
1829 } // end of wxListCtrl::SetImageList 
1831 void wxListCtrl::AssignImageList ( wxImageList
* pImageList
, int nWhich 
) 
1833     SetImageList( pImageList
, nWhich 
); 
1835     if (nWhich 
== wxIMAGE_LIST_NORMAL 
) 
1836         m_bOwnsImageListNormal 
= true; 
1837     else if (nWhich 
== wxIMAGE_LIST_SMALL 
) 
1838         m_bOwnsImageListSmall 
= true; 
1839     else if (nWhich 
== wxIMAGE_LIST_STATE 
) 
1840         m_bOwnsImageListState 
= true; 
1841 } // end of wxListCtrl::AssignImageList 
1843 // ---------------------------------------------------------------------------- 
1845 // ---------------------------------------------------------------------------- 
1847 // Arranges the items 
1848 bool wxListCtrl::Arrange ( int nFlag 
) 
1853     if (nFlag 
== wxLIST_ALIGN_SNAP_TO_GRID
) 
1855         ulType 
= CMA_ARRANGEGRID
; 
1856         if (nFlag 
== wxLIST_ALIGN_LEFT
) 
1857             ulFlags 
|= CMA_LEFT
; 
1858         else if (nFlag 
== wxLIST_ALIGN_TOP
) 
1860         else if (nFlag 
== wxLIST_ALIGN_DEFAULT
) 
1861             ulFlags 
|= CMA_LEFT
; 
1864         ulType 
= CMA_ARRANGESTANDARD
; 
1865     ::WinSendMsg( GetHWND() 
1871     // We do not support CMA_ARRANGESELECTED 
1874 } // end of wxListCtrl::Arrange 
1877 bool wxListCtrl::DeleteItem ( long lItem 
) 
1879     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
1880     if (LONGFROMMR(::WinSendMsg( GetHWND() 
1883                                 ,MPFROM2SHORT(1, CMA_FREE
) 
1890     // The virtual list control doesn't refresh itself correctly, help it 
1895         // We need to refresh all the lines below the one which was deleted 
1899         if (lItem 
> 0 && GetItemCount()) 
1901             GetItemRect( lItem 
- 1 
1907             vRectItem
.y 
= vRectItem
.height 
= 0; 
1909         wxRect                      vRectWin 
= GetRect(); 
1911         vRectWin
.height 
= vRectWin
.GetBottom() - vRectItem
.GetBottom(); 
1912         vRectWin
.y      
= vRectItem
.GetBottom(); 
1913         RefreshRect(vRectWin
); 
1916 } // end of wxListCtrl::DeleteItem 
1918 // Deletes all items 
1919 bool wxListCtrl::DeleteAllItems () 
1921     return((LONG
)::WinSendMsg( GetHWND() 
1924                               ,MPFROM2SHORT(0, CMA_FREE
) 
1926 } // end of wxListCtrl::DeleteAllItems 
1928 // Deletes all items 
1929 bool wxListCtrl::DeleteAllColumns () 
1931     while (m_nColCount 
> 0) 
1933         DeleteColumn(m_nColCount 
- 1); 
1937     wxASSERT_MSG(m_nColCount 
== 0, wxT("no columns should be left")); 
1939 } // end of wxListCtrl::DeleteAllColumns 
1942 bool wxListCtrl::DeleteColumn ( int nCol 
) 
1944     bool bSuccess 
= false; 
1945     PFIELDINFO pField 
= FindOS2ListFieldByColNum( GetHWND(), nCol 
); 
1946     bSuccess 
= ((LONG
)::WinSendMsg( GetHWND() 
1947                                    ,CM_REMOVEDETAILFIELDINFO
 
1949                                    ,MPFROM2SHORT((SHORT
)1, CMA_FREE
) 
1951     if (bSuccess 
&& (m_nColCount 
> 0)) 
1954 } // end of wxListCtrl::DeleteColumn 
1956 // Clears items, and columns if there are any. 
1957 void wxListCtrl::ClearAll () 
1960     if (m_nColCount 
> 0) 
1962 } // end of wxListCtrl::ClearAll 
1965 // OS/2 does not use a text control for its container labels.  You merely 
1966 // "open" a record for editting. 
1968 wxTextCtrl
* wxListCtrl::EditLabel ( 
1970 , wxClassInfo
*                      WXUNUSED(pTextControlClass
) 
1974     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1978     vEdit
.cb         
= sizeof(CNREDITDATA
); 
1979     vEdit
.hwndCnr    
= GetHWND(); 
1980     vEdit
.pRecord    
= &pRecord
->m_vRecord
; 
1981     vEdit
.pFieldInfo 
= NULL
; 
1982     vEdit
.ppszText   
= NULL
; 
1986     ::WinSendMsg( GetHWND() 
1992 } // end of wxListCtrl::EditLabel 
1994 // End label editing, optionally cancelling the edit.  Under OS/2 you close 
1995 // the record for editting 
1996 bool wxListCtrl::EndEditLabel ( bool WXUNUSED(bCancel
) ) 
1998     ::WinSendMsg( GetHWND() 
2004 } // end of wxListCtrl::EndEditLabel 
2006 // Ensures this item is visible 
2007 bool wxListCtrl::EnsureVisible ( long lItem 
) 
2009     PMYRECORD pRecord 
= FindOS2ListRecordByID( GetHWND(), lItem 
); 
2010     ::WinSendMsg( GetHWND() 
2011                  ,CM_INVALIDATERECORD
 
2013                  ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
) 
2016 } // end of wxListCtrl::EnsureVisible 
2018 // Find an item whose label matches this string, starting from the item after 'start' 
2019 // or the beginning if 'start' is -1. 
2020 long wxListCtrl::FindItem ( 
2022 , const wxString
&                   rsStr
 
2027     SEARCHSTRING                    vSearch
; 
2028     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2034     if (!::WinSendMsg( GetHWND() 
2037                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
2041     if (vCnrInfo
.flWindowAttr 
& CV_ICON
) 
2043     if (vCnrInfo
.flWindowAttr 
& CV_NAME
) 
2045     if (vCnrInfo
.flWindowAttr 
& CV_TEXT
) 
2047     if (vCnrInfo
.flWindowAttr 
& CV_DETAIL
) 
2050         ulFlag 
|= CV_EXACTLENGTH
; 
2052     vSearch
.cb              
= sizeof(SEARCHSTRING
); 
2053     vSearch
.pszSearch       
= (char*)rsStr
.c_str(); 
2054     vSearch
.fsPrefix        
= TRUE
; 
2055     vSearch
.fsCaseSensitive 
= TRUE
; 
2056     vSearch
.usView          
= ulFlag
; 
2060         pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2068         pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2076     return pRecord
->m_ulItemId
; 
2077 } // end of wxListCtrl::FindItem 
2079 // Find an item whose data matches this data, starting from the item after 'start' 
2080 // or the beginning if 'start' is -1. 
2081 long wxListCtrl::FindItem ( 
2086     long                            lIdx 
= lStart 
+ 1; 
2087     long                            lCount 
= GetItemCount(); 
2089     while (lIdx 
< lCount
) 
2091         if (GetItemData(lIdx
) == lData
) 
2096 } // end of wxListCtrl::FindItem 
2098 // Find an item nearest this position in the specified direction, starting from 
2099 // the item after 'start' or the beginning if 'start' is -1. 
2100 long wxListCtrl::FindItem ( 
2102 , const wxPoint
&                    rPoint
 
2107     QUERYRECORDRECT                 vQueryRect
; 
2108     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2115     if (!::WinSendMsg( GetHWND() 
2118                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
2122     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
2123     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
2124     vQueryRect
.fRightSplitWindow 
= TRUE
; 
2125     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
2127     ::WinSendMsg( GetHWND() 
2130                  ,MPFROMP(&vQueryRect
) 
2132     vLibRect
.SetLeft(vRect
.xLeft
); 
2133     vLibRect
.SetTop(vRect
.yTop
); 
2134     vLibRect
.SetRight(vRect
.xRight
); 
2135     vLibRect
.SetBottom(vRect
.yBottom
); 
2136     if (vLibRect
.Contains(rPoint
)) 
2137         return pRecord
->m_ulItemId
; 
2139     for (i 
= lStart 
+ 1; i 
< vCnrInfo
.cRecords
; i
++) 
2141         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
2144                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
2146         vQueryRect
.pRecord 
= (PRECORDCORE
)pRecord
; 
2147         ::WinSendMsg( GetHWND() 
2150                      ,MPFROMP(&vQueryRect
) 
2152         vLibRect
.SetLeft(vRect
.xLeft
); 
2153         vLibRect
.SetTop(vRect
.yTop
); 
2154         vLibRect
.SetRight(vRect
.xRight
); 
2155         vLibRect
.SetBottom(vRect
.yBottom
); 
2156         if (vLibRect
.Contains(rPoint
)) 
2157             return pRecord
->m_ulItemId
; 
2160 } // end of wxListCtrl::FindItem 
2162 // Determines which item (if any) is at the specified point, 
2163 // giving details in 'flags' (see wxLIST_HITTEST_... flags above) 
2164 long wxListCtrl::HitTest ( 
2165   const wxPoint
&                    rPoint
 
2166 , int&                              WXUNUSED(rFlags
) 
2169     PMYRECORD                       pRecord 
= NULL
; 
2170     QUERYRECFROMRECT                vQueryRect
; 
2175     // Get height for OS/2 point conversion 
2177     ::WinSendMsg( GetHWND() 
2178                  ,CM_QUERYVIEWPORTRECT
 
2180                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
2182     lHeight 
= vRect
.yTop 
- vRect
.yBottom
; 
2185     // For now just try and get a record in the general vicinity and forget 
2188     vRect
.xLeft   
= rPoint
.x 
- 2; 
2189     vRect
.xRight  
= rPoint
.x 
+ 2; 
2190     vRect
.yTop    
= (lHeight 
- rPoint
.y
) + 2; 
2191     vRect
.yBottom 
= (lHeight 
- rPoint
.y
) - 2; 
2193     vQueryRect
.cb 
= sizeof(QUERYRECFROMRECT
); 
2194     vQueryRect
.rect 
= vRect
; 
2195     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
2197     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2198                                       ,CM_QUERYRECORDFROMRECT
 
2200                                       ,MPFROMP(&vQueryRect
) 
2205     return pRecord
->m_ulItemId
; 
2206 } // end of wxListCtrl::HitTest 
2208 // Inserts an item, returning the index of the new item if successful, 
2210 long wxListCtrl::InsertItem ( 
2214     wxASSERT_MSG( !IsVirtual(), wxT("can't be used with virtual controls") ); 
2216     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND() 
2219     PMYRECORD                       pRecordAfter 
= NULL
; 
2220     PMYRECORD                       pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2222                                                                       ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
)) 
2226     ConvertToOS2ListItem( this 
2232     if (rInfo
.GetId() > 0) 
2233         pRecordAfter 
= FindOS2ListRecordByID( GetHWND() 
2237     RECORDINSERT                    vInsert
; 
2239     vInsert
.cb                
= sizeof(RECORDINSERT
); 
2240     vInsert
.pRecordParent     
= NULL
; 
2242         vInsert
.pRecordOrder  
= (PRECORDCORE
)CMA_FIRST
; 
2244         vInsert
.pRecordOrder  
= (PRECORDCORE
)pRecordAfter
; 
2245     vInsert
.zOrder            
= CMA_TOP
; 
2246     vInsert
.cRecordsInsert    
= 1; 
2247     vInsert
.fInvalidateRecord 
= TRUE
; 
2250     // Check whether we need to allocate our internal data 
2252     bool                            bNeedInternalData 
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) || 
2253                                                           rInfo
.HasAttributes() 
2255     if (bNeedInternalData
) 
2257         m_bAnyInternalData 
= true; 
2260         // Internal stucture that manages data 
2262         CListItemInternalData
*      pData 
= new CListItemInternalData(); 
2264         pRecord
->m_ulUserData 
= (unsigned long)pData
; 
2265         if (rInfo
.GetMask() & wxLIST_MASK_DATA
) 
2266             pData
->m_lParam 
= (WXLPARAM
)rInfo
.GetData(); 
2269         // Check whether it has any custom attributes 
2271         if (rInfo
.HasAttributes()) 
2274             // Take copy of attributes 
2276             pData
->m_pAttr 
= new wxListItemAttr(*rInfo
.GetAttributes()); 
2279     if (!::WinSendMsg( GetHWND() 
2286     // OS/2 must mannually bump the index's of following records 
2288     BumpRecordIds( GetHWND() 
2291     ::WinSendMsg( GetHWND() 
2292                  ,CM_INVALIDATEDETAILFIELDINFO
 
2296     return pRecord
->m_ulItemId
; 
2297 } // end of wxListCtrl::InsertItem 
2299 long wxListCtrl::InsertItem ( 
2301 , const wxString
&                   rsLabel
 
2306     memset(&vInfo
, '\0', sizeof(wxListItem
)); 
2307     vInfo
.m_text   
= rsLabel
; 
2308     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
2309     vInfo
.m_itemId 
= lIndex
; 
2310     return InsertItem(vInfo
); 
2311 } // end of wxListCtrl::InsertItem 
2313 // Inserts an image item 
2314 long wxListCtrl::InsertItem ( 
2321     vInfo
.m_image  
= nImageIndex
; 
2322     vInfo
.m_mask   
= wxLIST_MASK_IMAGE
; 
2323     vInfo
.m_itemId 
= lIndex
; 
2324     return InsertItem(vInfo
); 
2325 } // end of wxListCtrl::InsertItem 
2327 // Inserts an image/string item 
2328 long wxListCtrl::InsertItem ( 
2330 , const wxString
&                   rsLabel
 
2336     vInfo
.m_image  
= nImageIndex
; 
2337     vInfo
.m_text   
= rsLabel
; 
2338     vInfo
.m_mask   
= wxLIST_MASK_IMAGE 
| wxLIST_MASK_TEXT
; 
2339     vInfo
.m_itemId 
= lIndex
; 
2340     return InsertItem(vInfo
); 
2341 } // end of wxListCtrl::InsertItem 
2343 // For details view mode (only), inserts a column. 
2344 long wxListCtrl::InsertColumn ( 
2350     PFIELDINFO                      pField 
= (PFIELDINFO
)::WinSendMsg( GetHWND() 
2351                                                                       ,CM_ALLOCDETAILFIELDINFO
 
2355     PFIELDINFO                      pFieldAfter 
= FindOS2ListFieldByColNum ( GetHWND() 
2358     FIELDINFOINSERT                 vInsert
; 
2360     ConvertToOS2ListCol ( lCol
 
2365     vInsert
.cb                   
= sizeof(FIELDINFOINSERT
); 
2366     vInsert
.pFieldInfoOrder      
= pFieldAfter
; 
2367     vInsert
.fInvalidateFieldInfo 
= TRUE
; 
2368     vInsert
.cFieldInfoInsert     
= 1; 
2370     bSuccess 
= ::WinSendMsg( GetHWND() 
2371                             ,CM_INSERTDETAILFIELDINFO
 
2376 } // end of wxListCtrl::InsertColumn 
2378 long wxListCtrl::InsertColumn ( 
2380 , const wxString
&                   rsHeading
 
2387     vItem
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_FORMAT
; 
2388     vItem
.m_text 
= rsHeading
; 
2391         vItem
.m_mask 
|= wxLIST_MASK_WIDTH
; 
2392         vItem
.m_width 
= nWidth
; 
2394     vItem
.m_format 
= nFormat
; 
2396     return InsertColumn( lCol
 
2399 } // end of wxListCtrl::InsertColumn 
2401 // scroll the control by the given number of pixels (exception: in list view, 
2402 // dx is interpreted as number of columns) 
2403 bool wxListCtrl::ScrollList ( int nDx
, int nDy 
) 
2406         ::WinSendMsg( GetHWND() 
2408                      ,(MPARAM
)CMA_HORIZONTAL
 
2412         ::WinSendMsg( GetHWND() 
2414                      ,(MPARAM
)CMA_VERTICAL
 
2418 } // end of wxListCtrl::ScrollList 
2420 bool wxListCtrl::SortItems ( wxListCtrlCompare fn
, long lData 
) 
2422     SInternalDataSort vInternalData
; 
2424     vInternalData
.m_fnUser 
= fn
; 
2425     vInternalData
.m_lData  
= lData
; 
2427     // WPARAM cast is needed for mingw/cygwin 
2428     if (!::WinSendMsg( GetHWND() 
2430                       ,(PFN
)InternalDataCompareFunc
 
2431                       ,(PVOID
)&vInternalData
 
2434         wxLogDebug(wxT("CM_SORTRECORD failed")); 
2438 } // end of wxListCtrl::SortItems 
2440 // ---------------------------------------------------------------------------- 
2441 // message processing 
2442 // ---------------------------------------------------------------------------- 
2444 bool wxListCtrl::OS2Command ( WXUINT uCmd
, WXWORD wId 
) 
2446     if (uCmd 
== CN_ENDEDIT
) 
2448         wxCommandEvent 
vEvent( wxEVT_COMMAND_TEXT_UPDATED
, wId 
); 
2450         vEvent
.SetEventObject( this ); 
2451         ProcessCommand(vEvent
); 
2454     else if (uCmd 
== CN_KILLFOCUS
) 
2456         wxCommandEvent 
vEvent( wxEVT_KILL_FOCUS
, wId 
); 
2457         vEvent
.SetEventObject( this ); 
2458         ProcessCommand(vEvent
); 
2463 } // end of wxListCtrl::OS2Command 
2465 // Necessary for drawing hrules and vrules, if specified 
2466 void wxListCtrl::OnPaint ( wxPaintEvent
& rEvent 
) 
2468     wxPaintDC                       
vDc(this); 
2469     wxPen                           
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
) 
2473     wxSize                          vClientSize 
= GetClientSize(); 
2475     int                             nItemCount 
= GetItemCount(); 
2478     bool                            bDrawHRules 
= ((GetWindowStyle() & wxLC_HRULES
) != 0); 
2479     bool                            bDrawVRules 
= ((GetWindowStyle() & wxLC_VRULES
) != 0); 
2481     wxControl::OnPaint(rEvent
); 
2484     // Reset the device origin since it may have been set 
2486     vDc
.SetDeviceOrigin(0, 0); 
2487     if (!bDrawHRules 
&& !bDrawVRules
) 
2489     if ((GetWindowStyle() & wxLC_REPORT
) == 0) 
2492     vDc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
2496         long                        lTop 
= GetTopItem(); 
2498         for (i 
= lTop
; i 
< lTop 
+ GetCountPerPage() + 1; i
++) 
2504                 nCy 
= vItemRect
.GetTop(); 
2505                 if (i 
!= 0) // Don't draw the first one 
2514                 if (i 
== nItemCount 
- 1) 
2516                     nCy 
= vItemRect
.GetBottom(); 
2527     if (bDrawVRules 
&& (i 
> -1)) 
2529         wxRect                      vFirstItemRect
; 
2539             int                     nX 
= vItemRect
.GetX(); 
2541             for (nCol 
= 0; nCol 
< GetColumnCount(); nCol
++) 
2543                 int                 nColWidth 
= GetColumnWidth(nCol
); 
2546                 vDc
.DrawLine( nX 
- 1 
2547                              ,vFirstItemRect
.GetY() - 2 
2549                              ,vItemRect
.GetBottom() 
2554 } // end of wxListCtrl::OnPaint 
2556 // ---------------------------------------------------------------------------- 
2557 // virtual list controls 
2558 // ---------------------------------------------------------------------------- 
2560 wxString 
wxListCtrl::OnGetItemText ( 
2561   long                              WXUNUSED(lItem
) 
2562 , long                              WXUNUSED(lCol
) 
2565     // this is a pure virtual function, in fact - which is not really pure 
2566     // because the controls which are not virtual don't need to implement it 
2567     wxFAIL_MSG( wxT("not supposed to be called") ); 
2568     return wxEmptyString
; 
2569 } // end of wxListCtrl::OnGetItemText 
2571 int wxListCtrl::OnGetItemImage ( 
2572   long                              WXUNUSED(lItem
) 
2576     wxFAIL_MSG( wxT("not supposed to be called") ); 
2578 } // end of wxListCtrl::OnGetItemImage 
2580 int wxListCtrl::OnGetItemColumnImage ( 
2586         return OnGetItemImage(lItem
); 
2589 } // end of wxListCtrl::OnGetItemColumnImage 
2591 wxListItemAttr
* wxListCtrl::OnGetItemAttr ( 
2592   long                              WXUNUSED_UNLESS_DEBUG(lItem
) 
2595     wxASSERT_MSG( lItem 
>= 0 && lItem 
< GetItemCount(), 
2596                   wxT("invalid item index in OnGetItemAttr()") ); 
2599     // No attributes by default 
2602 } // end of wxListCtrl::OnGetItemAttr 
2604 void wxListCtrl::SetItemCount ( 
2608     wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") ); 
2611     // Cannot explicitly set the record count in OS/2 
2613 } // end of wxListCtrl::SetItemCount 
2615 void wxListCtrl::RefreshItem ( 
2625 } // end of wxListCtrl::RefreshItem 
2627 void wxListCtrl::RefreshItems ( long lItemFrom
, long lItemTo 
) 
2632     GetItemRect( lItemFrom 
, vRect1 
); 
2633     GetItemRect( lItemTo 
, vRect2 
); 
2635     wxRect vRect 
= vRect1
; 
2637     vRect
.height 
= vRect2
.GetBottom() - vRect1
.GetTop(); 
2639 } // end of wxListCtrl::RefreshItems 
2641 MRESULT 
wxListCtrl::OS2WindowProc( WXUINT uMsg
, 
2645     bool                            bProcessed 
= false; 
2647     wxListEvent                     
vEvent( wxEVT_NULL
 
2650     wxEventType                     vEventType 
= wxEVT_NULL
; 
2651     PCNRDRAGINIT                    pDragInit 
= NULL
; 
2652     PCNREDITDATA                    pEditData 
= NULL
; 
2653     PNOTIFYRECORDENTER              pNotifyEnter 
= NULL
; 
2655     vEvent
.SetEventObject(this); 
2660             // First off let's set some internal data 
2662             switch(SHORT2FROMMP(wParam
)) 
2668                         CListItemInternalData
*  pInternaldata 
= (CListItemInternalData 
*)lParam
; 
2672                             wxListItem
*     pItem 
= (wxListItem
*)&vEvent
.GetItem(); 
2674                             pItem
->SetData((long)pInternaldata
->m_lParam
); 
2680             // Now let's go through the codes we're interested in 
2682             switch(SHORT2FROMMP(wParam
)) 
2685                     pDragInit 
= (PCNRDRAGINIT
)lParam
; 
2688                         PMYRECORD       pRecord 
= (PMYRECORD
)pDragInit
->pRecord
; 
2690                         vEventType 
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
; 
2691                         vEvent
.m_itemIndex   
= pRecord
->m_ulItemId
; 
2692                         vEvent
.m_pointDrag
.x 
= pDragInit
->x
; 
2693                         vEvent
.m_pointDrag
.y 
= pDragInit
->y
; 
2698                     pEditData 
= (PCNREDITDATA
)lParam
; 
2701                         vEventType 
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
; 
2702                         ConvertFromOS2ListItem( GetHWND() 
2703                                                ,(wxListItem 
&)vEvent
.GetItem() 
2704                                                ,(PMYRECORD
)pEditData
->pRecord
 
2706                         vEvent
.m_itemIndex 
= vEvent
.GetItem().GetId(); 
2711                     pEditData 
= (PCNREDITDATA
)lParam
; 
2714                         vEventType 
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
; 
2715                         ConvertFromOS2ListItem( GetHWND() 
2716                                                ,(wxListItem 
&)vEvent
.GetItem() 
2717                                                ,(PMYRECORD
)pEditData
->pRecord
 
2719                         if (pEditData
->cbText 
== 0) 
2720                             return (MRESULT
)FALSE
; 
2721                         vEvent
.m_itemIndex 
= vEvent
.GetItem().GetId(); 
2726                     pNotifyEnter 
= (PNOTIFYRECORDENTER
)lParam
; 
2729                         wxListItem
*     pItem 
= (wxListItem
*)&vEvent
.GetItem(); 
2730                         PMYRECORD       pMyRecord 
= (PMYRECORD
)pNotifyEnter
->pRecord
; 
2732                         vEventType             
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
; 
2733                         vEvent
.m_itemIndex 
= pMyRecord
->m_ulItemId
; 
2734                         pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
)); 
2735                         pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
)); 
2740                     // Add the CN_DROP messages for Direct Manipulation 
2743             vEvent
.SetEventType(vEventType
); 
2744             bProcessed 
= HandleWindowEvent(vEvent
); 
2748         lRc 
= wxControl::OS2WindowProc( uMsg
 
2753 } // end of wxListCtrl::WindowProc 
2755 #endif // wxUSE_LISTCTRL