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"
36 #include "wx/textctrl.h"
37 #include "wx/imaglist.h"
38 #include "wx/listctrl.h"
39 #include "wx/dcclient.h"
41 #include "wx/os2/private.h"
44 // FIELDOFFSET in DETAIL view as defined in the OS2TK45 simply doesn't work
45 // We use this, which does!
48 #define FIELDOFFSET(type, field) ((ULONG)&(((type *)0)->field))
50 // ----------------------------------------------------------------------------
51 // private helper classes
52 // ----------------------------------------------------------------------------
54 /////////////////////////////////////////////////////////////////////////////
56 // Under OS/2 we have to use our own RECORDCORE based struct if we have
57 // user data to store in a PM Container Control (and wxListCtrl is a PM
58 // Container in ICON, NAME, TEXT or DETAIL view). m_ulUserData is a four
59 // byte value containing a pointer to our CListIntemInternalData class
62 // And now for the big time OS/2 Kludge. In traditional OS/2 PM
63 // applications using containers, programmers determine BEFORE creation
64 // how many records the view will have, initially, and how many columns
65 // the detail view of the container will have, as the container represents
66 // a known data block. Thus the OS/2 PM CV_DETAIL view, i.e.
67 // the wxWidgets wxLC_REPORT view, relies on STATIC structure for its
68 // columnar data. It gets the data to display by telling it the specific
69 // offset of the field in the struct containing the displayable data. That
70 // data has be of OS/2 Types, PSZ (char string), CDATE or CTIME format.
71 // wxWidgets is dynamic in nature, however. We insert columns, one at a
72 // time and do not know how many until the app is done inserting them. So
73 // for OS/2 I have to set a max allowable since they are fixed. We return
74 // an error to the app if they include more than we can handle.
76 // For example to display the data "Col 4 of Item 6" in a report view, I'd
78 // pRecord->m_pzColumn4 = "Col 4 of Item 6";
79 // pField->offStruct = FIELDOFFSET(MYRECORD, m_pzColumn4);
80 // and then call the PM API to set it.
82 // This really stinks but I can't use a pointer to another struct as the
83 // FIELDOFFSET call could only tell OS/2 the four byte value offset of
84 // pointer field and it would display giberish in the column.
85 /////////////////////////////////////////////////////////////////////////////
86 typedef struct _MYRECORD
89 unsigned long m_ulItemId
;
90 unsigned long m_ulUserData
; //actually a pointer value to real data (a CListItemInternalData class instance)
101 } MYRECORD
, *PMYRECORD
;
103 /////////////////////////////////////////////////////////////////////////////
104 // CLASS CListItemInternalData
107 // The MSW version had problems with SetTextColour() et al as the
108 // CListItemAttr's were stored keyed on the item index. If a item was
109 // inserted anywhere but the end of the list the the text attributes
110 // (colour etc) for the following items were out of sync.
113 // Under MSW the only way to associate data with a
114 // List item independent of its position in the list is to store a pointer
115 // to it in its lParam attribute. However user programs are already using
116 // this (via the SetItemData() GetItemData() calls).
118 // However what we can do is store a pointer to a structure which contains
119 // the attributes we want *and* a lParam for the users data, e.g.
121 // class CListItemInternalData
124 // GuiAdvCtrl_CListItemAttr* pAttr;
125 // long lParam; // user data
128 // To conserve memory, a CListItemInternalData is only allocated for a
129 // LV_ITEM if text attributes or user data(lparam) are being set.
131 // For OS/2, the lParam value points to whatever actual data we have
132 /////////////////////////////////////////////////////////////////////////////
133 class CListItemInternalData
137 CListItemInternalData(): m_pAttr(NULL
)
141 ~CListItemInternalData()
147 wxListItemAttr
* m_pAttr
;
148 WXLPARAM m_lParam
; // user data
149 PMYRECORD m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted
150 }; // end of CLASS CListItemInternalData
152 /////////////////////////////////////////////////////////////////////////////
153 // STRUCT SInternalDataSort
157 // fn is a function which takes 3 long arguments: item1, item2, data.
158 // item1 is the long data associated with a first item (NOT the index).
159 // item2 is the long data associated with a second item (NOT the index).
160 // data is the same value as passed to SortItems.
162 // The return value is a negative number if the first item should precede the
163 // second item, a positive number of the second item should precede the first,
164 // or zero if the two items are equivalent.
166 // data is arbitrary data to be passed to the sort function.
168 // Internal structures for proxying the user compare function
169 // so that we can pass it the *real* user data
170 /////////////////////////////////////////////////////////////////////////////
171 typedef struct internalDataSort
173 wxListCtrlCompare m_fnUser
;
175 } SInternalDataSort
; // end of STRUCT SInternalDataSort
177 // ----------------------------------------------------------------------------
178 // private helper functions
179 // ----------------------------------------------------------------------------
181 /////////////////////////////////////////////////////////////////////////////
183 // FindOS2ListFieldByColNum
185 // There is no way, under OS/2 to get a field in a container by index,
186 // directly, so you must get the first one, then cycle through the list
187 // until you get to where you want to be.
190 // hWnd -- window handle of container to search
191 // lIndex -- index to set
194 // pointer to the FIELDINFO struct at the index in the container record
196 /////////////////////////////////////////////////////////////////////////////
197 PFIELDINFO
FindOS2ListFieldByColNum (
202 PFIELDINFO pFieldInfo
= NULL
;
206 if (!::WinSendMsg( hWnd
209 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
212 for (i
= 0; i
< vCnrInfo
.cFields
; i
++)
215 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
216 ,CM_QUERYDETAILFIELDINFO
221 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
222 ,CM_QUERYDETAILFIELDINFO
228 if (i
== (ULONG
)lIndex
)
234 } // end of FindOS2ListFieldByColNum
236 /////////////////////////////////////////////////////////////////////////////
238 // FindOS2ListRecordByID
240 // There is no way, under OS/2 to get a record in a container by index,
241 // directly, so you must get the first one, then cycle through the list
242 // until you get to where you want to be.
245 // hWnd -- window handle of container to search
246 // lItemId -- index to set
249 // pointer to the internal RECORDCORE struct at the index in the container
251 /////////////////////////////////////////////////////////////////////////////
252 PMYRECORD
FindOS2ListRecordByID (
257 PMYRECORD pRecord
= NULL
;
261 if (!::WinSendMsg( hWnd
264 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
267 for (i
= 0; i
< vCnrInfo
.cRecords
; i
++)
270 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
273 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
276 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
279 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
283 if (pRecord
->m_ulItemId
== (ULONG
)lItemId
)
287 } // end of FindOS2ListRecordByID
289 /////////////////////////////////////////////////////////////////////////////
293 // Since OS/2 does not keep native record id's but wx insists on inserting
294 // and selecting via ID's, when we insert a record in the middle we need
295 // to bump the id's of each record after the one we just inserted.
298 // hWnd -- window handle of container to search
299 // pRecord -- record after which we starting bumping id's
304 /////////////////////////////////////////////////////////////////////////////
312 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
315 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
318 pRecord
->m_ulItemId
++;
320 } // end of BumpRecordIds
322 /////////////////////////////////////////////////////////////////////////////
326 // Get the internal data given a handle and an id
329 // hWnd -- window handle to the control in which item is located
330 // lItemId -- ID to get
333 // pointer to the internal data
336 // Under OS/2 PM a container item cannot be obtained via a simple index or
337 // id retrieval. We have to walk the record list if we are looking for
338 // a record at a specific index location
339 /////////////////////////////////////////////////////////////////////////////
340 CListItemInternalData
* GetInternalData (
345 PMYRECORD pRecord
= FindOS2ListRecordByID( hWnd
349 // Internal user data is stored AFTER the last field of the RECORDCORE
353 return((CListItemInternalData
*)(pRecord
->m_ulUserData
));
354 } // end of GetInternalData
356 /////////////////////////////////////////////////////////////////////////////
360 // Get the internal data given a pointer to a list control and an id
363 // pCtl -- pointer to control inwhich item is located
364 // lItemId -- ID to get
367 // pointer to the internal data
369 /////////////////////////////////////////////////////////////////////////////
370 CListItemInternalData
* GetInternalData (
375 return(GetInternalData( (HWND
)pCtl
->GetHWND()
378 } // end of GetInternalData
380 /////////////////////////////////////////////////////////////////////////////
382 // DeleteInternalData
384 // Delete the internal data for a record
387 // pCtl -- pointer to the list control containing the record
388 // lItemId -- the record index to delete the internal data from
391 // pointer to the internal data attribute
393 /////////////////////////////////////////////////////////////////////////////
394 void DeleteInternalData (
399 CListItemInternalData
* pData
= GetInternalData( pCtl
404 if (pData
->m_pMyRecord
)
405 pData
->m_pMyRecord
->m_ulUserData
= 0;
408 } // end of DeleteInternalData
410 // #pragma page "GetInternalDataAttr"
411 /////////////////////////////////////////////////////////////////////////////
413 // GetInternalDataAttr
415 // Get the internal data item attribute given a pointer to a list control
419 // pCtl -- pointer to control to set
420 // lItemId -- ID to set
423 // pointer to the internal data attribute
425 /////////////////////////////////////////////////////////////////////////////
426 wxListItemAttr
* GetInternalDataAttr (
431 CListItemInternalData
* pData
= GetInternalData( pCtl
436 return(pData
->m_pAttr
);
439 } // end of GetInternalDataAttr
441 /////////////////////////////////////////////////////////////////////////////
443 // InternalDataCompareFunc
445 // This is compare function we pass to PM. It wraps the real compare
446 // function in SInternalDataSort
449 // p1 -- is the first record structure to compare
450 // p2 -- is the second record structure to compare
451 // lStorage -- is the same value as passed to SortItems.
454 // pointer to the internal data attribute
456 /////////////////////////////////////////////////////////////////////////////
457 SHORT EXPENTRY
InternalDataCompareFunc (
463 SInternalDataSort
* pInternalData
= (SInternalDataSort
*)pStorage
;
464 CListItemInternalData
* pData1
= (CListItemInternalData
*)p1
->m_ulUserData
;
465 CListItemInternalData
* pData2
= (CListItemInternalData
*)p2
->m_ulUserData
;
466 long lD1
= (pData1
== NULL
? 0 : (long)pData1
->m_lParam
);
467 long lD2
= (pData2
== NULL
? 0 : (long)pData2
->m_lParam
);
469 return(pInternalData
->m_fnUser( lD1
471 ,pInternalData
->m_lData
473 } // end of InternalDataCompareFunc
475 /////////////////////////////////////////////////////////////////////////////
477 // ConvertFromOS2ListItem
479 // Convert from an internal PM List item to a Toolkit List item
482 // hWndListCtrl -- the control's windows handle
483 // rInfo -- the library list control to convert to
484 // pRecord -- the OS list control to convert from
489 /////////////////////////////////////////////////////////////////////////////
490 void ConvertFromOS2ListItem (
496 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)pRecord
->m_ulUserData
;
497 bool bNeedText
= FALSE
;
500 rInfo
.SetData(pInternaldata
->m_lParam
);
504 rInfo
.SetStateMask(0);
505 rInfo
.SetId((long)pRecord
->m_ulItemId
);
506 if (hWndListCtrl
!= 0)
508 pRecord
= FindOS2ListRecordByID( hWndListCtrl
514 // The wxListItem class is really set up to handle the WIN32 list item
515 // and OS/2 are not as complicated. Just set both state members to the
516 // same thing under OS/2
518 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DROPONABLE
)
520 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DROPHILITED
);
521 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DROPHILITED
);
523 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SELECTED
)
525 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SELECTED
);
526 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SELECTED
);
528 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DISABLED
)
530 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DISABLED
);
531 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DISABLED
);
533 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_FILTERED
)
535 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_FILTERED
);
536 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_FILTERED
);
538 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_INUSE
)
540 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_INUSE
);
541 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_INUSE
);
543 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_PICKED
)
545 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_PICKED
);
546 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_PICKED
);
548 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SOURCE
)
550 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SOURCE
);
551 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SOURCE
);
554 if (pRecord
->m_vRecord
.pszText
!= (PSZ
)NULL
)
556 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
);
557 rInfo
.SetText(pRecord
->m_vRecord
.pszText
);
559 if (pRecord
->m_vRecord
.pszIcon
!= (PSZ
)NULL
||
560 pRecord
->m_vRecord
.pszName
!= (PSZ
)NULL
)
562 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
);
563 rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
);
565 if (pRecord
->m_ulUserData
)
566 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
);
567 } // end of ConvertFromOS2ListItem
569 /////////////////////////////////////////////////////////////////////////////
573 // Convert from an library states to OS states
576 // lState -- the state
577 // pRecord -- the OS list control to use
582 /////////////////////////////////////////////////////////////////////////////
583 void ConvertToOS2Flags (
588 if (lState
& wxLIST_STATE_DROPHILITED
)
589 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DROPONABLE
;
590 if (lState
& wxLIST_STATE_SELECTED
)
591 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SELECTED
;
592 if (lState
& wxLIST_STATE_DISABLED
)
593 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DISABLED
;
594 if (lState
& wxLIST_STATE_FILTERED
)
595 pRecord
->m_vRecord
.flRecordAttr
|= CRA_FILTERED
;
596 if (lState
& wxLIST_STATE_INUSE
)
597 pRecord
->m_vRecord
.flRecordAttr
|= CRA_INUSE
;
598 if (lState
& wxLIST_STATE_PICKED
)
599 pRecord
->m_vRecord
.flRecordAttr
|= CRA_PICKED
;
600 if (lState
& wxLIST_STATE_SOURCE
)
601 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SOURCE
;
602 } // end of ConvertToOS2Flags
604 /////////////////////////////////////////////////////////////////////////////
606 // ConvertToOS2ListItem
608 // Convert from a library List item to an internal OS2 List item. We set
609 // only the fields we need to set. Some of them are set by the API when
610 // they are added to the container.
613 // pCtrl -- the control to use
614 // rInfo -- the item to convert
615 // pRecord -- the OS list control to use, should be zeroed out
616 // pFieldinfo -- a field struct that may contain columnar data for detail view
621 /////////////////////////////////////////////////////////////////////////////
622 void ConvertToOS2ListItem (
623 const wxListCtrl
* pCtrl
624 , const wxListItem
& rInfo
626 , PFIELDINFO pFieldInfo
629 pRecord
->m_ulItemId
= (ULONG
)rInfo
.GetId();
630 pRecord
->m_vRecord
.cb
= sizeof(RECORDCORE
);
631 if (rInfo
.GetMask() & wxLIST_MASK_STATE
)
633 ConvertToOS2Flags( rInfo
.m_state
637 if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON
||
638 pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
)
640 pRecord
->m_vRecord
.pszIcon
= (char*)rInfo
.GetText().c_str();
642 if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view
644 pRecord
->m_vRecord
.pszText
= (char*)rInfo
.GetText().c_str();
647 // In the case of a report view the text will be the data in the lead column
648 // ???? Don't know why, but that is how it works in other ports.
650 if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
)
654 switch(rInfo
.GetColumn())
657 pRecord
->m_pzColumn1
= (char*)rInfo
.GetText().c_str();
658 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn1
);
662 pRecord
->m_pzColumn2
= (char*)rInfo
.GetText().c_str();
663 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn2
);
667 pRecord
->m_pzColumn3
= (char*)rInfo
.GetText().c_str();
668 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn3
);
672 pRecord
->m_pzColumn4
= (char*)rInfo
.GetText().c_str();
673 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn4
);
677 pRecord
->m_pzColumn5
= (char*)rInfo
.GetText().c_str();
678 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn5
);
682 pRecord
->m_pzColumn6
= (char*)rInfo
.GetText().c_str();
683 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn6
);
687 pRecord
->m_pzColumn7
= (char*)rInfo
.GetText().c_str();
688 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn7
);
692 pRecord
->m_pzColumn8
= (char*)rInfo
.GetText().c_str();
693 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn8
);
697 pRecord
->m_pzColumn9
= (char*)rInfo
.GetText().c_str();
698 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn9
);
702 pRecord
->m_pzColumn10
= (char*)rInfo
.GetText().c_str();
703 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn10
);
707 wxFAIL_MSG( _T("wxOS2 does not support more than 10 columns in REPORT view") );
712 if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
)
714 pRecord
->m_vRecord
.hptrIcon
= (HPOINTER
)rInfo
.GetImage();
715 pRecord
->m_vRecord
.hptrMiniIcon
= (HPOINTER
)rInfo
.m_miniImage
;
717 } // end of ConvertToOS2ListItem
719 /////////////////////////////////////////////////////////////////////////////
721 // ConvertToOS2ListCol
723 // Convert from a library List column to an internal PM List column
726 // lCol -- the columnd to convert
727 // rItem -- the item to convert
728 // pField -- the OS list column to use
733 /////////////////////////////////////////////////////////////////////////////
734 void ConvertToOS2ListCol (
736 , const wxListItem
& rItem
740 memset(pField
, '\0', sizeof(FIELDINFO
));
741 pField
->cb
= sizeof(FIELDINFO
);
744 // Default some settings
746 pField
->flData
= CFA_HORZSEPARATOR
| CFA_SEPARATOR
;
747 pField
->flTitle
= CFA_CENTER
;
749 if (rItem
.GetMask() & wxLIST_MASK_TEXT
)
751 pField
->flData
|= CFA_STRING
;
752 pField
->pTitleData
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data
754 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
756 if (rItem
.m_format
== wxLIST_FORMAT_LEFT
)
757 pField
->flData
|= CFA_LEFT
;
758 else if (rItem
.m_format
== wxLIST_FORMAT_RIGHT
)
759 pField
->flData
|= CFA_RIGHT
;
760 else if (rItem
.m_format
== wxLIST_FORMAT_CENTRE
)
761 pField
->flData
|= CFA_CENTER
;
764 pField
->flData
|= CFA_CENTER
; // Just ensure the default is centered
765 if (rItem
.GetMask() & wxLIST_MASK_WIDTH
)
767 if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE
||
768 rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
))
769 pField
->cxWidth
= rItem
.GetWidth();
770 // else: OS/2 automatically sets the width if created with the approppriate style
774 // Still need to set the actual data
776 pField
->offStruct
= 0;
777 } // end of ConvertToOS2ListCol
779 // ----------------------------------------------------------------------------
781 // ----------------------------------------------------------------------------
783 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG
)
784 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG
)
785 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
)
786 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT
)
787 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM
)
788 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
)
789 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO
)
790 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO
)
791 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED
)
792 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED
)
793 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN
)
794 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM
)
795 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK
)
796 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_RIGHT_CLICK
)
797 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG
)
798 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_DRAGGING
)
799 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_END_DRAG
)
800 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
)
801 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
)
802 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED
)
803 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED
)
804 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT
)
806 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
807 IMPLEMENT_DYNAMIC_CLASS(wxListView
, wxListCtrl
)
808 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
810 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
812 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
)
813 EVT_PAINT(wxListCtrl::OnPaint
)
816 // ============================================================================
818 // ============================================================================
820 // ----------------------------------------------------------------------------
821 // wxListCtrl construction
822 // ----------------------------------------------------------------------------
824 void wxListCtrl::Init ()
826 m_pImageListNormal
= NULL
;
827 m_pImageListSmall
= NULL
;
828 m_pImageListState
= NULL
;
829 m_bOwnsImageListNormal
= FALSE
;
830 m_bOwnsImageListSmall
= FALSE
;
831 m_bOwnsImageListState
= FALSE
;
835 m_bAnyInternalData
= FALSE
;
836 m_bHasAnyAttr
= FALSE
;
837 } // end of wxListCtrl::Init
839 bool wxListCtrl::Create (
842 , const wxPoint
& rPos
843 , const wxSize
& rSize
845 , const wxValidator
& rValidator
846 , const wxString
& rsName
851 int nWidth
= rSize
.x
;
852 int nHeight
= rSize
.y
;
855 SetValidator(rValidator
);
856 #endif // wxUSE_VALIDATORS
859 SetWindowStyleFlag(lStyle
);
870 m_windowId
= (vId
== -1) ? NewControlId() : vId
;
872 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
874 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
)
875 lSstyle
|= WS_CLIPSIBLINGS
;
876 m_lBaseStyle
= lSstyle
;
877 if (!DoCreateControl( nX
884 pParent
->AddChild(this);
886 } // end of wxListCtrl::Create
888 bool wxListCtrl::DoCreateControl (
895 DWORD lWstyle
= m_lBaseStyle
;
896 long lOldStyle
= 0; // Dummy
900 lWstyle
|= ConvertToOS2Style( lOldStyle
901 ,GetWindowStyleFlag()
904 m_hWnd
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND()
909 ,GetParent()->GetHWND()
921 // Now set the display attributes of the container
923 if (!::WinSendMsg( GetHWND()
926 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
929 lWstyle
= ConvertViewToOS2Style(GetWindowStyleFlag());
930 vCnrInfo
.flWindowAttr
|= lWstyle
;
931 if (!::WinSendMsg( GetHWND()
934 ,(MPARAM
)CMA_FLWINDOWATTR
939 // And now set needed arrangement flags
941 lWstyle
= ConvertArrangeToOS2Style(GetWindowStyleFlag());
942 if (!::WinSendMsg( GetHWND()
944 ,(MPARAM
)CMA_ARRANGEGRID
948 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
949 SetForegroundColour(GetParent()->GetForegroundColour());
951 SetFont(*wxSMALL_FONT
);
960 } // end of wxListCtrl::DoCreateControl
962 void wxListCtrl::UpdateStyle ()
967 DWORD dwStyleNew
= ConvertToOS2Style( lDummy
968 ,GetWindowStyleFlag()
971 dwStyleNew
|= m_lBaseStyle
;
974 // Get the current window style.
976 ULONG dwStyleOld
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
);
979 // Only set the window style if the view bits have changed.
981 if (dwStyleOld
!= dwStyleNew
)
983 ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
);
986 } // end of wxListCtrl::UpdateStyle
988 void wxListCtrl::FreeAllInternalData ()
990 if (m_bAnyInternalData
)
992 int n
= GetItemCount();
995 for (i
= 0; i
< n
; i
++)
996 DeleteInternalData(this, (long)i
);
997 m_bAnyInternalData
= FALSE
;
999 } // end of wxListCtrl::FreeAllInternalData
1001 wxListCtrl::~wxListCtrl ()
1003 FreeAllInternalData();
1006 m_pTextCtrl
->SetHWND(0);
1007 m_pTextCtrl
->UnsubclassWin();
1012 if (m_bOwnsImageListNormal
)
1013 delete m_pImageListNormal
;
1014 if (m_bOwnsImageListSmall
)
1015 delete m_pImageListSmall
;
1016 if (m_bOwnsImageListState
)
1017 delete m_pImageListState
;
1018 } // end of wxListCtrl::~wxListCtrl
1020 // ----------------------------------------------------------------------------
1021 // set/get/change style
1022 // ----------------------------------------------------------------------------
1024 // Add or remove a single window style
1025 void wxListCtrl::SetSingleStyle (
1030 long lFlag
= GetWindowStyleFlag();
1033 // Get rid of conflicting styles
1037 if (lStyle
& wxLC_MASK_TYPE
)
1038 lFlag
= lFlag
& ~wxLC_MASK_TYPE
;
1039 if (lStyle
& wxLC_MASK_ALIGN
)
1040 lFlag
= lFlag
& ~wxLC_MASK_ALIGN
;
1041 if (lStyle
& wxLC_MASK_SORT
)
1042 lFlag
= lFlag
& ~wxLC_MASK_SORT
;
1056 m_windowStyle
= lFlag
;
1058 } // end of wxListCtrl::SetSingleStyle
1060 // Set the whole window style
1061 void wxListCtrl::SetWindowStyleFlag (
1065 m_windowStyle
= lFlag
;
1067 } // end of wxListCtrl::SetWindowStyleFlag
1069 long wxListCtrl::ConvertToOS2Style (
1077 // The only styles OS2 uses on creation are auto arrange, read only, and
1078 // and selection styles. This lib does not support OS/2 MINIRECORDCORE
1079 // or VERIFYPOINTER styles
1081 if (lStyle
& wxLC_AUTOARRANGE
)
1082 lWstyle
|= CCS_AUTOPOSITION
;
1083 if (lStyle
& wxLC_SINGLE_SEL
)
1084 lWstyle
|= CCS_SINGLESEL
;
1086 lWstyle
|= CCS_EXTENDSEL
;
1087 if (!(lStyle
& wxLC_EDIT_LABELS
))
1088 lWstyle
|= CCS_READONLY
;
1090 } // end of wxListCtrl::ConvertToOS2Style
1092 long wxListCtrl::ConvertArrangeToOS2Style (
1098 if (lStyle
& wxLC_ALIGN_LEFT
)
1100 lWstyle
|= CMA_LEFT
;
1103 if (lStyle
& wxLC_ALIGN_TOP
)
1108 } // end of wxListCtrl::ConvertArrangeToOS2Style
1110 long wxListCtrl::ConvertViewToOS2Style (
1114 long lWstyle
= CA_DRAWICON
; // we will only use icons
1116 if (lStyle
& wxLC_ICON
)
1120 if (lStyle
& wxLC_SMALL_ICON
)
1122 lWstyle
|= (CV_ICON
| CV_MINI
);
1124 if (lStyle
& wxLC_LIST
)
1128 if (lStyle
& wxLC_REPORT
)
1130 lWstyle
|= CV_DETAIL
;
1132 if (lStyle
& wxLC_VIRTUAL
)
1134 lWstyle
|= CA_OWNERDRAW
;
1136 if (lStyle
& wxLC_AUTOARRANGE
)
1140 if (!(lStyle
& wxLC_NO_HEADER
))
1142 lWstyle
|= CA_DETAILSVIEWTITLES
;
1145 } // end of wxListCtrl::ConvertViewToOS2Style
1147 // ----------------------------------------------------------------------------
1149 // ----------------------------------------------------------------------------
1151 // Sets the foreground, i.e. text, colour
1152 bool wxListCtrl::SetForegroundColour (
1153 const wxColour
& rCol
)
1155 ULONG ulColor
= wxColourToRGB(rCol
);
1157 if (!wxWindow::SetForegroundColour(rCol
))
1161 ::WinSetPresParam( GetHWND()
1167 } // end of wxListCtrl::SetForegroundColour
1169 // Sets the background colour
1170 bool wxListCtrl::SetBackgroundColour (
1171 const wxColour
& rCol
1174 if (!wxWindow::SetBackgroundColour(rCol
))
1178 // We set the same colour for both the "empty" background and the items
1181 ULONG ulColor
= wxColourToRGB(rCol
);
1183 ::WinSetPresParam( GetHWND()
1189 } // end of wxListCtrl::SetBackgroundColour
1191 // Gets information about this column
1192 bool wxListCtrl::GetColumn (
1197 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
1203 rItem
.SetWidth(pFieldInfo
->cxWidth
);
1204 if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) &&
1205 (pFieldInfo
->flData
& CFA_STRING
) &&
1206 (pFieldInfo
->pUserData
!= NULL
))
1208 rItem
.SetText((char*)pFieldInfo
->pUserData
);
1210 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
1212 if (pFieldInfo
->flData
& CFA_LEFT
)
1213 rItem
.m_format
= wxLIST_FORMAT_LEFT
;
1214 else if (pFieldInfo
->flData
& CFA_RIGHT
)
1215 rItem
.m_format
= wxLIST_FORMAT_RIGHT
;
1216 else if (pFieldInfo
->flData
& CFA_CENTER
)
1217 rItem
.m_format
= wxLIST_FORMAT_CENTRE
;
1220 } // end of wxListCtrl::GetColumn
1222 // Sets information about this column
1223 bool wxListCtrl::SetColumn (
1228 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND()
1231 ConvertToOS2ListCol( nCol
1236 // Since we changed the field pointed to, we invalidate to see the result
1238 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1240 } // end of wxListCtrl::SetColumn
1242 // Gets the column width
1243 int wxListCtrl::GetColumnWidth (
1247 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
1253 return((int)pFieldInfo
->cxWidth
);
1254 } // end of wxListCtrl::GetColumnWidth
1256 // Sets the column width
1257 bool wxListCtrl::SetColumnWidth (
1263 int nWidth2
= nWidth
;
1265 if (GetWindowStyleFlag() & wxLC_LIST
)
1268 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND()
1271 pFieldInfo
->cxWidth
= nWidth
;
1272 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1274 } // end of wxListCtrl::SetColumnWidth
1276 // Gets the number of items that can fit vertically in the
1277 // visible area of the list control (list or report view)
1278 // or the total number of items in the list control (icon
1279 // or small icon view)
1280 int wxListCtrl::GetCountPerPage () const
1282 QUERYRECORDRECT vQueryRect
;
1288 if (!::WinSendMsg( GetHWND()
1291 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1294 memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
));
1295 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1296 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
1297 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1298 else if (vCnrInfo
.flWindowAttr
& CV_NAME
)
1299 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1300 else if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
1301 vQueryRect
.fsExtent
= CMA_TEXT
;
1302 else if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
1303 vQueryRect
.fsExtent
= CMA_TEXT
;
1304 if (!::WinSendMsg( GetHWND()
1306 ,MPFROMP(&vRectRecord
)
1307 ,MPFROMP(&vQueryRect
)
1310 if (!::WinSendMsg( GetHWND()
1311 ,CM_QUERYVIEWPORTRECT
1312 ,MPFROMP(&vRectControl
)
1313 ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
)
1316 nCount
= (int)((int)((vRectControl
.xRight
- vRectControl
.xLeft
) / (vRectRecord
.xRight
- vRectRecord
.xLeft
)) *
1317 (int)((vRectControl
.yTop
- vRectControl
.yBottom
) / (vRectRecord
.yTop
- vRectRecord
.yBottom
))
1319 if (nCount
> (int)vCnrInfo
.cFields
)
1320 nCount
= (int)vCnrInfo
.cFields
;
1322 } // end of wxListCtrl::GetCountPerPage
1324 // Gets the edit control for editing labels.
1325 wxTextCtrl
* wxListCtrl::GetEditControl() const
1330 // Gets information about the item
1331 bool wxListCtrl::GetItem (
1335 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1340 // Give NULL as hwnd as we already have everything we need
1342 ConvertFromOS2ListItem( NULL
1347 } // end of wxListCtrl::GetItem
1349 // Sets information about the item
1350 bool wxListCtrl::SetItem (
1354 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
1357 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1361 ConvertToOS2ListItem( this
1368 // Check if setting attributes or lParam
1370 if (rInfo
.HasAttributes() || (rInfo
.GetMask() & wxLIST_MASK_DATA
))
1373 // Get internal item data
1374 // perhaps a cache here ?
1376 CListItemInternalData
* pData
= GetInternalData( this
1385 m_bAnyInternalData
= TRUE
;
1386 pData
= new CListItemInternalData();
1387 pRecord
->m_ulUserData
= (unsigned long)pData
;
1393 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
1394 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
1397 if (rInfo
.HasAttributes())
1400 *pData
->m_pAttr
= *rInfo
.GetAttributes();
1402 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
1404 pData
->m_pMyRecord
= pRecord
; // they point to each other
1408 // We need to update the item immediately to show the new image
1410 bool bUpdateNow
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0;
1413 // Check whether it has any custom attributes
1415 if (rInfo
.HasAttributes())
1417 m_bHasAnyAttr
= TRUE
;
1420 // If the colour has changed, we must redraw the item
1424 if (::WinIsWindowVisible(GetHWND()))
1426 ::WinSendMsg( GetHWND()
1427 ,CM_INVALIDATERECORD
1429 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1431 RefreshItem(pRecord
->m_ulItemId
);
1433 ::WinSendMsg( GetHWND()
1434 ,CM_INVALIDATEDETAILFIELDINFO
1439 } // end of wxListCtrl::SetItem
1441 long wxListCtrl::SetItem (
1444 , const wxString
& rsLabel
1450 vInfo
.m_text
= rsLabel
;
1451 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1452 vInfo
.m_itemId
= lIndex
;
1456 vInfo
.m_image
= nImageId
;
1457 vInfo
.m_mask
|= wxLIST_MASK_IMAGE
;
1459 return SetItem(vInfo
);
1460 } // end of wxListCtrl::SetItem
1462 // Gets the item state
1463 int wxListCtrl::GetItemState (
1470 vInfo
.m_mask
= wxLIST_MASK_STATE
;
1471 vInfo
.m_stateMask
= lStateMask
;
1472 vInfo
.m_itemId
= lItem
;
1474 if (!GetItem(vInfo
))
1476 return vInfo
.m_state
;
1477 } // end of wxListCtrl::GetItemState
1479 // Sets the item state
1480 bool wxListCtrl::SetItemState (
1486 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1491 // Don't use SetItem() here as it doesn't work with the virtual list
1494 ConvertToOS2Flags( lState
1499 // for the virtual list controls we need to refresh the previously focused
1500 // item manually when changing focus without changing selection
1501 // programmatically because otherwise it keeps its focus rectangle until
1502 // next repaint (yet another comctl32 bug)
1507 (lStateMask
& wxLIST_STATE_FOCUSED
) &&
1508 (lState
& wxLIST_STATE_FOCUSED
) )
1510 lFocusOld
= GetNextItem( -1
1512 ,wxLIST_STATE_FOCUSED
1519 ::WinSendMsg( GetHWND()
1520 ,CM_INVALIDATERECORD
1522 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1525 if (lFocusOld
!= -1)
1528 // No need to refresh the item if it was previously selected, it would
1529 // only result in annoying flicker
1531 if (!(GetItemState( lFocusOld
1532 ,wxLIST_STATE_SELECTED
1533 ) & wxLIST_STATE_SELECTED
))
1535 RefreshItem(lFocusOld
);
1539 } // end of wxListCtrl::SetItemState
1541 // Sets the item image
1542 bool wxListCtrl::SetItemImage (
1545 , int WXUNUSED(nSelImage
))
1549 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
1550 vInfo
.m_image
= nImage
;
1551 vInfo
.m_itemId
= lItem
;
1552 return SetItem(vInfo
);
1553 } // end of wxListCtrl::SetItemImage
1555 // Gets the item text
1556 wxString
wxListCtrl::GetItemText (
1562 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1563 vInfo
.m_itemId
= lItem
;
1565 if (!GetItem(vInfo
))
1566 return wxEmptyString
;
1567 return vInfo
.m_text
;
1568 } // end of wxListCtrl::GetItemText
1570 // Sets the item text
1571 void wxListCtrl::SetItemText (
1573 , const wxString
& rsStr
1578 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1579 vInfo
.m_itemId
= lItem
;
1580 vInfo
.m_text
= rsStr
;
1582 } // end of wxListCtrl::SetItemText
1584 // Gets the item data
1585 long wxListCtrl::GetItemData (
1591 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1592 vInfo
.m_itemId
= lItem
;
1593 if (!GetItem(vInfo
))
1595 return vInfo
.m_data
;
1596 } // end of wxListCtrl::GetItemData
1598 // Sets the item data
1599 bool wxListCtrl::SetItemData (
1606 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1607 vInfo
.m_itemId
= lItem
;
1608 vInfo
.m_data
= lData
;
1609 return SetItem(vInfo
);
1610 } // end of wxListCtrl::SetItemData
1612 // Gets the item rectangle
1613 bool wxListCtrl::GetItemRect (
1620 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1623 QUERYRECORDRECT vQueryRect
;
1629 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1630 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1631 vQueryRect
.fRightSplitWindow
= TRUE
;
1632 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1633 ::WinSendMsg( GetHWND()
1636 ,MPFROMP(&vQueryRect
)
1639 // remember OS/2 is backwards
1644 rRect
.x
= vRect
.xLeft
;
1645 rRect
.y
= nHeight
- vRect
.yTop
;
1646 rRect
.width
= vRect
.xRight
;
1647 rRect
.height
= nHeight
- vRect
.yBottom
;
1650 } // end of wxListCtrl::GetItemRect
1652 // Gets the item position
1653 bool wxListCtrl::GetItemPosition (
1659 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1662 QUERYRECORDRECT vQueryRect
;
1668 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1669 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1670 vQueryRect
.fRightSplitWindow
= TRUE
;
1671 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1672 ::WinSendMsg( GetHWND()
1675 ,MPFROMP(&vQueryRect
)
1678 // remember OS/2 is backwards
1683 rPos
.x
= vRect
.xLeft
;
1684 rPos
.y
= nHeight
- vRect
.yTop
;
1687 } // end of wxListCtrl::GetItemPosition
1689 // Sets the item position.
1690 bool wxListCtrl::SetItemPosition (
1692 , const wxPoint
& rPos
1696 // Items cannot be positioned in X/Y coord in OS/2
1699 } // end of wxListCtrl::SetItemPosition
1701 // Gets the number of items in the list control
1702 int wxListCtrl::GetItemCount () const
1706 if (!::WinSendMsg( GetHWND()
1709 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1712 return vCnrInfo
.cRecords
;
1713 } // end of wxListCtrl::GetItemCount
1715 // Retrieves the spacing between icons in pixels.
1716 // If small is TRUE, gets the spacing for the small icon
1717 // view, otherwise the large icon view.
1718 int wxListCtrl::GetItemSpacing (
1724 if (!::WinSendMsg( GetHWND()
1727 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1730 return vCnrInfo
.cyLineSpacing
;
1731 } // end of wxListCtrl::GetItemSpacing
1733 void wxListCtrl::SetItemTextColour (
1735 , const wxColour
& rCol
1740 vInfo
.m_itemId
= lItem
;
1741 vInfo
.SetTextColour(rCol
);
1743 } // end of wxListCtrl::SetItemTextColour
1745 wxColour
wxListCtrl::GetItemTextColour (
1751 vInfo
.m_itemId
= lItem
;
1753 return vInfo
.GetTextColour();
1754 } // end of wxListCtrl::GetItemTextColour
1756 void wxListCtrl::SetItemBackgroundColour (
1758 , const wxColour
& rCol
1763 vInfo
.m_itemId
= lItem
;
1764 vInfo
.SetBackgroundColour(rCol
);
1766 } // end of wxListCtrl::SetItemBackgroundColour
1768 wxColour
wxListCtrl::GetItemBackgroundColour (
1774 vInfo
.m_itemId
= lItem
;
1776 return vInfo
.GetBackgroundColour();
1777 } // end of wxListCtrl::GetItemBackgroundColour
1779 // Gets the number of selected items in the list control
1780 int wxListCtrl::GetSelectedItemCount () const
1782 PMYRECORD pRecord
= NULL
;
1784 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1785 ,CM_QUERYRECORDEMPHASIS
1787 ,(MPARAM
)CRA_SELECTED
1795 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1796 ,CM_QUERYRECORDEMPHASIS
1798 ,(MPARAM
)CRA_SELECTED
1804 } // end of wxListCtrl::GetSelectedItemCount
1806 // Gets the text colour of the listview
1807 wxColour
wxListCtrl::GetTextColour () const
1812 ::WinQueryPresParam( GetHWND()
1822 } // end of wxListCtrl::GetTextColour
1824 // Sets the text colour of the listview
1825 void wxListCtrl::SetTextColour (
1826 const wxColour
& rCol
1829 ULONG ulColor
= wxColourToRGB(rCol
);
1831 ::WinSetPresParam( GetHWND()
1836 } // end of wxListCtrl::SetTextColour
1838 // Gets the index of the topmost visible item when in
1839 // list or report view
1840 long wxListCtrl::GetTopItem () const
1842 PMYRECORD pRecord
= NULL
;
1843 QUERYRECFROMRECT vQueryRect
;
1846 ::WinSendMsg( GetHWND()
1847 ,CM_QUERYVIEWPORTRECT
1849 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1851 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1852 vQueryRect
.rect
= vRect
;
1853 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1855 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1856 ,CM_QUERYRECORDFROMRECT
1858 ,MPFROMP(&vQueryRect
)
1863 return (long)pRecord
->m_ulItemId
;
1864 } // end of wxListCtrl::GetTopItem
1866 // Searches for an item, starting from 'item'.
1867 // 'geometry' is one of
1868 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
1869 // 'state' is a state bit flag, one or more of
1870 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
1871 // item can be -1 to find the first item that matches the
1873 // Returns the item or -1 if unsuccessful.
1874 long wxListCtrl::GetNextItem (
1876 , int WXUNUSED(nGeom
)
1877 , int WXUNUSED(nState
)
1880 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1884 pRecord
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
;
1886 return((long)pRecord
->m_ulItemId
);
1888 } // end of wxListCtrl::GetNextItem
1890 wxImageList
* wxListCtrl::GetImageList (
1894 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1896 return m_pImageListNormal
;
1898 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1900 return m_pImageListSmall
;
1902 else if (nWhich
== wxIMAGE_LIST_STATE
)
1904 return m_pImageListState
;
1907 } // end of wxListCtrl::GetImageList
1909 void wxListCtrl::SetImageList (
1910 wxImageList
* pImageList
1914 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1916 if (m_bOwnsImageListNormal
)
1917 delete m_pImageListNormal
;
1918 m_pImageListNormal
= pImageList
;
1919 m_bOwnsImageListNormal
= FALSE
;
1921 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1923 if (m_bOwnsImageListSmall
)
1924 delete m_pImageListSmall
;
1925 m_pImageListSmall
= pImageList
;
1926 m_bOwnsImageListSmall
= FALSE
;
1928 else if (nWhich
== wxIMAGE_LIST_STATE
)
1930 if (m_bOwnsImageListState
)
1931 delete m_pImageListState
;
1932 m_pImageListState
= pImageList
;
1933 m_bOwnsImageListState
= FALSE
;
1935 } // end of wxListCtrl::SetImageList
1937 void wxListCtrl::AssignImageList (
1938 wxImageList
* pImageList
1942 SetImageList( pImageList
1945 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1946 m_bOwnsImageListNormal
= TRUE
;
1947 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1948 m_bOwnsImageListSmall
= TRUE
;
1949 else if (nWhich
== wxIMAGE_LIST_STATE
)
1950 m_bOwnsImageListState
= TRUE
;
1951 } // end of wxListCtrl::AssignImageList
1953 // ----------------------------------------------------------------------------
1955 // ----------------------------------------------------------------------------
1957 // Arranges the items
1958 bool wxListCtrl::Arrange (
1965 if (nFlag
== wxLIST_ALIGN_SNAP_TO_GRID
)
1967 ulType
= CMA_ARRANGEGRID
;
1968 if (nFlag
== wxLIST_ALIGN_LEFT
)
1969 ulFlags
|= CMA_LEFT
;
1970 else if (nFlag
== wxLIST_ALIGN_TOP
)
1972 else if (nFlag
== wxLIST_ALIGN_DEFAULT
)
1973 ulFlags
|= CMA_LEFT
;
1976 ulType
= CMA_ARRANGESTANDARD
;
1977 ::WinSendMsg( GetHWND()
1983 // We do not support CMA_ARRANGESELECTED
1986 } // end of wxListCtrl::Arrange
1989 bool wxListCtrl::DeleteItem (
1993 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1996 if (LONGFROMMR(::WinSendMsg( GetHWND()
1999 ,MPFROM2SHORT(1, CMA_FREE
)
2006 // The virtual list control doesn't refresh itself correctly, help it
2011 // We need to refresh all the lines below the one which was deleted
2015 if (lItem
> 0 && GetItemCount())
2017 GetItemRect( lItem
- 1
2023 vRectItem
.y
= vRectItem
.height
= 0;
2025 wxRect vRectWin
= GetRect();
2027 vRectWin
.height
= vRectWin
.GetBottom() - vRectItem
.GetBottom();
2028 vRectWin
.y
= vRectItem
.GetBottom();
2029 RefreshRect(vRectWin
);
2032 } // end of wxListCtrl::DeleteItem
2034 // Deletes all items
2035 bool wxListCtrl::DeleteAllItems ()
2037 return((LONG
)::WinSendMsg( GetHWND()
2040 ,MPFROM2SHORT(0, CMA_FREE
)
2042 } // end of wxListCtrl::DeleteAllItems
2044 // Deletes all items
2045 bool wxListCtrl::DeleteAllColumns ()
2047 while (m_nColCount
> 0)
2049 DeleteColumn(m_nColCount
- 1);
2053 wxASSERT_MSG(m_nColCount
== 0, wxT("no columns should be left"));
2055 } // end of wxListCtrl::DeleteAllColumns
2058 bool wxListCtrl::DeleteColumn (
2062 bool bSuccess
= FALSE
;
2063 PFIELDINFO pField
= FindOS2ListFieldByColNum( GetHWND()
2066 bSuccess
= ((LONG
)::WinSendMsg( GetHWND()
2067 ,CM_REMOVEDETAILFIELDINFO
2069 ,MPFROM2SHORT((SHORT
)1, CMA_FREE
)
2071 if (bSuccess
&& (m_nColCount
> 0))
2074 } // end of wxListCtrl::DeleteColumn
2076 // Clears items, and columns if there are any.
2077 void wxListCtrl::ClearAll ()
2080 if (m_nColCount
> 0)
2082 } // end of wxListCtrl::ClearAll
2085 // OS/2 does not use a text control for its container labels. You merely
2086 // "open" a record for editting.
2088 wxTextCtrl
* wxListCtrl::EditLabel (
2090 , wxClassInfo
* WXUNUSED(pTextControlClass
)
2094 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2098 vEdit
.cb
= sizeof(CNREDITDATA
);
2099 vEdit
.hwndCnr
= GetHWND();
2100 vEdit
.pRecord
= &pRecord
->m_vRecord
;
2101 vEdit
.pFieldInfo
= NULL
;
2102 vEdit
.ppszText
= NULL
;
2106 ::WinSendMsg( GetHWND()
2112 } // end of wxListCtrl::EditLabel
2114 // End label editing, optionally cancelling the edit. Under OS/2 you close
2115 // the record for editting
2116 bool wxListCtrl::EndEditLabel (
2117 bool WXUNUSED(bCancel
)
2120 ::WinSendMsg( GetHWND()
2126 } // end of wxListCtrl::EndEditLabel
2128 // Ensures this item is visible
2129 bool wxListCtrl::EnsureVisible (
2133 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2136 ::WinSendMsg( GetHWND()
2137 ,CM_INVALIDATERECORD
2139 ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
)
2142 } // end of wxListCtrl::EnsureVisible
2144 // Find an item whose label matches this string, starting from the item after 'start'
2145 // or the beginning if 'start' is -1.
2146 long wxListCtrl::FindItem (
2148 , const wxString
& rsStr
2153 SEARCHSTRING vSearch
;
2154 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2160 if (!::WinSendMsg( GetHWND()
2163 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2167 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
2169 if (vCnrInfo
.flWindowAttr
& CV_NAME
)
2171 if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
2173 if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
2176 ulFlag
|= CV_EXACTLENGTH
;
2178 vSearch
.cb
= sizeof(SEARCHSTRING
);
2179 vSearch
.pszSearch
= (char*)rsStr
.c_str();
2180 vSearch
.fsPrefix
= TRUE
;
2181 vSearch
.fsCaseSensitive
= TRUE
;
2182 vSearch
.usView
= ulFlag
;
2186 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2194 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2202 return pRecord
->m_ulItemId
;
2203 } // end of wxListCtrl::FindItem
2205 // Find an item whose data matches this data, starting from the item after 'start'
2206 // or the beginning if 'start' is -1.
2207 long wxListCtrl::FindItem (
2212 long lIdx
= lStart
+ 1;
2213 long lCount
= GetItemCount();
2215 while (lIdx
< lCount
)
2217 if (GetItemData(lIdx
) == lData
)
2222 } // end of wxListCtrl::FindItem
2224 // Find an item nearest this position in the specified direction, starting from
2225 // the item after 'start' or the beginning if 'start' is -1.
2226 long wxListCtrl::FindItem (
2228 , const wxPoint
& rPoint
2233 QUERYRECORDRECT vQueryRect
;
2234 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2241 if (!::WinSendMsg( GetHWND()
2244 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2248 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
2249 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
2250 vQueryRect
.fRightSplitWindow
= TRUE
;
2251 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
2253 ::WinSendMsg( GetHWND()
2256 ,MPFROMP(&vQueryRect
)
2258 vLibRect
.SetLeft(vRect
.xLeft
);
2259 vLibRect
.SetTop(vRect
.yTop
);
2260 vLibRect
.SetRight(vRect
.xRight
);
2261 vLibRect
.SetBottom(vRect
.yBottom
);
2262 if (vLibRect
.Inside(rPoint
))
2263 return pRecord
->m_ulItemId
;
2265 for (i
= lStart
+ 1; i
< vCnrInfo
.cRecords
; i
++)
2267 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
2270 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
2272 vQueryRect
.pRecord
= (PRECORDCORE
)pRecord
;
2273 ::WinSendMsg( GetHWND()
2276 ,MPFROMP(&vQueryRect
)
2278 vLibRect
.SetLeft(vRect
.xLeft
);
2279 vLibRect
.SetTop(vRect
.yTop
);
2280 vLibRect
.SetRight(vRect
.xRight
);
2281 vLibRect
.SetBottom(vRect
.yBottom
);
2282 if (vLibRect
.Inside(rPoint
))
2283 return pRecord
->m_ulItemId
;
2286 } // end of wxListCtrl::FindItem
2288 // Determines which item (if any) is at the specified point,
2289 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
2290 long wxListCtrl::HitTest (
2291 const wxPoint
& rPoint
2292 , int& WXUNUSED(rFlags
)
2295 PMYRECORD pRecord
= NULL
;
2296 QUERYRECFROMRECT vQueryRect
;
2301 // Get height for OS/2 point conversion
2303 ::WinSendMsg( GetHWND()
2304 ,CM_QUERYVIEWPORTRECT
2306 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
2308 lHeight
= vRect
.yTop
- vRect
.yBottom
;
2311 // For now just try and get a record in the general vicinity and forget
2314 vRect
.xLeft
= rPoint
.x
- 2;
2315 vRect
.xRight
= rPoint
.x
+ 2;
2316 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
2317 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
2319 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
2320 vQueryRect
.rect
= vRect
;
2321 vQueryRect
.fsSearch
= CMA_PARTIAL
;
2323 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2324 ,CM_QUERYRECORDFROMRECT
2326 ,MPFROMP(&vQueryRect
)
2331 return pRecord
->m_ulItemId
;
2332 } // end of wxListCtrl::HitTest
2334 // Inserts an item, returning the index of the new item if successful,
2336 long wxListCtrl::InsertItem (
2340 wxASSERT_MSG( !IsVirtual(), _T("can't be used with virtual controls") );
2342 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
2345 PMYRECORD pRecordAfter
= NULL
;
2346 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2348 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
2352 ConvertToOS2ListItem( this
2358 if (rInfo
.GetId() > 0)
2359 pRecordAfter
= FindOS2ListRecordByID( GetHWND()
2363 RECORDINSERT vInsert
;
2365 vInsert
.cb
= sizeof(RECORDINSERT
);
2366 vInsert
.pRecordParent
= NULL
;
2368 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
2370 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
2371 vInsert
.zOrder
= CMA_TOP
;
2372 vInsert
.cRecordsInsert
= 1;
2373 vInsert
.fInvalidateRecord
= TRUE
;
2376 // Check wether we need to allocate our internal data
2378 bool bNeedInternalData
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) ||
2379 rInfo
.HasAttributes()
2381 if (bNeedInternalData
)
2383 m_bAnyInternalData
= TRUE
;
2386 // Internal stucture that manages data
2388 CListItemInternalData
* pData
= new CListItemInternalData();
2390 pRecord
->m_ulUserData
= (unsigned long)pData
;
2391 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
2392 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
2395 // Check whether it has any custom attributes
2397 if (rInfo
.HasAttributes())
2400 // Take copy of attributes
2402 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
2405 if (!::WinSendMsg( GetHWND()
2412 // OS/2 must mannually bump the index's of following records
2414 BumpRecordIds( GetHWND()
2417 ::WinSendMsg( GetHWND()
2418 ,CM_INVALIDATEDETAILFIELDINFO
2422 return pRecord
->m_ulItemId
;
2423 } // end of wxListCtrl::InsertItem
2425 long wxListCtrl::InsertItem (
2427 , const wxString
& rsLabel
2432 memset(&vInfo
, '\0', sizeof(wxListItem
));
2433 vInfo
.m_text
= rsLabel
;
2434 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
2435 vInfo
.m_itemId
= lIndex
;
2436 return InsertItem(vInfo
);
2437 } // end of wxListCtrl::InsertItem
2439 // Inserts an image item
2440 long wxListCtrl::InsertItem (
2447 vInfo
.m_image
= nImageIndex
;
2448 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
2449 vInfo
.m_itemId
= lIndex
;
2450 return InsertItem(vInfo
);
2451 } // end of wxListCtrl::InsertItem
2453 // Inserts an image/string item
2454 long wxListCtrl::InsertItem (
2456 , const wxString
& rsLabel
2462 vInfo
.m_image
= nImageIndex
;
2463 vInfo
.m_text
= rsLabel
;
2464 vInfo
.m_mask
= wxLIST_MASK_IMAGE
| wxLIST_MASK_TEXT
;
2465 vInfo
.m_itemId
= lIndex
;
2466 return InsertItem(vInfo
);
2467 } // end of wxListCtrl::InsertItem
2469 // For details view mode (only), inserts a column.
2470 long wxListCtrl::InsertColumn (
2476 PFIELDINFO pField
= (PFIELDINFO
)::WinSendMsg( GetHWND()
2477 ,CM_ALLOCDETAILFIELDINFO
2481 PFIELDINFO pFieldAfter
= FindOS2ListFieldByColNum ( GetHWND()
2484 FIELDINFOINSERT vInsert
;
2486 ConvertToOS2ListCol ( lCol
2491 vInsert
.cb
= sizeof(FIELDINFOINSERT
);
2492 vInsert
.pFieldInfoOrder
= pFieldAfter
;
2493 vInsert
.fInvalidateFieldInfo
= TRUE
;
2494 vInsert
.cFieldInfoInsert
= 1;
2496 bSuccess
= ::WinSendMsg( GetHWND()
2497 ,CM_INSERTDETAILFIELDINFO
2502 } // end of wxListCtrl::InsertColumn
2504 long wxListCtrl::InsertColumn (
2506 , const wxString
& rsHeading
2513 vItem
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
2514 vItem
.m_text
= rsHeading
;
2517 vItem
.m_mask
|= wxLIST_MASK_WIDTH
;
2518 vItem
.m_width
= nWidth
;
2520 vItem
.m_format
= nFormat
;
2522 return InsertColumn( lCol
2525 } // end of wxListCtrl::InsertColumn
2527 // scroll the control by the given number of pixels (exception: in list view,
2528 // dx is interpreted as number of columns)
2529 bool wxListCtrl::ScrollList (
2535 ::WinSendMsg( GetHWND()
2537 ,(MPARAM
)CMA_HORIZONTAL
2541 ::WinSendMsg( GetHWND()
2543 ,(MPARAM
)CMA_VERTICAL
2547 } // end of wxListCtrl::ScrollList
2549 bool wxListCtrl::SortItems (
2550 wxListCtrlCompare fn
2554 SInternalDataSort vInternalData
;
2556 vInternalData
.m_fnUser
= fn
;
2557 vInternalData
.m_lData
= lData
;
2559 // WPARAM cast is needed for mingw/cygwin
2560 if (!::WinSendMsg( GetHWND()
2562 ,(PFN
)InternalDataCompareFunc
2563 ,(PVOID
)&vInternalData
2566 wxLogDebug(_T("CM_SORTRECORD failed"));
2570 } // end of wxListCtrl::SortItems
2572 // ----------------------------------------------------------------------------
2573 // message processing
2574 // ----------------------------------------------------------------------------
2576 bool wxListCtrl::OS2Command (
2581 if (uCmd
== CN_ENDEDIT
)
2583 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
2587 vEvent
.SetEventObject( this );
2588 ProcessCommand(vEvent
);
2591 else if (uCmd
== CN_KILLFOCUS
)
2593 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
2596 vEvent
.SetEventObject( this );
2597 ProcessCommand(vEvent
);
2602 } // end of wxListCtrl::OS2Command
2604 // Necessary for drawing hrules and vrules, if specified
2605 void wxListCtrl::OnPaint (
2606 wxPaintEvent
& rEvent
2609 wxPaintDC
vDc(this);
2610 wxPen
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
)
2614 wxSize vClientSize
= GetClientSize();
2616 int nItemCount
= GetItemCount();
2619 bool bDrawHRules
= ((GetWindowStyle() & wxLC_HRULES
) != 0);
2620 bool bDrawVRules
= ((GetWindowStyle() & wxLC_VRULES
) != 0);
2622 wxControl::OnPaint(rEvent
);
2625 // Reset the device origin since it may have been set
2627 vDc
.SetDeviceOrigin(0, 0);
2628 if (!bDrawHRules
&& !bDrawVRules
)
2630 if ((GetWindowStyle() & wxLC_REPORT
) == 0)
2633 vDc
.SetBrush(*wxTRANSPARENT_BRUSH
);
2637 long lTop
= GetTopItem();
2639 for (i
= lTop
; i
< lTop
+ GetCountPerPage() + 1; i
++)
2645 nCy
= vItemRect
.GetTop();
2646 if (i
!= 0) // Don't draw the first one
2655 if (i
== nItemCount
- 1)
2657 nCy
= vItemRect
.GetBottom();
2668 if (bDrawVRules
&& (i
> -1))
2670 wxRect vFirstItemRect
;
2680 int nX
= vItemRect
.GetX();
2682 for (nCol
= 0; nCol
< GetColumnCount(); nCol
++)
2684 int nColWidth
= GetColumnWidth(nCol
);
2687 vDc
.DrawLine( nX
- 1
2688 ,vFirstItemRect
.GetY() - 2
2690 ,vItemRect
.GetBottom()
2695 } // end of wxListCtrl::OnPaint
2697 // ----------------------------------------------------------------------------
2698 // virtual list controls
2699 // ----------------------------------------------------------------------------
2701 wxString
wxListCtrl::OnGetItemText (
2702 long WXUNUSED(lItem
)
2703 , long WXUNUSED(lCol
)
2706 // this is a pure virtual function, in fact - which is not really pure
2707 // because the controls which are not virtual don't need to implement it
2708 wxFAIL_MSG( _T("not supposed to be called") );
2709 return wxEmptyString
;
2710 } // end of wxListCtrl::OnGetItemText
2712 int wxListCtrl::OnGetItemImage (
2713 long WXUNUSED(lItem
)
2717 wxFAIL_MSG( _T("not supposed to be called") );
2719 } // end of wxListCtrl::OnGetItemImage
2721 int wxListCtrl::OnGetItemColumnImage (
2727 return OnGetItemImage(lItem
);
2730 } // end of wxListCtrl::OnGetItemColumnImage
2732 wxListItemAttr
* wxListCtrl::OnGetItemAttr (
2733 long WXUNUSED_UNLESS_DEBUG(lItem
)
2736 wxASSERT_MSG( lItem
>= 0 && lItem
< GetItemCount(),
2737 _T("invalid item index in OnGetItemAttr()") );
2740 // No attributes by default
2743 } // end of wxListCtrl::OnGetItemAttr
2745 void wxListCtrl::SetItemCount (
2749 wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
2752 // Cannot explicitly set the record count in OS/2
2754 } // end of wxListCtrl::SetItemCount
2756 void wxListCtrl::RefreshItem (
2766 } // end of wxListCtrl::RefreshItem
2768 void wxListCtrl::RefreshItems (
2776 GetItemRect( lItemFrom
2779 GetItemRect( lItemTo
2783 wxRect vRect
= vRect1
;
2785 vRect
.height
= vRect2
.GetBottom() - vRect1
.GetTop();
2787 } // end of wxListCtrl::RefreshItems
2789 MRESULT
wxListCtrl::OS2WindowProc(
2795 bool bProcessed
= FALSE
;
2797 wxListEvent
vEvent( wxEVT_NULL
2800 wxEventType vEventType
= wxEVT_NULL
;
2801 PCNRDRAGINIT pDragInit
= NULL
;
2802 PCNREDITDATA pEditData
= NULL
;
2803 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
2805 vEvent
.SetEventObject(this);
2810 // First off let's set some internal data
2812 switch(SHORT2FROMMP(wParam
))
2818 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)lParam
;
2822 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2824 pItem
->SetData((long)pInternaldata
->m_lParam
);
2830 // Now let's go through the codes we're interested in
2832 switch(SHORT2FROMMP(wParam
))
2835 pDragInit
= (PCNRDRAGINIT
)lParam
;
2838 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2840 vEventType
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
;
2841 vEvent
.m_itemIndex
= pRecord
->m_ulItemId
;
2842 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2843 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2848 pEditData
= (PCNREDITDATA
)lParam
;
2851 vEventType
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
;
2852 ConvertFromOS2ListItem( GetHWND()
2853 ,(wxListItem
&)vEvent
.GetItem()
2854 ,(PMYRECORD
)pEditData
->pRecord
2856 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2861 pEditData
= (PCNREDITDATA
)lParam
;
2864 vEventType
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
;
2865 ConvertFromOS2ListItem( GetHWND()
2866 ,(wxListItem
&)vEvent
.GetItem()
2867 ,(PMYRECORD
)pEditData
->pRecord
2869 if (pEditData
->cbText
== 0)
2870 return (MRESULT
)FALSE
;
2871 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2876 pNotifyEnter
= (PNOTIFYRECORDENTER
)lParam
;
2879 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2880 PMYRECORD pMyRecord
= (PMYRECORD
)pNotifyEnter
->pRecord
;
2882 vEventType
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
;
2883 vEvent
.m_itemIndex
= pMyRecord
->m_ulItemId
;
2884 pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
));
2885 pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
));
2890 // Add the CN_DROP messages for Direct Manipulation
2893 vEvent
.SetEventType(vEventType
);
2894 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
2898 lRc
= wxControl::OS2WindowProc( uMsg
2903 } // end of wxListCtrl::WindowProc
2905 #endif // wxUSE_LISTCTRL