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 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "listctrl.h" 
  22     #pragma implementation "listctrlbase.h" 
  25 // For compilers that support precompilation, includes "wx.h". 
  26 #include "wx/wxprec.h" 
  38     #include "wx/settings.h" 
  41 #include "wx/textctrl.h" 
  42 #include "wx/imaglist.h" 
  43 #include "wx/listctrl.h" 
  44 #include "wx/dcclient.h" 
  46 #include "wx/os2/private.h" 
  49 // FIELDOFFSET in DETAIL view as defined in the OS2TK45 simply doesn't work 
  50 // We use this, which does! 
  53 #define FIELDOFFSET(type, field)    ((ULONG)&(((type *)0)->field)) 
  55 // ---------------------------------------------------------------------------- 
  56 // private helper classes 
  57 // ---------------------------------------------------------------------------- 
  59 ///////////////////////////////////////////////////////////////////////////// 
  61 //   Under OS/2 we have to use our own RECORDCORE based struct if we have 
  62 //   user data to store in a PM Container Control (and wxListCtrl is a PM 
  63 //   Container in ICON, NAME, TEXT or DETAIL view). m_ulUserData is a four 
  64 //   byte value containing a pointer to our CListIntemInternalData class 
  67 //   And now for the big time OS/2 Kludge.  In traditional OS/2 PM 
  68 //   applications using containers, programmers determine BEFORE creation 
  69 //   how many records the view will have, initially, and how many columns 
  70 //   the detail view of the container will have, as the container represents 
  71 //   a known data block.  Thus the OS/2 PM CV_DETAIL view, i.e. 
  72 //   the wxWidgets wxLC_REPORT view, relies on STATIC structure for its 
  73 //   columnar data.  It gets the data to display by telling it the specific 
  74 //   offset of the field in the struct containing the displayable data.  That 
  75 //   data has be of OS/2 Types, PSZ (char string), CDATE or CTIME format. 
  76 //   wxWidgets is dynamic in nature, however.  We insert columns, one at a 
  77 //   time and do not know how many until the app is done inserting them. So 
  78 //   for OS/2 I have to set a max allowable since they are fixed.  We return 
  79 //   an error to the app if they include more than we can handle. 
  81 //   For example to display the data "Col 4 of Item 6" in a report view, I'd 
  83 //   pRecord->m_pzColumn4 = "Col 4 of Item 6"; 
  84 //   pField->offStruct = FIELDOFFSET(MYRECORD, m_pzColumn4); 
  85 //   and then call the PM API to set it. 
  87 //   This really stinks but I can't use a pointer to another struct as the 
  88 //   FIELDOFFSET call could only tell OS/2 the four byte value offset of 
  89 //   pointer field and it would display giberish in the column. 
  90 ///////////////////////////////////////////////////////////////////////////// 
  91 typedef struct _MYRECORD
 
  94     unsigned long                   m_ulItemId
; 
  95     unsigned long                   m_ulUserData
; //actually a pointer value to real data (a CListItemInternalData class instance) 
 106 } MYRECORD
, *PMYRECORD
; 
 108 ///////////////////////////////////////////////////////////////////////////// 
 109 // CLASS CListItemInternalData 
 112 //  The MSW version had problems with SetTextColour() et al as the 
 113 //  CListItemAttr's were stored keyed on the item index. If a item was 
 114 //  inserted anywhere but the end of the list the the text attributes 
 115 //  (colour etc) for the following items were out of sync. 
 118 //  Under MSW the only way to associate data with a 
 119 //  List item independant of its position in the list is to store a pointer 
 120 //  to it in its lParam attribute. However user programs are already using 
 121 //  this (via the SetItemData() GetItemData() calls). 
 123 //  However what we can do is store a pointer to a structure which contains 
 124 //  the attributes we want *and* a lParam for the users data, e.g. 
 126 //  class CListItemInternalData 
 129 //       GuiAdvCtrl_CListItemAttr* pAttr; 
 130 //       long                      lParam; // user data 
 133 //  To conserve memory, a CListItemInternalData is only allocated for a 
 134 //  LV_ITEM if text attributes or user data(lparam) are being set. 
 136 //  For OS/2, the lParam value points to whatever actual data we have 
 137 ///////////////////////////////////////////////////////////////////////////// 
 138 class CListItemInternalData
 
 142     CListItemInternalData(): m_pAttr(NULL
) 
 146     ~CListItemInternalData() 
 152     wxListItemAttr
*                 m_pAttr
; 
 153     WXLPARAM                        m_lParam
; // user data 
 154     PMYRECORD                       m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted 
 155 }; // end of CLASS CListItemInternalData 
 157 ///////////////////////////////////////////////////////////////////////////// 
 158 // STRUCT SInternalDataSort 
 162 // fn is a function which takes 3 long arguments: item1, item2, data. 
 163 // item1 is the long data associated with a first item (NOT the index). 
 164 // item2 is the long data associated with a second item (NOT the index). 
 165 // data is the same value as passed to SortItems. 
 167 // The return value is a negative number if the first item should precede the 
 168 // second item, a positive number of the second item should precede the first, 
 169 // or zero if the two items are equivalent. 
 171 // data is arbitrary data to be passed to the sort function. 
 173 // Internal structures for proxying the user compare function 
 174 // so that we can pass it the *real* user data 
 175 ///////////////////////////////////////////////////////////////////////////// 
 176 typedef struct internalDataSort
 
 178     wxListCtrlCompare               m_fnUser
; 
 180 } SInternalDataSort
; // end of STRUCT SInternalDataSort 
 182 // ---------------------------------------------------------------------------- 
 183 // private helper functions 
 184 // ---------------------------------------------------------------------------- 
 186 ///////////////////////////////////////////////////////////////////////////// 
 188 // FindOS2ListFieldByColNum 
 190 //  There is no way, under OS/2 to get a field in a container by index, 
 191 //  directly, so you must get the first one, then cycle through the list 
 192 //  until you get to where you want to be. 
 195 //  hWnd   -- window handle of container to search 
 196 //  lIndex -- index to set 
 199 //  pointer to the FIELDINFO struct at the index in the container record 
 201 ///////////////////////////////////////////////////////////////////////////// 
 202 PFIELDINFO 
FindOS2ListFieldByColNum ( 
 207     PFIELDINFO                      pFieldInfo 
= NULL
; 
 211     if (!::WinSendMsg( hWnd
 
 214                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 217     for (i 
= 0; i 
< vCnrInfo
.cFields
; i
++) 
 220             pFieldInfo 
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 221                                                               ,CM_QUERYDETAILFIELDINFO
 
 226             pFieldInfo 
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 227                                                               ,CM_QUERYDETAILFIELDINFO
 
 233         if (i 
== (ULONG
)lIndex
) 
 239 } // end of FindOS2ListFieldByColNum 
 241 ///////////////////////////////////////////////////////////////////////////// 
 243 // FindOS2ListRecordByID 
 245 //  There is no way, under OS/2 to get a record in a container by index, 
 246 //  directly, so you must get the first one, then cycle through the list 
 247 //  until you get to where you want to be. 
 250 //  hWnd    -- window handle of container to search 
 251 //  lItemId -- index to set 
 254 //  pointer to the internal RECORDCORE struct at the index in the container 
 256 ///////////////////////////////////////////////////////////////////////////// 
 257 PMYRECORD 
FindOS2ListRecordByID ( 
 262     PMYRECORD                       pRecord 
= NULL
; 
 266     if (!::WinSendMsg( hWnd
 
 269                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 272     for (i 
= 0; i 
< vCnrInfo
.cRecords
; i
++) 
 275             pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 278                                                           ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
 281             pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 284                                                           ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
 288         if (pRecord
->m_ulItemId 
== (ULONG
)lItemId
) 
 292 } // end of FindOS2ListRecordByID 
 294 ///////////////////////////////////////////////////////////////////////////// 
 298 //  Since OS/2 does not keep native record id's but wx insists on inserting 
 299 //  and selecting via ID's, when we insert a record in the middle we need 
 300 //  to bump the id's of each record after the one we just inserted. 
 303 //  hWnd    -- window handle of container to search 
 304 //  pRecord -- record after which we starting bumping id's 
 309 ///////////////////////////////////////////////////////////////////////////// 
 317         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
 
 320                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
 323             pRecord
->m_ulItemId
++; 
 325 } // end of BumpRecordIds 
 327 ///////////////////////////////////////////////////////////////////////////// 
 331 //  Get the internal data given a handle and an id 
 334 //  hWnd    -- window handle to the control in which item is located 
 335 //  lItemId -- ID to get 
 338 //  pointer to the internal data 
 341 //  Under OS/2 PM a container item cannot be obtained via a simple index or 
 342 //  id retrieval.  We have to walk the record list if we are looking for 
 343 //  a record at a specific index location 
 344 ///////////////////////////////////////////////////////////////////////////// 
 345 CListItemInternalData
* GetInternalData ( 
 350     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( hWnd
 
 354     // Internal user data is stored AFTER the last field of the RECORDCORE 
 358     return((CListItemInternalData 
*)(pRecord
->m_ulUserData
)); 
 359 } // end of GetInternalData 
 361 ///////////////////////////////////////////////////////////////////////////// 
 365 //  Get the internal data given a pointer to a list control and an id 
 368 //  pCtl    -- pointer to control inwhich item is located 
 369 //  lItemId -- ID to get 
 372 //  pointer to the internal data 
 374 ///////////////////////////////////////////////////////////////////////////// 
 375 CListItemInternalData
* GetInternalData ( 
 380     return(GetInternalData( (HWND
)pCtl
->GetHWND() 
 383 } // end of GetInternalData 
 385 ///////////////////////////////////////////////////////////////////////////// 
 387 // DeleteInternalData 
 389 //  Delete the internal data for a record 
 392 //  pCtl    -- pointer to the list control containing the record 
 393 //  lItemId -- the record index to delete the internal data from 
 396 //  pointer to the internal data attribute 
 398 ///////////////////////////////////////////////////////////////////////////// 
 399 void DeleteInternalData ( 
 404     CListItemInternalData
*          pData 
= GetInternalData( pCtl
 
 409         if (pData
->m_pMyRecord
) 
 410             pData
->m_pMyRecord
->m_ulUserData 
= 0; 
 413 } // end of DeleteInternalData 
 415 // #pragma page   "GetInternalDataAttr" 
 416 ///////////////////////////////////////////////////////////////////////////// 
 418 // GetInternalDataAttr 
 420 //  Get the internal data item attribute given a pointer to a list control 
 424 //  pCtl    -- pointer to control to set 
 425 //  lItemId -- ID to set 
 428 //  pointer to the internal data attribute 
 430 ///////////////////////////////////////////////////////////////////////////// 
 431 wxListItemAttr
* GetInternalDataAttr ( 
 436     CListItemInternalData
*          pData 
= GetInternalData( pCtl
 
 441         return(pData
->m_pAttr
); 
 444 } // end of GetInternalDataAttr 
 446 ///////////////////////////////////////////////////////////////////////////// 
 448 // InternalDataCompareFunc 
 450 //  This is compare function we pass to PM.  It wraps the real compare 
 451 //  function in SInternalDataSort 
 454 //  p1       -- is the first record structure to compare 
 455 //  p2       -- is the second record structure to compare 
 456 //  lStorage -- is the same value as passed to SortItems. 
 459 //  pointer to the internal data attribute 
 461 ///////////////////////////////////////////////////////////////////////////// 
 462 SHORT EXPENTRY 
InternalDataCompareFunc ( 
 468     SInternalDataSort
*              pInternalData 
= (SInternalDataSort 
*)pStorage
; 
 469     CListItemInternalData
*          pData1 
= (CListItemInternalData 
*)p1
->m_ulUserData
; 
 470     CListItemInternalData
*          pData2 
= (CListItemInternalData 
*)p2
->m_ulUserData
; 
 471     long                            lD1 
= (pData1 
== NULL 
? 0 : (long)pData1
->m_lParam
); 
 472     long                            lD2 
= (pData2 
== NULL 
? 0 : (long)pData2
->m_lParam
); 
 474     return(pInternalData
->m_fnUser( lD1
 
 476                                    ,pInternalData
->m_lData
 
 478 } // end of InternalDataCompareFunc 
 480 ///////////////////////////////////////////////////////////////////////////// 
 482 // ConvertFromOS2ListItem 
 484 //  Convert from an internal PM List item to a Toolkit List item 
 487 //  hWndListCtrl -- the control's windows handle 
 488 //  rInfo        -- the library list control to convert to 
 489 //  pRecord      -- the OS list control to convert from 
 494 ///////////////////////////////////////////////////////////////////////////// 
 495 void ConvertFromOS2ListItem ( 
 501     CListItemInternalData
*          pInternaldata 
= (CListItemInternalData 
*)pRecord
->m_ulUserData
; 
 502     bool                            bNeedText 
= FALSE
; 
 505         rInfo
.SetData(pInternaldata
->m_lParam
); 
 509     rInfo
.SetStateMask(0); 
 510     rInfo
.SetId((long)pRecord
->m_ulItemId
); 
 511     if (hWndListCtrl 
!= 0) 
 513         pRecord 
= FindOS2ListRecordByID( hWndListCtrl
 
 519     // The wxListItem class is really set up to handle the WIN32 list item 
 520     // and OS/2 are not as complicated.  Just set both state members to the 
 521     // same thing under OS/2 
 523     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_DROPONABLE
) 
 525         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_DROPHILITED
); 
 526         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_DROPHILITED
); 
 528     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_SELECTED
) 
 530         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_SELECTED
); 
 531         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_SELECTED
); 
 533     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_DISABLED
) 
 535         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_DISABLED
); 
 536         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_DISABLED
); 
 538     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_FILTERED
) 
 540         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_FILTERED
); 
 541         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_FILTERED
); 
 543     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_INUSE
) 
 545         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_INUSE
); 
 546         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_INUSE
); 
 548     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_PICKED
) 
 550         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_PICKED
); 
 551         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_PICKED
); 
 553     if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_SOURCE
) 
 555         rInfo
.SetStateMask(rInfo
.m_stateMask 
| wxLIST_STATE_SOURCE
); 
 556         rInfo
.SetState(rInfo
.m_state 
| wxLIST_STATE_SOURCE
); 
 559     if (pRecord
->m_vRecord
.pszText 
!= (PSZ
)NULL
) 
 561         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
); 
 562         rInfo
.SetText(pRecord
->m_vRecord
.pszText
); 
 564     if (pRecord
->m_vRecord
.pszIcon 
!= (PSZ
)NULL 
|| 
 565         pRecord
->m_vRecord
.pszName 
!= (PSZ
)NULL
) 
 567         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
); 
 568         rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
); 
 570     if (pRecord
->m_ulUserData
) 
 571         rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
); 
 572 } // end of ConvertFromOS2ListItem 
 574 ///////////////////////////////////////////////////////////////////////////// 
 578 //  Convert from an library states to OS states 
 581 //  lState       -- the state 
 582 //  pRecord      -- the OS list control to use 
 587 ///////////////////////////////////////////////////////////////////////////// 
 588 void ConvertToOS2Flags ( 
 593     if (lState 
& wxLIST_STATE_DROPHILITED
) 
 594         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_DROPONABLE
; 
 595     if (lState 
& wxLIST_STATE_SELECTED
) 
 596         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_SELECTED
; 
 597     if (lState 
& wxLIST_STATE_DISABLED
) 
 598         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_DISABLED
; 
 599     if (lState 
& wxLIST_STATE_FILTERED
) 
 600         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_FILTERED
; 
 601     if (lState 
& wxLIST_STATE_INUSE
) 
 602         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_INUSE
; 
 603     if (lState 
& wxLIST_STATE_PICKED
) 
 604         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_PICKED
; 
 605     if (lState 
& wxLIST_STATE_SOURCE
) 
 606         pRecord
->m_vRecord
.flRecordAttr 
|= CRA_SOURCE
; 
 607 } // end of ConvertToOS2Flags 
 609 ///////////////////////////////////////////////////////////////////////////// 
 611 // ConvertToOS2ListItem 
 613 //  Convert from a library List item to an internal OS2 List item. We set 
 614 //  only the fields we need to set.  Some of them are set by the API when 
 615 //  they are added to the container. 
 618 //  pCtrl      -- the control to use 
 619 //  rInfo      -- the item to convert 
 620 //  pRecord    -- the OS list control to use, should be zeroed out 
 621 //  pFieldinfo -- a field struct that may contain columnar data for detail view 
 626 ///////////////////////////////////////////////////////////////////////////// 
 627 void ConvertToOS2ListItem ( 
 628   const wxListCtrl
*                 pCtrl
 
 629 , const wxListItem
&                 rInfo
 
 631 , PFIELDINFO                        pFieldInfo
 
 634     pRecord
->m_ulItemId    
= (ULONG
)rInfo
.GetId(); 
 635     pRecord
->m_vRecord
.cb 
= sizeof(RECORDCORE
); 
 636     if (rInfo
.GetMask() & wxLIST_MASK_STATE
) 
 638         ConvertToOS2Flags( rInfo
.m_state
 
 642     if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON 
|| 
 643         pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
) 
 645         pRecord
->m_vRecord
.pszIcon 
= (char*)rInfo
.GetText().c_str(); 
 647     if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view 
 649         pRecord
->m_vRecord
.pszText 
= (char*)rInfo
.GetText().c_str(); 
 652     // In the case of a report view the text will be the data in the lead column 
 653     // ???? Don't know why, but that is how it works in other ports. 
 655     if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
) 
 659             switch(rInfo
.GetColumn()) 
 662                     pRecord
->m_pzColumn1 
= (char*)rInfo
.GetText().c_str(); 
 663                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn1
); 
 667                     pRecord
->m_pzColumn2 
= (char*)rInfo
.GetText().c_str(); 
 668                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn2
); 
 672                     pRecord
->m_pzColumn3 
= (char*)rInfo
.GetText().c_str(); 
 673                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn3
); 
 677                     pRecord
->m_pzColumn4 
= (char*)rInfo
.GetText().c_str(); 
 678                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn4
); 
 682                     pRecord
->m_pzColumn5 
= (char*)rInfo
.GetText().c_str(); 
 683                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn5
); 
 687                     pRecord
->m_pzColumn6 
= (char*)rInfo
.GetText().c_str(); 
 688                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn6
); 
 692                     pRecord
->m_pzColumn7 
= (char*)rInfo
.GetText().c_str(); 
 693                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn7
); 
 697                     pRecord
->m_pzColumn8 
= (char*)rInfo
.GetText().c_str(); 
 698                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn8
); 
 702                     pRecord
->m_pzColumn9 
= (char*)rInfo
.GetText().c_str(); 
 703                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn9
); 
 707                     pRecord
->m_pzColumn10 
= (char*)rInfo
.GetText().c_str(); 
 708                     pFieldInfo
->offStruct 
= FIELDOFFSET(MYRECORD
, m_pzColumn10
); 
 712                     wxFAIL_MSG( _T("wxOS2 does not support more than 10 columns in REPORT view") ); 
 717     if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) 
 719         pRecord
->m_vRecord
.hptrIcon      
= (HPOINTER
)rInfo
.GetImage(); 
 720         pRecord
->m_vRecord
.hptrMiniIcon  
= (HPOINTER
)rInfo
.m_miniImage
; 
 722 } // end of ConvertToOS2ListItem 
 724 ///////////////////////////////////////////////////////////////////////////// 
 726 // ConvertToOS2ListCol 
 728 //  Convert from a library List column to an internal PM List column 
 731 //  lCol   -- the columnd to convert 
 732 //  rItem  -- the item to convert 
 733 //  pField -- the OS list column to use 
 738 ///////////////////////////////////////////////////////////////////////////// 
 739 void ConvertToOS2ListCol ( 
 741 , const wxListItem
&                 rItem
 
 745     memset(pField
, '\0', sizeof(FIELDINFO
)); 
 746     pField
->cb 
= sizeof(FIELDINFO
); 
 749     // Default some settings 
 751     pField
->flData  
= CFA_HORZSEPARATOR 
| CFA_SEPARATOR
; 
 752     pField
->flTitle 
= CFA_CENTER
; 
 754     if (rItem
.GetMask() & wxLIST_MASK_TEXT
) 
 756         pField
->flData 
|= CFA_STRING
; 
 757         pField
->pTitleData 
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data 
 759     if (rItem
.GetMask() & wxLIST_MASK_FORMAT
) 
 761         if (rItem
.m_format 
== wxLIST_FORMAT_LEFT
) 
 762             pField
->flData 
|= CFA_LEFT
; 
 763         else if (rItem
.m_format 
== wxLIST_FORMAT_RIGHT
) 
 764             pField
->flData 
|= CFA_RIGHT
; 
 765         else if (rItem
.m_format 
== wxLIST_FORMAT_CENTRE
) 
 766             pField
->flData 
|= CFA_CENTER
; 
 769         pField
->flData 
|= CFA_CENTER
;  // Just ensure the default is centered 
 770     if (rItem
.GetMask() & wxLIST_MASK_WIDTH
) 
 772         if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE 
|| 
 773              rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
)) 
 774             pField
->cxWidth 
= rItem
.GetWidth(); 
 775         // else: OS/2 automatically sets the width if created with the approppriate style 
 779     // Still need to set the actual data 
 781     pField
->offStruct 
= 0; 
 782 } // end of ConvertToOS2ListCol 
 784 // ---------------------------------------------------------------------------- 
 786 // ---------------------------------------------------------------------------- 
 788 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG
) 
 789 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG
) 
 790 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
) 
 791 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT
) 
 792 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM
) 
 793 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
) 
 794 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO
) 
 795 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO
) 
 796 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED
) 
 797 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED
) 
 798 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN
) 
 799 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM
) 
 800 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK
) 
 801 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_RIGHT_CLICK
) 
 802 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG
) 
 803 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_DRAGGING
) 
 804 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_END_DRAG
) 
 805 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
) 
 806 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
) 
 807 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED
) 
 808 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED
) 
 809 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT
) 
 811 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
) 
 812 IMPLEMENT_DYNAMIC_CLASS(wxListView
, wxListCtrl
) 
 813 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
) 
 815 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
) 
 817 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
) 
 818     EVT_PAINT(wxListCtrl::OnPaint
) 
 821 // ============================================================================ 
 823 // ============================================================================ 
 825 // ---------------------------------------------------------------------------- 
 826 // wxListCtrl construction 
 827 // ---------------------------------------------------------------------------- 
 829 void wxListCtrl::Init () 
 831     m_pImageListNormal     
= NULL
; 
 832     m_pImageListSmall      
= NULL
; 
 833     m_pImageListState      
= NULL
; 
 834     m_bOwnsImageListNormal 
= FALSE
; 
 835     m_bOwnsImageListSmall  
= FALSE
; 
 836     m_bOwnsImageListState  
= FALSE
; 
 840     m_bAnyInternalData     
= FALSE
; 
 841     m_bHasAnyAttr          
= FALSE
; 
 842 } // end of wxListCtrl::Init 
 844 bool wxListCtrl::Create ( 
 847 , const wxPoint
&                    rPos
 
 848 , const wxSize
&                     rSize
 
 850 , const wxValidator
&                rValidator
 
 851 , const wxString
&                   rsName
 
 856     int                             nWidth 
= rSize
.x
; 
 857     int                             nHeight 
= rSize
.y
; 
 860     SetValidator(rValidator
); 
 861 #endif // wxUSE_VALIDATORS 
 864     SetWindowStyleFlag(lStyle
); 
 875     m_windowId 
= (vId 
== -1) ? NewControlId() : vId
; 
 877     long                            lSstyle 
= WS_VISIBLE 
| WS_TABSTOP
; 
 879     if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
) 
 880         lSstyle 
|= WS_CLIPSIBLINGS
; 
 881     m_lBaseStyle 
= lSstyle
; 
 882     if (!DoCreateControl( nX
 
 889         pParent
->AddChild(this); 
 891 } // end of wxListCtrl::Create 
 893 bool wxListCtrl::DoCreateControl ( 
 900     DWORD                           lWstyle 
= m_lBaseStyle
; 
 901     long                            lOldStyle 
= 0; // Dummy 
 905     lWstyle 
|= ConvertToOS2Style( lOldStyle
 
 906                                  ,GetWindowStyleFlag() 
 909     m_hWnd 
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND() 
 914                                        ,GetParent()->GetHWND() 
 926     // Now set the display attributes of the container 
 928     if (!::WinSendMsg( GetHWND() 
 931                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 934     lWstyle 
= ConvertViewToOS2Style(GetWindowStyleFlag()); 
 935     vCnrInfo
.flWindowAttr 
|= lWstyle
; 
 936     if (!::WinSendMsg( GetHWND() 
 939                       ,(MPARAM
)CMA_FLWINDOWATTR
 
 944     // And now set needed arrangement flags 
 946     lWstyle 
= ConvertArrangeToOS2Style(GetWindowStyleFlag()); 
 947     if (!::WinSendMsg( GetHWND() 
 949                       ,(MPARAM
)CMA_ARRANGEGRID
 
 953     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 954     SetForegroundColour(GetParent()->GetForegroundColour()); 
 956     SetFont(*wxSMALL_FONT
); 
 965 } // end of wxListCtrl::DoCreateControl 
 967 void wxListCtrl::UpdateStyle () 
 972         DWORD                       dwStyleNew 
= ConvertToOS2Style( lDummy
 
 973                                                                    ,GetWindowStyleFlag() 
 976         dwStyleNew 
|= m_lBaseStyle
; 
 979         // Get the current window style. 
 981         ULONG                       dwStyleOld 
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
); 
 984         // Only set the window style if the view bits have changed. 
 986         if (dwStyleOld 
!= dwStyleNew
) 
 988             ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
); 
 991 } // end of wxListCtrl::UpdateStyle 
 993 void wxListCtrl::FreeAllInternalData () 
 995     if (m_bAnyInternalData
) 
 997         int                         n 
= GetItemCount(); 
1000         for (i 
= 0; i 
< n
; i
++) 
1001             DeleteInternalData(this, (long)i
); 
1002         m_bAnyInternalData 
= FALSE
; 
1004 } // end of wxListCtrl::FreeAllInternalData 
1006 wxListCtrl::~wxListCtrl () 
1008     FreeAllInternalData(); 
1011         m_pTextCtrl
->SetHWND(0); 
1012         m_pTextCtrl
->UnsubclassWin(); 
1017     if (m_bOwnsImageListNormal
) 
1018         delete m_pImageListNormal
; 
1019     if (m_bOwnsImageListSmall
) 
1020         delete m_pImageListSmall
; 
1021     if (m_bOwnsImageListState
) 
1022         delete m_pImageListState
; 
1023 } // end of wxListCtrl::~wxListCtrl 
1025 // ---------------------------------------------------------------------------- 
1026 // set/get/change style 
1027 // ---------------------------------------------------------------------------- 
1029 // Add or remove a single window style 
1030 void wxListCtrl::SetSingleStyle ( 
1035     long                            lFlag 
= GetWindowStyleFlag(); 
1038     // Get rid of conflicting styles 
1042         if (lStyle 
& wxLC_MASK_TYPE
) 
1043             lFlag 
= lFlag 
& ~wxLC_MASK_TYPE
; 
1044         if (lStyle 
& wxLC_MASK_ALIGN 
) 
1045             lFlag 
= lFlag 
& ~wxLC_MASK_ALIGN
; 
1046         if (lStyle 
& wxLC_MASK_SORT 
) 
1047             lFlag 
= lFlag 
& ~wxLC_MASK_SORT
; 
1061     m_windowStyle 
= lFlag
; 
1063 } // end of wxListCtrl::SetSingleStyle 
1065 // Set the whole window style 
1066 void wxListCtrl::SetWindowStyleFlag ( 
1070     m_windowStyle 
= lFlag
; 
1072 } // end of wxListCtrl::SetWindowStyleFlag 
1074 long wxListCtrl::ConvertToOS2Style ( 
1082     // The only styles OS2 uses on creation are auto arrange, read only, and 
1083     // and selection styles.  This lib does not support OS/2 MINIRECORDCORE 
1084     // or VERIFYPOINTER styles 
1086     if (lStyle 
& wxLC_AUTOARRANGE
) 
1087         lWstyle 
|= CCS_AUTOPOSITION
; 
1088     if (lStyle 
& wxLC_SINGLE_SEL
) 
1089         lWstyle 
|= CCS_SINGLESEL
; 
1091         lWstyle 
|= CCS_EXTENDSEL
; 
1092     if (!(lStyle 
& wxLC_EDIT_LABELS
)) 
1093         lWstyle 
|= CCS_READONLY
; 
1095 } // end of wxListCtrl::ConvertToOS2Style 
1097 long wxListCtrl::ConvertArrangeToOS2Style ( 
1103     if (lStyle 
& wxLC_ALIGN_LEFT
) 
1105         lWstyle 
|= CMA_LEFT
; 
1108     if (lStyle 
& wxLC_ALIGN_TOP
) 
1113 } // end of wxListCtrl::ConvertArrangeToOS2Style 
1115 long wxListCtrl::ConvertViewToOS2Style ( 
1119     long                            lWstyle 
= CA_DRAWICON
; // we will only use icons 
1121     if (lStyle 
& wxLC_ICON
) 
1125     if (lStyle 
& wxLC_SMALL_ICON
) 
1127         lWstyle 
|= (CV_ICON 
| CV_MINI
); 
1129     if (lStyle 
& wxLC_LIST
) 
1133     if (lStyle 
& wxLC_REPORT
) 
1135         lWstyle 
|= CV_DETAIL
; 
1137     if (lStyle 
& wxLC_VIRTUAL
) 
1139         lWstyle 
|= CA_OWNERDRAW
; 
1141     if (lStyle 
& wxLC_AUTOARRANGE
) 
1145     if (!(lStyle 
& wxLC_NO_HEADER
)) 
1147         lWstyle 
|= CA_DETAILSVIEWTITLES
; 
1150 } // end of wxListCtrl::ConvertViewToOS2Style 
1152 // ---------------------------------------------------------------------------- 
1154 // ---------------------------------------------------------------------------- 
1156 // Sets the foreground, i.e. text, colour 
1157 bool wxListCtrl::SetForegroundColour ( 
1158   const wxColour
&                   rCol
) 
1160     ULONG                           ulColor 
= wxColourToRGB(rCol
); 
1162     if (!wxWindow::SetForegroundColour(rCol
)) 
1166     ::WinSetPresParam( GetHWND() 
1172 } // end of wxListCtrl::SetForegroundColour 
1174 // Sets the background colour 
1175 bool wxListCtrl::SetBackgroundColour ( 
1176   const wxColour
&                   rCol
 
1179     if (!wxWindow::SetBackgroundColour(rCol
)) 
1183     // We set the same colour for both the "empty" background and the items 
1186     ULONG                           ulColor 
= wxColourToRGB(rCol
); 
1188     ::WinSetPresParam( GetHWND() 
1194 } // end of wxListCtrl::SetBackgroundColour 
1196 // Gets information about this column 
1197 bool wxListCtrl::GetColumn ( 
1202     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND() 
1208     rItem
.SetWidth(pFieldInfo
->cxWidth
); 
1209     if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) && 
1210         (pFieldInfo
->flData 
& CFA_STRING
) && 
1211         (pFieldInfo
->pUserData 
!= NULL
)) 
1213         rItem
.SetText((char*)pFieldInfo
->pUserData
); 
1215     if (rItem
.GetMask() & wxLIST_MASK_FORMAT 
) 
1217         if (pFieldInfo
->flData 
& CFA_LEFT
) 
1218             rItem
.m_format 
= wxLIST_FORMAT_LEFT
; 
1219         else if (pFieldInfo
->flData 
& CFA_RIGHT
) 
1220             rItem
.m_format 
= wxLIST_FORMAT_RIGHT
; 
1221         else if (pFieldInfo
->flData 
& CFA_CENTER
) 
1222             rItem
.m_format 
= wxLIST_FORMAT_CENTRE
; 
1225 } // end of wxListCtrl::GetColumn 
1227 // Sets information about this column 
1228 bool wxListCtrl::SetColumn ( 
1233     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum( GetHWND() 
1236     ConvertToOS2ListCol( nCol
 
1241     // Since we changed the field pointed to, we invalidate to see the result 
1243     ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
); 
1245 } // end of wxListCtrl::SetColumn 
1247 // Gets the column width 
1248 int wxListCtrl::GetColumnWidth ( 
1252     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND() 
1258     return((int)pFieldInfo
->cxWidth
); 
1259 } // end of wxListCtrl::GetColumnWidth 
1261 // Sets the column width 
1262 bool wxListCtrl::SetColumnWidth ( 
1268     int                             nWidth2 
= nWidth
; 
1270     if (GetWindowStyleFlag() & wxLC_LIST
) 
1273     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum( GetHWND() 
1276     pFieldInfo
->cxWidth 
= nWidth
; 
1277     ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
); 
1279 } // end of wxListCtrl::SetColumnWidth 
1281 // Gets the number of items that can fit vertically in the 
1282 // visible area of the list control (list or report view) 
1283 // or the total number of items in the list control (icon 
1284 // or small icon view) 
1285 int wxListCtrl::GetCountPerPage () const 
1287     QUERYRECORDRECT                 vQueryRect
; 
1293     if (!::WinSendMsg( GetHWND() 
1296                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1299     memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
)); 
1300     vQueryRect
.cb 
= sizeof(QUERYRECORDRECT
); 
1301     if (vCnrInfo
.flWindowAttr 
& CV_ICON
) 
1302         vQueryRect
.fsExtent 
= CMA_ICON 
| CMA_TEXT
; 
1303     else if (vCnrInfo
.flWindowAttr 
& CV_NAME
) 
1304         vQueryRect
.fsExtent 
= CMA_ICON 
| CMA_TEXT
; 
1305     else if (vCnrInfo
.flWindowAttr 
& CV_TEXT
) 
1306         vQueryRect
.fsExtent 
= CMA_TEXT
; 
1307     else if (vCnrInfo
.flWindowAttr 
& CV_DETAIL
) 
1308         vQueryRect
.fsExtent 
= CMA_TEXT
; 
1309     if (!::WinSendMsg( GetHWND() 
1311                       ,MPFROMP(&vRectRecord
) 
1312                       ,MPFROMP(&vQueryRect
) 
1315     if (!::WinSendMsg( GetHWND() 
1316                       ,CM_QUERYVIEWPORTRECT
 
1317                       ,MPFROMP(&vRectControl
) 
1318                       ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
) 
1321     nCount 
= (int)((int)((vRectControl
.xRight 
- vRectControl
.xLeft
) / (vRectRecord
.xRight 
- vRectRecord
.xLeft
)) * 
1322                    (int)((vRectControl
.yTop 
- vRectControl
.yBottom
) / (vRectRecord
.yTop 
- vRectRecord
.yBottom
)) 
1324     if (nCount 
> (int)vCnrInfo
.cFields
) 
1325         nCount 
= (int)vCnrInfo
.cFields
; 
1327 } // end of wxListCtrl::GetCountPerPage 
1329 // Gets the edit control for editing labels. 
1330 wxTextCtrl
* wxListCtrl::GetEditControl() const 
1335 // Gets information about the item 
1336 bool wxListCtrl::GetItem ( 
1340     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1345     // Give NULL as hwnd as we already have everything we need 
1347     ConvertFromOS2ListItem( NULL
 
1352 } // end of wxListCtrl::GetItem 
1354 // Sets information about the item 
1355 bool wxListCtrl::SetItem ( 
1359     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND() 
1362     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1366     ConvertToOS2ListItem( this 
1373     // Check if setting attributes or lParam 
1375     if (rInfo
.HasAttributes() || (rInfo
.GetMask()  & wxLIST_MASK_DATA
)) 
1378         // Get internal item data 
1379         // perhaps a cache here ? 
1381         CListItemInternalData
*      pData 
= GetInternalData( this 
1390             m_bAnyInternalData    
= TRUE
; 
1391             pData                 
= new CListItemInternalData(); 
1392             pRecord
->m_ulUserData 
= (unsigned long)pData
; 
1398         if (rInfo
.GetMask()  & wxLIST_MASK_DATA
) 
1399             pData
->m_lParam 
= (WXLPARAM
)rInfo
.GetData(); 
1402         if (rInfo
.HasAttributes()) 
1405                 *pData
->m_pAttr 
= *rInfo
.GetAttributes(); 
1407                 pData
->m_pAttr 
= new wxListItemAttr(*rInfo
.GetAttributes()); 
1409         pData
->m_pMyRecord 
= pRecord
;  // they point to each other 
1413     // We need to update the item immediately to show the new image 
1415     bool                            bUpdateNow 
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0; 
1418     // Check whether it has any custom attributes 
1420     if (rInfo
.HasAttributes()) 
1422         m_bHasAnyAttr 
= TRUE
; 
1425         // If the colour has changed, we must redraw the item 
1429     if (::WinIsWindowVisible(GetHWND())) 
1431         ::WinSendMsg( GetHWND() 
1432                      ,CM_INVALIDATERECORD
 
1434                      ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1436         RefreshItem(pRecord
->m_ulItemId
); 
1438     ::WinSendMsg( GetHWND() 
1439                  ,CM_INVALIDATEDETAILFIELDINFO
 
1444 } // end of wxListCtrl::SetItem 
1446 long wxListCtrl::SetItem ( 
1449 , const wxString
&                   rsLabel
 
1455     vInfo
.m_text   
= rsLabel
; 
1456     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1457     vInfo
.m_itemId 
= lIndex
; 
1461         vInfo
.m_image 
= nImageId
; 
1462         vInfo
.m_mask 
|= wxLIST_MASK_IMAGE
; 
1464     return SetItem(vInfo
); 
1465 } // end of wxListCtrl::SetItem 
1467 // Gets the item state 
1468 int wxListCtrl::GetItemState ( 
1475     vInfo
.m_mask      
= wxLIST_MASK_STATE
; 
1476     vInfo
.m_stateMask 
= lStateMask
; 
1477     vInfo
.m_itemId    
= lItem
; 
1479     if (!GetItem(vInfo
)) 
1481     return vInfo
.m_state
; 
1482 } // end of wxListCtrl::GetItemState 
1484 // Sets the item state 
1485 bool wxListCtrl::SetItemState ( 
1491     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1496     // Don't use SetItem() here as it doesn't work with the virtual list 
1499     ConvertToOS2Flags( lState
 
1504     // for the virtual list controls we need to refresh the previously focused 
1505     // item manually when changing focus without changing selection 
1506     // programmatically because otherwise it keeps its focus rectangle until 
1507     // next repaint (yet another comctl32 bug) 
1512         (lStateMask 
& wxLIST_STATE_FOCUSED
) && 
1513          (lState 
& wxLIST_STATE_FOCUSED
) ) 
1515         lFocusOld 
= GetNextItem( -1 
1517                                 ,wxLIST_STATE_FOCUSED
 
1524     ::WinSendMsg( GetHWND() 
1525                  ,CM_INVALIDATERECORD
 
1527                  ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1530     if (lFocusOld 
!= -1) 
1533         // No need to refresh the item if it was previously selected, it would 
1534         // only result in annoying flicker 
1536         if (!(GetItemState( lFocusOld
 
1537                            ,wxLIST_STATE_SELECTED
 
1538                           ) & wxLIST_STATE_SELECTED
)) 
1540             RefreshItem(lFocusOld
); 
1544 } // end of wxListCtrl::SetItemState 
1546 // Sets the item image 
1547 bool wxListCtrl::SetItemImage ( 
1550 , int                               WXUNUSED(nSelImage
)) 
1554     vInfo
.m_mask   
= wxLIST_MASK_IMAGE
; 
1555     vInfo
.m_image  
= nImage
; 
1556     vInfo
.m_itemId 
= lItem
; 
1557     return SetItem(vInfo
); 
1558 } // end of wxListCtrl::SetItemImage 
1560 // Gets the item text 
1561 wxString 
wxListCtrl::GetItemText ( 
1567     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1568     vInfo
.m_itemId 
= lItem
; 
1570     if (!GetItem(vInfo
)) 
1571         return wxEmptyString
; 
1572     return vInfo
.m_text
; 
1573 } // end of wxListCtrl::GetItemText 
1575 // Sets the item text 
1576 void wxListCtrl::SetItemText ( 
1578 , const wxString
&                   rsStr
 
1583     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
1584     vInfo
.m_itemId 
= lItem
; 
1585     vInfo
.m_text   
= rsStr
; 
1587 } // end of wxListCtrl::SetItemText 
1589 // Gets the item data 
1590 long wxListCtrl::GetItemData ( 
1596     vInfo
.m_mask   
= wxLIST_MASK_DATA
; 
1597     vInfo
.m_itemId 
= lItem
; 
1598     if (!GetItem(vInfo
)) 
1600     return vInfo
.m_data
; 
1601 } // end of wxListCtrl::GetItemData 
1603 // Sets the item data 
1604 bool wxListCtrl::SetItemData ( 
1611     vInfo
.m_mask   
= wxLIST_MASK_DATA
; 
1612     vInfo
.m_itemId 
= lItem
; 
1613     vInfo
.m_data   
= lData
; 
1614     return SetItem(vInfo
); 
1615 } // end of wxListCtrl::SetItemData 
1617 // Gets the item rectangle 
1618 bool wxListCtrl::GetItemRect ( 
1625     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1628     QUERYRECORDRECT                 vQueryRect
; 
1634     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
1635     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
1636     vQueryRect
.fRightSplitWindow 
= TRUE
; 
1637     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
1638     ::WinSendMsg( GetHWND() 
1641                  ,MPFROMP(&vQueryRect
) 
1644     // remember OS/2 is backwards 
1649     rRect
.x      
= vRect
.xLeft
; 
1650     rRect
.y      
= nHeight 
- vRect
.yTop
; 
1651     rRect
.width  
= vRect
.xRight
; 
1652     rRect
.height 
= nHeight 
- vRect
.yBottom
; 
1655 } // end of wxListCtrl::GetItemRect 
1657 // Gets the item position 
1658 bool wxListCtrl::GetItemPosition ( 
1664     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1667     QUERYRECORDRECT                 vQueryRect
; 
1673     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
1674     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
1675     vQueryRect
.fRightSplitWindow 
= TRUE
; 
1676     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
1677     ::WinSendMsg( GetHWND() 
1680                  ,MPFROMP(&vQueryRect
) 
1683     // remember OS/2 is backwards 
1688     rPos
.x   
= vRect
.xLeft
; 
1689     rPos
.y   
= nHeight 
- vRect
.yTop
; 
1692 } // end of wxListCtrl::GetItemPosition 
1694 // Sets the item position. 
1695 bool wxListCtrl::SetItemPosition ( 
1697 , const wxPoint
&                    rPos
 
1701     // Items cannot be positioned in X/Y coord in OS/2 
1704 } // end of wxListCtrl::SetItemPosition 
1706 // Gets the number of items in the list control 
1707 int wxListCtrl::GetItemCount () const 
1711     if (!::WinSendMsg( GetHWND() 
1714                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1717     return vCnrInfo
.cRecords
; 
1718 } // end of wxListCtrl::GetItemCount 
1720 // Retrieves the spacing between icons in pixels. 
1721 // If small is TRUE, gets the spacing for the small icon 
1722 // view, otherwise the large icon view. 
1723 int wxListCtrl::GetItemSpacing ( 
1729     if (!::WinSendMsg( GetHWND() 
1732                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
1735     return vCnrInfo
.cyLineSpacing
; 
1736 } // end of wxListCtrl::GetItemSpacing 
1738 void wxListCtrl::SetItemTextColour ( 
1740 , const wxColour
&                   rCol
 
1745     vInfo
.m_itemId 
= lItem
; 
1746     vInfo
.SetTextColour(rCol
); 
1748 } // end of wxListCtrl::SetItemTextColour 
1750 wxColour 
wxListCtrl::GetItemTextColour ( 
1756     vInfo
.m_itemId 
= lItem
; 
1758     return vInfo
.GetTextColour(); 
1759 } // end of wxListCtrl::GetItemTextColour 
1761 void wxListCtrl::SetItemBackgroundColour ( 
1763 , const wxColour
&                   rCol
 
1768     vInfo
.m_itemId 
= lItem
; 
1769     vInfo
.SetBackgroundColour(rCol
); 
1771 } // end of wxListCtrl::SetItemBackgroundColour 
1773 wxColour 
wxListCtrl::GetItemBackgroundColour ( 
1779     vInfo
.m_itemId 
= lItem
; 
1781     return vInfo
.GetBackgroundColour(); 
1782 } // end of wxListCtrl::GetItemBackgroundColour 
1784 // Gets the number of selected items in the list control 
1785 int wxListCtrl::GetSelectedItemCount () const 
1787     PMYRECORD                       pRecord 
= NULL
; 
1789     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1790                                                   ,CM_QUERYRECORDEMPHASIS
 
1792                                                   ,(MPARAM
)CRA_SELECTED
 
1800         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1801                                                       ,CM_QUERYRECORDEMPHASIS
 
1803                                                       ,(MPARAM
)CRA_SELECTED
 
1809 } // end of wxListCtrl::GetSelectedItemCount 
1811 // Gets the text colour of the listview 
1812 wxColour 
wxListCtrl::GetTextColour () const 
1817     ::WinQueryPresParam( GetHWND() 
1827 } // end of wxListCtrl::GetTextColour 
1829 // Sets the text colour of the listview 
1830 void wxListCtrl::SetTextColour ( 
1831   const wxColour
&                   rCol
 
1834     ULONG                           ulColor 
= wxColourToRGB(rCol
); 
1836     ::WinSetPresParam( GetHWND() 
1841 } // end of wxListCtrl::SetTextColour 
1843 // Gets the index of the topmost visible item when in 
1844 // list or report view 
1845 long wxListCtrl::GetTopItem () const 
1847     PMYRECORD                       pRecord 
= NULL
; 
1848     QUERYRECFROMRECT                vQueryRect
; 
1851     ::WinSendMsg( GetHWND() 
1852                  ,CM_QUERYVIEWPORTRECT
 
1854                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
1856     vQueryRect
.cb        
= sizeof(QUERYRECFROMRECT
); 
1857     vQueryRect
.rect      
= vRect
; 
1858     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
1860     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1861                                       ,CM_QUERYRECORDFROMRECT
 
1863                                       ,MPFROMP(&vQueryRect
) 
1868     return (long)pRecord
->m_ulItemId
; 
1869 } // end of wxListCtrl::GetTopItem 
1871 // Searches for an item, starting from 'item'. 
1872 // 'geometry' is one of 
1873 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT. 
1874 // 'state' is a state bit flag, one or more of 
1875 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT. 
1876 // item can be -1 to find the first item that matches the 
1878 // Returns the item or -1 if unsuccessful. 
1879 long wxListCtrl::GetNextItem ( 
1881 , int                               WXUNUSED(nGeom
) 
1882 , int                               WXUNUSED(nState
) 
1885     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
1889     pRecord 
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
; 
1891         return((long)pRecord
->m_ulItemId
); 
1893 } // end of wxListCtrl::GetNextItem 
1895 wxImageList
* wxListCtrl::GetImageList ( 
1899     if (nWhich 
== wxIMAGE_LIST_NORMAL 
) 
1901         return m_pImageListNormal
; 
1903     else if (nWhich 
== wxIMAGE_LIST_SMALL 
) 
1905         return m_pImageListSmall
; 
1907     else if (nWhich 
== wxIMAGE_LIST_STATE 
) 
1909         return m_pImageListState
; 
1912 } // end of wxListCtrl::GetImageList 
1914 void wxListCtrl::SetImageList ( 
1915   wxImageList
*                      pImageList
 
1919     if (nWhich 
== wxIMAGE_LIST_NORMAL
) 
1921         if (m_bOwnsImageListNormal
) 
1922             delete m_pImageListNormal
; 
1923         m_pImageListNormal     
= pImageList
; 
1924         m_bOwnsImageListNormal 
= FALSE
; 
1926     else if (nWhich 
== wxIMAGE_LIST_SMALL
) 
1928         if (m_bOwnsImageListSmall
) 
1929             delete m_pImageListSmall
; 
1930         m_pImageListSmall    
= pImageList
; 
1931         m_bOwnsImageListSmall 
= FALSE
; 
1933     else if (nWhich 
== wxIMAGE_LIST_STATE
) 
1935         if (m_bOwnsImageListState
) 
1936             delete m_pImageListState
; 
1937         m_pImageListState     
= pImageList
; 
1938         m_bOwnsImageListState 
= FALSE
; 
1940 } // end of wxListCtrl::SetImageList 
1942 void wxListCtrl::AssignImageList ( 
1943   wxImageList
*                      pImageList
 
1947     SetImageList( pImageList
 
1950     if (nWhich 
== wxIMAGE_LIST_NORMAL 
) 
1951         m_bOwnsImageListNormal 
= TRUE
; 
1952     else if (nWhich 
== wxIMAGE_LIST_SMALL 
) 
1953         m_bOwnsImageListSmall 
= TRUE
; 
1954     else if (nWhich 
== wxIMAGE_LIST_STATE 
) 
1955         m_bOwnsImageListState 
= TRUE
; 
1956 } // end of wxListCtrl::AssignImageList 
1958 // ---------------------------------------------------------------------------- 
1960 // ---------------------------------------------------------------------------- 
1962 // Arranges the items 
1963 bool wxListCtrl::Arrange ( 
1970     if (nFlag 
== wxLIST_ALIGN_SNAP_TO_GRID
) 
1972         ulType 
= CMA_ARRANGEGRID
; 
1973         if (nFlag 
== wxLIST_ALIGN_LEFT
) 
1974             ulFlags 
|= CMA_LEFT
; 
1975         else if (nFlag 
== wxLIST_ALIGN_TOP
) 
1977         else if (nFlag 
== wxLIST_ALIGN_DEFAULT
) 
1978             ulFlags 
|= CMA_LEFT
; 
1981         ulType 
= CMA_ARRANGESTANDARD
; 
1982     ::WinSendMsg( GetHWND() 
1988     // We do not support CMA_ARRANGESELECTED 
1991 } // end of wxListCtrl::Arrange 
1994 bool wxListCtrl::DeleteItem ( 
1998     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2001     if (LONGFROMMR(::WinSendMsg( GetHWND() 
2004                                 ,MPFROM2SHORT(1, CMA_FREE
) 
2011     // The virtual list control doesn't refresh itself correctly, help it 
2016         // We need to refresh all the lines below the one which was deleted 
2020         if (lItem 
> 0 && GetItemCount()) 
2022             GetItemRect( lItem 
- 1 
2028             vRectItem
.y 
= vRectItem
.height 
= 0; 
2030         wxRect                      vRectWin 
= GetRect(); 
2032         vRectWin
.height 
= vRectWin
.GetBottom() - vRectItem
.GetBottom(); 
2033         vRectWin
.y      
= vRectItem
.GetBottom(); 
2034         RefreshRect(vRectWin
); 
2037 } // end of wxListCtrl::DeleteItem 
2039 // Deletes all items 
2040 bool wxListCtrl::DeleteAllItems () 
2042     return((LONG
)::WinSendMsg( GetHWND() 
2045                               ,MPFROM2SHORT(0, CMA_FREE
) 
2047 } // end of wxListCtrl::DeleteAllItems 
2049 // Deletes all items 
2050 bool wxListCtrl::DeleteAllColumns () 
2052     while (m_nColCount 
> 0) 
2054         DeleteColumn(m_nColCount 
- 1); 
2058     wxASSERT_MSG(m_nColCount 
== 0, wxT("no columns should be left")); 
2060 } // end of wxListCtrl::DeleteAllColumns 
2063 bool wxListCtrl::DeleteColumn ( 
2067     bool                            bSuccess 
= FALSE
; 
2068     PFIELDINFO                      pField 
= FindOS2ListFieldByColNum( GetHWND() 
2071     bSuccess 
= ((LONG
)::WinSendMsg( GetHWND() 
2072                                    ,CM_REMOVEDETAILFIELDINFO
 
2074                                    ,MPFROM2SHORT((SHORT
)1, CMA_FREE
) 
2076     if (bSuccess 
&& (m_nColCount 
> 0)) 
2079 } // end of wxListCtrl::DeleteColumn 
2081 // Clears items, and columns if there are any. 
2082 void wxListCtrl::ClearAll () 
2085     if (m_nColCount 
> 0) 
2087 } // end of wxListCtrl::ClearAll 
2090 // OS/2 does not use a text control for its container labels.  You merely 
2091 // "open" a record for editting. 
2093 wxTextCtrl
* wxListCtrl::EditLabel ( 
2095 , wxClassInfo
*                      WXUNUSED(pTextControlClass
) 
2099     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2103     vEdit
.cb         
= sizeof(CNREDITDATA
); 
2104     vEdit
.hwndCnr    
= GetHWND(); 
2105     vEdit
.pRecord    
= &pRecord
->m_vRecord
; 
2106     vEdit
.pFieldInfo 
= NULL
; 
2107     vEdit
.ppszText   
= NULL
; 
2111     ::WinSendMsg( GetHWND() 
2117 } // end of wxListCtrl::EditLabel 
2119 // End label editing, optionally cancelling the edit.  Under OS/2 you close 
2120 // the record for editting 
2121 bool wxListCtrl::EndEditLabel ( 
2122   bool                              WXUNUSED(bCancel
) 
2125     ::WinSendMsg( GetHWND() 
2131 } // end of wxListCtrl::EndEditLabel 
2133 // Ensures this item is visible 
2134 bool wxListCtrl::EnsureVisible ( 
2138     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2141     ::WinSendMsg( GetHWND() 
2142                  ,CM_INVALIDATERECORD
 
2144                  ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
) 
2147 } // end of wxListCtrl::EnsureVisible 
2149 // Find an item whose label matches this string, starting from the item after 'start' 
2150 // or the beginning if 'start' is -1. 
2151 long wxListCtrl::FindItem ( 
2153 , const wxString
&                   rsStr
 
2158     SEARCHSTRING                    vSearch
; 
2159     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2165     if (!::WinSendMsg( GetHWND() 
2168                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
2172     if (vCnrInfo
.flWindowAttr 
& CV_ICON
) 
2174     if (vCnrInfo
.flWindowAttr 
& CV_NAME
) 
2176     if (vCnrInfo
.flWindowAttr 
& CV_TEXT
) 
2178     if (vCnrInfo
.flWindowAttr 
& CV_DETAIL
) 
2181         ulFlag 
|= CV_EXACTLENGTH
; 
2183     vSearch
.cb              
= sizeof(SEARCHSTRING
); 
2184     vSearch
.pszSearch       
= (char*)rsStr
.c_str(); 
2185     vSearch
.fsPrefix        
= TRUE
; 
2186     vSearch
.fsCaseSensitive 
= TRUE
; 
2187     vSearch
.usView          
= ulFlag
; 
2191         pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2199         pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2207     return pRecord
->m_ulItemId
; 
2208 } // end of wxListCtrl::FindItem 
2210 // Find an item whose data matches this data, starting from the item after 'start' 
2211 // or the beginning if 'start' is -1. 
2212 long wxListCtrl::FindItem ( 
2217     long                            lIdx 
= lStart 
+ 1; 
2218     long                            lCount 
= GetItemCount(); 
2220     while (lIdx 
< lCount
) 
2222         if (GetItemData(lIdx
) == lData
) 
2227 } // end of wxListCtrl::FindItem 
2229 // Find an item nearest this position in the specified direction, starting from 
2230 // the item after 'start' or the beginning if 'start' is -1. 
2231 long wxListCtrl::FindItem ( 
2233 , const wxPoint
&                    rPoint
 
2238     QUERYRECORDRECT                 vQueryRect
; 
2239     PMYRECORD                       pRecord 
= FindOS2ListRecordByID( GetHWND() 
2246     if (!::WinSendMsg( GetHWND() 
2249                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
2253     vQueryRect
.cb                
= sizeof(QUERYRECORDRECT
); 
2254     vQueryRect
.pRecord           
= &pRecord
->m_vRecord
; 
2255     vQueryRect
.fRightSplitWindow 
= TRUE
; 
2256     vQueryRect
.fsExtent          
= CMA_ICON 
| CMA_TEXT
; 
2258     ::WinSendMsg( GetHWND() 
2261                  ,MPFROMP(&vQueryRect
) 
2263     vLibRect
.SetLeft(vRect
.xLeft
); 
2264     vLibRect
.SetTop(vRect
.yTop
); 
2265     vLibRect
.SetRight(vRect
.xRight
); 
2266     vLibRect
.SetBottom(vRect
.yBottom
); 
2267     if (vLibRect
.Inside(rPoint
)) 
2268         return pRecord
->m_ulItemId
; 
2270     for (i 
= lStart 
+ 1; i 
< vCnrInfo
.cRecords
; i
++) 
2272         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
2275                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
2277         vQueryRect
.pRecord 
= (PRECORDCORE
)pRecord
; 
2278         ::WinSendMsg( GetHWND() 
2281                      ,MPFROMP(&vQueryRect
) 
2283         vLibRect
.SetLeft(vRect
.xLeft
); 
2284         vLibRect
.SetTop(vRect
.yTop
); 
2285         vLibRect
.SetRight(vRect
.xRight
); 
2286         vLibRect
.SetBottom(vRect
.yBottom
); 
2287         if (vLibRect
.Inside(rPoint
)) 
2288             return pRecord
->m_ulItemId
; 
2291 } // end of wxListCtrl::FindItem 
2293 // Determines which item (if any) is at the specified point, 
2294 // giving details in 'flags' (see wxLIST_HITTEST_... flags above) 
2295 long wxListCtrl::HitTest ( 
2296   const wxPoint
&                    rPoint
 
2297 , int&                              WXUNUSED(rFlags
) 
2300     PMYRECORD                       pRecord 
= NULL
; 
2301     QUERYRECFROMRECT                vQueryRect
; 
2306     // Get height for OS/2 point conversion 
2308     ::WinSendMsg( GetHWND() 
2309                  ,CM_QUERYVIEWPORTRECT
 
2311                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
2313     lHeight 
= vRect
.yTop 
- vRect
.yBottom
; 
2316     // For now just try and get a record in the general vicinity and forget 
2319     vRect
.xLeft   
= rPoint
.x 
- 2; 
2320     vRect
.xRight  
= rPoint
.x 
+ 2; 
2321     vRect
.yTop    
= (lHeight 
- rPoint
.y
) + 2; 
2322     vRect
.yBottom 
= (lHeight 
- rPoint
.y
) - 2; 
2324     vQueryRect
.cb 
= sizeof(QUERYRECFROMRECT
); 
2325     vQueryRect
.rect 
= vRect
; 
2326     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
2328     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2329                                       ,CM_QUERYRECORDFROMRECT
 
2331                                       ,MPFROMP(&vQueryRect
) 
2336     return pRecord
->m_ulItemId
; 
2337 } // end of wxListCtrl::HitTest 
2339 // Inserts an item, returning the index of the new item if successful, 
2341 long wxListCtrl::InsertItem ( 
2345     wxASSERT_MSG( !IsVirtual(), _T("can't be used with virtual controls") ); 
2347     PFIELDINFO                      pFieldInfo 
= FindOS2ListFieldByColNum ( GetHWND() 
2350     PMYRECORD                       pRecordAfter 
= NULL
; 
2351     PMYRECORD                       pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
2353                                                                       ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
)) 
2357     ConvertToOS2ListItem( this 
2363     if (rInfo
.GetId() > 0) 
2364         pRecordAfter 
= FindOS2ListRecordByID( GetHWND() 
2368     RECORDINSERT                    vInsert
; 
2370     vInsert
.cb                
= sizeof(RECORDINSERT
); 
2371     vInsert
.pRecordParent     
= NULL
; 
2373         vInsert
.pRecordOrder  
= (PRECORDCORE
)CMA_FIRST
; 
2375         vInsert
.pRecordOrder  
= (PRECORDCORE
)pRecordAfter
; 
2376     vInsert
.zOrder            
= CMA_TOP
; 
2377     vInsert
.cRecordsInsert    
= 1; 
2378     vInsert
.fInvalidateRecord 
= TRUE
; 
2381     // Check wether we need to allocate our internal data 
2383     bool                            bNeedInternalData 
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) || 
2384                                                           rInfo
.HasAttributes() 
2386     if (bNeedInternalData
) 
2388         m_bAnyInternalData 
= TRUE
; 
2391         // Internal stucture that manages data 
2393         CListItemInternalData
*      pData 
= new CListItemInternalData(); 
2395         pRecord
->m_ulUserData 
= (unsigned long)pData
; 
2396         if (rInfo
.GetMask() & wxLIST_MASK_DATA
) 
2397             pData
->m_lParam 
= (WXLPARAM
)rInfo
.GetData(); 
2400         // Check whether it has any custom attributes 
2402         if (rInfo
.HasAttributes()) 
2405             // Take copy of attributes 
2407             pData
->m_pAttr 
= new wxListItemAttr(*rInfo
.GetAttributes()); 
2410     if (!::WinSendMsg( GetHWND() 
2417     // OS/2 must mannually bump the index's of following records 
2419     BumpRecordIds( GetHWND() 
2422     ::WinSendMsg( GetHWND() 
2423                  ,CM_INVALIDATEDETAILFIELDINFO
 
2427     return pRecord
->m_ulItemId
; 
2428 } // end of wxListCtrl::InsertItem 
2430 long wxListCtrl::InsertItem ( 
2432 , const wxString
&                   rsLabel
 
2437     memset(&vInfo
, '\0', sizeof(wxListItem
)); 
2438     vInfo
.m_text   
= rsLabel
; 
2439     vInfo
.m_mask   
= wxLIST_MASK_TEXT
; 
2440     vInfo
.m_itemId 
= lIndex
; 
2441     return InsertItem(vInfo
); 
2442 } // end of wxListCtrl::InsertItem 
2444 // Inserts an image item 
2445 long wxListCtrl::InsertItem ( 
2452     vInfo
.m_image  
= nImageIndex
; 
2453     vInfo
.m_mask   
= wxLIST_MASK_IMAGE
; 
2454     vInfo
.m_itemId 
= lIndex
; 
2455     return InsertItem(vInfo
); 
2456 } // end of wxListCtrl::InsertItem 
2458 // Inserts an image/string item 
2459 long wxListCtrl::InsertItem ( 
2461 , const wxString
&                   rsLabel
 
2467     vInfo
.m_image  
= nImageIndex
; 
2468     vInfo
.m_text   
= rsLabel
; 
2469     vInfo
.m_mask   
= wxLIST_MASK_IMAGE 
| wxLIST_MASK_TEXT
; 
2470     vInfo
.m_itemId 
= lIndex
; 
2471     return InsertItem(vInfo
); 
2472 } // end of wxListCtrl::InsertItem 
2474 // For details view mode (only), inserts a column. 
2475 long wxListCtrl::InsertColumn ( 
2481     PFIELDINFO                      pField 
= (PFIELDINFO
)::WinSendMsg( GetHWND() 
2482                                                                       ,CM_ALLOCDETAILFIELDINFO
 
2486     PFIELDINFO                      pFieldAfter 
= FindOS2ListFieldByColNum ( GetHWND() 
2489     FIELDINFOINSERT                 vInsert
; 
2491     ConvertToOS2ListCol ( lCol
 
2496     vInsert
.cb                   
= sizeof(FIELDINFOINSERT
); 
2497     vInsert
.pFieldInfoOrder      
= pFieldAfter
; 
2498     vInsert
.fInvalidateFieldInfo 
= TRUE
; 
2499     vInsert
.cFieldInfoInsert     
= 1; 
2501     bSuccess 
= ::WinSendMsg( GetHWND() 
2502                             ,CM_INSERTDETAILFIELDINFO
 
2507 } // end of wxListCtrl::InsertColumn 
2509 long wxListCtrl::InsertColumn ( 
2511 , const wxString
&                   rsHeading
 
2518     vItem
.m_mask 
= wxLIST_MASK_TEXT 
| wxLIST_MASK_FORMAT
; 
2519     vItem
.m_text 
= rsHeading
; 
2522         vItem
.m_mask 
|= wxLIST_MASK_WIDTH
; 
2523         vItem
.m_width 
= nWidth
; 
2525     vItem
.m_format 
= nFormat
; 
2527     return InsertColumn( lCol
 
2530 } // end of wxListCtrl::InsertColumn 
2532 // scroll the control by the given number of pixels (exception: in list view, 
2533 // dx is interpreted as number of columns) 
2534 bool wxListCtrl::ScrollList ( 
2540         ::WinSendMsg( GetHWND() 
2542                      ,(MPARAM
)CMA_HORIZONTAL
 
2546         ::WinSendMsg( GetHWND() 
2548                      ,(MPARAM
)CMA_VERTICAL
 
2552 } // end of wxListCtrl::ScrollList 
2554 bool wxListCtrl::SortItems ( 
2555   wxListCtrlCompare                 fn
 
2559     SInternalDataSort               vInternalData
; 
2561     vInternalData
.m_fnUser 
= fn
; 
2562     vInternalData
.m_lData  
= lData
; 
2564     // WPARAM cast is needed for mingw/cygwin 
2565     if (!::WinSendMsg( GetHWND() 
2567                       ,(PFN
)InternalDataCompareFunc
 
2568                       ,(PVOID
)&vInternalData
 
2571         wxLogDebug(_T("CM_SORTRECORD failed")); 
2575 } // end of wxListCtrl::SortItems 
2577 // ---------------------------------------------------------------------------- 
2578 // message processing 
2579 // ---------------------------------------------------------------------------- 
2581 bool wxListCtrl::OS2Command ( 
2586     if (uCmd 
== CN_ENDEDIT
) 
2588         wxCommandEvent              
vEvent( wxEVT_COMMAND_TEXT_UPDATED
 
2592         vEvent
.SetEventObject( this ); 
2593         ProcessCommand(vEvent
); 
2596     else if (uCmd 
== CN_KILLFOCUS
) 
2598         wxCommandEvent              
vEvent( wxEVT_KILL_FOCUS
 
2601         vEvent
.SetEventObject( this ); 
2602         ProcessCommand(vEvent
); 
2607 } // end of wxListCtrl::OS2Command 
2609 // Necessary for drawing hrules and vrules, if specified 
2610 void wxListCtrl::OnPaint ( 
2611   wxPaintEvent
&                     rEvent
 
2614     wxPaintDC                       
vDc(this); 
2615     wxPen                           
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
) 
2619     wxSize                          vClientSize 
= GetClientSize(); 
2621     int                             nItemCount 
= GetItemCount(); 
2624     bool                            bDrawHRules 
= ((GetWindowStyle() & wxLC_HRULES
) != 0); 
2625     bool                            bDrawVRules 
= ((GetWindowStyle() & wxLC_VRULES
) != 0); 
2627     wxControl::OnPaint(rEvent
); 
2630     // Reset the device origin since it may have been set 
2632     vDc
.SetDeviceOrigin(0, 0); 
2633     if (!bDrawHRules 
&& !bDrawVRules
) 
2635     if ((GetWindowStyle() & wxLC_REPORT
) == 0) 
2638     vDc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
2642         long                        lTop 
= GetTopItem(); 
2644         for (i 
= lTop
; i 
< lTop 
+ GetCountPerPage() + 1; i
++) 
2650                 nCy 
= vItemRect
.GetTop(); 
2651                 if (i 
!= 0) // Don't draw the first one 
2660                 if (i 
== nItemCount 
- 1) 
2662                     nCy 
= vItemRect
.GetBottom(); 
2673     if (bDrawVRules 
&& (i 
> -1)) 
2675         wxRect                      vFirstItemRect
; 
2685             int                     nX 
= vItemRect
.GetX(); 
2687             for (nCol 
= 0; nCol 
< GetColumnCount(); nCol
++) 
2689                 int                 nColWidth 
= GetColumnWidth(nCol
); 
2692                 vDc
.DrawLine( nX 
- 1 
2693                              ,vFirstItemRect
.GetY() - 2 
2695                              ,vItemRect
.GetBottom() 
2700 } // end of wxListCtrl::OnPaint 
2702 // ---------------------------------------------------------------------------- 
2703 // virtual list controls 
2704 // ---------------------------------------------------------------------------- 
2706 wxString 
wxListCtrl::OnGetItemText ( 
2707   long                              WXUNUSED(lItem
) 
2708 , long                              WXUNUSED(lCol
) 
2711     // this is a pure virtual function, in fact - which is not really pure 
2712     // because the controls which are not virtual don't need to implement it 
2713     wxFAIL_MSG( _T("not supposed to be called") ); 
2714     return wxEmptyString
; 
2715 } // end of wxListCtrl::OnGetItemText 
2717 int wxListCtrl::OnGetItemImage ( 
2718   long                              WXUNUSED(lItem
) 
2722     wxFAIL_MSG( _T("not supposed to be called") ); 
2724 } // end of wxListCtrl::OnGetItemImage 
2726 wxListItemAttr
* wxListCtrl::OnGetItemAttr ( 
2727   long                              WXUNUSED_UNLESS_DEBUG(lItem
) 
2730     wxASSERT_MSG( lItem 
>= 0 && lItem 
< GetItemCount(), 
2731                   _T("invalid item index in OnGetItemAttr()") ); 
2734     // No attributes by default 
2737 } // end of wxListCtrl::OnGetItemAttr 
2739 void wxListCtrl::SetItemCount ( 
2743     wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") ); 
2746     // Cannot explicitly set the record count in OS/2 
2748 } // end of wxListCtrl::SetItemCount 
2750 void wxListCtrl::RefreshItem ( 
2760 } // end of wxListCtrl::RefreshItem 
2762 void wxListCtrl::RefreshItems ( 
2770     GetItemRect( lItemFrom
 
2773     GetItemRect( lItemTo
 
2777     wxRect                          vRect 
= vRect1
; 
2779     vRect
.height 
= vRect2
.GetBottom() - vRect1
.GetTop(); 
2781 } // end of wxListCtrl::RefreshItems 
2783 MRESULT 
wxListCtrl::OS2WindowProc( 
2789     bool                            bProcessed 
= FALSE
; 
2791     wxListEvent                     
vEvent( wxEVT_NULL
 
2794     wxEventType                     vEventType 
= wxEVT_NULL
; 
2795     PCNRDRAGINIT                    pDragInit 
= NULL
; 
2796     PCNREDITDATA                    pEditData 
= NULL
; 
2797     PNOTIFYRECORDENTER              pNotifyEnter 
= NULL
; 
2799     vEvent
.SetEventObject(this); 
2804             // First off let's set some internal data 
2806             switch(SHORT2FROMMP(wParam
)) 
2812                         CListItemInternalData
*  pInternaldata 
= (CListItemInternalData 
*)lParam
; 
2816                             wxListItem
*     pItem 
= (wxListItem
*)&vEvent
.GetItem(); 
2818                             pItem
->SetData((long)pInternaldata
->m_lParam
); 
2824             // Now let's go through the codes we're interested in 
2826             switch(SHORT2FROMMP(wParam
)) 
2829                     pDragInit 
= (PCNRDRAGINIT
)lParam
; 
2832                         PMYRECORD       pRecord 
= (PMYRECORD
)pDragInit
->pRecord
; 
2834                         vEventType 
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
; 
2835                         vEvent
.m_itemIndex   
= pRecord
->m_ulItemId
; 
2836                         vEvent
.m_pointDrag
.x 
= pDragInit
->x
; 
2837                         vEvent
.m_pointDrag
.y 
= pDragInit
->y
; 
2842                     pEditData 
= (PCNREDITDATA
)lParam
; 
2845                         vEventType 
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
; 
2846                         ConvertFromOS2ListItem( GetHWND() 
2847                                                ,(wxListItem 
&)vEvent
.GetItem() 
2848                                                ,(PMYRECORD
)pEditData
->pRecord
 
2850                         vEvent
.m_itemIndex 
= vEvent
.GetItem().GetId(); 
2855                     pEditData 
= (PCNREDITDATA
)lParam
; 
2858                         vEventType 
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
; 
2859                         ConvertFromOS2ListItem( GetHWND() 
2860                                                ,(wxListItem 
&)vEvent
.GetItem() 
2861                                                ,(PMYRECORD
)pEditData
->pRecord
 
2863                         if (pEditData
->cbText 
== 0) 
2864                             return (MRESULT
)FALSE
; 
2865                         vEvent
.m_itemIndex 
= vEvent
.GetItem().GetId(); 
2870                     pNotifyEnter 
= (PNOTIFYRECORDENTER
)lParam
; 
2873                         wxListItem
*     pItem 
= (wxListItem
*)&vEvent
.GetItem(); 
2874                         PMYRECORD       pMyRecord 
= (PMYRECORD
)pNotifyEnter
->pRecord
; 
2876                         vEventType             
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
; 
2877                         vEvent
.m_itemIndex 
= pMyRecord
->m_ulItemId
; 
2878                         pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
)); 
2879                         pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
)); 
2884                     // Add the CN_DROP messages for Direct Manipulation 
2887             vEvent
.SetEventType(vEventType
); 
2888             bProcessed 
= GetEventHandler()->ProcessEvent(vEvent
); 
2892         lRc 
= wxControl::OS2WindowProc( uMsg
 
2897 } // end of wxListCtrl::WindowProc 
2899 #endif // wxUSE_LISTCTRL