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