1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/listctrl.cpp
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
33 #include "wx/settings.h"
34 #include "wx/dcclient.h"
35 #include "wx/textctrl.h"
38 #include "wx/imaglist.h"
39 #include "wx/listctrl.h"
41 #include "wx/os2/private.h"
44 // FIELDOFFSET in DETAIL view as defined in the OS2TK45 simply doesn't work
45 // We use this, which does!
48 #define FIELDOFFSET(type, field) ((ULONG)&(((type *)0)->field))
50 // ----------------------------------------------------------------------------
51 // private helper classes
52 // ----------------------------------------------------------------------------
54 /////////////////////////////////////////////////////////////////////////////
56 // Under OS/2 we have to use our own RECORDCORE based struct if we have
57 // user data to store in a PM Container Control (and wxListCtrl is a PM
58 // Container in ICON, NAME, TEXT or DETAIL view). m_ulUserData is a four
59 // byte value containing a pointer to our CListIntemInternalData class
62 // And now for the big time OS/2 Kludge. In traditional OS/2 PM
63 // applications using containers, programmers determine BEFORE creation
64 // how many records the view will have, initially, and how many columns
65 // the detail view of the container will have, as the container represents
66 // a known data block. Thus the OS/2 PM CV_DETAIL view, i.e.
67 // the wxWidgets wxLC_REPORT view, relies on STATIC structure for its
68 // columnar data. It gets the data to display by telling it the specific
69 // offset of the field in the struct containing the displayable data. That
70 // data has be of OS/2 Types, PSZ (char string), CDATE or CTIME format.
71 // wxWidgets is dynamic in nature, however. We insert columns, one at a
72 // time and do not know how many until the app is done inserting them. So
73 // for OS/2 I have to set a max allowable since they are fixed. We return
74 // an error to the app if they include more than we can handle.
76 // For example to display the data "Col 4 of Item 6" in a report view, I'd
78 // pRecord->m_pzColumn4 = "Col 4 of Item 6";
79 // pField->offStruct = FIELDOFFSET(MYRECORD, m_pzColumn4);
80 // and then call the PM API to set it.
82 // This really stinks but I can't use a pointer to another struct as the
83 // FIELDOFFSET call could only tell OS/2 the four byte value offset of
84 // pointer field and it would display giberish in the column.
85 /////////////////////////////////////////////////////////////////////////////
86 typedef struct _MYRECORD
89 unsigned long m_ulItemId
;
90 unsigned long m_ulUserData
; //actually a pointer value to real data (a CListItemInternalData class instance)
101 } MYRECORD
, *PMYRECORD
;
103 /////////////////////////////////////////////////////////////////////////////
104 // CLASS CListItemInternalData
107 // The MSW version had problems with SetTextColour() et al as the
108 // CListItemAttr's were stored keyed on the item index. If a item was
109 // inserted anywhere but the end of the list the the text attributes
110 // (colour etc) for the following items were out of sync.
113 // Under MSW the only way to associate data with a
114 // List item independent of its position in the list is to store a pointer
115 // to it in its lParam attribute. However user programs are already using
116 // this (via the SetItemData() GetItemData() calls).
118 // However what we can do is store a pointer to a structure which contains
119 // the attributes we want *and* a lParam for the users data, e.g.
121 // class CListItemInternalData
124 // GuiAdvCtrl_CListItemAttr* pAttr;
125 // long lParam; // user data
128 // To conserve memory, a CListItemInternalData is only allocated for a
129 // LV_ITEM if text attributes or user data(lparam) are being set.
131 // For OS/2, the lParam value points to whatever actual data we have
132 /////////////////////////////////////////////////////////////////////////////
133 class CListItemInternalData
137 CListItemInternalData(): m_pAttr(NULL
)
141 ~CListItemInternalData()
147 wxListItemAttr
* m_pAttr
;
148 WXLPARAM m_lParam
; // user data
149 PMYRECORD m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted
150 }; // end of CLASS CListItemInternalData
152 /////////////////////////////////////////////////////////////////////////////
153 // STRUCT SInternalDataSort
157 // fn is a function which takes 3 long arguments: item1, item2, data.
158 // item1 is the long data associated with a first item (NOT the index).
159 // item2 is the long data associated with a second item (NOT the index).
160 // data is the same value as passed to SortItems.
162 // The return value is a negative number if the first item should precede the
163 // second item, a positive number of the second item should precede the first,
164 // or zero if the two items are equivalent.
166 // data is arbitrary data to be passed to the sort function.
168 // Internal structures for proxying the user compare function
169 // so that we can pass it the *real* user data
170 /////////////////////////////////////////////////////////////////////////////
171 typedef struct internalDataSort
173 wxListCtrlCompare m_fnUser
;
175 } SInternalDataSort
; // end of STRUCT SInternalDataSort
177 // ----------------------------------------------------------------------------
178 // private helper functions
179 // ----------------------------------------------------------------------------
181 /////////////////////////////////////////////////////////////////////////////
183 // FindOS2ListFieldByColNum
185 // There is no way, under OS/2 to get a field in a container by index,
186 // directly, so you must get the first one, then cycle through the list
187 // until you get to where you want to be.
190 // hWnd -- window handle of container to search
191 // lIndex -- index to set
194 // pointer to the FIELDINFO struct at the index in the container record
196 /////////////////////////////////////////////////////////////////////////////
197 PFIELDINFO
FindOS2ListFieldByColNum (
202 PFIELDINFO pFieldInfo
= NULL
;
206 if (!::WinSendMsg( hWnd
209 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
212 for (i
= 0; i
< vCnrInfo
.cFields
; i
++)
215 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
216 ,CM_QUERYDETAILFIELDINFO
221 pFieldInfo
= (PFIELDINFO
)PVOIDFROMMR(::WinSendMsg( hWnd
222 ,CM_QUERYDETAILFIELDINFO
228 if (i
== (ULONG
)lIndex
)
234 } // end of FindOS2ListFieldByColNum
236 /////////////////////////////////////////////////////////////////////////////
238 // FindOS2ListRecordByID
240 // There is no way, under OS/2 to get a record in a container by index,
241 // directly, so you must get the first one, then cycle through the list
242 // until you get to where you want to be.
245 // hWnd -- window handle of container to search
246 // lItemId -- index to set
249 // pointer to the internal RECORDCORE struct at the index in the container
251 /////////////////////////////////////////////////////////////////////////////
252 PMYRECORD
FindOS2ListRecordByID (
257 PMYRECORD pRecord
= NULL
;
261 if (!::WinSendMsg( hWnd
264 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
267 for (i
= 0; i
< vCnrInfo
.cRecords
; i
++)
270 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
273 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
276 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
279 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
283 if (pRecord
->m_ulItemId
== (ULONG
)lItemId
)
287 } // end of FindOS2ListRecordByID
289 /////////////////////////////////////////////////////////////////////////////
293 // Since OS/2 does not keep native record id's but wx insists on inserting
294 // and selecting via ID's, when we insert a record in the middle we need
295 // to bump the id's of each record after the one we just inserted.
298 // hWnd -- window handle of container to search
299 // pRecord -- record after which we starting bumping id's
304 /////////////////////////////////////////////////////////////////////////////
312 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
315 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
318 pRecord
->m_ulItemId
++;
320 } // end of BumpRecordIds
322 /////////////////////////////////////////////////////////////////////////////
326 // Get the internal data given a handle and an id
329 // hWnd -- window handle to the control in which item is located
330 // lItemId -- ID to get
333 // pointer to the internal data
336 // Under OS/2 PM a container item cannot be obtained via a simple index or
337 // id retrieval. We have to walk the record list if we are looking for
338 // a record at a specific index location
339 /////////////////////////////////////////////////////////////////////////////
340 CListItemInternalData
* GetInternalData (
345 PMYRECORD pRecord
= FindOS2ListRecordByID( hWnd
349 // Internal user data is stored AFTER the last field of the RECORDCORE
353 return((CListItemInternalData
*)(pRecord
->m_ulUserData
));
354 } // end of GetInternalData
356 /////////////////////////////////////////////////////////////////////////////
360 // Get the internal data given a pointer to a list control and an id
363 // pCtl -- pointer to control inwhich item is located
364 // lItemId -- ID to get
367 // pointer to the internal data
369 /////////////////////////////////////////////////////////////////////////////
370 CListItemInternalData
* GetInternalData (
375 return(GetInternalData( (HWND
)pCtl
->GetHWND()
378 } // end of GetInternalData
380 /////////////////////////////////////////////////////////////////////////////
382 // DeleteInternalData
384 // Delete the internal data for a record
387 // pCtl -- pointer to the list control containing the record
388 // lItemId -- the record index to delete the internal data from
391 // pointer to the internal data attribute
393 /////////////////////////////////////////////////////////////////////////////
394 void DeleteInternalData (
399 CListItemInternalData
* pData
= GetInternalData( pCtl
404 if (pData
->m_pMyRecord
)
405 pData
->m_pMyRecord
->m_ulUserData
= 0;
408 } // end of DeleteInternalData
410 // #pragma page "GetInternalDataAttr"
411 /////////////////////////////////////////////////////////////////////////////
413 // GetInternalDataAttr
415 // Get the internal data item attribute given a pointer to a list control
419 // pCtl -- pointer to control to set
420 // lItemId -- ID to set
423 // pointer to the internal data attribute
425 /////////////////////////////////////////////////////////////////////////////
426 wxListItemAttr
* GetInternalDataAttr (
431 CListItemInternalData
* pData
= GetInternalData( pCtl
436 return(pData
->m_pAttr
);
439 } // end of GetInternalDataAttr
441 /////////////////////////////////////////////////////////////////////////////
443 // InternalDataCompareFunc
445 // This is compare function we pass to PM. It wraps the real compare
446 // function in SInternalDataSort
449 // p1 -- is the first record structure to compare
450 // p2 -- is the second record structure to compare
451 // lStorage -- is the same value as passed to SortItems.
454 // pointer to the internal data attribute
456 /////////////////////////////////////////////////////////////////////////////
457 SHORT EXPENTRY
InternalDataCompareFunc (
463 SInternalDataSort
* pInternalData
= (SInternalDataSort
*)pStorage
;
464 CListItemInternalData
* pData1
= (CListItemInternalData
*)p1
->m_ulUserData
;
465 CListItemInternalData
* pData2
= (CListItemInternalData
*)p2
->m_ulUserData
;
466 long lD1
= (pData1
== NULL
? 0 : (long)pData1
->m_lParam
);
467 long lD2
= (pData2
== NULL
? 0 : (long)pData2
->m_lParam
);
469 return(pInternalData
->m_fnUser( lD1
471 ,pInternalData
->m_lData
473 } // end of InternalDataCompareFunc
475 /////////////////////////////////////////////////////////////////////////////
477 // ConvertFromOS2ListItem
479 // Convert from an internal PM List item to a Toolkit List item
482 // hWndListCtrl -- the control's windows handle
483 // rInfo -- the library list control to convert to
484 // pRecord -- the OS list control to convert from
489 /////////////////////////////////////////////////////////////////////////////
490 void ConvertFromOS2ListItem ( HWND hWndListCtrl
,
494 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)pRecord
->m_ulUserData
;
495 bool bNeedText
= false;
498 rInfo
.SetData(pInternaldata
->m_lParam
);
502 rInfo
.SetStateMask(0);
503 rInfo
.SetId((long)pRecord
->m_ulItemId
);
504 if (hWndListCtrl
!= 0)
506 pRecord
= FindOS2ListRecordByID( hWndListCtrl
512 // The wxListItem class is really set up to handle the WIN32 list item
513 // and OS/2 are not as complicated. Just set both state members to the
514 // same thing under OS/2
516 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DROPONABLE
)
518 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DROPHILITED
);
519 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DROPHILITED
);
521 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SELECTED
)
523 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SELECTED
);
524 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SELECTED
);
526 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_DISABLED
)
528 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_DISABLED
);
529 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_DISABLED
);
531 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_FILTERED
)
533 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_FILTERED
);
534 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_FILTERED
);
536 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_INUSE
)
538 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_INUSE
);
539 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_INUSE
);
541 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_PICKED
)
543 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_PICKED
);
544 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_PICKED
);
546 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SOURCE
)
548 rInfo
.SetStateMask(rInfo
.m_stateMask
| wxLIST_STATE_SOURCE
);
549 rInfo
.SetState(rInfo
.m_state
| wxLIST_STATE_SOURCE
);
552 if (pRecord
->m_vRecord
.pszText
!= (PSZ
)NULL
)
554 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_TEXT
);
555 rInfo
.SetText(pRecord
->m_vRecord
.pszText
);
557 if (pRecord
->m_vRecord
.pszIcon
!= (PSZ
)NULL
||
558 pRecord
->m_vRecord
.pszName
!= (PSZ
)NULL
)
560 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_IMAGE
);
561 rInfo
.SetImage(pRecord
->m_vRecord
.hptrIcon
);
563 if (pRecord
->m_ulUserData
)
564 rInfo
.SetMask(rInfo
.GetMask() | wxLIST_MASK_DATA
);
565 } // end of ConvertFromOS2ListItem
567 /////////////////////////////////////////////////////////////////////////////
571 // Convert from an library states to OS states
574 // lState -- the state
575 // pRecord -- the OS list control to use
580 /////////////////////////////////////////////////////////////////////////////
581 void ConvertToOS2Flags (
586 if (lState
& wxLIST_STATE_DROPHILITED
)
587 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DROPONABLE
;
588 if (lState
& wxLIST_STATE_SELECTED
)
589 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SELECTED
;
590 if (lState
& wxLIST_STATE_DISABLED
)
591 pRecord
->m_vRecord
.flRecordAttr
|= CRA_DISABLED
;
592 if (lState
& wxLIST_STATE_FILTERED
)
593 pRecord
->m_vRecord
.flRecordAttr
|= CRA_FILTERED
;
594 if (lState
& wxLIST_STATE_INUSE
)
595 pRecord
->m_vRecord
.flRecordAttr
|= CRA_INUSE
;
596 if (lState
& wxLIST_STATE_PICKED
)
597 pRecord
->m_vRecord
.flRecordAttr
|= CRA_PICKED
;
598 if (lState
& wxLIST_STATE_SOURCE
)
599 pRecord
->m_vRecord
.flRecordAttr
|= CRA_SOURCE
;
600 } // end of ConvertToOS2Flags
602 /////////////////////////////////////////////////////////////////////////////
604 // ConvertToOS2ListItem
606 // Convert from a library List item to an internal OS2 List item. We set
607 // only the fields we need to set. Some of them are set by the API when
608 // they are added to the container.
611 // pCtrl -- the control to use
612 // rInfo -- the item to convert
613 // pRecord -- the OS list control to use, should be zeroed out
614 // pFieldinfo -- a field struct that may contain columnar data for detail view
619 /////////////////////////////////////////////////////////////////////////////
620 void ConvertToOS2ListItem (
621 const wxListCtrl
* pCtrl
622 , const wxListItem
& rInfo
624 , PFIELDINFO pFieldInfo
627 pRecord
->m_ulItemId
= (ULONG
)rInfo
.GetId();
628 pRecord
->m_vRecord
.cb
= sizeof(RECORDCORE
);
629 if (rInfo
.GetMask() & wxLIST_MASK_STATE
)
631 ConvertToOS2Flags( rInfo
.m_state
635 if (pCtrl
->GetWindowStyleFlag() & wxLC_ICON
||
636 pCtrl
->GetWindowStyleFlag() & wxLC_SMALL_ICON
)
638 pRecord
->m_vRecord
.pszIcon
= (char*)rInfo
.GetText().c_str();
640 if (pCtrl
->GetWindowStyleFlag() & wxLC_LIST
) // PM TEXT view
642 pRecord
->m_vRecord
.pszText
= (char*)rInfo
.GetText().c_str();
645 // In the case of a report view the text will be the data in the lead column
646 // ???? Don't know why, but that is how it works in other ports.
648 if (pCtrl
->GetWindowStyleFlag() & wxLC_REPORT
)
652 switch(rInfo
.GetColumn())
655 pRecord
->m_pzColumn1
= (char*)rInfo
.GetText().c_str();
656 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn1
);
660 pRecord
->m_pzColumn2
= (char*)rInfo
.GetText().c_str();
661 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn2
);
665 pRecord
->m_pzColumn3
= (char*)rInfo
.GetText().c_str();
666 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn3
);
670 pRecord
->m_pzColumn4
= (char*)rInfo
.GetText().c_str();
671 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn4
);
675 pRecord
->m_pzColumn5
= (char*)rInfo
.GetText().c_str();
676 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn5
);
680 pRecord
->m_pzColumn6
= (char*)rInfo
.GetText().c_str();
681 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn6
);
685 pRecord
->m_pzColumn7
= (char*)rInfo
.GetText().c_str();
686 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn7
);
690 pRecord
->m_pzColumn8
= (char*)rInfo
.GetText().c_str();
691 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn8
);
695 pRecord
->m_pzColumn9
= (char*)rInfo
.GetText().c_str();
696 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn9
);
700 pRecord
->m_pzColumn10
= (char*)rInfo
.GetText().c_str();
701 pFieldInfo
->offStruct
= FIELDOFFSET(MYRECORD
, m_pzColumn10
);
705 wxFAIL_MSG( wxT("wxOS2 does not support more than 10 columns in REPORT view") );
710 if (rInfo
.GetMask() & wxLIST_MASK_IMAGE
)
712 pRecord
->m_vRecord
.hptrIcon
= (HPOINTER
)rInfo
.GetImage();
713 pRecord
->m_vRecord
.hptrMiniIcon
= (HPOINTER
)rInfo
.m_miniImage
;
715 } // end of ConvertToOS2ListItem
717 /////////////////////////////////////////////////////////////////////////////
719 // ConvertToOS2ListCol
721 // Convert from a library List column to an internal PM List column
724 // lCol -- the columnd to convert
725 // rItem -- the item to convert
726 // pField -- the OS list column to use
731 /////////////////////////////////////////////////////////////////////////////
732 void ConvertToOS2ListCol (
734 , const wxListItem
& rItem
738 memset(pField
, '\0', sizeof(FIELDINFO
));
739 pField
->cb
= sizeof(FIELDINFO
);
742 // Default some settings
744 pField
->flData
= CFA_HORZSEPARATOR
| CFA_SEPARATOR
;
745 pField
->flTitle
= CFA_CENTER
;
747 if (rItem
.GetMask() & wxLIST_MASK_TEXT
)
749 pField
->flData
|= CFA_STRING
;
750 pField
->pTitleData
= (PVOID
)rItem
.GetText().c_str(); // text is column title not data
752 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
754 if (rItem
.m_format
== wxLIST_FORMAT_LEFT
)
755 pField
->flData
|= CFA_LEFT
;
756 else if (rItem
.m_format
== wxLIST_FORMAT_RIGHT
)
757 pField
->flData
|= CFA_RIGHT
;
758 else if (rItem
.m_format
== wxLIST_FORMAT_CENTRE
)
759 pField
->flData
|= CFA_CENTER
;
762 pField
->flData
|= CFA_CENTER
; // Just ensure the default is centered
763 if (rItem
.GetMask() & wxLIST_MASK_WIDTH
)
765 if (!(rItem
.GetWidth() == wxLIST_AUTOSIZE
||
766 rItem
.GetWidth() == wxLIST_AUTOSIZE_USEHEADER
))
767 pField
->cxWidth
= rItem
.GetWidth();
768 // else: OS/2 automatically sets the width if created with the approppriate style
772 // Still need to set the actual data
774 pField
->offStruct
= 0;
775 } // end of ConvertToOS2ListCol
778 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
779 IMPLEMENT_DYNAMIC_CLASS(wxListView
, wxListCtrl
)
780 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
782 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
784 BEGIN_EVENT_TABLE(wxListCtrl
, wxControl
)
785 EVT_PAINT(wxListCtrl::OnPaint
)
788 // ============================================================================
790 // ============================================================================
792 // ----------------------------------------------------------------------------
793 // wxListCtrl construction
794 // ----------------------------------------------------------------------------
796 void wxListCtrl::Init ()
798 m_pImageListNormal
= NULL
;
799 m_pImageListSmall
= NULL
;
800 m_pImageListState
= NULL
;
801 m_bOwnsImageListNormal
= false;
802 m_bOwnsImageListSmall
= false;
803 m_bOwnsImageListState
= false;
807 m_bAnyInternalData
= false;
808 m_bHasAnyAttr
= false;
809 } // end of wxListCtrl::Init
811 bool wxListCtrl::Create ( wxWindow
* pParent
,
816 const wxValidator
& rValidator
,
817 const wxString
& rsName
)
821 int nWidth
= rSize
.x
;
822 int nHeight
= rSize
.y
;
825 SetValidator(rValidator
);
826 #endif // wxUSE_VALIDATORS
829 SetWindowStyleFlag(lStyle
);
840 m_windowId
= (vId
== -1) ? NewControlId() : vId
;
842 long lSstyle
= WS_VISIBLE
| WS_TABSTOP
;
844 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS
)
845 lSstyle
|= WS_CLIPSIBLINGS
;
846 m_lBaseStyle
= lSstyle
;
847 if (!DoCreateControl( nX
854 pParent
->AddChild(this);
856 } // end of wxListCtrl::Create
858 bool wxListCtrl::DoCreateControl ( int nX
, int nY
,
859 int nWidth
, int nHeight
)
861 DWORD lWstyle
= m_lBaseStyle
;
862 long lOldStyle
= 0; // Dummy
866 lWstyle
|= ConvertToOS2Style( lOldStyle
867 ,GetWindowStyleFlag()
870 m_hWnd
= (WXHWND
)::WinCreateWindow( GetParent()->GetHWND()
875 ,GetParent()->GetHWND()
887 // Now set the display attributes of the container
889 if (!::WinSendMsg( GetHWND()
892 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
895 lWstyle
= ConvertViewToOS2Style(GetWindowStyleFlag());
896 vCnrInfo
.flWindowAttr
|= lWstyle
;
897 if (!::WinSendMsg( GetHWND()
900 ,(MPARAM
)CMA_FLWINDOWATTR
905 // And now set needed arrangement flags
907 lWstyle
= ConvertArrangeToOS2Style(GetWindowStyleFlag());
908 if (!::WinSendMsg( GetHWND()
910 ,(MPARAM
)CMA_ARRANGEGRID
914 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
915 SetForegroundColour(GetParent()->GetForegroundColour());
917 SetFont(*wxSMALL_FONT
);
920 SetSize( nX
, nY
, nWidth
, nHeight
);
922 } // end of wxListCtrl::DoCreateControl
924 void wxListCtrl::UpdateStyle ()
929 DWORD dwStyleNew
= ConvertToOS2Style( lDummy
, GetWindowStyleFlag() );
931 dwStyleNew
|= m_lBaseStyle
;
934 // Get the current window style.
936 ULONG dwStyleOld
= ::WinQueryWindowULong(GetHWND(), QWL_STYLE
);
939 // Only set the window style if the view bits have changed.
941 if (dwStyleOld
!= dwStyleNew
)
943 ::WinSetWindowULong(GetHWND(), QWL_STYLE
, dwStyleNew
);
946 } // end of wxListCtrl::UpdateStyle
948 void wxListCtrl::FreeAllInternalData ()
950 if (m_bAnyInternalData
)
952 int n
= GetItemCount();
955 for (i
= 0; i
< n
; i
++)
956 DeleteInternalData(this, (long)i
);
957 m_bAnyInternalData
= false;
959 } // end of wxListCtrl::FreeAllInternalData
961 wxListCtrl::~wxListCtrl ()
963 FreeAllInternalData();
966 m_pTextCtrl
->SetHWND(0);
967 m_pTextCtrl
->UnsubclassWin();
972 if (m_bOwnsImageListNormal
)
973 delete m_pImageListNormal
;
974 if (m_bOwnsImageListSmall
)
975 delete m_pImageListSmall
;
976 if (m_bOwnsImageListState
)
977 delete m_pImageListState
;
978 } // end of wxListCtrl::~wxListCtrl
980 // ----------------------------------------------------------------------------
981 // set/get/change style
982 // ----------------------------------------------------------------------------
984 // Add or remove a single window style
985 void wxListCtrl::SetSingleStyle (
990 long lFlag
= GetWindowStyleFlag();
993 // Get rid of conflicting styles
997 if (lStyle
& wxLC_MASK_TYPE
)
998 lFlag
= lFlag
& ~wxLC_MASK_TYPE
;
999 if (lStyle
& wxLC_MASK_ALIGN
)
1000 lFlag
= lFlag
& ~wxLC_MASK_ALIGN
;
1001 if (lStyle
& wxLC_MASK_SORT
)
1002 lFlag
= lFlag
& ~wxLC_MASK_SORT
;
1016 m_windowStyle
= lFlag
;
1018 } // end of wxListCtrl::SetSingleStyle
1020 // Set the whole window style
1021 void wxListCtrl::SetWindowStyleFlag (
1025 m_windowStyle
= lFlag
;
1027 } // end of wxListCtrl::SetWindowStyleFlag
1029 long wxListCtrl::ConvertToOS2Style (
1037 // The only styles OS2 uses on creation are auto arrange, read only, and
1038 // and selection styles. This lib does not support OS/2 MINIRECORDCORE
1039 // or VERIFYPOINTER styles
1041 if (lStyle
& wxLC_AUTOARRANGE
)
1042 lWstyle
|= CCS_AUTOPOSITION
;
1043 if (lStyle
& wxLC_SINGLE_SEL
)
1044 lWstyle
|= CCS_SINGLESEL
;
1046 lWstyle
|= CCS_EXTENDSEL
;
1047 if (!(lStyle
& wxLC_EDIT_LABELS
))
1048 lWstyle
|= CCS_READONLY
;
1050 } // end of wxListCtrl::ConvertToOS2Style
1052 long wxListCtrl::ConvertArrangeToOS2Style (
1058 if (lStyle
& wxLC_ALIGN_LEFT
)
1060 lWstyle
|= CMA_LEFT
;
1063 if (lStyle
& wxLC_ALIGN_TOP
)
1068 } // end of wxListCtrl::ConvertArrangeToOS2Style
1070 long wxListCtrl::ConvertViewToOS2Style (
1074 long lWstyle
= CA_DRAWICON
; // we will only use icons
1076 if (lStyle
& wxLC_ICON
)
1080 if (lStyle
& wxLC_SMALL_ICON
)
1082 lWstyle
|= (CV_ICON
| CV_MINI
);
1084 if (lStyle
& wxLC_LIST
)
1088 if (lStyle
& wxLC_REPORT
)
1090 lWstyle
|= CV_DETAIL
;
1092 if (lStyle
& wxLC_VIRTUAL
)
1094 lWstyle
|= CA_OWNERDRAW
;
1096 if (lStyle
& wxLC_AUTOARRANGE
)
1100 if (!(lStyle
& wxLC_NO_HEADER
))
1102 lWstyle
|= CA_DETAILSVIEWTITLES
;
1105 } // end of wxListCtrl::ConvertViewToOS2Style
1107 // ----------------------------------------------------------------------------
1109 // ----------------------------------------------------------------------------
1111 // Sets the foreground, i.e. text, colour
1112 bool wxListCtrl::SetForegroundColour (const wxColour
& rCol
)
1114 ULONG ulColor
= wxColourToRGB(rCol
);
1116 if (!wxWindow::SetForegroundColour(rCol
))
1119 ::WinSetPresParam( GetHWND()
1125 } // end of wxListCtrl::SetForegroundColour
1127 // Sets the background colour
1128 bool wxListCtrl::SetBackgroundColour ( const wxColour
& rCol
)
1130 if (!wxWindow::SetBackgroundColour(rCol
))
1134 // We set the same colour for both the "empty" background and the items
1137 ULONG ulColor
= wxColourToRGB(rCol
);
1139 ::WinSetPresParam( GetHWND()
1145 } // end of wxListCtrl::SetBackgroundColour
1147 // Gets information about this column
1148 bool wxListCtrl::GetColumn ( int nCol
, wxListItem
& rItem
) const
1150 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), nCol
);
1154 rItem
.SetWidth(pFieldInfo
->cxWidth
);
1155 if ((rItem
.GetMask() & wxLIST_MASK_TEXT
) &&
1156 (pFieldInfo
->flData
& CFA_STRING
) &&
1157 (pFieldInfo
->pUserData
!= NULL
))
1159 rItem
.SetText((char*)pFieldInfo
->pUserData
);
1161 if (rItem
.GetMask() & wxLIST_MASK_FORMAT
)
1163 if (pFieldInfo
->flData
& CFA_LEFT
)
1164 rItem
.m_format
= wxLIST_FORMAT_LEFT
;
1165 else if (pFieldInfo
->flData
& CFA_RIGHT
)
1166 rItem
.m_format
= wxLIST_FORMAT_RIGHT
;
1167 else if (pFieldInfo
->flData
& CFA_CENTER
)
1168 rItem
.m_format
= wxLIST_FORMAT_CENTRE
;
1171 } // end of wxListCtrl::GetColumn
1173 // Sets information about this column
1174 bool wxListCtrl::SetColumn ( int nCol
, wxListItem
& rItem
)
1176 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1177 ConvertToOS2ListCol( nCol
, rItem
, pFieldInfo
);
1179 // Since we changed the field pointed to, we invalidate to see the result
1181 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1183 } // end of wxListCtrl::SetColumn
1185 // Gets the column width
1186 int wxListCtrl::GetColumnWidth ( int nCol
) const
1188 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), nCol
);
1192 return((int)pFieldInfo
->cxWidth
);
1193 } // end of wxListCtrl::GetColumnWidth
1195 // Sets the column width
1196 bool wxListCtrl::SetColumnWidth ( int nCol
, int nWidth
)
1199 int nWidth2
= nWidth
;
1201 if (GetWindowStyleFlag() & wxLC_LIST
)
1204 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1205 pFieldInfo
->cxWidth
= nWidth
;
1206 ::WinSendMsg(GetHWND(), CM_INVALIDATEDETAILFIELDINFO
, NULL
, NULL
);
1208 } // end of wxListCtrl::SetColumnWidth
1210 // Gets the number of items that can fit vertically in the
1211 // visible area of the list control (list or report view)
1212 // or the total number of items in the list control (icon
1213 // or small icon view)
1214 int wxListCtrl::GetCountPerPage () const
1216 QUERYRECORDRECT vQueryRect
;
1222 if (!::WinSendMsg( GetHWND()
1225 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1228 memset(&vQueryRect
, '\0', sizeof(QUERYRECORDRECT
));
1229 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1230 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
1231 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1232 else if (vCnrInfo
.flWindowAttr
& CV_NAME
)
1233 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1234 else if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
1235 vQueryRect
.fsExtent
= CMA_TEXT
;
1236 else if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
1237 vQueryRect
.fsExtent
= CMA_TEXT
;
1238 if (!::WinSendMsg( GetHWND()
1240 ,MPFROMP(&vRectRecord
)
1241 ,MPFROMP(&vQueryRect
)
1244 if (!::WinSendMsg( GetHWND()
1245 ,CM_QUERYVIEWPORTRECT
1246 ,MPFROMP(&vRectControl
)
1247 ,MPFROM2SHORT(CMA_WINDOW
, (USHORT
)FALSE
)
1250 nCount
= (int)((int)((vRectControl
.xRight
- vRectControl
.xLeft
) / (vRectRecord
.xRight
- vRectRecord
.xLeft
)) *
1251 (int)((vRectControl
.yTop
- vRectControl
.yBottom
) / (vRectRecord
.yTop
- vRectRecord
.yBottom
))
1253 if (nCount
> (int)vCnrInfo
.cFields
)
1254 nCount
= (int)vCnrInfo
.cFields
;
1256 } // end of wxListCtrl::GetCountPerPage
1258 // Gets the edit control for editing labels.
1259 wxTextCtrl
* wxListCtrl::GetEditControl() const
1264 // Gets information about the item
1265 bool wxListCtrl::GetItem ( wxListItem
& rInfo
) const
1267 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() );
1270 // Give NULL as hwnd as we already have everything we need
1272 ConvertFromOS2ListItem( NULL
, rInfo
, pRecord
);
1274 } // end of wxListCtrl::GetItem
1276 // Sets information about the item
1277 bool wxListCtrl::SetItem ( wxListItem
& rInfo
)
1279 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND(), rInfo
.GetColumn() );
1280 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), rInfo
.GetId() );
1282 ConvertToOS2ListItem( this
1289 // Check if setting attributes or lParam
1291 if (rInfo
.HasAttributes() || (rInfo
.GetMask() & wxLIST_MASK_DATA
))
1294 // Get internal item data
1295 // perhaps a cache here ?
1297 CListItemInternalData
* pData
= GetInternalData( this
1306 m_bAnyInternalData
= true;
1307 pData
= new CListItemInternalData();
1308 pRecord
->m_ulUserData
= (unsigned long)pData
;
1314 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
1315 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
1318 if (rInfo
.HasAttributes())
1321 *pData
->m_pAttr
= *rInfo
.GetAttributes();
1323 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
1325 pData
->m_pMyRecord
= pRecord
; // they point to each other
1329 // We need to update the item immediately to show the new image
1331 bool bUpdateNow
= (rInfo
.GetMask() & wxLIST_MASK_IMAGE
) != 0;
1334 // Check whether it has any custom attributes
1336 if (rInfo
.HasAttributes())
1338 m_bHasAnyAttr
= true;
1341 // If the colour has changed, we must redraw the item
1345 if (::WinIsWindowVisible(GetHWND()))
1347 ::WinSendMsg( GetHWND()
1348 ,CM_INVALIDATERECORD
1350 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1352 RefreshItem(pRecord
->m_ulItemId
);
1354 ::WinSendMsg( GetHWND()
1355 ,CM_INVALIDATEDETAILFIELDINFO
1360 } // end of wxListCtrl::SetItem
1362 long wxListCtrl::SetItem (
1365 , const wxString
& rsLabel
1371 vInfo
.m_text
= rsLabel
;
1372 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1373 vInfo
.m_itemId
= lIndex
;
1377 vInfo
.m_image
= nImageId
;
1378 vInfo
.m_mask
|= wxLIST_MASK_IMAGE
;
1380 return SetItem(vInfo
);
1381 } // end of wxListCtrl::SetItem
1383 // Gets the item state
1384 int wxListCtrl::GetItemState (
1391 vInfo
.m_mask
= wxLIST_MASK_STATE
;
1392 vInfo
.m_stateMask
= lStateMask
;
1393 vInfo
.m_itemId
= lItem
;
1395 if (!GetItem(vInfo
))
1397 return vInfo
.m_state
;
1398 } // end of wxListCtrl::GetItemState
1400 // Sets the item state
1401 bool wxListCtrl::SetItemState ( long lItem
, long lState
, long lStateMask
)
1403 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1406 // Don't use SetItem() here as it doesn't work with the virtual list
1409 ConvertToOS2Flags( lState
, pRecord
);
1412 // for the virtual list controls we need to refresh the previously focused
1413 // item manually when changing focus without changing selection
1414 // programmatically because otherwise it keeps its focus rectangle until
1415 // next repaint (yet another comctl32 bug)
1420 (lStateMask
& wxLIST_STATE_FOCUSED
) &&
1421 (lState
& wxLIST_STATE_FOCUSED
) )
1423 lFocusOld
= GetNextItem( -1
1425 ,wxLIST_STATE_FOCUSED
1432 ::WinSendMsg( GetHWND()
1433 ,CM_INVALIDATERECORD
1435 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1438 if (lFocusOld
!= -1)
1441 // No need to refresh the item if it was previously selected, it would
1442 // only result in annoying flicker
1444 if (!(GetItemState( lFocusOld
1445 ,wxLIST_STATE_SELECTED
1446 ) & wxLIST_STATE_SELECTED
))
1448 RefreshItem(lFocusOld
);
1452 } // end of wxListCtrl::SetItemState
1454 // Sets the item image
1455 bool wxListCtrl::SetItemImage (
1458 , int WXUNUSED(nSelImage
))
1460 return SetItemColumnInfo(lItem
, 0, nImage
);
1461 } // end of wxListCtrl::SetItemImage
1463 // Sets the item image
1464 bool wxListCtrl::SetItemColumnImage (
1471 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
1472 vInfo
.m_image
= nImage
;
1473 vInfo
.m_itemId
= lItem
;
1474 vInfo
.m_col
= lColumn
;
1475 return SetItem(vInfo
);
1476 } // end of wxListCtrl::SetItemColumnImage
1478 // Gets the item text
1479 wxString
wxListCtrl::GetItemText (
1485 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1486 vInfo
.m_itemId
= lItem
;
1488 if (!GetItem(vInfo
))
1489 return wxEmptyString
;
1490 return vInfo
.m_text
;
1491 } // end of wxListCtrl::GetItemText
1493 // Sets the item text
1494 void wxListCtrl::SetItemText (
1496 , const wxString
& rsStr
1501 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
1502 vInfo
.m_itemId
= lItem
;
1503 vInfo
.m_text
= rsStr
;
1505 } // end of wxListCtrl::SetItemText
1507 // Gets the item data
1508 long wxListCtrl::GetItemData (
1514 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1515 vInfo
.m_itemId
= lItem
;
1516 if (!GetItem(vInfo
))
1518 return vInfo
.m_data
;
1519 } // end of wxListCtrl::GetItemData
1521 // Sets the item data
1522 bool wxListCtrl::SetItemPtrData (
1529 vInfo
.m_mask
= wxLIST_MASK_DATA
;
1530 vInfo
.m_itemId
= lItem
;
1531 vInfo
.m_data
= lData
;
1532 return SetItem(vInfo
);
1533 } // end of wxListCtrl::SetItemPtrData
1535 // Gets the item rectangle
1536 bool wxListCtrl::GetItemRect ( long lItem
,
1541 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1542 QUERYRECORDRECT vQueryRect
;
1548 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1549 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1550 vQueryRect
.fRightSplitWindow
= TRUE
;
1551 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1552 ::WinSendMsg( GetHWND()
1555 ,MPFROMP(&vQueryRect
)
1558 // remember OS/2 is backwards
1560 GetClientSize( NULL
, &nHeight
);
1561 rRect
.x
= vRect
.xLeft
;
1562 rRect
.y
= nHeight
- vRect
.yTop
;
1563 rRect
.width
= vRect
.xRight
;
1564 rRect
.height
= nHeight
- vRect
.yBottom
;
1567 } // end of wxListCtrl::GetItemRect
1569 // Gets the item position
1570 bool wxListCtrl::GetItemPosition ( long lItem
, wxPoint
& rPos
) const
1573 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND() , lItem
);
1574 QUERYRECORDRECT vQueryRect
;
1580 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
1581 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
1582 vQueryRect
.fRightSplitWindow
= TRUE
;
1583 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
1584 ::WinSendMsg( GetHWND()
1587 ,MPFROMP(&vQueryRect
)
1590 // remember OS/2 is backwards
1592 GetClientSize( NULL
, &nHeight
);
1593 rPos
.x
= vRect
.xLeft
;
1594 rPos
.y
= nHeight
- vRect
.yTop
;
1597 } // end of wxListCtrl::GetItemPosition
1599 // Sets the item position.
1600 bool wxListCtrl::SetItemPosition ( long lItem
, const wxPoint
& rPos
)
1603 // Items cannot be positioned in X/Y coord in OS/2
1606 } // end of wxListCtrl::SetItemPosition
1608 // Gets the number of items in the list control
1609 int wxListCtrl::GetItemCount () const
1613 if (!::WinSendMsg( GetHWND()
1616 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1619 return vCnrInfo
.cRecords
;
1620 } // end of wxListCtrl::GetItemCount
1622 // Retrieves the spacing between icons in pixels.
1623 // If bIsSmall is true, gets the spacing for the small icon
1624 // view, otherwise the large icon view.
1625 int wxListCtrl::GetItemSpacing ( bool bIsSmall
) const
1629 if (!::WinSendMsg( GetHWND()
1632 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
1635 return vCnrInfo
.cyLineSpacing
;
1636 } // end of wxListCtrl::GetItemSpacing
1638 void wxListCtrl::SetItemTextColour (
1640 , const wxColour
& rCol
1645 vInfo
.m_itemId
= lItem
;
1646 vInfo
.SetTextColour(rCol
);
1648 } // end of wxListCtrl::SetItemTextColour
1650 wxColour
wxListCtrl::GetItemTextColour (
1656 vInfo
.m_itemId
= lItem
;
1658 return vInfo
.GetTextColour();
1659 } // end of wxListCtrl::GetItemTextColour
1661 void wxListCtrl::SetItemBackgroundColour (
1663 , const wxColour
& rCol
1668 vInfo
.m_itemId
= lItem
;
1669 vInfo
.SetBackgroundColour(rCol
);
1671 } // end of wxListCtrl::SetItemBackgroundColour
1673 wxColour
wxListCtrl::GetItemBackgroundColour (
1679 vInfo
.m_itemId
= lItem
;
1681 return vInfo
.GetBackgroundColour();
1682 } // end of wxListCtrl::GetItemBackgroundColour
1684 // Gets the number of selected items in the list control
1685 int wxListCtrl::GetSelectedItemCount () const
1687 PMYRECORD pRecord
= NULL
;
1689 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1690 ,CM_QUERYRECORDEMPHASIS
1692 ,(MPARAM
)CRA_SELECTED
1700 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1701 ,CM_QUERYRECORDEMPHASIS
1703 ,(MPARAM
)CRA_SELECTED
1709 } // end of wxListCtrl::GetSelectedItemCount
1711 // Gets the text colour of the listview
1712 wxColour
wxListCtrl::GetTextColour () const
1717 ::WinQueryPresParam( GetHWND()
1727 } // end of wxListCtrl::GetTextColour
1729 // Sets the text colour of the listview
1730 void wxListCtrl::SetTextColour (
1731 const wxColour
& rCol
1734 ULONG ulColor
= wxColourToRGB(rCol
);
1736 ::WinSetPresParam( GetHWND()
1741 } // end of wxListCtrl::SetTextColour
1743 // Gets the index of the topmost visible item when in
1744 // list or report view
1745 long wxListCtrl::GetTopItem () const
1747 PMYRECORD pRecord
= NULL
;
1748 QUERYRECFROMRECT vQueryRect
;
1751 ::WinSendMsg( GetHWND()
1752 ,CM_QUERYVIEWPORTRECT
1754 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1756 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1757 vQueryRect
.rect
= vRect
;
1758 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1760 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1761 ,CM_QUERYRECORDFROMRECT
1763 ,MPFROMP(&vQueryRect
)
1768 return (long)pRecord
->m_ulItemId
;
1769 } // end of wxListCtrl::GetTopItem
1771 // Searches for an item, starting from 'item'.
1772 // 'geometry' is one of
1773 // wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
1774 // 'state' is a state bit flag, one or more of
1775 // wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
1776 // item can be -1 to find the first item that matches the
1778 // Returns the item or -1 if unsuccessful.
1779 long wxListCtrl::GetNextItem (
1781 , int WXUNUSED(nGeom
)
1782 , int WXUNUSED(nState
)
1785 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1789 pRecord
= (PMYRECORD
)pRecord
->m_vRecord
.preccNextRecord
;
1791 return((long)pRecord
->m_ulItemId
);
1793 } // end of wxListCtrl::GetNextItem
1795 wxImageList
* wxListCtrl::GetImageList (
1799 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1801 return m_pImageListNormal
;
1803 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1805 return m_pImageListSmall
;
1807 else if (nWhich
== wxIMAGE_LIST_STATE
)
1809 return m_pImageListState
;
1812 } // end of wxListCtrl::GetImageList
1814 void wxListCtrl::SetImageList ( wxImageList
* pImageList
,
1817 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1819 if (m_bOwnsImageListNormal
)
1820 delete m_pImageListNormal
;
1821 m_pImageListNormal
= pImageList
;
1822 m_bOwnsImageListNormal
= false;
1824 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1826 if (m_bOwnsImageListSmall
)
1827 delete m_pImageListSmall
;
1828 m_pImageListSmall
= pImageList
;
1829 m_bOwnsImageListSmall
= false;
1831 else if (nWhich
== wxIMAGE_LIST_STATE
)
1833 if (m_bOwnsImageListState
)
1834 delete m_pImageListState
;
1835 m_pImageListState
= pImageList
;
1836 m_bOwnsImageListState
= false;
1838 } // end of wxListCtrl::SetImageList
1840 void wxListCtrl::AssignImageList ( wxImageList
* pImageList
, int nWhich
)
1842 SetImageList( pImageList
, nWhich
);
1844 if (nWhich
== wxIMAGE_LIST_NORMAL
)
1845 m_bOwnsImageListNormal
= true;
1846 else if (nWhich
== wxIMAGE_LIST_SMALL
)
1847 m_bOwnsImageListSmall
= true;
1848 else if (nWhich
== wxIMAGE_LIST_STATE
)
1849 m_bOwnsImageListState
= true;
1850 } // end of wxListCtrl::AssignImageList
1852 // ----------------------------------------------------------------------------
1854 // ----------------------------------------------------------------------------
1856 // Arranges the items
1857 bool wxListCtrl::Arrange ( int nFlag
)
1862 if (nFlag
== wxLIST_ALIGN_SNAP_TO_GRID
)
1864 ulType
= CMA_ARRANGEGRID
;
1865 if (nFlag
== wxLIST_ALIGN_LEFT
)
1866 ulFlags
|= CMA_LEFT
;
1867 else if (nFlag
== wxLIST_ALIGN_TOP
)
1869 else if (nFlag
== wxLIST_ALIGN_DEFAULT
)
1870 ulFlags
|= CMA_LEFT
;
1873 ulType
= CMA_ARRANGESTANDARD
;
1874 ::WinSendMsg( GetHWND()
1880 // We do not support CMA_ARRANGESELECTED
1883 } // end of wxListCtrl::Arrange
1886 bool wxListCtrl::DeleteItem ( long lItem
)
1888 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
1889 if (LONGFROMMR(::WinSendMsg( GetHWND()
1892 ,MPFROM2SHORT(1, CMA_FREE
)
1899 // The virtual list control doesn't refresh itself correctly, help it
1904 // We need to refresh all the lines below the one which was deleted
1908 if (lItem
> 0 && GetItemCount())
1910 GetItemRect( lItem
- 1
1916 vRectItem
.y
= vRectItem
.height
= 0;
1918 wxRect vRectWin
= GetRect();
1920 vRectWin
.height
= vRectWin
.GetBottom() - vRectItem
.GetBottom();
1921 vRectWin
.y
= vRectItem
.GetBottom();
1922 RefreshRect(vRectWin
);
1925 } // end of wxListCtrl::DeleteItem
1927 // Deletes all items
1928 bool wxListCtrl::DeleteAllItems ()
1930 return((LONG
)::WinSendMsg( GetHWND()
1933 ,MPFROM2SHORT(0, CMA_FREE
)
1935 } // end of wxListCtrl::DeleteAllItems
1937 // Deletes all items
1938 bool wxListCtrl::DeleteAllColumns ()
1940 while (m_nColCount
> 0)
1942 DeleteColumn(m_nColCount
- 1);
1946 wxASSERT_MSG(m_nColCount
== 0, wxT("no columns should be left"));
1948 } // end of wxListCtrl::DeleteAllColumns
1951 bool wxListCtrl::DeleteColumn ( int nCol
)
1953 bool bSuccess
= false;
1954 PFIELDINFO pField
= FindOS2ListFieldByColNum( GetHWND(), nCol
);
1955 bSuccess
= ((LONG
)::WinSendMsg( GetHWND()
1956 ,CM_REMOVEDETAILFIELDINFO
1958 ,MPFROM2SHORT((SHORT
)1, CMA_FREE
)
1960 if (bSuccess
&& (m_nColCount
> 0))
1963 } // end of wxListCtrl::DeleteColumn
1965 // Clears items, and columns if there are any.
1966 void wxListCtrl::ClearAll ()
1969 if (m_nColCount
> 0)
1971 } // end of wxListCtrl::ClearAll
1974 // OS/2 does not use a text control for its container labels. You merely
1975 // "open" a record for editting.
1977 wxTextCtrl
* wxListCtrl::EditLabel (
1979 , wxClassInfo
* WXUNUSED(pTextControlClass
)
1983 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
1987 vEdit
.cb
= sizeof(CNREDITDATA
);
1988 vEdit
.hwndCnr
= GetHWND();
1989 vEdit
.pRecord
= &pRecord
->m_vRecord
;
1990 vEdit
.pFieldInfo
= NULL
;
1991 vEdit
.ppszText
= NULL
;
1995 ::WinSendMsg( GetHWND()
2001 } // end of wxListCtrl::EditLabel
2003 // End label editing, optionally cancelling the edit. Under OS/2 you close
2004 // the record for editting
2005 bool wxListCtrl::EndEditLabel ( bool WXUNUSED(bCancel
) )
2007 ::WinSendMsg( GetHWND()
2013 } // end of wxListCtrl::EndEditLabel
2015 // Ensures this item is visible
2016 bool wxListCtrl::EnsureVisible ( long lItem
)
2018 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND(), lItem
);
2019 ::WinSendMsg( GetHWND()
2020 ,CM_INVALIDATERECORD
2022 ,MPFROM2SHORT((SHORT
)1, CMA_NOREPOSITION
)
2025 } // end of wxListCtrl::EnsureVisible
2027 // Find an item whose label matches this string, starting from the item after 'start'
2028 // or the beginning if 'start' is -1.
2029 long wxListCtrl::FindItem (
2031 , const wxString
& rsStr
2036 SEARCHSTRING vSearch
;
2037 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2043 if (!::WinSendMsg( GetHWND()
2046 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2050 if (vCnrInfo
.flWindowAttr
& CV_ICON
)
2052 if (vCnrInfo
.flWindowAttr
& CV_NAME
)
2054 if (vCnrInfo
.flWindowAttr
& CV_TEXT
)
2056 if (vCnrInfo
.flWindowAttr
& CV_DETAIL
)
2059 ulFlag
|= CV_EXACTLENGTH
;
2061 vSearch
.cb
= sizeof(SEARCHSTRING
);
2062 vSearch
.pszSearch
= (char*)rsStr
.c_str();
2063 vSearch
.fsPrefix
= TRUE
;
2064 vSearch
.fsCaseSensitive
= TRUE
;
2065 vSearch
.usView
= ulFlag
;
2069 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2077 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2085 return pRecord
->m_ulItemId
;
2086 } // end of wxListCtrl::FindItem
2088 // Find an item whose data matches this data, starting from the item after 'start'
2089 // or the beginning if 'start' is -1.
2090 long wxListCtrl::FindItem (
2095 long lIdx
= lStart
+ 1;
2096 long lCount
= GetItemCount();
2098 while (lIdx
< lCount
)
2100 if (GetItemData(lIdx
) == lData
)
2105 } // end of wxListCtrl::FindItem
2107 // Find an item nearest this position in the specified direction, starting from
2108 // the item after 'start' or the beginning if 'start' is -1.
2109 long wxListCtrl::FindItem (
2111 , const wxPoint
& rPoint
2116 QUERYRECORDRECT vQueryRect
;
2117 PMYRECORD pRecord
= FindOS2ListRecordByID( GetHWND()
2124 if (!::WinSendMsg( GetHWND()
2127 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
2131 vQueryRect
.cb
= sizeof(QUERYRECORDRECT
);
2132 vQueryRect
.pRecord
= &pRecord
->m_vRecord
;
2133 vQueryRect
.fRightSplitWindow
= TRUE
;
2134 vQueryRect
.fsExtent
= CMA_ICON
| CMA_TEXT
;
2136 ::WinSendMsg( GetHWND()
2139 ,MPFROMP(&vQueryRect
)
2141 vLibRect
.SetLeft(vRect
.xLeft
);
2142 vLibRect
.SetTop(vRect
.yTop
);
2143 vLibRect
.SetRight(vRect
.xRight
);
2144 vLibRect
.SetBottom(vRect
.yBottom
);
2145 if (vLibRect
.Contains(rPoint
))
2146 return pRecord
->m_ulItemId
;
2148 for (i
= lStart
+ 1; i
< vCnrInfo
.cRecords
; i
++)
2150 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
2153 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
2155 vQueryRect
.pRecord
= (PRECORDCORE
)pRecord
;
2156 ::WinSendMsg( GetHWND()
2159 ,MPFROMP(&vQueryRect
)
2161 vLibRect
.SetLeft(vRect
.xLeft
);
2162 vLibRect
.SetTop(vRect
.yTop
);
2163 vLibRect
.SetRight(vRect
.xRight
);
2164 vLibRect
.SetBottom(vRect
.yBottom
);
2165 if (vLibRect
.Contains(rPoint
))
2166 return pRecord
->m_ulItemId
;
2169 } // end of wxListCtrl::FindItem
2171 // Determines which item (if any) is at the specified point,
2172 // giving details in 'flags' (see wxLIST_HITTEST_... flags above)
2173 long wxListCtrl::HitTest (
2174 const wxPoint
& rPoint
2175 , int& WXUNUSED(rFlags
)
2178 PMYRECORD pRecord
= NULL
;
2179 QUERYRECFROMRECT vQueryRect
;
2184 // Get height for OS/2 point conversion
2186 ::WinSendMsg( GetHWND()
2187 ,CM_QUERYVIEWPORTRECT
2189 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
2191 lHeight
= vRect
.yTop
- vRect
.yBottom
;
2194 // For now just try and get a record in the general vicinity and forget
2197 vRect
.xLeft
= rPoint
.x
- 2;
2198 vRect
.xRight
= rPoint
.x
+ 2;
2199 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
2200 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
2202 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
2203 vQueryRect
.rect
= vRect
;
2204 vQueryRect
.fsSearch
= CMA_PARTIAL
;
2206 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2207 ,CM_QUERYRECORDFROMRECT
2209 ,MPFROMP(&vQueryRect
)
2214 return pRecord
->m_ulItemId
;
2215 } // end of wxListCtrl::HitTest
2217 // Inserts an item, returning the index of the new item if successful,
2219 long wxListCtrl::InsertItem (
2223 wxASSERT_MSG( !IsVirtual(), wxT("can't be used with virtual controls") );
2225 PFIELDINFO pFieldInfo
= FindOS2ListFieldByColNum ( GetHWND()
2228 PMYRECORD pRecordAfter
= NULL
;
2229 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
2231 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
2235 ConvertToOS2ListItem( this
2241 if (rInfo
.GetId() > 0)
2242 pRecordAfter
= FindOS2ListRecordByID( GetHWND()
2246 RECORDINSERT vInsert
;
2248 vInsert
.cb
= sizeof(RECORDINSERT
);
2249 vInsert
.pRecordParent
= NULL
;
2251 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
2253 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
2254 vInsert
.zOrder
= CMA_TOP
;
2255 vInsert
.cRecordsInsert
= 1;
2256 vInsert
.fInvalidateRecord
= TRUE
;
2259 // Check wether we need to allocate our internal data
2261 bool bNeedInternalData
= ((rInfo
.GetMask() & wxLIST_MASK_DATA
) ||
2262 rInfo
.HasAttributes()
2264 if (bNeedInternalData
)
2266 m_bAnyInternalData
= true;
2269 // Internal stucture that manages data
2271 CListItemInternalData
* pData
= new CListItemInternalData();
2273 pRecord
->m_ulUserData
= (unsigned long)pData
;
2274 if (rInfo
.GetMask() & wxLIST_MASK_DATA
)
2275 pData
->m_lParam
= (WXLPARAM
)rInfo
.GetData();
2278 // Check whether it has any custom attributes
2280 if (rInfo
.HasAttributes())
2283 // Take copy of attributes
2285 pData
->m_pAttr
= new wxListItemAttr(*rInfo
.GetAttributes());
2288 if (!::WinSendMsg( GetHWND()
2295 // OS/2 must mannually bump the index's of following records
2297 BumpRecordIds( GetHWND()
2300 ::WinSendMsg( GetHWND()
2301 ,CM_INVALIDATEDETAILFIELDINFO
2305 return pRecord
->m_ulItemId
;
2306 } // end of wxListCtrl::InsertItem
2308 long wxListCtrl::InsertItem (
2310 , const wxString
& rsLabel
2315 memset(&vInfo
, '\0', sizeof(wxListItem
));
2316 vInfo
.m_text
= rsLabel
;
2317 vInfo
.m_mask
= wxLIST_MASK_TEXT
;
2318 vInfo
.m_itemId
= lIndex
;
2319 return InsertItem(vInfo
);
2320 } // end of wxListCtrl::InsertItem
2322 // Inserts an image item
2323 long wxListCtrl::InsertItem (
2330 vInfo
.m_image
= nImageIndex
;
2331 vInfo
.m_mask
= wxLIST_MASK_IMAGE
;
2332 vInfo
.m_itemId
= lIndex
;
2333 return InsertItem(vInfo
);
2334 } // end of wxListCtrl::InsertItem
2336 // Inserts an image/string item
2337 long wxListCtrl::InsertItem (
2339 , const wxString
& rsLabel
2345 vInfo
.m_image
= nImageIndex
;
2346 vInfo
.m_text
= rsLabel
;
2347 vInfo
.m_mask
= wxLIST_MASK_IMAGE
| wxLIST_MASK_TEXT
;
2348 vInfo
.m_itemId
= lIndex
;
2349 return InsertItem(vInfo
);
2350 } // end of wxListCtrl::InsertItem
2352 // For details view mode (only), inserts a column.
2353 long wxListCtrl::InsertColumn (
2359 PFIELDINFO pField
= (PFIELDINFO
)::WinSendMsg( GetHWND()
2360 ,CM_ALLOCDETAILFIELDINFO
2364 PFIELDINFO pFieldAfter
= FindOS2ListFieldByColNum ( GetHWND()
2367 FIELDINFOINSERT vInsert
;
2369 ConvertToOS2ListCol ( lCol
2374 vInsert
.cb
= sizeof(FIELDINFOINSERT
);
2375 vInsert
.pFieldInfoOrder
= pFieldAfter
;
2376 vInsert
.fInvalidateFieldInfo
= TRUE
;
2377 vInsert
.cFieldInfoInsert
= 1;
2379 bSuccess
= ::WinSendMsg( GetHWND()
2380 ,CM_INSERTDETAILFIELDINFO
2385 } // end of wxListCtrl::InsertColumn
2387 long wxListCtrl::InsertColumn (
2389 , const wxString
& rsHeading
2396 vItem
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
2397 vItem
.m_text
= rsHeading
;
2400 vItem
.m_mask
|= wxLIST_MASK_WIDTH
;
2401 vItem
.m_width
= nWidth
;
2403 vItem
.m_format
= nFormat
;
2405 return InsertColumn( lCol
2408 } // end of wxListCtrl::InsertColumn
2410 // scroll the control by the given number of pixels (exception: in list view,
2411 // dx is interpreted as number of columns)
2412 bool wxListCtrl::ScrollList ( int nDx
, int nDy
)
2415 ::WinSendMsg( GetHWND()
2417 ,(MPARAM
)CMA_HORIZONTAL
2421 ::WinSendMsg( GetHWND()
2423 ,(MPARAM
)CMA_VERTICAL
2427 } // end of wxListCtrl::ScrollList
2429 bool wxListCtrl::SortItems ( wxListCtrlCompare fn
, long lData
)
2431 SInternalDataSort vInternalData
;
2433 vInternalData
.m_fnUser
= fn
;
2434 vInternalData
.m_lData
= lData
;
2436 // WPARAM cast is needed for mingw/cygwin
2437 if (!::WinSendMsg( GetHWND()
2439 ,(PFN
)InternalDataCompareFunc
2440 ,(PVOID
)&vInternalData
2443 wxLogDebug(wxT("CM_SORTRECORD failed"));
2447 } // end of wxListCtrl::SortItems
2449 // ----------------------------------------------------------------------------
2450 // message processing
2451 // ----------------------------------------------------------------------------
2453 bool wxListCtrl::OS2Command ( WXUINT uCmd
, WXWORD wId
)
2455 if (uCmd
== CN_ENDEDIT
)
2457 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
, wId
);
2459 vEvent
.SetEventObject( this );
2460 ProcessCommand(vEvent
);
2463 else if (uCmd
== CN_KILLFOCUS
)
2465 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
, wId
);
2466 vEvent
.SetEventObject( this );
2467 ProcessCommand(vEvent
);
2472 } // end of wxListCtrl::OS2Command
2474 // Necessary for drawing hrules and vrules, if specified
2475 void wxListCtrl::OnPaint ( wxPaintEvent
& rEvent
)
2477 wxPaintDC
vDc(this);
2478 wxPen
vPen(wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT
)
2482 wxSize vClientSize
= GetClientSize();
2484 int nItemCount
= GetItemCount();
2487 bool bDrawHRules
= ((GetWindowStyle() & wxLC_HRULES
) != 0);
2488 bool bDrawVRules
= ((GetWindowStyle() & wxLC_VRULES
) != 0);
2490 wxControl::OnPaint(rEvent
);
2493 // Reset the device origin since it may have been set
2495 vDc
.SetDeviceOrigin(0, 0);
2496 if (!bDrawHRules
&& !bDrawVRules
)
2498 if ((GetWindowStyle() & wxLC_REPORT
) == 0)
2501 vDc
.SetBrush(*wxTRANSPARENT_BRUSH
);
2505 long lTop
= GetTopItem();
2507 for (i
= lTop
; i
< lTop
+ GetCountPerPage() + 1; i
++)
2513 nCy
= vItemRect
.GetTop();
2514 if (i
!= 0) // Don't draw the first one
2523 if (i
== nItemCount
- 1)
2525 nCy
= vItemRect
.GetBottom();
2536 if (bDrawVRules
&& (i
> -1))
2538 wxRect vFirstItemRect
;
2548 int nX
= vItemRect
.GetX();
2550 for (nCol
= 0; nCol
< GetColumnCount(); nCol
++)
2552 int nColWidth
= GetColumnWidth(nCol
);
2555 vDc
.DrawLine( nX
- 1
2556 ,vFirstItemRect
.GetY() - 2
2558 ,vItemRect
.GetBottom()
2563 } // end of wxListCtrl::OnPaint
2565 // ----------------------------------------------------------------------------
2566 // virtual list controls
2567 // ----------------------------------------------------------------------------
2569 wxString
wxListCtrl::OnGetItemText (
2570 long WXUNUSED(lItem
)
2571 , long WXUNUSED(lCol
)
2574 // this is a pure virtual function, in fact - which is not really pure
2575 // because the controls which are not virtual don't need to implement it
2576 wxFAIL_MSG( wxT("not supposed to be called") );
2577 return wxEmptyString
;
2578 } // end of wxListCtrl::OnGetItemText
2580 int wxListCtrl::OnGetItemImage (
2581 long WXUNUSED(lItem
)
2585 wxFAIL_MSG( wxT("not supposed to be called") );
2587 } // end of wxListCtrl::OnGetItemImage
2589 int wxListCtrl::OnGetItemColumnImage (
2595 return OnGetItemImage(lItem
);
2598 } // end of wxListCtrl::OnGetItemColumnImage
2600 wxListItemAttr
* wxListCtrl::OnGetItemAttr (
2601 long WXUNUSED_UNLESS_DEBUG(lItem
)
2604 wxASSERT_MSG( lItem
>= 0 && lItem
< GetItemCount(),
2605 wxT("invalid item index in OnGetItemAttr()") );
2608 // No attributes by default
2611 } // end of wxListCtrl::OnGetItemAttr
2613 void wxListCtrl::SetItemCount (
2617 wxASSERT_MSG( IsVirtual(), wxT("this is for virtual controls only") );
2620 // Cannot explicitly set the record count in OS/2
2622 } // end of wxListCtrl::SetItemCount
2624 void wxListCtrl::RefreshItem (
2634 } // end of wxListCtrl::RefreshItem
2636 void wxListCtrl::RefreshItems ( long lItemFrom
, long lItemTo
)
2641 GetItemRect( lItemFrom
, vRect1
);
2642 GetItemRect( lItemTo
, vRect2
);
2644 wxRect vRect
= vRect1
;
2646 vRect
.height
= vRect2
.GetBottom() - vRect1
.GetTop();
2648 } // end of wxListCtrl::RefreshItems
2650 MRESULT
wxListCtrl::OS2WindowProc( WXUINT uMsg
,
2654 bool bProcessed
= false;
2656 wxListEvent
vEvent( wxEVT_NULL
2659 wxEventType vEventType
= wxEVT_NULL
;
2660 PCNRDRAGINIT pDragInit
= NULL
;
2661 PCNREDITDATA pEditData
= NULL
;
2662 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
2664 vEvent
.SetEventObject(this);
2669 // First off let's set some internal data
2671 switch(SHORT2FROMMP(wParam
))
2677 CListItemInternalData
* pInternaldata
= (CListItemInternalData
*)lParam
;
2681 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2683 pItem
->SetData((long)pInternaldata
->m_lParam
);
2689 // Now let's go through the codes we're interested in
2691 switch(SHORT2FROMMP(wParam
))
2694 pDragInit
= (PCNRDRAGINIT
)lParam
;
2697 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2699 vEventType
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
;
2700 vEvent
.m_itemIndex
= pRecord
->m_ulItemId
;
2701 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2702 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2707 pEditData
= (PCNREDITDATA
)lParam
;
2710 vEventType
= wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
;
2711 ConvertFromOS2ListItem( GetHWND()
2712 ,(wxListItem
&)vEvent
.GetItem()
2713 ,(PMYRECORD
)pEditData
->pRecord
2715 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2720 pEditData
= (PCNREDITDATA
)lParam
;
2723 vEventType
= wxEVT_COMMAND_LIST_END_LABEL_EDIT
;
2724 ConvertFromOS2ListItem( GetHWND()
2725 ,(wxListItem
&)vEvent
.GetItem()
2726 ,(PMYRECORD
)pEditData
->pRecord
2728 if (pEditData
->cbText
== 0)
2729 return (MRESULT
)FALSE
;
2730 vEvent
.m_itemIndex
= vEvent
.GetItem().GetId();
2735 pNotifyEnter
= (PNOTIFYRECORDENTER
)lParam
;
2738 wxListItem
* pItem
= (wxListItem
*)&vEvent
.GetItem();
2739 PMYRECORD pMyRecord
= (PMYRECORD
)pNotifyEnter
->pRecord
;
2741 vEventType
= wxEVT_COMMAND_LIST_ITEM_ACTIVATED
;
2742 vEvent
.m_itemIndex
= pMyRecord
->m_ulItemId
;
2743 pItem
->SetText(GetItemText(pMyRecord
->m_ulItemId
));
2744 pItem
->SetData(GetItemData(pMyRecord
->m_ulItemId
));
2749 // Add the CN_DROP messages for Direct Manipulation
2752 vEvent
.SetEventType(vEventType
);
2753 bProcessed
= HandleWindowEvent(vEvent
);
2757 lRc
= wxControl::OS2WindowProc( uMsg
2762 } // end of wxListCtrl::WindowProc
2764 #endif // wxUSE_LISTCTRL