1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/listctrl.cpp
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
33 #include "wx/settings.h"
34 #include "wx/dcclient.h"
35 #include "wx/textctrl.h"
38 #include "wx/imaglist.h"
39 #include "wx/listctrl.h"
41 #include "wx/os2/private.h"
44 // FIELDOFFSET in DETAIL view as defined in the OS2TK45 simply doesn't work
45 // We use this, which does!
48 #define FIELDOFFSET(type, field) ((ULONG)&(((type *)0)->field))
50 // ----------------------------------------------------------------------------
51 // private helper classes
52 // ----------------------------------------------------------------------------
54 /////////////////////////////////////////////////////////////////////////////
56 // Under OS/2 we have to use our own RECORDCORE based struct if we have
57 // user data to store in a PM Container Control (and wxListCtrl is a PM
58 // Container in ICON, NAME, TEXT or DETAIL view). m_ulUserData is a four
59 // byte value containing a pointer to our CListIntemInternalData class
62 // And now for the big time OS/2 Kludge. In traditional OS/2 PM
63 // applications using containers, programmers determine BEFORE creation
64 // how many records the view will have, initially, and how many columns
65 // the detail view of the container will have, as the container represents
66 // a known data block. Thus the OS/2 PM CV_DETAIL view, i.e.
67 // the wxWidgets wxLC_REPORT view, relies on STATIC structure for its
68 // columnar data. It gets the data to display by telling it the specific
69 // offset of the field in the struct containing the displayable data. That
70 // data has be of OS/2 Types, PSZ (char string), CDATE or CTIME format.
71 // wxWidgets is dynamic in nature, however. We insert columns, one at a
72 // time and do not know how many until the app is done inserting them. So
73 // for OS/2 I have to set a max allowable since they are fixed. We return
74 // an error to the app if they include more than we can handle.
76 // For example to display the data "Col 4 of Item 6" in a report view, I'd
78 // pRecord->m_pzColumn4 = "Col 4 of Item 6";
79 // pField->offStruct = FIELDOFFSET(MYRECORD, m_pzColumn4);
80 // and then call the PM API to set it.
82 // This really stinks but I can't use a pointer to another struct as the
83 // FIELDOFFSET call could only tell OS/2 the four byte value offset of
84 // pointer field and it would display giberish in the column.
85 /////////////////////////////////////////////////////////////////////////////
86 typedef struct _MYRECORD
89 unsigned long m_ulItemId
;
90 unsigned long m_ulUserData
; //actually a pointer value to real data (a CListItemInternalData class instance)
101 } MYRECORD
, *PMYRECORD
;
103 /////////////////////////////////////////////////////////////////////////////
104 // CLASS CListItemInternalData
107 // The MSW version had problems with SetTextColour() et al as the
108 // CListItemAttr's were stored keyed on the item index. If a item was
109 // inserted anywhere but the end of the list the the text attributes
110 // (colour etc) for the following items were out of sync.
113 // Under MSW the only way to associate data with a
114 // List item independent of its position in the list is to store a pointer
115 // to it in its lParam attribute. However user programs are already using
116 // this (via the SetItemData() GetItemData() calls).
118 // However what we can do is store a pointer to a structure which contains
119 // the attributes we want *and* a lParam for the users data, e.g.
121 // class CListItemInternalData
124 // GuiAdvCtrl_CListItemAttr* pAttr;
125 // long lParam; // user data
128 // To conserve memory, a CListItemInternalData is only allocated for a
129 // LV_ITEM if text attributes or user data(lparam) are being set.
131 // For OS/2, the lParam value points to whatever actual data we have
132 /////////////////////////////////////////////////////////////////////////////
133 class CListItemInternalData
137 CListItemInternalData(): m_pAttr(NULL
)
141 ~CListItemInternalData()
147 wxListItemAttr
* m_pAttr
;
148 WXLPARAM m_lParam
; // user data
149 PMYRECORD m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted
150 }; // end of CLASS CListItemInternalData
152 /////////////////////////////////////////////////////////////////////////////
153 // STRUCT SInternalDataSort
157 // fn is a function which takes 3 long arguments: item1, item2, data.
158 // item1 is the long data associated with a first item (NOT the index).
159 // item2 is the long data associated with a second item (NOT the index).
160 // data is the same value as passed to SortItems.
162 // The return value is a negative number if the first item should precede the
163 // second item, a positive number of the second item should precede the first,
164 // or zero if the two items are equivalent.
166 // data is arbitrary data to be passed to the sort function.
168 // Internal structures for proxying the user compare function
169 // so that we can pass it the *real* user data
170 /////////////////////////////////////////////////////////////////////////////
171 typedef struct internalDataSort
173 wxListCtrlCompare m_fnUser
;
175 } SInternalDataSort
; // end of STRUCT SInternalDataSort
177 // ----------------------------------------------------------------------------
178 // private helper functions
179 // ----------------------------------------------------------------------------
181 /////////////////////////////////////////////////////////////////////////////
183 // FindOS2ListFieldByColNum
185 // There is no way, under OS/2 to get a field in a container by index,
186 // directly, so you must get the first one, then cycle through the list
187 // until you get to where you want to be.
190 // hWnd -- window handle of container to search
191 // lIndex -- index to set
194 // pointer to the FIELDINFO struct at the index in the container record
196 /////////////////////////////////////////////////////////////////////////////
197 PFIELDINFO
FindOS2ListFieldByColNum (
202 PFIELDINFO pFieldInfo
= NULL
;
206 if (!::WinSendMsg( hWnd
209 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
212 for (i
= 0; i
< vCnrInfo
.cFields
; i
++)
215 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
216 ,CM_QUERYDETAILFIELDINFO
221 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
222 ,CM_QUERYDETAILFIELDINFO
228 if (i
== (ULONG
)lIndex
)
234 } // end of FindOS2ListFieldByColNum
236 /////////////////////////////////////////////////////////////////////////////
238 // FindOS2ListRecordByID
240 // There is no way, under OS/2 to get a record in a container by index,
241 // directly, so you must get the first one, then cycle through the list
242 // until you get to where you want to be.
245 // hWnd -- window handle of container to search
246 // lItemId -- index to set
249 // pointer to the internal RECORDCORE struct at the index in the container
251 /////////////////////////////////////////////////////////////////////////////
252 PMYRECORD
FindOS2ListRecordByID (
257 PMYRECORD pRecord
= NULL
;
261 if (!::WinSendMsg( hWnd
264 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
267 for (i
= 0; i
< vCnrInfo
.cRecords
; i
++)
270 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
273 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
276 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
279 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
283 if (pRecord
->m_ulItemId
== (ULONG
)lItemId
)
287 } // end of FindOS2ListRecordByID
289 /////////////////////////////////////////////////////////////////////////////
293 // Since OS/2 does not keep native record id's but wx insists on inserting
294 // and selecting via ID's, when we insert a record in the middle we need
295 // to bump the id's of each record after the one we just inserted.
298 // hWnd -- window handle of container to search
299 // pRecord -- record after which we starting bumping id's
304 /////////////////////////////////////////////////////////////////////////////
312 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
315 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
318 pRecord
->m_ulItemId
++;
320 } // end of BumpRecordIds
322 /////////////////////////////////////////////////////////////////////////////
326 // Get the internal data given a handle and an id
329 // hWnd -- window handle to the control in which item is located
330 // lItemId -- ID to get
333 // pointer to the internal data
336 // Under OS/2 PM a container item cannot be obtained via a simple index or
337 // id retrieval. We have to walk the record list if we are looking for
338 // a record at a specific index location
339 /////////////////////////////////////////////////////////////////////////////
340 CListItemInternalData
* GetInternalData (
345 PMYRECORD pRecord
= FindOS2ListRecordByID( hWnd
349 // Internal user data is stored AFTER the last field of the RECORDCORE
353 return((CListItemInternalData
*)(pRecord
->m_ulUserData
));
354 } // end of GetInternalData
356 /////////////////////////////////////////////////////////////////////////////
360 // Get the internal data given a pointer to a list control and an id
363 // pCtl -- pointer to control inwhich item is located
364 // lItemId -- ID to get
367 // pointer to the internal data
369 /////////////////////////////////////////////////////////////////////////////
370 CListItemInternalData
* GetInternalData (
375 return(GetInternalData( (HWND
)pCtl
->GetHWND()
378 } // end of GetInternalData
380 /////////////////////////////////////////////////////////////////////////////
382 // DeleteInternalData
384 // Delete the internal data for a record
387 // pCtl -- pointer to the list control containing the record
388 // lItemId -- the record index to delete the internal data from
391 // pointer to the internal data attribute
393 /////////////////////////////////////////////////////////////////////////////
394 void DeleteInternalData (
399 CListItemInternalData
* pData
= GetInternalData( pCtl
404 if (pData
->m_pMyRecord
)
405 pData
->m_pMyRecord
->m_ulUserData
= 0;
408 } // end of DeleteInternalData
410 // #pragma page "GetInternalDataAttr"
411 /////////////////////////////////////////////////////////////////////////////
413 // GetInternalDataAttr
415 // Get the internal data item attribute given a pointer to a list control
419 // pCtl -- pointer to control to set
420 // lItemId -- ID to set
423 // pointer to the internal data attribute
425 /////////////////////////////////////////////////////////////////////////////
426 wxListItemAttr
* GetInternalDataAttr (
431 CListItemInternalData
* pData
= GetInternalData( pCtl
436 return(pData
->m_pAttr
);
439 } // end of GetInternalDataAttr
441 /////////////////////////////////////////////////////////////////////////////
443 // InternalDataCompareFunc
445 // This is compare function we pass to PM. It wraps the real compare
446 // function in SInternalDataSort
449 // p1 -- is the first record structure to compare
450 // p2 -- is the second record structure to compare
451 // lStorage -- is the same value as passed to SortItems.
454 // pointer to the internal data attribute
456 /////////////////////////////////////////////////////////////////////////////
457 SHORT EXPENTRY
InternalDataCompareFunc (
463 SInternalDataSort
* pInternalData
= (SInternalDataSort
*)pStorage
;
464 CListItemInternalData
* pData1
= (CListItemInternalData
*)p1
->m_ulUserData
;
465 CListItemInternalData
* pData2
= (CListItemInternalData
*)p2
->m_ulUserData
;
466 long lD1
= (pData1
== NULL
? 0 : (long)pData1
->m_lParam
);
467 long lD2
= (pData2
== NULL
? 0 : (long)pData2
->m_lParam
);
469 return(pInternalData
->m_fnUser( lD1
471 ,pInternalData
->m_lData
473 } // end of InternalDataCompareFunc
475 /////////////////////////////////////////////////////////////////////////////
477 // ConvertFromOS2ListItem
479 // Convert from an internal PM List item to a Toolkit List item
482 // hWndListCtrl -- the control's windows handle
483 // rInfo -- the library list control to convert to
484 // pRecord -- the OS list control to convert from
489 /////////////////////////////////////////////////////////////////////////////
490 void ConvertFromOS2ListItem ( HWND hWndListCtrl
,
494 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)pRecord
->m_ulUserData
;
495 bool bNeedText
= false;
498 rInfo
.SetData(pInternaldata
->m_lParam
);
502 rInfo
.SetStateMask(0);
503 rInfo
.SetId((long)pRecord
->m_ulItemId
);
504 if (hWndListCtrl
!= 0)
506 pRecord
= FindOS2ListRecordByID( hWndListCtrl
512 // The wxListItem class is really set up to handle the WIN32 list item
513 // and OS/2 are not as complicated. Just set both state members to the
514 // same thing under OS/2
516 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DROPONABLE
)
518 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DROPHILITED
);
519 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DROPHILITED
);
521 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SELECTED
)
523 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SELECTED
);
524 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SELECTED
);
526 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DISABLED
)
528 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DISABLED
);
529 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DISABLED
);
531 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_FILTERED
)
533 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_FILTERED
);
534 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_FILTERED
);
536 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_INUSE
)
538 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_INUSE
);
539 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_INUSE
);
541 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_PICKED
)
543 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_PICKED
);
544 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_PICKED
);
546 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SOURCE
)
548 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SOURCE
);
549 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SOURCE
);
552 if (pRecord
->m_vRecord
.pszText
!= (PSZ
)NULL
)
554 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
);
555 rInfo
.SetText(pRecord
->m_vRecord
.pszText
);
557 if (pRecord
->m_vRecord
.pszIcon
!= (PSZ
)NULL
||
558 pRecord
->m_vRecord
.pszName
!= (PSZ
)NULL
)
560 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
);
561 rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
);
563 if (pRecord
->m_ulUserData
)
564 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
);
565 } // end of ConvertFromOS2ListItem
567 /////////////////////////////////////////////////////////////////////////////
571 // Convert from an library states to OS states
574 // lState -- the state
575 // pRecord -- the OS list control to use
580 /////////////////////////////////////////////////////////////////////////////
581 void ConvertToOS2Flags (
586 if (lState
& wxLIST_STATE_DROPHILITED
)
587 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DROPONABLE
;
588 if (lState
& wxLIST_STATE_SELECTED
)
589 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SELECTED
;
590 if (lState
& wxLIST_STATE_DISABLED
)
591 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DISABLED
;
592 if (lState
& wxLIST_STATE_FILTERED
)
593 pRecord
->m_vRecord
.flRecordAttr
|= CRA_FILTERED
;
594 if (lState
& wxLIST_STATE_INUSE
)
595 pRecord
->m_vRecord
.flRecordAttr
|= CRA_INUSE
;
596 if (lState
& wxLIST_STATE_PICKED
)
597 pRecord
->m_vRecord
.flRecordAttr
|= CRA_PICKED
;
598 if (lState
& wxLIST_STATE_SOURCE
)
599 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SOURCE
;
600 } // end of ConvertToOS2Flags
602 /////////////////////////////////////////////////////////////////////////////
604 // ConvertToOS2ListItem
606 // Convert from a library List item to an internal OS2 List item. We set
607 // only the fields we need to set. Some of them are set by the API when
608 // they are added to the container.
611 // pCtrl -- the control to use
612 // rInfo -- the item to convert
613 // pRecord -- the OS list control to use, should be zeroed out
614 // pFieldinfo -- a field struct that may contain columnar data for detail view
619 /////////////////////////////////////////////////////////////////////////////
620 void ConvertToOS2ListItem (
621 const wxListCtrl
* pCtrl
622 , const wxListItem
& rInfo
624 , PFIELDINFO pFieldInfo
627 pRecord
->m_ulItemId
= (ULONG
)rInfo
.GetId();
628 pRecord
->m_vRecord
.cb
= sizeof(RECORDCORE
);
629 if (rInfo
.GetMask() & wxLIST_MASK_STATE
)
631 ConvertToOS2Flags( rInfo
.m_state
635 if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON
||
636 pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
)
638 pRecord
->m_vRecord
.pszIcon
= (char*)rInfo
.GetText().c_str();
640 if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view
642 pRecord
->m_vRecord
.pszText
= (char*)rInfo
.GetText().c_str();
645 // In the case of a report view the text will be the data in the lead column
646 // ???? Don't know why, but that is how it works in other ports.
648 if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
)
652 switch(rInfo
.GetColumn())
655 pRecord
->m_pzColumn1
= (char*)rInfo
.GetText().c_str();
656 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn1
);
660 pRecord
->m_pzColumn2
= (char*)rInfo
.GetText().c_str();
661 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn2
);
665 pRecord
->m_pzColumn3
= (char*)rInfo
.GetText().c_str();
666 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn3
);
670 pRecord
->m_pzColumn4
= (char*)rInfo
.GetText().c_str();
671 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn4
);
675 pRecord
->m_pzColumn5
= (char*)rInfo
.GetText().c_str();
676 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn5
);
680 pRecord
->m_pzColumn6
= (char*)rInfo
.GetText().c_str();
681 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn6
);
685 pRecord
->m_pzColumn7
= (char*)rInfo
.GetText().c_str();
686 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn7
);
690 pRecord
->m_pzColumn8
= (char*)rInfo
.GetText().c_str();
691 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn8
);
695 pRecord
->m_pzColumn9
= (char*)rInfo
.GetText().c_str();
696 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn9
);
700 pRecord
->m_pzColumn10
= (char*)rInfo
.GetText().c_str();
701 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn10
);
705 wxFAIL_MSG( _T("wxOS2 does not support more than 10 columns in REPORT view") );
710 if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
)
712 pRecord
->m_vRecord
.hptrIcon
= (HPOINTER
)rInfo
.GetImage();
713 pRecord
->m_vRecord
.hptrMiniIcon
= (HPOINTER
)rInfo
.m_miniImage
;
715 } // end of ConvertToOS2ListItem
717 /////////////////////////////////////////////////////////////////////////////
719 // ConvertToOS2ListCol
721 // Convert from a library List column to an internal PM List column
724 // lCol -- the columnd to convert
725 // rItem -- the item to convert
726 // pField -- the OS list column to use
731 /////////////////////////////////////////////////////////////////////////////
732 void ConvertToOS2ListCol (
734 , const wxListItem
& rItem
738 memset(pField
, '\0', sizeof(FIELDINFO
));
739 pField
->cb
= sizeof(FIELDINFO
);
742 // Default some settings
744 pField
->flData
= CFA_HORZSEPARATOR
| CFA_SEPARATOR
;
745 pField
->flTitle
= CFA_CENTER
;
747 if (rItem
.GetMask() & wxLIST_MASK_TEXT
)
749 pField
->flData
|= CFA_STRING
;
750 pField
->pTitleData
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data
752 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
754 if (rItem
.m_format
== wxLIST_FORMAT_LEFT
)
755 pField
->flData
|= CFA_LEFT
;
756 else if (rItem
.m_format
== wxLIST_FORMAT_RIGHT
)
757 pField
->flData
|= CFA_RIGHT
;
758 else if (rItem
.m_format
== wxLIST_FORMAT_CENTRE
)
759 pField
->flData
|= CFA_CENTER
;
762 pField
->flData
|= CFA_CENTER
; // Just ensure the default is centered
763 if (rItem
.GetMask() & wxLIST_MASK_WIDTH
)
765 if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE
||
766 rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
))
767 pField
->cxWidth
= rItem
.GetWidth();
768 // else: OS/2 automatically sets the width if created with the approppriate style
772 // Still need to set the actual data
774 pField
->offStruct
= 0;
775 } // end of ConvertToOS2ListCol
777 // ----------------------------------------------------------------------------
779 // ----------------------------------------------------------------------------
781 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG
)
782 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG
)
783 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
)
784 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT
)
785 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM
)
786 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
)
787 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO
)
788 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO
)
789 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED
)
790 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED
)
791 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN
)
792 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM
)
793 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK
)
794 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_RIGHT_CLICK
)
795 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG
)
796 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_DRAGGING
)
797 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_END_DRAG
)
798 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
)
799 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
)
800 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED
)
801 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED
)
802 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT
)
804 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
805 IMPLEMENT_DYNAMIC_CLASS(wxListView
, wxListCtrl
)
806 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
808 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
810 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
)
811 EVT_PAINT(wxListCtrl::OnPaint
)
814 // ============================================================================
816 // ============================================================================
818 // ----------------------------------------------------------------------------
819 // wxListCtrl construction
820 // ----------------------------------------------------------------------------
822 void wxListCtrl::Init ()
824 m_pImageListNormal
= NULL
;
825 m_pImageListSmall
= NULL
;
826 m_pImageListState
= NULL
;
827 m_bOwnsImageListNormal
= false;
828 m_bOwnsImageListSmall
= false;
829 m_bOwnsImageListState
= false;
833 m_bAnyInternalData
= false;
834 m_bHasAnyAttr
= false;
835 } // end of wxListCtrl::Init
837 bool wxListCtrl::Create ( wxWindow
* pParent
,
842 const wxValidator
& rValidator
,
843 const wxString
& rsName
)
847 int nWidth
= rSize
.x
;
848 int nHeight
= rSize
.y
;
851 SetValidator(rValidator
);
852 #endif // wxUSE_VALIDATORS
855 SetWindowStyleFlag(lStyle
);
866 m_windowId
= (vId
== -1) ? NewControlId() : vId
;
868 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
870 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
)
871 lSstyle
|= WS_CLIPSIBLINGS
;
872 m_lBaseStyle
= lSstyle
;
873 if (!DoCreateControl( nX
880 pParent
->AddChild(this);
882 } // end of wxListCtrl::Create
884 bool wxListCtrl::DoCreateControl ( int nX
, int nY
,
885 int nWidth
, int nHeight
)
887 DWORD lWstyle
= m_lBaseStyle
;
888 long lOldStyle
= 0; // Dummy
892 lWstyle
|= ConvertToOS2Style( lOldStyle
893 ,GetWindowStyleFlag()
896 m_hWnd
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND()
901 ,GetParent()->GetHWND()
913 // Now set the display attributes of the container
915 if (!::WinSendMsg( GetHWND()
918 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
921 lWstyle
= ConvertViewToOS2Style(GetWindowStyleFlag());
922 vCnrInfo
.flWindowAttr
|= lWstyle
;
923 if (!::WinSendMsg( GetHWND()
926 ,(MPARAM
)CMA_FLWINDOWATTR
931 // And now set needed arrangement flags
933 lWstyle
= ConvertArrangeToOS2Style(GetWindowStyleFlag());
934 if (!::WinSendMsg( GetHWND()
936 ,(MPARAM
)CMA_ARRANGEGRID
940 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
941 SetForegroundColour(GetParent()->GetForegroundColour());
943 SetFont(*wxSMALL_FONT
);
946 SetSize( nX
, nY
, nWidth
, nHeight
);
948 } // end of wxListCtrl::DoCreateControl
950 void wxListCtrl::UpdateStyle ()
955 DWORD dwStyleNew
= ConvertToOS2Style( lDummy
, GetWindowStyleFlag() );
957 dwStyleNew
|= m_lBaseStyle
;
960 // Get the current window style.
962 ULONG dwStyleOld
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
);
965 // Only set the window style if the view bits have changed.
967 if (dwStyleOld
!= dwStyleNew
)
969 ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
);
972 } // end of wxListCtrl::UpdateStyle
974 void wxListCtrl::FreeAllInternalData ()
976 if (m_bAnyInternalData
)
978 int n
= GetItemCount();
981 for (i
= 0; i
< n
; i
++)
982 DeleteInternalData(this, (long)i
);
983 m_bAnyInternalData
= false;
985 } // end of wxListCtrl::FreeAllInternalData
987 wxListCtrl::~wxListCtrl ()
989 FreeAllInternalData();
992 m_pTextCtrl
->SetHWND(0);
993 m_pTextCtrl
->UnsubclassWin();
998 if (m_bOwnsImageListNormal
)
999 delete m_pImageListNormal
;
1000 if (m_bOwnsImageListSmall
)
1001 delete m_pImageListSmall
;
1002 if (m_bOwnsImageListState
)
1003 delete m_pImageListState
;
1004 } // end of wxListCtrl::~wxListCtrl
1006 // ----------------------------------------------------------------------------
1007 // set/get/change style
1008 // ----------------------------------------------------------------------------
1010 // Add or remove a single window style
1011 void wxListCtrl::SetSingleStyle (
1016 long lFlag
= GetWindowStyleFlag();
1019 // Get rid of conflicting styles
1023 if (lStyle
& wxLC_MASK_TYPE
)
1024 lFlag
= lFlag
& ~wxLC_MASK_TYPE
;
1025 if (lStyle
& wxLC_MASK_ALIGN
)
1026 lFlag
= lFlag
& ~wxLC_MASK_ALIGN
;
1027 if (lStyle
& wxLC_MASK_SORT
)
1028 lFlag
= lFlag
& ~wxLC_MASK_SORT
;
1042 m_windowStyle
= lFlag
;
1044 } // end of wxListCtrl::SetSingleStyle
1046 // Set the whole window style
1047 void wxListCtrl::SetWindowStyleFlag (
1051 m_windowStyle
= lFlag
;
1053 } // end of wxListCtrl::SetWindowStyleFlag
1055 long wxListCtrl::ConvertToOS2Style (
1063 // The only styles OS2 uses on creation are auto arrange, read only, and
1064 // and selection styles. This lib does not support OS/2 MINIRECORDCORE
1065 // or VERIFYPOINTER styles
1067 if (lStyle
& wxLC_AUTOARRANGE
)
1068 lWstyle
|= CCS_AUTOPOSITION
;
1069 if (lStyle
& wxLC_SINGLE_SEL
)
1070 lWstyle
|= CCS_SINGLESEL
;
1072 lWstyle
|= CCS_EXTENDSEL
;
1073 if (!(lStyle
& wxLC_EDIT_LABELS
))
1074 lWstyle
|= CCS_READONLY
;
1076 } // end of wxListCtrl::ConvertToOS2Style
1078 long wxListCtrl::ConvertArrangeToOS2Style (
1084 if (lStyle
& wxLC_ALIGN_LEFT
)
1086 lWstyle
|= CMA_LEFT
;
1089 if (lStyle
& wxLC_ALIGN_TOP
)
1094 } // end of wxListCtrl::ConvertArrangeToOS2Style
1096 long wxListCtrl::ConvertViewToOS2Style (
1100 long lWstyle
= CA_DRAWICON
; // we will only use icons
1102 if (lStyle
& wxLC_ICON
)
1106 if (lStyle
& wxLC_SMALL_ICON
)
1108 lWstyle
|= (CV_ICON
| CV_MINI
);
1110 if (lStyle
& wxLC_LIST
)
1114 if (lStyle
& wxLC_REPORT
)
1116 lWstyle
|= CV_DETAIL
;
1118 if (lStyle
& wxLC_VIRTUAL
)
1120 lWstyle
|= CA_OWNERDRAW
;
1122 if (lStyle
& wxLC_AUTOARRANGE
)
1126 if (!(lStyle
& wxLC_NO_HEADER
))
1128 lWstyle
|= CA_DETAILSVIEWTITLES
;
1131 } // end of wxListCtrl::ConvertViewToOS2Style
1133 // ----------------------------------------------------------------------------
1135 // ----------------------------------------------------------------------------
1137 // Sets the foreground, i.e. text, colour
1138 bool wxListCtrl::SetForegroundColour (const wxColour
& rCol
)
1140 ULONG ulColor
= wxColourToRGB(rCol
);
1142 if (!wxWindow::SetForegroundColour(rCol
))
1145 ::WinSetPresParam( GetHWND()
1151 } // end of wxListCtrl::SetForegroundColour
1153 // Sets the background colour
1154 bool wxListCtrl::SetBackgroundColour ( const wxColour
& rCol
)
1156 if (!wxWindow::SetBackgroundColour(rCol
))
1160 // We set the same colour for both the "empty" background and the items
1163 ULONG ulColor
= wxColourToRGB(rCol
);
1165 ::WinSetPresParam( GetHWND()
1171 } // end of wxListCtrl::SetBackgroundColour
1173 // Gets information about this column
1174 bool wxListCtrl::GetColumn ( int nCol
, wxListItem
& rItem
) const
1176 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), nCol
);
1180 rItem
.SetWidth(pFieldInfo
->cxWidth
);
1181 if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) &&
1182 (pFieldInfo
->flData
& CFA_STRING
) &&
1183 (pFieldInfo
->pUserData
!= NULL
))
1185 rItem
.SetText((char*)pFieldInfo
->pUserData
);
1187 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
1189 if (pFieldInfo
->flData
& CFA_LEFT
)
1190 rItem
.m_format
= wxLIST_FORMAT_LEFT
;
1191 else if (pFieldInfo
->flData
& CFA_RIGHT
)
1192 rItem
.m_format
= wxLIST_FORMAT_RIGHT
;
1193 else if (pFieldInfo
->flData
& CFA_CENTER
)
1194 rItem
.m_format
= wxLIST_FORMAT_CENTRE
;
1197 } // end of wxListCtrl::GetColumn
1199 // Sets information about this column
1200 bool wxListCtrl::SetColumn ( int nCol
, wxListItem
& rItem
)
1202 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1203 ConvertToOS2ListCol( nCol
, rItem
, pFieldInfo
);
1205 // Since we changed the field pointed to, we invalidate to see the result
1207 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1209 } // end of wxListCtrl::SetColumn
1211 // Gets the column width
1212 int wxListCtrl::GetColumnWidth ( int nCol
) const
1214 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), nCol
);
1218 return((int)pFieldInfo
->cxWidth
);
1219 } // end of wxListCtrl::GetColumnWidth
1221 // Sets the column width
1222 bool wxListCtrl::SetColumnWidth ( int nCol
, int nWidth
)
1225 int nWidth2
= nWidth
;
1227 if (GetWindowStyleFlag() & wxLC_LIST
)
1230 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1231 pFieldInfo
->cxWidth
= nWidth
;
1232 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1234 } // end of wxListCtrl::SetColumnWidth
1236 // Gets the number of items that can fit vertically in the
1237 // visible area of the list control (list or report view)
1238 // or the total number of items in the list control (icon
1239 // or small icon view)
1240 int wxListCtrl::GetCountPerPage () const
1242 QUERYRECORDRECT vQueryRect
;
1248 if (!::WinSendMsg( GetHWND()
1251 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1254 memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
));
1255 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1256 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
1257 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1258 else if (vCnrInfo
.flWindowAttr
& CV_NAME
)
1259 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1260 else if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
1261 vQueryRect
.fsExtent
= CMA_TEXT
;
1262 else if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
1263 vQueryRect
.fsExtent
= CMA_TEXT
;
1264 if (!::WinSendMsg( GetHWND()
1266 ,MPFROMP(&vRectRecord
)
1267 ,MPFROMP(&vQueryRect
)
1270 if (!::WinSendMsg( GetHWND()
1271 ,CM_QUERYVIEWPORTRECT
1272 ,MPFROMP(&vRectControl
)
1273 ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
)
1276 nCount
= (int)((int)((vRectControl
.xRight
- vRectControl
.xLeft
) / (vRectRecord
.xRight
- vRectRecord
.xLeft
)) *
1277 (int)((vRectControl
.yTop
- vRectControl
.yBottom
) / (vRectRecord
.yTop
- vRectRecord
.yBottom
))
1279 if (nCount
> (int)vCnrInfo
.cFields
)
1280 nCount
= (int)vCnrInfo
.cFields
;
1282 } // end of wxListCtrl::GetCountPerPage
1284 // Gets the edit control for editing labels.
1285 wxTextCtrl
* wxListCtrl::GetEditControl() const
1290 // Gets information about the item
1291 bool wxListCtrl::GetItem ( wxListItem
& rInfo
) const
1293 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() );
1296 // Give NULL as hwnd as we already have everything we need
1298 ConvertFromOS2ListItem( NULL
, rInfo
, pRecord
);
1300 } // end of wxListCtrl::GetItem
1302 // Sets information about the item
1303 bool wxListCtrl::SetItem ( wxListItem
& rInfo
)
1305 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), rInfo
.GetColumn() );
1306 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() );
1308 ConvertToOS2ListItem( this
1315 // Check if setting attributes or lParam
1317 if (rInfo
.HasAttributes() || (rInfo
.GetMask() & wxLIST_MASK_DATA
))
1320 // Get internal item data
1321 // perhaps a cache here ?
1323 CListItemInternalData
* pData
= GetInternalData( this
1332 m_bAnyInternalData
= true;
1333 pData
= new CListItemInternalData();
1334 pRecord
->m_ulUserData
= (unsigned long)pData
;
1340 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
1341 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
1344 if (rInfo
.HasAttributes())
1347 *pData
->m_pAttr
= *rInfo
.GetAttributes();
1349 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
1351 pData
->m_pMyRecord
= pRecord
; // they point to each other
1355 // We need to update the item immediately to show the new image
1357 bool bUpdateNow
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0;
1360 // Check whether it has any custom attributes
1362 if (rInfo
.HasAttributes())
1364 m_bHasAnyAttr
= true;
1367 // If the colour has changed, we must redraw the item
1371 if (::WinIsWindowVisible(GetHWND()))
1373 ::WinSendMsg( GetHWND()
1374 ,CM_INVALIDATERECORD
1376 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1378 RefreshItem(pRecord
->m_ulItemId
);
1380 ::WinSendMsg( GetHWND()
1381 ,CM_INVALIDATEDETAILFIELDINFO
1386 } // end of wxListCtrl::SetItem
1388 long wxListCtrl::SetItem (
1391 , const wxString
& rsLabel
1397 vInfo
.m_text
= rsLabel
;
1398 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1399 vInfo
.m_itemId
= lIndex
;
1403 vInfo
.m_image
= nImageId
;
1404 vInfo
.m_mask
|= wxLIST_MASK_IMAGE
;
1406 return SetItem(vInfo
);
1407 } // end of wxListCtrl::SetItem
1409 // Gets the item state
1410 int wxListCtrl::GetItemState (
1417 vInfo
.m_mask
= wxLIST_MASK_STATE
;
1418 vInfo
.m_stateMask
= lStateMask
;
1419 vInfo
.m_itemId
= lItem
;
1421 if (!GetItem(vInfo
))
1423 return vInfo
.m_state
;
1424 } // end of wxListCtrl::GetItemState
1426 // Sets the item state
1427 bool wxListCtrl::SetItemState ( long lItem
, long lState
, long lStateMask
)
1429 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1432 // Don't use SetItem() here as it doesn't work with the virtual list
1435 ConvertToOS2Flags( lState
, pRecord
);
1438 // for the virtual list controls we need to refresh the previously focused
1439 // item manually when changing focus without changing selection
1440 // programmatically because otherwise it keeps its focus rectangle until
1441 // next repaint (yet another comctl32 bug)
1446 (lStateMask
& wxLIST_STATE_FOCUSED
) &&
1447 (lState
& wxLIST_STATE_FOCUSED
) )
1449 lFocusOld
= GetNextItem( -1
1451 ,wxLIST_STATE_FOCUSED
1458 ::WinSendMsg( GetHWND()
1459 ,CM_INVALIDATERECORD
1461 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1464 if (lFocusOld
!= -1)
1467 // No need to refresh the item if it was previously selected, it would
1468 // only result in annoying flicker
1470 if (!(GetItemState( lFocusOld
1471 ,wxLIST_STATE_SELECTED
1472 ) & wxLIST_STATE_SELECTED
))
1474 RefreshItem(lFocusOld
);
1478 } // end of wxListCtrl::SetItemState
1480 // Sets the item image
1481 bool wxListCtrl::SetItemImage (
1484 , int WXUNUSED(nSelImage
))
1486 return SetItemColumnInfo(lItem
, 0, nImage
);
1487 } // end of wxListCtrl::SetItemImage
1489 // Sets the item image
1490 bool wxListCtrl::SetItemColumnImage (
1497 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
1498 vInfo
.m_image
= nImage
;
1499 vInfo
.m_itemId
= lItem
;
1500 vInfo
.m_col
= lColumn
;
1501 return SetItem(vInfo
);
1502 } // end of wxListCtrl::SetItemColumnImage
1504 // Gets the item text
1505 wxString
wxListCtrl::GetItemText (
1511 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1512 vInfo
.m_itemId
= lItem
;
1514 if (!GetItem(vInfo
))
1515 return wxEmptyString
;
1516 return vInfo
.m_text
;
1517 } // end of wxListCtrl::GetItemText
1519 // Sets the item text
1520 void wxListCtrl::SetItemText (
1522 , const wxString
& rsStr
1527 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1528 vInfo
.m_itemId
= lItem
;
1529 vInfo
.m_text
= rsStr
;
1531 } // end of wxListCtrl::SetItemText
1533 // Gets the item data
1534 long wxListCtrl::GetItemData (
1540 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1541 vInfo
.m_itemId
= lItem
;
1542 if (!GetItem(vInfo
))
1544 return vInfo
.m_data
;
1545 } // end of wxListCtrl::GetItemData
1547 // Sets the item data
1548 bool wxListCtrl::SetItemData (
1555 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1556 vInfo
.m_itemId
= lItem
;
1557 vInfo
.m_data
= lData
;
1558 return SetItem(vInfo
);
1559 } // end of wxListCtrl::SetItemData
1561 // Gets the item rectangle
1562 bool wxListCtrl::GetItemRect ( long lItem
,
1567 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1568 QUERYRECORDRECT vQueryRect
;
1574 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1575 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1576 vQueryRect
.fRightSplitWindow
= TRUE
;
1577 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1578 ::WinSendMsg( GetHWND()
1581 ,MPFROMP(&vQueryRect
)
1584 // remember OS/2 is backwards
1586 GetClientSize( NULL
, &nHeight
);
1587 rRect
.x
= vRect
.xLeft
;
1588 rRect
.y
= nHeight
- vRect
.yTop
;
1589 rRect
.width
= vRect
.xRight
;
1590 rRect
.height
= nHeight
- vRect
.yBottom
;
1593 } // end of wxListCtrl::GetItemRect
1595 // Gets the item position
1596 bool wxListCtrl::GetItemPosition ( long lItem
, wxPoint
& rPos
) const
1599 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND() , lItem
);
1600 QUERYRECORDRECT vQueryRect
;
1606 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1607 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1608 vQueryRect
.fRightSplitWindow
= TRUE
;
1609 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1610 ::WinSendMsg( GetHWND()
1613 ,MPFROMP(&vQueryRect
)
1616 // remember OS/2 is backwards
1618 GetClientSize( NULL
, &nHeight
);
1619 rPos
.x
= vRect
.xLeft
;
1620 rPos
.y
= nHeight
- vRect
.yTop
;
1623 } // end of wxListCtrl::GetItemPosition
1625 // Sets the item position.
1626 bool wxListCtrl::SetItemPosition ( long lItem
, const wxPoint
& rPos
)
1629 // Items cannot be positioned in X/Y coord in OS/2
1632 } // end of wxListCtrl::SetItemPosition
1634 // Gets the number of items in the list control
1635 int wxListCtrl::GetItemCount () const
1639 if (!::WinSendMsg( GetHWND()
1642 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1645 return vCnrInfo
.cRecords
;
1646 } // end of wxListCtrl::GetItemCount
1648 // Retrieves the spacing between icons in pixels.
1649 // If bIsSmall is true, gets the spacing for the small icon
1650 // view, otherwise the large icon view.
1651 int wxListCtrl::GetItemSpacing ( bool bIsSmall
) const
1655 if (!::WinSendMsg( GetHWND()
1658 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1661 return vCnrInfo
.cyLineSpacing
;
1662 } // end of wxListCtrl::GetItemSpacing
1664 void wxListCtrl::SetItemTextColour (
1666 , const wxColour
& rCol
1671 vInfo
.m_itemId
= lItem
;
1672 vInfo
.SetTextColour(rCol
);
1674 } // end of wxListCtrl::SetItemTextColour
1676 wxColour
wxListCtrl::GetItemTextColour (
1682 vInfo
.m_itemId
= lItem
;
1684 return vInfo
.GetTextColour();
1685 } // end of wxListCtrl::GetItemTextColour
1687 void wxListCtrl::SetItemBackgroundColour (
1689 , const wxColour
& rCol
1694 vInfo
.m_itemId
= lItem
;
1695 vInfo
.SetBackgroundColour(rCol
);
1697 } // end of wxListCtrl::SetItemBackgroundColour
1699 wxColour
wxListCtrl::GetItemBackgroundColour (
1705 vInfo
.m_itemId
= lItem
;
1707 return vInfo
.GetBackgroundColour();
1708 } // end of wxListCtrl::GetItemBackgroundColour
1710 // Gets the number of selected items in the list control
1711 int wxListCtrl::GetSelectedItemCount () const
1713 PMYRECORD pRecord
= NULL
;
1715 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1716 ,CM_QUERYRECORDEMPHASIS
1718 ,(MPARAM
)CRA_SELECTED
1726 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1727 ,CM_QUERYRECORDEMPHASIS
1729 ,(MPARAM
)CRA_SELECTED
1735 } // end of wxListCtrl::GetSelectedItemCount
1737 // Gets the text colour of the listview
1738 wxColour
wxListCtrl::GetTextColour () const
1743 ::WinQueryPresParam( GetHWND()
1753 } // end of wxListCtrl::GetTextColour
1755 // Sets the text colour of the listview
1756 void wxListCtrl::SetTextColour (
1757 const wxColour
& rCol
1760 ULONG ulColor
= wxColourToRGB(rCol
);
1762 ::WinSetPresParam( GetHWND()
1767 } // end of wxListCtrl::SetTextColour
1769 // Gets the index of the topmost visible item when in
1770 // list or report view
1771 long wxListCtrl::GetTopItem () const
1773 PMYRECORD pRecord
= NULL
;
1774 QUERYRECFROMRECT vQueryRect
;
1777 ::WinSendMsg( GetHWND()
1778 ,CM_QUERYVIEWPORTRECT
1780 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1782 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1783 vQueryRect
.rect
= vRect
;
1784 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1786 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1787 ,CM_QUERYRECORDFROMRECT
1789 ,MPFROMP(&vQueryRect
)
1794 return (long)pRecord
->m_ulItemId
;
1795 } // end of wxListCtrl::GetTopItem
1797 // Searches for an item, starting from 'item'.
1798 // 'geometry' is one of
1799 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
1800 // 'state' is a state bit flag, one or more of
1801 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
1802 // item can be -1 to find the first item that matches the
1804 // Returns the item or -1 if unsuccessful.
1805 long wxListCtrl::GetNextItem (
1807 , int WXUNUSED(nGeom
)
1808 , int WXUNUSED(nState
)
1811 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1815 pRecord
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
;
1817 return((long)pRecord
->m_ulItemId
);
1819 } // end of wxListCtrl::GetNextItem
1821 wxImageList
* wxListCtrl::GetImageList (
1825 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1827 return m_pImageListNormal
;
1829 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1831 return m_pImageListSmall
;
1833 else if (nWhich
== wxIMAGE_LIST_STATE
)
1835 return m_pImageListState
;
1838 } // end of wxListCtrl::GetImageList
1840 void wxListCtrl::SetImageList ( wxImageList
* pImageList
,
1843 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1845 if (m_bOwnsImageListNormal
)
1846 delete m_pImageListNormal
;
1847 m_pImageListNormal
= pImageList
;
1848 m_bOwnsImageListNormal
= false;
1850 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1852 if (m_bOwnsImageListSmall
)
1853 delete m_pImageListSmall
;
1854 m_pImageListSmall
= pImageList
;
1855 m_bOwnsImageListSmall
= false;
1857 else if (nWhich
== wxIMAGE_LIST_STATE
)
1859 if (m_bOwnsImageListState
)
1860 delete m_pImageListState
;
1861 m_pImageListState
= pImageList
;
1862 m_bOwnsImageListState
= false;
1864 } // end of wxListCtrl::SetImageList
1866 void wxListCtrl::AssignImageList ( wxImageList
* pImageList
, int nWhich
)
1868 SetImageList( pImageList
, nWhich
);
1870 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1871 m_bOwnsImageListNormal
= true;
1872 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1873 m_bOwnsImageListSmall
= true;
1874 else if (nWhich
== wxIMAGE_LIST_STATE
)
1875 m_bOwnsImageListState
= true;
1876 } // end of wxListCtrl::AssignImageList
1878 // ----------------------------------------------------------------------------
1880 // ----------------------------------------------------------------------------
1882 // Arranges the items
1883 bool wxListCtrl::Arrange ( int nFlag
)
1888 if (nFlag
== wxLIST_ALIGN_SNAP_TO_GRID
)
1890 ulType
= CMA_ARRANGEGRID
;
1891 if (nFlag
== wxLIST_ALIGN_LEFT
)
1892 ulFlags
|= CMA_LEFT
;
1893 else if (nFlag
== wxLIST_ALIGN_TOP
)
1895 else if (nFlag
== wxLIST_ALIGN_DEFAULT
)
1896 ulFlags
|= CMA_LEFT
;
1899 ulType
= CMA_ARRANGESTANDARD
;
1900 ::WinSendMsg( GetHWND()
1906 // We do not support CMA_ARRANGESELECTED
1909 } // end of wxListCtrl::Arrange
1912 bool wxListCtrl::DeleteItem ( long lItem
)
1914 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1915 if (LONGFROMMR(::WinSendMsg( GetHWND()
1918 ,MPFROM2SHORT(1, CMA_FREE
)
1925 // The virtual list control doesn't refresh itself correctly, help it
1930 // We need to refresh all the lines below the one which was deleted
1934 if (lItem
> 0 && GetItemCount())
1936 GetItemRect( lItem
- 1
1942 vRectItem
.y
= vRectItem
.height
= 0;
1944 wxRect vRectWin
= GetRect();
1946 vRectWin
.height
= vRectWin
.GetBottom() - vRectItem
.GetBottom();
1947 vRectWin
.y
= vRectItem
.GetBottom();
1948 RefreshRect(vRectWin
);
1951 } // end of wxListCtrl::DeleteItem
1953 // Deletes all items
1954 bool wxListCtrl::DeleteAllItems ()
1956 return((LONG
)::WinSendMsg( GetHWND()
1959 ,MPFROM2SHORT(0, CMA_FREE
)
1961 } // end of wxListCtrl::DeleteAllItems
1963 // Deletes all items
1964 bool wxListCtrl::DeleteAllColumns ()
1966 while (m_nColCount
> 0)
1968 DeleteColumn(m_nColCount
- 1);
1972 wxASSERT_MSG(m_nColCount
== 0, wxT("no columns should be left"));
1974 } // end of wxListCtrl::DeleteAllColumns
1977 bool wxListCtrl::DeleteColumn ( int nCol
)
1979 bool bSuccess
= false;
1980 PFIELDINFO pField
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1981 bSuccess
= ((LONG
)::WinSendMsg( GetHWND()
1982 ,CM_REMOVEDETAILFIELDINFO
1984 ,MPFROM2SHORT((SHORT
)1, CMA_FREE
)
1986 if (bSuccess
&& (m_nColCount
> 0))
1989 } // end of wxListCtrl::DeleteColumn
1991 // Clears items, and columns if there are any.
1992 void wxListCtrl::ClearAll ()
1995 if (m_nColCount
> 0)
1997 } // end of wxListCtrl::ClearAll
2000 // OS/2 does not use a text control for its container labels. You merely
2001 // "open" a record for editting.
2003 wxTextCtrl
* wxListCtrl::EditLabel (
2005 , wxClassInfo
* WXUNUSED(pTextControlClass
)
2009 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2013 vEdit
.cb
= sizeof(CNREDITDATA
);
2014 vEdit
.hwndCnr
= GetHWND();
2015 vEdit
.pRecord
= &pRecord
->m_vRecord
;
2016 vEdit
.pFieldInfo
= NULL
;
2017 vEdit
.ppszText
= NULL
;
2021 ::WinSendMsg( GetHWND()
2027 } // end of wxListCtrl::EditLabel
2029 // End label editing, optionally cancelling the edit. Under OS/2 you close
2030 // the record for editting
2031 bool wxListCtrl::EndEditLabel ( bool WXUNUSED(bCancel
) )
2033 ::WinSendMsg( GetHWND()
2039 } // end of wxListCtrl::EndEditLabel
2041 // Ensures this item is visible
2042 bool wxListCtrl::EnsureVisible ( long lItem
)
2044 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
2045 ::WinSendMsg( GetHWND()
2046 ,CM_INVALIDATERECORD
2048 ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
)
2051 } // end of wxListCtrl::EnsureVisible
2053 // Find an item whose label matches this string, starting from the item after 'start'
2054 // or the beginning if 'start' is -1.
2055 long wxListCtrl::FindItem (
2057 , const wxString
& rsStr
2062 SEARCHSTRING vSearch
;
2063 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2069 if (!::WinSendMsg( GetHWND()
2072 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2076 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
2078 if (vCnrInfo
.flWindowAttr
& CV_NAME
)
2080 if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
2082 if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
2085 ulFlag
|= CV_EXACTLENGTH
;
2087 vSearch
.cb
= sizeof(SEARCHSTRING
);
2088 vSearch
.pszSearch
= (char*)rsStr
.c_str();
2089 vSearch
.fsPrefix
= TRUE
;
2090 vSearch
.fsCaseSensitive
= TRUE
;
2091 vSearch
.usView
= ulFlag
;
2095 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2103 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2111 return pRecord
->m_ulItemId
;
2112 } // end of wxListCtrl::FindItem
2114 // Find an item whose data matches this data, starting from the item after 'start'
2115 // or the beginning if 'start' is -1.
2116 long wxListCtrl::FindItem (
2121 long lIdx
= lStart
+ 1;
2122 long lCount
= GetItemCount();
2124 while (lIdx
< lCount
)
2126 if (GetItemData(lIdx
) == lData
)
2131 } // end of wxListCtrl::FindItem
2133 // Find an item nearest this position in the specified direction, starting from
2134 // the item after 'start' or the beginning if 'start' is -1.
2135 long wxListCtrl::FindItem (
2137 , const wxPoint
& rPoint
2142 QUERYRECORDRECT vQueryRect
;
2143 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2150 if (!::WinSendMsg( GetHWND()
2153 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2157 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
2158 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
2159 vQueryRect
.fRightSplitWindow
= TRUE
;
2160 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
2162 ::WinSendMsg( GetHWND()
2165 ,MPFROMP(&vQueryRect
)
2167 vLibRect
.SetLeft(vRect
.xLeft
);
2168 vLibRect
.SetTop(vRect
.yTop
);
2169 vLibRect
.SetRight(vRect
.xRight
);
2170 vLibRect
.SetBottom(vRect
.yBottom
);
2171 if (vLibRect
.Inside(rPoint
))
2172 return pRecord
->m_ulItemId
;
2174 for (i
= lStart
+ 1; i
< vCnrInfo
.cRecords
; i
++)
2176 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
2179 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
2181 vQueryRect
.pRecord
= (PRECORDCORE
)pRecord
;
2182 ::WinSendMsg( GetHWND()
2185 ,MPFROMP(&vQueryRect
)
2187 vLibRect
.SetLeft(vRect
.xLeft
);
2188 vLibRect
.SetTop(vRect
.yTop
);
2189 vLibRect
.SetRight(vRect
.xRight
);
2190 vLibRect
.SetBottom(vRect
.yBottom
);
2191 if (vLibRect
.Inside(rPoint
))
2192 return pRecord
->m_ulItemId
;
2195 } // end of wxListCtrl::FindItem
2197 // Determines which item (if any) is at the specified point,
2198 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
2199 long wxListCtrl::HitTest (
2200 const wxPoint
& rPoint
2201 , int& WXUNUSED(rFlags
)
2204 PMYRECORD pRecord
= NULL
;
2205 QUERYRECFROMRECT vQueryRect
;
2210 // Get height for OS/2 point conversion
2212 ::WinSendMsg( GetHWND()
2213 ,CM_QUERYVIEWPORTRECT
2215 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
2217 lHeight
= vRect
.yTop
- vRect
.yBottom
;
2220 // For now just try and get a record in the general vicinity and forget
2223 vRect
.xLeft
= rPoint
.x
- 2;
2224 vRect
.xRight
= rPoint
.x
+ 2;
2225 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
2226 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
2228 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
2229 vQueryRect
.rect
= vRect
;
2230 vQueryRect
.fsSearch
= CMA_PARTIAL
;
2232 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2233 ,CM_QUERYRECORDFROMRECT
2235 ,MPFROMP(&vQueryRect
)
2240 return pRecord
->m_ulItemId
;
2241 } // end of wxListCtrl::HitTest
2243 // Inserts an item, returning the index of the new item if successful,
2245 long wxListCtrl::InsertItem (
2249 wxASSERT_MSG( !IsVirtual(), _T("can't be used with virtual controls") );
2251 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
2254 PMYRECORD pRecordAfter
= NULL
;
2255 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2257 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
2261 ConvertToOS2ListItem( this
2267 if (rInfo
.GetId() > 0)
2268 pRecordAfter
= FindOS2ListRecordByID( GetHWND()
2272 RECORDINSERT vInsert
;
2274 vInsert
.cb
= sizeof(RECORDINSERT
);
2275 vInsert
.pRecordParent
= NULL
;
2277 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
2279 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
2280 vInsert
.zOrder
= CMA_TOP
;
2281 vInsert
.cRecordsInsert
= 1;
2282 vInsert
.fInvalidateRecord
= TRUE
;
2285 // Check wether we need to allocate our internal data
2287 bool bNeedInternalData
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) ||
2288 rInfo
.HasAttributes()
2290 if (bNeedInternalData
)
2292 m_bAnyInternalData
= true;
2295 // Internal stucture that manages data
2297 CListItemInternalData
* pData
= new CListItemInternalData();
2299 pRecord
->m_ulUserData
= (unsigned long)pData
;
2300 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
2301 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
2304 // Check whether it has any custom attributes
2306 if (rInfo
.HasAttributes())
2309 // Take copy of attributes
2311 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
2314 if (!::WinSendMsg( GetHWND()
2321 // OS/2 must mannually bump the index's of following records
2323 BumpRecordIds( GetHWND()
2326 ::WinSendMsg( GetHWND()
2327 ,CM_INVALIDATEDETAILFIELDINFO
2331 return pRecord
->m_ulItemId
;
2332 } // end of wxListCtrl::InsertItem
2334 long wxListCtrl::InsertItem (
2336 , const wxString
& rsLabel
2341 memset(&vInfo
, '\0', sizeof(wxListItem
));
2342 vInfo
.m_text
= rsLabel
;
2343 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
2344 vInfo
.m_itemId
= lIndex
;
2345 return InsertItem(vInfo
);
2346 } // end of wxListCtrl::InsertItem
2348 // Inserts an image item
2349 long wxListCtrl::InsertItem (
2356 vInfo
.m_image
= nImageIndex
;
2357 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
2358 vInfo
.m_itemId
= lIndex
;
2359 return InsertItem(vInfo
);
2360 } // end of wxListCtrl::InsertItem
2362 // Inserts an image/string item
2363 long wxListCtrl::InsertItem (
2365 , const wxString
& rsLabel
2371 vInfo
.m_image
= nImageIndex
;
2372 vInfo
.m_text
= rsLabel
;
2373 vInfo
.m_mask
= wxLIST_MASK_IMAGE
| wxLIST_MASK_TEXT
;
2374 vInfo
.m_itemId
= lIndex
;
2375 return InsertItem(vInfo
);
2376 } // end of wxListCtrl::InsertItem
2378 // For details view mode (only), inserts a column.
2379 long wxListCtrl::InsertColumn (
2385 PFIELDINFO pField
= (PFIELDINFO
)::WinSendMsg( GetHWND()
2386 ,CM_ALLOCDETAILFIELDINFO
2390 PFIELDINFO pFieldAfter
= FindOS2ListFieldByColNum ( GetHWND()
2393 FIELDINFOINSERT vInsert
;
2395 ConvertToOS2ListCol ( lCol
2400 vInsert
.cb
= sizeof(FIELDINFOINSERT
);
2401 vInsert
.pFieldInfoOrder
= pFieldAfter
;
2402 vInsert
.fInvalidateFieldInfo
= TRUE
;
2403 vInsert
.cFieldInfoInsert
= 1;
2405 bSuccess
= ::WinSendMsg( GetHWND()
2406 ,CM_INSERTDETAILFIELDINFO
2411 } // end of wxListCtrl::InsertColumn
2413 long wxListCtrl::InsertColumn (
2415 , const wxString
& rsHeading
2422 vItem
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
2423 vItem
.m_text
= rsHeading
;
2426 vItem
.m_mask
|= wxLIST_MASK_WIDTH
;
2427 vItem
.m_width
= nWidth
;
2429 vItem
.m_format
= nFormat
;
2431 return InsertColumn( lCol
2434 } // end of wxListCtrl::InsertColumn
2436 // scroll the control by the given number of pixels (exception: in list view,
2437 // dx is interpreted as number of columns)
2438 bool wxListCtrl::ScrollList ( int nDx
, int nDy
)
2441 ::WinSendMsg( GetHWND()
2443 ,(MPARAM
)CMA_HORIZONTAL
2447 ::WinSendMsg( GetHWND()
2449 ,(MPARAM
)CMA_VERTICAL
2453 } // end of wxListCtrl::ScrollList
2455 bool wxListCtrl::SortItems ( wxListCtrlCompare fn
, long lData
)
2457 SInternalDataSort vInternalData
;
2459 vInternalData
.m_fnUser
= fn
;
2460 vInternalData
.m_lData
= lData
;
2462 // WPARAM cast is needed for mingw/cygwin
2463 if (!::WinSendMsg( GetHWND()
2465 ,(PFN
)InternalDataCompareFunc
2466 ,(PVOID
)&vInternalData
2469 wxLogDebug(_T("CM_SORTRECORD failed"));
2473 } // end of wxListCtrl::SortItems
2475 // ----------------------------------------------------------------------------
2476 // message processing
2477 // ----------------------------------------------------------------------------
2479 bool wxListCtrl::OS2Command ( WXUINT uCmd
, WXWORD wId
)
2481 if (uCmd
== CN_ENDEDIT
)
2483 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
, wId
);
2485 vEvent
.SetEventObject( this );
2486 ProcessCommand(vEvent
);
2489 else if (uCmd
== CN_KILLFOCUS
)
2491 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
, wId
);
2492 vEvent
.SetEventObject( this );
2493 ProcessCommand(vEvent
);
2498 } // end of wxListCtrl::OS2Command
2500 // Necessary for drawing hrules and vrules, if specified
2501 void wxListCtrl::OnPaint ( wxPaintEvent
& rEvent
)
2503 wxPaintDC
vDc(this);
2504 wxPen
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
)
2508 wxSize vClientSize
= GetClientSize();
2510 int nItemCount
= GetItemCount();
2513 bool bDrawHRules
= ((GetWindowStyle() & wxLC_HRULES
) != 0);
2514 bool bDrawVRules
= ((GetWindowStyle() & wxLC_VRULES
) != 0);
2516 wxControl::OnPaint(rEvent
);
2519 // Reset the device origin since it may have been set
2521 vDc
.SetDeviceOrigin(0, 0);
2522 if (!bDrawHRules
&& !bDrawVRules
)
2524 if ((GetWindowStyle() & wxLC_REPORT
) == 0)
2527 vDc
.SetBrush(*wxTRANSPARENT_BRUSH
);
2531 long lTop
= GetTopItem();
2533 for (i
= lTop
; i
< lTop
+ GetCountPerPage() + 1; i
++)
2539 nCy
= vItemRect
.GetTop();
2540 if (i
!= 0) // Don't draw the first one
2549 if (i
== nItemCount
- 1)
2551 nCy
= vItemRect
.GetBottom();
2562 if (bDrawVRules
&& (i
> -1))
2564 wxRect vFirstItemRect
;
2574 int nX
= vItemRect
.GetX();
2576 for (nCol
= 0; nCol
< GetColumnCount(); nCol
++)
2578 int nColWidth
= GetColumnWidth(nCol
);
2581 vDc
.DrawLine( nX
- 1
2582 ,vFirstItemRect
.GetY() - 2
2584 ,vItemRect
.GetBottom()
2589 } // end of wxListCtrl::OnPaint
2591 // ----------------------------------------------------------------------------
2592 // virtual list controls
2593 // ----------------------------------------------------------------------------
2595 wxString
wxListCtrl::OnGetItemText (
2596 long WXUNUSED(lItem
)
2597 , long WXUNUSED(lCol
)
2600 // this is a pure virtual function, in fact - which is not really pure
2601 // because the controls which are not virtual don't need to implement it
2602 wxFAIL_MSG( _T("not supposed to be called") );
2603 return wxEmptyString
;
2604 } // end of wxListCtrl::OnGetItemText
2606 int wxListCtrl::OnGetItemImage (
2607 long WXUNUSED(lItem
)
2611 wxFAIL_MSG( _T("not supposed to be called") );
2613 } // end of wxListCtrl::OnGetItemImage
2615 int wxListCtrl::OnGetItemColumnImage (
2621 return OnGetItemImage(lItem
);
2624 } // end of wxListCtrl::OnGetItemColumnImage
2626 wxListItemAttr
* wxListCtrl::OnGetItemAttr (
2627 long WXUNUSED_UNLESS_DEBUG(lItem
)
2630 wxASSERT_MSG( lItem
>= 0 && lItem
< GetItemCount(),
2631 _T("invalid item index in OnGetItemAttr()") );
2634 // No attributes by default
2637 } // end of wxListCtrl::OnGetItemAttr
2639 void wxListCtrl::SetItemCount (
2643 wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
2646 // Cannot explicitly set the record count in OS/2
2648 } // end of wxListCtrl::SetItemCount
2650 void wxListCtrl::RefreshItem (
2660 } // end of wxListCtrl::RefreshItem
2662 void wxListCtrl::RefreshItems ( long lItemFrom
, long lItemTo
)
2667 GetItemRect( lItemFrom
, vRect1
);
2668 GetItemRect( lItemTo
, vRect2
);
2670 wxRect vRect
= vRect1
;
2672 vRect
.height
= vRect2
.GetBottom() - vRect1
.GetTop();
2674 } // end of wxListCtrl::RefreshItems
2676 MRESULT
wxListCtrl::OS2WindowProc( WXUINT uMsg
,
2680 bool bProcessed
= false;
2682 wxListEvent
vEvent( wxEVT_NULL
2685 wxEventType vEventType
= wxEVT_NULL
;
2686 PCNRDRAGINIT pDragInit
= NULL
;
2687 PCNREDITDATA pEditData
= NULL
;
2688 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
2690 vEvent
.SetEventObject(this);
2695 // First off let's set some internal data
2697 switch(SHORT2FROMMP(wParam
))
2703 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)lParam
;
2707 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2709 pItem
->SetData((long)pInternaldata
->m_lParam
);
2715 // Now let's go through the codes we're interested in
2717 switch(SHORT2FROMMP(wParam
))
2720 pDragInit
= (PCNRDRAGINIT
)lParam
;
2723 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2725 vEventType
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
;
2726 vEvent
.m_itemIndex
= pRecord
->m_ulItemId
;
2727 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2728 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2733 pEditData
= (PCNREDITDATA
)lParam
;
2736 vEventType
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
;
2737 ConvertFromOS2ListItem( GetHWND()
2738 ,(wxListItem
&)vEvent
.GetItem()
2739 ,(PMYRECORD
)pEditData
->pRecord
2741 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2746 pEditData
= (PCNREDITDATA
)lParam
;
2749 vEventType
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
;
2750 ConvertFromOS2ListItem( GetHWND()
2751 ,(wxListItem
&)vEvent
.GetItem()
2752 ,(PMYRECORD
)pEditData
->pRecord
2754 if (pEditData
->cbText
== 0)
2755 return (MRESULT
)FALSE
;
2756 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2761 pNotifyEnter
= (PNOTIFYRECORDENTER
)lParam
;
2764 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2765 PMYRECORD pMyRecord
= (PMYRECORD
)pNotifyEnter
->pRecord
;
2767 vEventType
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
;
2768 vEvent
.m_itemIndex
= pMyRecord
->m_ulItemId
;
2769 pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
));
2770 pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
));
2775 // Add the CN_DROP messages for Direct Manipulation
2778 vEvent
.SetEventType(vEventType
);
2779 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
2783 lRc
= wxControl::OS2WindowProc( uMsg
2788 } // end of wxListCtrl::WindowProc
2790 #endif // wxUSE_LISTCTRL