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()
146 wxListItemAttr
* m_pAttr
;
147 WXLPARAM m_lParam
; // user data
148 PMYRECORD m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted
149 }; // end of CLASS CListItemInternalData
151 /////////////////////////////////////////////////////////////////////////////
152 // STRUCT SInternalDataSort
156 // fn is a function which takes 3 long arguments: item1, item2, data.
157 // item1 is the long data associated with a first item (NOT the index).
158 // item2 is the long data associated with a second item (NOT the index).
159 // data is the same value as passed to SortItems.
161 // The return value is a negative number if the first item should precede the
162 // second item, a positive number of the second item should precede the first,
163 // or zero if the two items are equivalent.
165 // data is arbitrary data to be passed to the sort function.
167 // Internal structures for proxying the user compare function
168 // so that we can pass it the *real* user data
169 /////////////////////////////////////////////////////////////////////////////
170 typedef struct internalDataSort
172 wxListCtrlCompare m_fnUser
;
174 } SInternalDataSort
; // end of STRUCT SInternalDataSort
176 // ----------------------------------------------------------------------------
177 // private helper functions
178 // ----------------------------------------------------------------------------
180 /////////////////////////////////////////////////////////////////////////////
182 // FindOS2ListFieldByColNum
184 // There is no way, under OS/2 to get a field in a container by index,
185 // directly, so you must get the first one, then cycle through the list
186 // until you get to where you want to be.
189 // hWnd -- window handle of container to search
190 // lIndex -- index to set
193 // pointer to the FIELDINFO struct at the index in the container record
195 /////////////////////////////////////////////////////////////////////////////
196 PFIELDINFO
FindOS2ListFieldByColNum (
201 PFIELDINFO pFieldInfo
= NULL
;
205 if (!::WinSendMsg( hWnd
208 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
211 for (i
= 0; i
< vCnrInfo
.cFields
; i
++)
214 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
215 ,CM_QUERYDETAILFIELDINFO
220 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
221 ,CM_QUERYDETAILFIELDINFO
227 if (i
== (ULONG
)lIndex
)
233 } // end of FindOS2ListFieldByColNum
235 /////////////////////////////////////////////////////////////////////////////
237 // FindOS2ListRecordByID
239 // There is no way, under OS/2 to get a record in a container by index,
240 // directly, so you must get the first one, then cycle through the list
241 // until you get to where you want to be.
244 // hWnd -- window handle of container to search
245 // lItemId -- index to set
248 // pointer to the internal RECORDCORE struct at the index in the container
250 /////////////////////////////////////////////////////////////////////////////
251 PMYRECORD
FindOS2ListRecordByID (
256 PMYRECORD pRecord
= NULL
;
260 if (!::WinSendMsg( hWnd
263 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
266 for (i
= 0; i
< vCnrInfo
.cRecords
; i
++)
269 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
272 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
275 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
278 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
282 if (pRecord
->m_ulItemId
== (ULONG
)lItemId
)
286 } // end of FindOS2ListRecordByID
288 /////////////////////////////////////////////////////////////////////////////
292 // Since OS/2 does not keep native record id's but wx insists on inserting
293 // and selecting via ID's, when we insert a record in the middle we need
294 // to bump the id's of each record after the one we just inserted.
297 // hWnd -- window handle of container to search
298 // pRecord -- record after which we starting bumping id's
303 /////////////////////////////////////////////////////////////////////////////
311 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
314 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
317 pRecord
->m_ulItemId
++;
319 } // end of BumpRecordIds
321 /////////////////////////////////////////////////////////////////////////////
325 // Get the internal data given a handle and an id
328 // hWnd -- window handle to the control in which item is located
329 // lItemId -- ID to get
332 // pointer to the internal data
335 // Under OS/2 PM a container item cannot be obtained via a simple index or
336 // id retrieval. We have to walk the record list if we are looking for
337 // a record at a specific index location
338 /////////////////////////////////////////////////////////////////////////////
339 CListItemInternalData
* GetInternalData (
344 PMYRECORD pRecord
= FindOS2ListRecordByID( hWnd
348 // Internal user data is stored AFTER the last field of the RECORDCORE
352 return((CListItemInternalData
*)(pRecord
->m_ulUserData
));
353 } // end of GetInternalData
355 /////////////////////////////////////////////////////////////////////////////
359 // Get the internal data given a pointer to a list control and an id
362 // pCtl -- pointer to control inwhich item is located
363 // lItemId -- ID to get
366 // pointer to the internal data
368 /////////////////////////////////////////////////////////////////////////////
369 CListItemInternalData
* GetInternalData (
374 return(GetInternalData( (HWND
)pCtl
->GetHWND()
377 } // end of GetInternalData
379 /////////////////////////////////////////////////////////////////////////////
381 // DeleteInternalData
383 // Delete the internal data for a record
386 // pCtl -- pointer to the list control containing the record
387 // lItemId -- the record index to delete the internal data from
390 // pointer to the internal data attribute
392 /////////////////////////////////////////////////////////////////////////////
393 void DeleteInternalData (
398 CListItemInternalData
* pData
= GetInternalData( pCtl
403 if (pData
->m_pMyRecord
)
404 pData
->m_pMyRecord
->m_ulUserData
= 0;
407 } // end of DeleteInternalData
409 // #pragma page "GetInternalDataAttr"
410 /////////////////////////////////////////////////////////////////////////////
412 // GetInternalDataAttr
414 // Get the internal data item attribute given a pointer to a list control
418 // pCtl -- pointer to control to set
419 // lItemId -- ID to set
422 // pointer to the internal data attribute
424 /////////////////////////////////////////////////////////////////////////////
425 wxListItemAttr
* GetInternalDataAttr (
430 CListItemInternalData
* pData
= GetInternalData( pCtl
435 return(pData
->m_pAttr
);
438 } // end of GetInternalDataAttr
440 /////////////////////////////////////////////////////////////////////////////
442 // InternalDataCompareFunc
444 // This is compare function we pass to PM. It wraps the real compare
445 // function in SInternalDataSort
448 // p1 -- is the first record structure to compare
449 // p2 -- is the second record structure to compare
450 // lStorage -- is the same value as passed to SortItems.
453 // pointer to the internal data attribute
455 /////////////////////////////////////////////////////////////////////////////
456 SHORT EXPENTRY
InternalDataCompareFunc (
462 SInternalDataSort
* pInternalData
= (SInternalDataSort
*)pStorage
;
463 CListItemInternalData
* pData1
= (CListItemInternalData
*)p1
->m_ulUserData
;
464 CListItemInternalData
* pData2
= (CListItemInternalData
*)p2
->m_ulUserData
;
465 long lD1
= (pData1
== NULL
? 0 : (long)pData1
->m_lParam
);
466 long lD2
= (pData2
== NULL
? 0 : (long)pData2
->m_lParam
);
468 return(pInternalData
->m_fnUser( lD1
470 ,pInternalData
->m_lData
472 } // end of InternalDataCompareFunc
474 /////////////////////////////////////////////////////////////////////////////
476 // ConvertFromOS2ListItem
478 // Convert from an internal PM List item to a Toolkit List item
481 // hWndListCtrl -- the control's windows handle
482 // rInfo -- the library list control to convert to
483 // pRecord -- the OS list control to convert from
488 /////////////////////////////////////////////////////////////////////////////
489 void ConvertFromOS2ListItem ( HWND hWndListCtrl
,
493 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)pRecord
->m_ulUserData
;
494 bool bNeedText
= false;
497 rInfo
.SetData(pInternaldata
->m_lParam
);
501 rInfo
.SetStateMask(0);
502 rInfo
.SetId((long)pRecord
->m_ulItemId
);
503 if (hWndListCtrl
!= 0)
505 pRecord
= FindOS2ListRecordByID( hWndListCtrl
511 // The wxListItem class is really set up to handle the WIN32 list item
512 // and OS/2 are not as complicated. Just set both state members to the
513 // same thing under OS/2
515 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DROPONABLE
)
517 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DROPHILITED
);
518 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DROPHILITED
);
520 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SELECTED
)
522 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SELECTED
);
523 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SELECTED
);
525 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DISABLED
)
527 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DISABLED
);
528 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DISABLED
);
530 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_FILTERED
)
532 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_FILTERED
);
533 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_FILTERED
);
535 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_INUSE
)
537 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_INUSE
);
538 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_INUSE
);
540 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_PICKED
)
542 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_PICKED
);
543 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_PICKED
);
545 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SOURCE
)
547 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SOURCE
);
548 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SOURCE
);
551 if (pRecord
->m_vRecord
.pszText
!= (PSZ
)NULL
)
553 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
);
554 rInfo
.SetText(pRecord
->m_vRecord
.pszText
);
556 if (pRecord
->m_vRecord
.pszIcon
!= (PSZ
)NULL
||
557 pRecord
->m_vRecord
.pszName
!= (PSZ
)NULL
)
559 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
);
560 rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
);
562 if (pRecord
->m_ulUserData
)
563 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
);
564 } // end of ConvertFromOS2ListItem
566 /////////////////////////////////////////////////////////////////////////////
570 // Convert from an library states to OS states
573 // lState -- the state
574 // pRecord -- the OS list control to use
579 /////////////////////////////////////////////////////////////////////////////
580 void ConvertToOS2Flags (
585 if (lState
& wxLIST_STATE_DROPHILITED
)
586 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DROPONABLE
;
587 if (lState
& wxLIST_STATE_SELECTED
)
588 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SELECTED
;
589 if (lState
& wxLIST_STATE_DISABLED
)
590 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DISABLED
;
591 if (lState
& wxLIST_STATE_FILTERED
)
592 pRecord
->m_vRecord
.flRecordAttr
|= CRA_FILTERED
;
593 if (lState
& wxLIST_STATE_INUSE
)
594 pRecord
->m_vRecord
.flRecordAttr
|= CRA_INUSE
;
595 if (lState
& wxLIST_STATE_PICKED
)
596 pRecord
->m_vRecord
.flRecordAttr
|= CRA_PICKED
;
597 if (lState
& wxLIST_STATE_SOURCE
)
598 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SOURCE
;
599 } // end of ConvertToOS2Flags
601 /////////////////////////////////////////////////////////////////////////////
603 // ConvertToOS2ListItem
605 // Convert from a library List item to an internal OS2 List item. We set
606 // only the fields we need to set. Some of them are set by the API when
607 // they are added to the container.
610 // pCtrl -- the control to use
611 // rInfo -- the item to convert
612 // pRecord -- the OS list control to use, should be zeroed out
613 // pFieldinfo -- a field struct that may contain columnar data for detail view
618 /////////////////////////////////////////////////////////////////////////////
619 void ConvertToOS2ListItem (
620 const wxListCtrl
* pCtrl
621 , const wxListItem
& rInfo
623 , PFIELDINFO pFieldInfo
626 pRecord
->m_ulItemId
= (ULONG
)rInfo
.GetId();
627 pRecord
->m_vRecord
.cb
= sizeof(RECORDCORE
);
628 if (rInfo
.GetMask() & wxLIST_MASK_STATE
)
630 ConvertToOS2Flags( rInfo
.m_state
634 if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON
||
635 pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
)
637 pRecord
->m_vRecord
.pszIcon
= (char*)rInfo
.GetText().c_str();
639 if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view
641 pRecord
->m_vRecord
.pszText
= (char*)rInfo
.GetText().c_str();
644 // In the case of a report view the text will be the data in the lead column
645 // ???? Don't know why, but that is how it works in other ports.
647 if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
)
651 switch(rInfo
.GetColumn())
654 pRecord
->m_pzColumn1
= (char*)rInfo
.GetText().c_str();
655 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn1
);
659 pRecord
->m_pzColumn2
= (char*)rInfo
.GetText().c_str();
660 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn2
);
664 pRecord
->m_pzColumn3
= (char*)rInfo
.GetText().c_str();
665 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn3
);
669 pRecord
->m_pzColumn4
= (char*)rInfo
.GetText().c_str();
670 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn4
);
674 pRecord
->m_pzColumn5
= (char*)rInfo
.GetText().c_str();
675 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn5
);
679 pRecord
->m_pzColumn6
= (char*)rInfo
.GetText().c_str();
680 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn6
);
684 pRecord
->m_pzColumn7
= (char*)rInfo
.GetText().c_str();
685 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn7
);
689 pRecord
->m_pzColumn8
= (char*)rInfo
.GetText().c_str();
690 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn8
);
694 pRecord
->m_pzColumn9
= (char*)rInfo
.GetText().c_str();
695 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn9
);
699 pRecord
->m_pzColumn10
= (char*)rInfo
.GetText().c_str();
700 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn10
);
704 wxFAIL_MSG( wxT("wxOS2 does not support more than 10 columns in REPORT view") );
709 if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
)
711 pRecord
->m_vRecord
.hptrIcon
= (HPOINTER
)rInfo
.GetImage();
712 pRecord
->m_vRecord
.hptrMiniIcon
= (HPOINTER
)rInfo
.m_miniImage
;
714 } // end of ConvertToOS2ListItem
716 /////////////////////////////////////////////////////////////////////////////
718 // ConvertToOS2ListCol
720 // Convert from a library List column to an internal PM List column
723 // lCol -- the columnd to convert
724 // rItem -- the item to convert
725 // pField -- the OS list column to use
730 /////////////////////////////////////////////////////////////////////////////
731 void ConvertToOS2ListCol (
733 , const wxListItem
& rItem
737 memset(pField
, '\0', sizeof(FIELDINFO
));
738 pField
->cb
= sizeof(FIELDINFO
);
741 // Default some settings
743 pField
->flData
= CFA_HORZSEPARATOR
| CFA_SEPARATOR
;
744 pField
->flTitle
= CFA_CENTER
;
746 if (rItem
.GetMask() & wxLIST_MASK_TEXT
)
748 pField
->flData
|= CFA_STRING
;
749 pField
->pTitleData
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data
751 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
753 if (rItem
.m_format
== wxLIST_FORMAT_LEFT
)
754 pField
->flData
|= CFA_LEFT
;
755 else if (rItem
.m_format
== wxLIST_FORMAT_RIGHT
)
756 pField
->flData
|= CFA_RIGHT
;
757 else if (rItem
.m_format
== wxLIST_FORMAT_CENTRE
)
758 pField
->flData
|= CFA_CENTER
;
761 pField
->flData
|= CFA_CENTER
; // Just ensure the default is centered
762 if (rItem
.GetMask() & wxLIST_MASK_WIDTH
)
764 if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE
||
765 rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
))
766 pField
->cxWidth
= rItem
.GetWidth();
767 // else: OS/2 automatically sets the width if created with the approppriate style
771 // Still need to set the actual data
773 pField
->offStruct
= 0;
774 } // end of ConvertToOS2ListCol
777 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
778 IMPLEMENT_DYNAMIC_CLASS(wxListView
, wxListCtrl
)
779 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
781 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
783 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
)
784 EVT_PAINT(wxListCtrl::OnPaint
)
787 // ============================================================================
789 // ============================================================================
791 // ----------------------------------------------------------------------------
792 // wxListCtrl construction
793 // ----------------------------------------------------------------------------
795 void wxListCtrl::Init ()
797 m_pImageListNormal
= NULL
;
798 m_pImageListSmall
= NULL
;
799 m_pImageListState
= NULL
;
800 m_bOwnsImageListNormal
= false;
801 m_bOwnsImageListSmall
= false;
802 m_bOwnsImageListState
= false;
806 m_bAnyInternalData
= false;
807 m_bHasAnyAttr
= false;
808 } // end of wxListCtrl::Init
810 bool wxListCtrl::Create ( wxWindow
* pParent
,
815 const wxValidator
& rValidator
,
816 const wxString
& rsName
)
820 int nWidth
= rSize
.x
;
821 int nHeight
= rSize
.y
;
824 SetValidator(rValidator
);
825 #endif // wxUSE_VALIDATORS
828 SetWindowStyleFlag(lStyle
);
839 m_windowId
= (vId
== -1) ? NewControlId() : vId
;
841 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
843 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
)
844 lSstyle
|= WS_CLIPSIBLINGS
;
845 m_lBaseStyle
= lSstyle
;
846 if (!DoCreateControl( nX
853 pParent
->AddChild(this);
855 } // end of wxListCtrl::Create
857 bool wxListCtrl::DoCreateControl ( int nX
, int nY
,
858 int nWidth
, int nHeight
)
860 DWORD lWstyle
= m_lBaseStyle
;
861 long lOldStyle
= 0; // Dummy
865 lWstyle
|= ConvertToOS2Style( lOldStyle
866 ,GetWindowStyleFlag()
869 m_hWnd
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND()
874 ,GetParent()->GetHWND()
886 // Now set the display attributes of the container
888 if (!::WinSendMsg( GetHWND()
891 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
894 lWstyle
= ConvertViewToOS2Style(GetWindowStyleFlag());
895 vCnrInfo
.flWindowAttr
|= lWstyle
;
896 if (!::WinSendMsg( GetHWND()
899 ,(MPARAM
)CMA_FLWINDOWATTR
904 // And now set needed arrangement flags
906 lWstyle
= ConvertArrangeToOS2Style(GetWindowStyleFlag());
907 if (!::WinSendMsg( GetHWND()
909 ,(MPARAM
)CMA_ARRANGEGRID
913 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
914 SetForegroundColour(GetParent()->GetForegroundColour());
916 SetFont(*wxSMALL_FONT
);
919 SetSize( nX
, nY
, nWidth
, nHeight
);
921 } // end of wxListCtrl::DoCreateControl
923 void wxListCtrl::UpdateStyle ()
928 DWORD dwStyleNew
= ConvertToOS2Style( lDummy
, GetWindowStyleFlag() );
930 dwStyleNew
|= m_lBaseStyle
;
933 // Get the current window style.
935 ULONG dwStyleOld
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
);
938 // Only set the window style if the view bits have changed.
940 if (dwStyleOld
!= dwStyleNew
)
942 ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
);
945 } // end of wxListCtrl::UpdateStyle
947 void wxListCtrl::FreeAllInternalData ()
949 if (m_bAnyInternalData
)
951 int n
= GetItemCount();
954 for (i
= 0; i
< n
; i
++)
955 DeleteInternalData(this, (long)i
);
956 m_bAnyInternalData
= false;
958 } // end of wxListCtrl::FreeAllInternalData
960 wxListCtrl::~wxListCtrl ()
962 FreeAllInternalData();
965 m_pTextCtrl
->SetHWND(0);
966 m_pTextCtrl
->UnsubclassWin();
967 wxDELETE(m_pTextCtrl
);
970 if (m_bOwnsImageListNormal
)
971 delete m_pImageListNormal
;
972 if (m_bOwnsImageListSmall
)
973 delete m_pImageListSmall
;
974 if (m_bOwnsImageListState
)
975 delete m_pImageListState
;
976 } // end of wxListCtrl::~wxListCtrl
978 // ----------------------------------------------------------------------------
979 // set/get/change style
980 // ----------------------------------------------------------------------------
982 // Add or remove a single window style
983 void wxListCtrl::SetSingleStyle (
988 long lFlag
= GetWindowStyleFlag();
991 // Get rid of conflicting styles
995 if (lStyle
& wxLC_MASK_TYPE
)
996 lFlag
= lFlag
& ~wxLC_MASK_TYPE
;
997 if (lStyle
& wxLC_MASK_ALIGN
)
998 lFlag
= lFlag
& ~wxLC_MASK_ALIGN
;
999 if (lStyle
& wxLC_MASK_SORT
)
1000 lFlag
= lFlag
& ~wxLC_MASK_SORT
;
1014 m_windowStyle
= lFlag
;
1016 } // end of wxListCtrl::SetSingleStyle
1018 // Set the whole window style
1019 void wxListCtrl::SetWindowStyleFlag (
1023 m_windowStyle
= lFlag
;
1025 } // end of wxListCtrl::SetWindowStyleFlag
1027 long wxListCtrl::ConvertToOS2Style (
1035 // The only styles OS2 uses on creation are auto arrange, read only, and
1036 // and selection styles. This lib does not support OS/2 MINIRECORDCORE
1037 // or VERIFYPOINTER styles
1039 if (lStyle
& wxLC_AUTOARRANGE
)
1040 lWstyle
|= CCS_AUTOPOSITION
;
1041 if (lStyle
& wxLC_SINGLE_SEL
)
1042 lWstyle
|= CCS_SINGLESEL
;
1044 lWstyle
|= CCS_EXTENDSEL
;
1045 if (!(lStyle
& wxLC_EDIT_LABELS
))
1046 lWstyle
|= CCS_READONLY
;
1048 } // end of wxListCtrl::ConvertToOS2Style
1050 long wxListCtrl::ConvertArrangeToOS2Style (
1056 if (lStyle
& wxLC_ALIGN_LEFT
)
1058 lWstyle
|= CMA_LEFT
;
1061 if (lStyle
& wxLC_ALIGN_TOP
)
1066 } // end of wxListCtrl::ConvertArrangeToOS2Style
1068 long wxListCtrl::ConvertViewToOS2Style (
1072 long lWstyle
= CA_DRAWICON
; // we will only use icons
1074 if (lStyle
& wxLC_ICON
)
1078 if (lStyle
& wxLC_SMALL_ICON
)
1080 lWstyle
|= (CV_ICON
| CV_MINI
);
1082 if (lStyle
& wxLC_LIST
)
1086 if (lStyle
& wxLC_REPORT
)
1088 lWstyle
|= CV_DETAIL
;
1090 if (lStyle
& wxLC_VIRTUAL
)
1092 lWstyle
|= CA_OWNERDRAW
;
1094 if (lStyle
& wxLC_AUTOARRANGE
)
1098 if (!(lStyle
& wxLC_NO_HEADER
))
1100 lWstyle
|= CA_DETAILSVIEWTITLES
;
1103 } // end of wxListCtrl::ConvertViewToOS2Style
1105 // ----------------------------------------------------------------------------
1107 // ----------------------------------------------------------------------------
1109 // Sets the foreground, i.e. text, colour
1110 bool wxListCtrl::SetForegroundColour (const wxColour
& rCol
)
1112 ULONG ulColor
= wxColourToRGB(rCol
);
1114 if (!wxWindow::SetForegroundColour(rCol
))
1117 ::WinSetPresParam( GetHWND()
1123 } // end of wxListCtrl::SetForegroundColour
1125 // Sets the background colour
1126 bool wxListCtrl::SetBackgroundColour ( const wxColour
& rCol
)
1128 if (!wxWindow::SetBackgroundColour(rCol
))
1132 // We set the same colour for both the "empty" background and the items
1135 ULONG ulColor
= wxColourToRGB(rCol
);
1137 ::WinSetPresParam( GetHWND()
1143 } // end of wxListCtrl::SetBackgroundColour
1145 // Gets information about this column
1146 bool wxListCtrl::GetColumn ( int nCol
, wxListItem
& rItem
) const
1148 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), nCol
);
1152 rItem
.SetWidth(pFieldInfo
->cxWidth
);
1153 if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) &&
1154 (pFieldInfo
->flData
& CFA_STRING
) &&
1155 (pFieldInfo
->pUserData
!= NULL
))
1157 rItem
.SetText((char*)pFieldInfo
->pUserData
);
1159 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
1161 if (pFieldInfo
->flData
& CFA_LEFT
)
1162 rItem
.m_format
= wxLIST_FORMAT_LEFT
;
1163 else if (pFieldInfo
->flData
& CFA_RIGHT
)
1164 rItem
.m_format
= wxLIST_FORMAT_RIGHT
;
1165 else if (pFieldInfo
->flData
& CFA_CENTER
)
1166 rItem
.m_format
= wxLIST_FORMAT_CENTRE
;
1169 } // end of wxListCtrl::GetColumn
1171 // Sets information about this column
1172 bool wxListCtrl::SetColumn ( int nCol
, wxListItem
& rItem
)
1174 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1175 ConvertToOS2ListCol( nCol
, rItem
, pFieldInfo
);
1177 // Since we changed the field pointed to, we invalidate to see the result
1179 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1181 } // end of wxListCtrl::SetColumn
1183 // Gets the column width
1184 int wxListCtrl::GetColumnWidth ( int nCol
) const
1186 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), nCol
);
1190 return((int)pFieldInfo
->cxWidth
);
1191 } // end of wxListCtrl::GetColumnWidth
1193 // Sets the column width
1194 bool wxListCtrl::SetColumnWidth ( int nCol
, int nWidth
)
1197 int nWidth2
= nWidth
;
1199 if (GetWindowStyleFlag() & wxLC_LIST
)
1202 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1203 pFieldInfo
->cxWidth
= nWidth
;
1204 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1206 } // end of wxListCtrl::SetColumnWidth
1208 // Gets the number of items that can fit vertically in the
1209 // visible area of the list control (list or report view)
1210 // or the total number of items in the list control (icon
1211 // or small icon view)
1212 int wxListCtrl::GetCountPerPage () const
1214 QUERYRECORDRECT vQueryRect
;
1220 if (!::WinSendMsg( GetHWND()
1223 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1226 memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
));
1227 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1228 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
1229 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1230 else if (vCnrInfo
.flWindowAttr
& CV_NAME
)
1231 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1232 else if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
1233 vQueryRect
.fsExtent
= CMA_TEXT
;
1234 else if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
1235 vQueryRect
.fsExtent
= CMA_TEXT
;
1236 if (!::WinSendMsg( GetHWND()
1238 ,MPFROMP(&vRectRecord
)
1239 ,MPFROMP(&vQueryRect
)
1242 if (!::WinSendMsg( GetHWND()
1243 ,CM_QUERYVIEWPORTRECT
1244 ,MPFROMP(&vRectControl
)
1245 ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
)
1248 nCount
= (int)((int)((vRectControl
.xRight
- vRectControl
.xLeft
) / (vRectRecord
.xRight
- vRectRecord
.xLeft
)) *
1249 (int)((vRectControl
.yTop
- vRectControl
.yBottom
) / (vRectRecord
.yTop
- vRectRecord
.yBottom
))
1251 if (nCount
> (int)vCnrInfo
.cFields
)
1252 nCount
= (int)vCnrInfo
.cFields
;
1254 } // end of wxListCtrl::GetCountPerPage
1256 // Gets the edit control for editing labels.
1257 wxTextCtrl
* wxListCtrl::GetEditControl() const
1262 // Gets information about the item
1263 bool wxListCtrl::GetItem ( wxListItem
& rInfo
) const
1265 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() );
1268 // Give NULL as hwnd as we already have everything we need
1270 ConvertFromOS2ListItem( NULL
, rInfo
, pRecord
);
1272 } // end of wxListCtrl::GetItem
1274 // Sets information about the item
1275 bool wxListCtrl::SetItem ( wxListItem
& rInfo
)
1277 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), rInfo
.GetColumn() );
1278 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() );
1280 ConvertToOS2ListItem( this
1287 // Check if setting attributes or lParam
1289 if (rInfo
.HasAttributes() || (rInfo
.GetMask() & wxLIST_MASK_DATA
))
1292 // Get internal item data
1293 // perhaps a cache here ?
1295 CListItemInternalData
* pData
= GetInternalData( this
1304 m_bAnyInternalData
= true;
1305 pData
= new CListItemInternalData();
1306 pRecord
->m_ulUserData
= (unsigned long)pData
;
1312 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
1313 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
1316 if (rInfo
.HasAttributes())
1319 *pData
->m_pAttr
= *rInfo
.GetAttributes();
1321 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
1323 pData
->m_pMyRecord
= pRecord
; // they point to each other
1327 // We need to update the item immediately to show the new image
1329 bool bUpdateNow
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0;
1332 // Check whether it has any custom attributes
1334 if (rInfo
.HasAttributes())
1336 m_bHasAnyAttr
= true;
1339 // If the colour has changed, we must redraw the item
1343 if (::WinIsWindowVisible(GetHWND()))
1345 ::WinSendMsg( GetHWND()
1346 ,CM_INVALIDATERECORD
1348 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1350 RefreshItem(pRecord
->m_ulItemId
);
1352 ::WinSendMsg( GetHWND()
1353 ,CM_INVALIDATEDETAILFIELDINFO
1358 } // end of wxListCtrl::SetItem
1360 long wxListCtrl::SetItem (
1363 , const wxString
& rsLabel
1369 vInfo
.m_text
= rsLabel
;
1370 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1371 vInfo
.m_itemId
= lIndex
;
1375 vInfo
.m_image
= nImageId
;
1376 vInfo
.m_mask
|= wxLIST_MASK_IMAGE
;
1378 return SetItem(vInfo
);
1379 } // end of wxListCtrl::SetItem
1381 // Gets the item state
1382 int wxListCtrl::GetItemState (
1389 vInfo
.m_mask
= wxLIST_MASK_STATE
;
1390 vInfo
.m_stateMask
= lStateMask
;
1391 vInfo
.m_itemId
= lItem
;
1393 if (!GetItem(vInfo
))
1395 return vInfo
.m_state
;
1396 } // end of wxListCtrl::GetItemState
1398 // Sets the item state
1399 bool wxListCtrl::SetItemState ( long lItem
, long lState
, long lStateMask
)
1401 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1404 // Don't use SetItem() here as it doesn't work with the virtual list
1407 ConvertToOS2Flags( lState
, pRecord
);
1410 // for the virtual list controls we need to refresh the previously focused
1411 // item manually when changing focus without changing selection
1412 // programmatically because otherwise it keeps its focus rectangle until
1413 // next repaint (yet another comctl32 bug)
1418 (lStateMask
& wxLIST_STATE_FOCUSED
) &&
1419 (lState
& wxLIST_STATE_FOCUSED
) )
1421 lFocusOld
= GetNextItem( -1
1423 ,wxLIST_STATE_FOCUSED
1430 ::WinSendMsg( GetHWND()
1431 ,CM_INVALIDATERECORD
1433 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1436 if (lFocusOld
!= -1)
1439 // No need to refresh the item if it was previously selected, it would
1440 // only result in annoying flicker
1442 if (!(GetItemState( lFocusOld
1443 ,wxLIST_STATE_SELECTED
1444 ) & wxLIST_STATE_SELECTED
))
1446 RefreshItem(lFocusOld
);
1450 } // end of wxListCtrl::SetItemState
1452 // Sets the item image
1453 bool wxListCtrl::SetItemImage (
1456 , int WXUNUSED(nSelImage
))
1458 return SetItemColumnInfo(lItem
, 0, nImage
);
1459 } // end of wxListCtrl::SetItemImage
1461 // Sets the item image
1462 bool wxListCtrl::SetItemColumnImage (
1469 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
1470 vInfo
.m_image
= nImage
;
1471 vInfo
.m_itemId
= lItem
;
1472 vInfo
.m_col
= lColumn
;
1473 return SetItem(vInfo
);
1474 } // end of wxListCtrl::SetItemColumnImage
1476 // Gets the item text
1477 wxString
wxListCtrl::GetItemText (
1483 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1484 vInfo
.m_itemId
= lItem
;
1486 if (!GetItem(vInfo
))
1487 return wxEmptyString
;
1488 return vInfo
.m_text
;
1489 } // end of wxListCtrl::GetItemText
1491 // Sets the item text
1492 void wxListCtrl::SetItemText (
1494 , const wxString
& rsStr
1499 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1500 vInfo
.m_itemId
= lItem
;
1501 vInfo
.m_text
= rsStr
;
1503 } // end of wxListCtrl::SetItemText
1505 // Gets the item data
1506 long wxListCtrl::GetItemData (
1512 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1513 vInfo
.m_itemId
= lItem
;
1514 if (!GetItem(vInfo
))
1516 return vInfo
.m_data
;
1517 } // end of wxListCtrl::GetItemData
1519 // Sets the item data
1520 bool wxListCtrl::SetItemPtrData (
1527 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1528 vInfo
.m_itemId
= lItem
;
1529 vInfo
.m_data
= lData
;
1530 return SetItem(vInfo
);
1531 } // end of wxListCtrl::SetItemPtrData
1533 // Gets the item rectangle
1534 bool wxListCtrl::GetItemRect ( long lItem
,
1539 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1540 QUERYRECORDRECT vQueryRect
;
1546 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1547 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1548 vQueryRect
.fRightSplitWindow
= TRUE
;
1549 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1550 ::WinSendMsg( GetHWND()
1553 ,MPFROMP(&vQueryRect
)
1556 // remember OS/2 is backwards
1558 GetClientSize( NULL
, &nHeight
);
1559 rRect
.x
= vRect
.xLeft
;
1560 rRect
.y
= nHeight
- vRect
.yTop
;
1561 rRect
.width
= vRect
.xRight
;
1562 rRect
.height
= nHeight
- vRect
.yBottom
;
1565 } // end of wxListCtrl::GetItemRect
1567 // Gets the item position
1568 bool wxListCtrl::GetItemPosition ( long lItem
, wxPoint
& rPos
) const
1571 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND() , lItem
);
1572 QUERYRECORDRECT vQueryRect
;
1578 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1579 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1580 vQueryRect
.fRightSplitWindow
= TRUE
;
1581 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1582 ::WinSendMsg( GetHWND()
1585 ,MPFROMP(&vQueryRect
)
1588 // remember OS/2 is backwards
1590 GetClientSize( NULL
, &nHeight
);
1591 rPos
.x
= vRect
.xLeft
;
1592 rPos
.y
= nHeight
- vRect
.yTop
;
1595 } // end of wxListCtrl::GetItemPosition
1597 // Sets the item position.
1598 bool wxListCtrl::SetItemPosition ( long lItem
, const wxPoint
& rPos
)
1601 // Items cannot be positioned in X/Y coord in OS/2
1604 } // end of wxListCtrl::SetItemPosition
1606 // Gets the number of items in the list control
1607 int wxListCtrl::GetItemCount () const
1611 if (!::WinSendMsg( GetHWND()
1614 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1617 return vCnrInfo
.cRecords
;
1618 } // end of wxListCtrl::GetItemCount
1620 // Retrieves the spacing between icons in pixels.
1621 // If bIsSmall is true, gets the spacing for the small icon
1622 // view, otherwise the large icon view.
1623 int wxListCtrl::GetItemSpacing ( bool bIsSmall
) const
1627 if (!::WinSendMsg( GetHWND()
1630 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1633 return vCnrInfo
.cyLineSpacing
;
1634 } // end of wxListCtrl::GetItemSpacing
1636 void wxListCtrl::SetItemTextColour (
1638 , const wxColour
& rCol
1643 vInfo
.m_itemId
= lItem
;
1644 vInfo
.SetTextColour(rCol
);
1646 } // end of wxListCtrl::SetItemTextColour
1648 wxColour
wxListCtrl::GetItemTextColour (
1654 vInfo
.m_itemId
= lItem
;
1656 return vInfo
.GetTextColour();
1657 } // end of wxListCtrl::GetItemTextColour
1659 void wxListCtrl::SetItemBackgroundColour (
1661 , const wxColour
& rCol
1666 vInfo
.m_itemId
= lItem
;
1667 vInfo
.SetBackgroundColour(rCol
);
1669 } // end of wxListCtrl::SetItemBackgroundColour
1671 wxColour
wxListCtrl::GetItemBackgroundColour (
1677 vInfo
.m_itemId
= lItem
;
1679 return vInfo
.GetBackgroundColour();
1680 } // end of wxListCtrl::GetItemBackgroundColour
1682 // Gets the number of selected items in the list control
1683 int wxListCtrl::GetSelectedItemCount () const
1685 PMYRECORD pRecord
= NULL
;
1687 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1688 ,CM_QUERYRECORDEMPHASIS
1690 ,(MPARAM
)CRA_SELECTED
1698 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1699 ,CM_QUERYRECORDEMPHASIS
1701 ,(MPARAM
)CRA_SELECTED
1707 } // end of wxListCtrl::GetSelectedItemCount
1709 // Gets the text colour of the listview
1710 wxColour
wxListCtrl::GetTextColour () const
1715 ::WinQueryPresParam( GetHWND()
1725 } // end of wxListCtrl::GetTextColour
1727 // Sets the text colour of the listview
1728 void wxListCtrl::SetTextColour (
1729 const wxColour
& rCol
1732 ULONG ulColor
= wxColourToRGB(rCol
);
1734 ::WinSetPresParam( GetHWND()
1739 } // end of wxListCtrl::SetTextColour
1741 // Gets the index of the topmost visible item when in
1742 // list or report view
1743 long wxListCtrl::GetTopItem () const
1745 PMYRECORD pRecord
= NULL
;
1746 QUERYRECFROMRECT vQueryRect
;
1749 ::WinSendMsg( GetHWND()
1750 ,CM_QUERYVIEWPORTRECT
1752 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1754 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1755 vQueryRect
.rect
= vRect
;
1756 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1758 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1759 ,CM_QUERYRECORDFROMRECT
1761 ,MPFROMP(&vQueryRect
)
1766 return (long)pRecord
->m_ulItemId
;
1767 } // end of wxListCtrl::GetTopItem
1769 // Searches for an item, starting from 'item'.
1770 // 'geometry' is one of
1771 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
1772 // 'state' is a state bit flag, one or more of
1773 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
1774 // item can be -1 to find the first item that matches the
1776 // Returns the item or -1 if unsuccessful.
1777 long wxListCtrl::GetNextItem (
1779 , int WXUNUSED(nGeom
)
1780 , int WXUNUSED(nState
)
1783 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1787 pRecord
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
;
1789 return((long)pRecord
->m_ulItemId
);
1791 } // end of wxListCtrl::GetNextItem
1793 wxImageList
* wxListCtrl::GetImageList (
1797 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1799 return m_pImageListNormal
;
1801 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1803 return m_pImageListSmall
;
1805 else if (nWhich
== wxIMAGE_LIST_STATE
)
1807 return m_pImageListState
;
1810 } // end of wxListCtrl::GetImageList
1812 void wxListCtrl::SetImageList ( wxImageList
* pImageList
,
1815 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1817 if (m_bOwnsImageListNormal
)
1818 delete m_pImageListNormal
;
1819 m_pImageListNormal
= pImageList
;
1820 m_bOwnsImageListNormal
= false;
1822 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1824 if (m_bOwnsImageListSmall
)
1825 delete m_pImageListSmall
;
1826 m_pImageListSmall
= pImageList
;
1827 m_bOwnsImageListSmall
= false;
1829 else if (nWhich
== wxIMAGE_LIST_STATE
)
1831 if (m_bOwnsImageListState
)
1832 delete m_pImageListState
;
1833 m_pImageListState
= pImageList
;
1834 m_bOwnsImageListState
= false;
1836 } // end of wxListCtrl::SetImageList
1838 void wxListCtrl::AssignImageList ( wxImageList
* pImageList
, int nWhich
)
1840 SetImageList( pImageList
, nWhich
);
1842 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1843 m_bOwnsImageListNormal
= true;
1844 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1845 m_bOwnsImageListSmall
= true;
1846 else if (nWhich
== wxIMAGE_LIST_STATE
)
1847 m_bOwnsImageListState
= true;
1848 } // end of wxListCtrl::AssignImageList
1850 // ----------------------------------------------------------------------------
1852 // ----------------------------------------------------------------------------
1854 // Arranges the items
1855 bool wxListCtrl::Arrange ( int nFlag
)
1860 if (nFlag
== wxLIST_ALIGN_SNAP_TO_GRID
)
1862 ulType
= CMA_ARRANGEGRID
;
1863 if (nFlag
== wxLIST_ALIGN_LEFT
)
1864 ulFlags
|= CMA_LEFT
;
1865 else if (nFlag
== wxLIST_ALIGN_TOP
)
1867 else if (nFlag
== wxLIST_ALIGN_DEFAULT
)
1868 ulFlags
|= CMA_LEFT
;
1871 ulType
= CMA_ARRANGESTANDARD
;
1872 ::WinSendMsg( GetHWND()
1878 // We do not support CMA_ARRANGESELECTED
1881 } // end of wxListCtrl::Arrange
1884 bool wxListCtrl::DeleteItem ( long lItem
)
1886 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1887 if (LONGFROMMR(::WinSendMsg( GetHWND()
1890 ,MPFROM2SHORT(1, CMA_FREE
)
1897 // The virtual list control doesn't refresh itself correctly, help it
1902 // We need to refresh all the lines below the one which was deleted
1906 if (lItem
> 0 && GetItemCount())
1908 GetItemRect( lItem
- 1
1914 vRectItem
.y
= vRectItem
.height
= 0;
1916 wxRect vRectWin
= GetRect();
1918 vRectWin
.height
= vRectWin
.GetBottom() - vRectItem
.GetBottom();
1919 vRectWin
.y
= vRectItem
.GetBottom();
1920 RefreshRect(vRectWin
);
1923 } // end of wxListCtrl::DeleteItem
1925 // Deletes all items
1926 bool wxListCtrl::DeleteAllItems ()
1928 return((LONG
)::WinSendMsg( GetHWND()
1931 ,MPFROM2SHORT(0, CMA_FREE
)
1933 } // end of wxListCtrl::DeleteAllItems
1935 // Deletes all items
1936 bool wxListCtrl::DeleteAllColumns ()
1938 while (m_nColCount
> 0)
1940 DeleteColumn(m_nColCount
- 1);
1944 wxASSERT_MSG(m_nColCount
== 0, wxT("no columns should be left"));
1946 } // end of wxListCtrl::DeleteAllColumns
1949 bool wxListCtrl::DeleteColumn ( int nCol
)
1951 bool bSuccess
= false;
1952 PFIELDINFO pField
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1953 bSuccess
= ((LONG
)::WinSendMsg( GetHWND()
1954 ,CM_REMOVEDETAILFIELDINFO
1956 ,MPFROM2SHORT((SHORT
)1, CMA_FREE
)
1958 if (bSuccess
&& (m_nColCount
> 0))
1961 } // end of wxListCtrl::DeleteColumn
1963 // Clears items, and columns if there are any.
1964 void wxListCtrl::ClearAll ()
1967 if (m_nColCount
> 0)
1969 } // end of wxListCtrl::ClearAll
1972 // OS/2 does not use a text control for its container labels. You merely
1973 // "open" a record for editting.
1975 wxTextCtrl
* wxListCtrl::EditLabel (
1977 , wxClassInfo
* WXUNUSED(pTextControlClass
)
1981 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1985 vEdit
.cb
= sizeof(CNREDITDATA
);
1986 vEdit
.hwndCnr
= GetHWND();
1987 vEdit
.pRecord
= &pRecord
->m_vRecord
;
1988 vEdit
.pFieldInfo
= NULL
;
1989 vEdit
.ppszText
= NULL
;
1993 ::WinSendMsg( GetHWND()
1999 } // end of wxListCtrl::EditLabel
2001 // End label editing, optionally cancelling the edit. Under OS/2 you close
2002 // the record for editting
2003 bool wxListCtrl::EndEditLabel ( bool WXUNUSED(bCancel
) )
2005 ::WinSendMsg( GetHWND()
2011 } // end of wxListCtrl::EndEditLabel
2013 // Ensures this item is visible
2014 bool wxListCtrl::EnsureVisible ( long lItem
)
2016 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
2017 ::WinSendMsg( GetHWND()
2018 ,CM_INVALIDATERECORD
2020 ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
)
2023 } // end of wxListCtrl::EnsureVisible
2025 // Find an item whose label matches this string, starting from the item after 'start'
2026 // or the beginning if 'start' is -1.
2027 long wxListCtrl::FindItem (
2029 , const wxString
& rsStr
2034 SEARCHSTRING vSearch
;
2035 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2041 if (!::WinSendMsg( GetHWND()
2044 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2048 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
2050 if (vCnrInfo
.flWindowAttr
& CV_NAME
)
2052 if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
2054 if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
2057 ulFlag
|= CV_EXACTLENGTH
;
2059 vSearch
.cb
= sizeof(SEARCHSTRING
);
2060 vSearch
.pszSearch
= (char*)rsStr
.c_str();
2061 vSearch
.fsPrefix
= TRUE
;
2062 vSearch
.fsCaseSensitive
= TRUE
;
2063 vSearch
.usView
= ulFlag
;
2067 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2075 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2083 return pRecord
->m_ulItemId
;
2084 } // end of wxListCtrl::FindItem
2086 // Find an item whose data matches this data, starting from the item after 'start'
2087 // or the beginning if 'start' is -1.
2088 long wxListCtrl::FindItem (
2093 long lIdx
= lStart
+ 1;
2094 long lCount
= GetItemCount();
2096 while (lIdx
< lCount
)
2098 if (GetItemData(lIdx
) == lData
)
2103 } // end of wxListCtrl::FindItem
2105 // Find an item nearest this position in the specified direction, starting from
2106 // the item after 'start' or the beginning if 'start' is -1.
2107 long wxListCtrl::FindItem (
2109 , const wxPoint
& rPoint
2114 QUERYRECORDRECT vQueryRect
;
2115 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2122 if (!::WinSendMsg( GetHWND()
2125 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2129 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
2130 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
2131 vQueryRect
.fRightSplitWindow
= TRUE
;
2132 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
2134 ::WinSendMsg( GetHWND()
2137 ,MPFROMP(&vQueryRect
)
2139 vLibRect
.SetLeft(vRect
.xLeft
);
2140 vLibRect
.SetTop(vRect
.yTop
);
2141 vLibRect
.SetRight(vRect
.xRight
);
2142 vLibRect
.SetBottom(vRect
.yBottom
);
2143 if (vLibRect
.Contains(rPoint
))
2144 return pRecord
->m_ulItemId
;
2146 for (i
= lStart
+ 1; i
< vCnrInfo
.cRecords
; i
++)
2148 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
2151 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
2153 vQueryRect
.pRecord
= (PRECORDCORE
)pRecord
;
2154 ::WinSendMsg( GetHWND()
2157 ,MPFROMP(&vQueryRect
)
2159 vLibRect
.SetLeft(vRect
.xLeft
);
2160 vLibRect
.SetTop(vRect
.yTop
);
2161 vLibRect
.SetRight(vRect
.xRight
);
2162 vLibRect
.SetBottom(vRect
.yBottom
);
2163 if (vLibRect
.Contains(rPoint
))
2164 return pRecord
->m_ulItemId
;
2167 } // end of wxListCtrl::FindItem
2169 // Determines which item (if any) is at the specified point,
2170 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
2171 long wxListCtrl::HitTest (
2172 const wxPoint
& rPoint
2173 , int& WXUNUSED(rFlags
)
2176 PMYRECORD pRecord
= NULL
;
2177 QUERYRECFROMRECT vQueryRect
;
2182 // Get height for OS/2 point conversion
2184 ::WinSendMsg( GetHWND()
2185 ,CM_QUERYVIEWPORTRECT
2187 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
2189 lHeight
= vRect
.yTop
- vRect
.yBottom
;
2192 // For now just try and get a record in the general vicinity and forget
2195 vRect
.xLeft
= rPoint
.x
- 2;
2196 vRect
.xRight
= rPoint
.x
+ 2;
2197 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
2198 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
2200 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
2201 vQueryRect
.rect
= vRect
;
2202 vQueryRect
.fsSearch
= CMA_PARTIAL
;
2204 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2205 ,CM_QUERYRECORDFROMRECT
2207 ,MPFROMP(&vQueryRect
)
2212 return pRecord
->m_ulItemId
;
2213 } // end of wxListCtrl::HitTest
2215 // Inserts an item, returning the index of the new item if successful,
2217 long wxListCtrl::InsertItem (
2221 wxASSERT_MSG( !IsVirtual(), wxT("can't be used with virtual controls") );
2223 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
2226 PMYRECORD pRecordAfter
= NULL
;
2227 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2229 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
2233 ConvertToOS2ListItem( this
2239 if (rInfo
.GetId() > 0)
2240 pRecordAfter
= FindOS2ListRecordByID( GetHWND()
2244 RECORDINSERT vInsert
;
2246 vInsert
.cb
= sizeof(RECORDINSERT
);
2247 vInsert
.pRecordParent
= NULL
;
2249 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
2251 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
2252 vInsert
.zOrder
= CMA_TOP
;
2253 vInsert
.cRecordsInsert
= 1;
2254 vInsert
.fInvalidateRecord
= TRUE
;
2257 // Check wether we need to allocate our internal data
2259 bool bNeedInternalData
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) ||
2260 rInfo
.HasAttributes()
2262 if (bNeedInternalData
)
2264 m_bAnyInternalData
= true;
2267 // Internal stucture that manages data
2269 CListItemInternalData
* pData
= new CListItemInternalData();
2271 pRecord
->m_ulUserData
= (unsigned long)pData
;
2272 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
2273 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
2276 // Check whether it has any custom attributes
2278 if (rInfo
.HasAttributes())
2281 // Take copy of attributes
2283 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
2286 if (!::WinSendMsg( GetHWND()
2293 // OS/2 must mannually bump the index's of following records
2295 BumpRecordIds( GetHWND()
2298 ::WinSendMsg( GetHWND()
2299 ,CM_INVALIDATEDETAILFIELDINFO
2303 return pRecord
->m_ulItemId
;
2304 } // end of wxListCtrl::InsertItem
2306 long wxListCtrl::InsertItem (
2308 , const wxString
& rsLabel
2313 memset(&vInfo
, '\0', sizeof(wxListItem
));
2314 vInfo
.m_text
= rsLabel
;
2315 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
2316 vInfo
.m_itemId
= lIndex
;
2317 return InsertItem(vInfo
);
2318 } // end of wxListCtrl::InsertItem
2320 // Inserts an image item
2321 long wxListCtrl::InsertItem (
2328 vInfo
.m_image
= nImageIndex
;
2329 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
2330 vInfo
.m_itemId
= lIndex
;
2331 return InsertItem(vInfo
);
2332 } // end of wxListCtrl::InsertItem
2334 // Inserts an image/string item
2335 long wxListCtrl::InsertItem (
2337 , const wxString
& rsLabel
2343 vInfo
.m_image
= nImageIndex
;
2344 vInfo
.m_text
= rsLabel
;
2345 vInfo
.m_mask
= wxLIST_MASK_IMAGE
| wxLIST_MASK_TEXT
;
2346 vInfo
.m_itemId
= lIndex
;
2347 return InsertItem(vInfo
);
2348 } // end of wxListCtrl::InsertItem
2350 // For details view mode (only), inserts a column.
2351 long wxListCtrl::InsertColumn (
2357 PFIELDINFO pField
= (PFIELDINFO
)::WinSendMsg( GetHWND()
2358 ,CM_ALLOCDETAILFIELDINFO
2362 PFIELDINFO pFieldAfter
= FindOS2ListFieldByColNum ( GetHWND()
2365 FIELDINFOINSERT vInsert
;
2367 ConvertToOS2ListCol ( lCol
2372 vInsert
.cb
= sizeof(FIELDINFOINSERT
);
2373 vInsert
.pFieldInfoOrder
= pFieldAfter
;
2374 vInsert
.fInvalidateFieldInfo
= TRUE
;
2375 vInsert
.cFieldInfoInsert
= 1;
2377 bSuccess
= ::WinSendMsg( GetHWND()
2378 ,CM_INSERTDETAILFIELDINFO
2383 } // end of wxListCtrl::InsertColumn
2385 long wxListCtrl::InsertColumn (
2387 , const wxString
& rsHeading
2394 vItem
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
2395 vItem
.m_text
= rsHeading
;
2398 vItem
.m_mask
|= wxLIST_MASK_WIDTH
;
2399 vItem
.m_width
= nWidth
;
2401 vItem
.m_format
= nFormat
;
2403 return InsertColumn( lCol
2406 } // end of wxListCtrl::InsertColumn
2408 // scroll the control by the given number of pixels (exception: in list view,
2409 // dx is interpreted as number of columns)
2410 bool wxListCtrl::ScrollList ( int nDx
, int nDy
)
2413 ::WinSendMsg( GetHWND()
2415 ,(MPARAM
)CMA_HORIZONTAL
2419 ::WinSendMsg( GetHWND()
2421 ,(MPARAM
)CMA_VERTICAL
2425 } // end of wxListCtrl::ScrollList
2427 bool wxListCtrl::SortItems ( wxListCtrlCompare fn
, long lData
)
2429 SInternalDataSort vInternalData
;
2431 vInternalData
.m_fnUser
= fn
;
2432 vInternalData
.m_lData
= lData
;
2434 // WPARAM cast is needed for mingw/cygwin
2435 if (!::WinSendMsg( GetHWND()
2437 ,(PFN
)InternalDataCompareFunc
2438 ,(PVOID
)&vInternalData
2441 wxLogDebug(wxT("CM_SORTRECORD failed"));
2445 } // end of wxListCtrl::SortItems
2447 // ----------------------------------------------------------------------------
2448 // message processing
2449 // ----------------------------------------------------------------------------
2451 bool wxListCtrl::OS2Command ( WXUINT uCmd
, WXWORD wId
)
2453 if (uCmd
== CN_ENDEDIT
)
2455 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
, wId
);
2457 vEvent
.SetEventObject( this );
2458 ProcessCommand(vEvent
);
2461 else if (uCmd
== CN_KILLFOCUS
)
2463 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
, wId
);
2464 vEvent
.SetEventObject( this );
2465 ProcessCommand(vEvent
);
2470 } // end of wxListCtrl::OS2Command
2472 // Necessary for drawing hrules and vrules, if specified
2473 void wxListCtrl::OnPaint ( wxPaintEvent
& rEvent
)
2475 wxPaintDC
vDc(this);
2476 wxPen
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
)
2480 wxSize vClientSize
= GetClientSize();
2482 int nItemCount
= GetItemCount();
2485 bool bDrawHRules
= ((GetWindowStyle() & wxLC_HRULES
) != 0);
2486 bool bDrawVRules
= ((GetWindowStyle() & wxLC_VRULES
) != 0);
2488 wxControl::OnPaint(rEvent
);
2491 // Reset the device origin since it may have been set
2493 vDc
.SetDeviceOrigin(0, 0);
2494 if (!bDrawHRules
&& !bDrawVRules
)
2496 if ((GetWindowStyle() & wxLC_REPORT
) == 0)
2499 vDc
.SetBrush(*wxTRANSPARENT_BRUSH
);
2503 long lTop
= GetTopItem();
2505 for (i
= lTop
; i
< lTop
+ GetCountPerPage() + 1; i
++)
2511 nCy
= vItemRect
.GetTop();
2512 if (i
!= 0) // Don't draw the first one
2521 if (i
== nItemCount
- 1)
2523 nCy
= vItemRect
.GetBottom();
2534 if (bDrawVRules
&& (i
> -1))
2536 wxRect vFirstItemRect
;
2546 int nX
= vItemRect
.GetX();
2548 for (nCol
= 0; nCol
< GetColumnCount(); nCol
++)
2550 int nColWidth
= GetColumnWidth(nCol
);
2553 vDc
.DrawLine( nX
- 1
2554 ,vFirstItemRect
.GetY() - 2
2556 ,vItemRect
.GetBottom()
2561 } // end of wxListCtrl::OnPaint
2563 // ----------------------------------------------------------------------------
2564 // virtual list controls
2565 // ----------------------------------------------------------------------------
2567 wxString
wxListCtrl::OnGetItemText (
2568 long WXUNUSED(lItem
)
2569 , long WXUNUSED(lCol
)
2572 // this is a pure virtual function, in fact - which is not really pure
2573 // because the controls which are not virtual don't need to implement it
2574 wxFAIL_MSG( wxT("not supposed to be called") );
2575 return wxEmptyString
;
2576 } // end of wxListCtrl::OnGetItemText
2578 int wxListCtrl::OnGetItemImage (
2579 long WXUNUSED(lItem
)
2583 wxFAIL_MSG( wxT("not supposed to be called") );
2585 } // end of wxListCtrl::OnGetItemImage
2587 int wxListCtrl::OnGetItemColumnImage (
2593 return OnGetItemImage(lItem
);
2596 } // end of wxListCtrl::OnGetItemColumnImage
2598 wxListItemAttr
* wxListCtrl::OnGetItemAttr (
2599 long WXUNUSED_UNLESS_DEBUG(lItem
)
2602 wxASSERT_MSG( lItem
>= 0 && lItem
< GetItemCount(),
2603 wxT("invalid item index in OnGetItemAttr()") );
2606 // No attributes by default
2609 } // end of wxListCtrl::OnGetItemAttr
2611 void wxListCtrl::SetItemCount (
2615 wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") );
2618 // Cannot explicitly set the record count in OS/2
2620 } // end of wxListCtrl::SetItemCount
2622 void wxListCtrl::RefreshItem (
2632 } // end of wxListCtrl::RefreshItem
2634 void wxListCtrl::RefreshItems ( long lItemFrom
, long lItemTo
)
2639 GetItemRect( lItemFrom
, vRect1
);
2640 GetItemRect( lItemTo
, vRect2
);
2642 wxRect vRect
= vRect1
;
2644 vRect
.height
= vRect2
.GetBottom() - vRect1
.GetTop();
2646 } // end of wxListCtrl::RefreshItems
2648 MRESULT
wxListCtrl::OS2WindowProc( WXUINT uMsg
,
2652 bool bProcessed
= false;
2654 wxListEvent
vEvent( wxEVT_NULL
2657 wxEventType vEventType
= wxEVT_NULL
;
2658 PCNRDRAGINIT pDragInit
= NULL
;
2659 PCNREDITDATA pEditData
= NULL
;
2660 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
2662 vEvent
.SetEventObject(this);
2667 // First off let's set some internal data
2669 switch(SHORT2FROMMP(wParam
))
2675 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)lParam
;
2679 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2681 pItem
->SetData((long)pInternaldata
->m_lParam
);
2687 // Now let's go through the codes we're interested in
2689 switch(SHORT2FROMMP(wParam
))
2692 pDragInit
= (PCNRDRAGINIT
)lParam
;
2695 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2697 vEventType
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
;
2698 vEvent
.m_itemIndex
= pRecord
->m_ulItemId
;
2699 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2700 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2705 pEditData
= (PCNREDITDATA
)lParam
;
2708 vEventType
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
;
2709 ConvertFromOS2ListItem( GetHWND()
2710 ,(wxListItem
&)vEvent
.GetItem()
2711 ,(PMYRECORD
)pEditData
->pRecord
2713 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2718 pEditData
= (PCNREDITDATA
)lParam
;
2721 vEventType
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
;
2722 ConvertFromOS2ListItem( GetHWND()
2723 ,(wxListItem
&)vEvent
.GetItem()
2724 ,(PMYRECORD
)pEditData
->pRecord
2726 if (pEditData
->cbText
== 0)
2727 return (MRESULT
)FALSE
;
2728 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2733 pNotifyEnter
= (PNOTIFYRECORDENTER
)lParam
;
2736 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2737 PMYRECORD pMyRecord
= (PMYRECORD
)pNotifyEnter
->pRecord
;
2739 vEventType
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
;
2740 vEvent
.m_itemIndex
= pMyRecord
->m_ulItemId
;
2741 pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
));
2742 pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
));
2747 // Add the CN_DROP messages for Direct Manipulation
2750 vEvent
.SetEventType(vEventType
);
2751 bProcessed
= HandleWindowEvent(vEvent
);
2755 lRc
= wxControl::OS2WindowProc( uMsg
2760 } // end of wxListCtrl::WindowProc
2762 #endif // wxUSE_LISTCTRL