]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
added a preImage of the selection in order to avoid unnecessary events being triggered
[wxWidgets.git] / src / msw / listctrl.cpp
index c527a6f0d387454d4ee9c8f77f168e48f9d382fb..13d2bff72e53d35568bd061f698b7d948673dd66 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        listctrl.cpp
+// Name:        src/msw/listctrl.cpp
 // Purpose:     wxListCtrl
 // Author:      Julian Smart
 // Modified by:
@@ -153,6 +153,7 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_END_DRAG)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT)
 
 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
@@ -1485,6 +1486,8 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
     // -----------------
 
     wxListEvent event(wxEVT_NULL, m_windowId);
+    event.SetEventObject(this);
+
     wxEventType eventType = wxEVT_NULL;
 
     NMHDR *nmhdr = (NMHDR *)lParam;
@@ -1654,22 +1657,52 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 break;
 
             case LVN_ITEMCHANGED:
-                // This needs to be sent to wxListCtrl as a rather more concrete
-                // event. For now, just detect a selection or deselection.
-                if ( (nmLV->uNewState & LVIS_SELECTED) && !(nmLV->uOldState & LVIS_SELECTED) )
-                {
-                    eventType = wxEVT_COMMAND_LIST_ITEM_SELECTED;
-                    event.m_itemIndex = nmLV->iItem;
-                }
-                else if ( !(nmLV->uNewState & LVIS_SELECTED) && (nmLV->uOldState & LVIS_SELECTED) )
+                // we translate this catch all message into more interesting
+                // (and more easy to process) wxWindows events
+
+                // first of all, we deal with the state change events only
+                if ( nmLV->uChanged & LVIF_STATE )
                 {
-                    eventType = wxEVT_COMMAND_LIST_ITEM_DESELECTED;
-                    event.m_itemIndex = nmLV->iItem;
+                    // temp vars for readability
+                    const UINT stOld = nmLV->uOldState;
+                    const UINT stNew = nmLV->uNewState;
+
+                    // has the focus changed?
+                    if ( !(stOld & LVIS_FOCUSED) && (stNew & LVIS_FOCUSED) )
+                    {
+                        eventType = wxEVT_COMMAND_LIST_ITEM_FOCUSED;
+                        event.m_itemIndex = nmLV->iItem;
+                    }
+
+                    if ( (stNew & LVIS_SELECTED) != (stOld & LVIS_SELECTED) )
+                    {
+                        if ( eventType != wxEVT_NULL )
+                        {
+                            // focus and selection have both changed: send the
+                            // focus event from here and the selection one
+                            // below
+                            event.SetEventType(eventType);
+                            (void)GetEventHandler()->ProcessEvent(event);
+                        }
+                        else // no focus event to send
+                        {
+                            // then need to set m_itemIndex as it wasn't done
+                            // above
+                            event.m_itemIndex = nmLV->iItem;
+                        }
+
+                        eventType = stNew & LVIS_SELECTED
+                                        ? wxEVT_COMMAND_LIST_ITEM_SELECTED
+                                        : wxEVT_COMMAND_LIST_ITEM_DESELECTED;
+                    }
                 }
-                else
+
+                if ( eventType == wxEVT_NULL )
                 {
+                    // not an interesting event for us
                     return FALSE;
                 }
+
                 break;
 
             case LVN_KEYDOWN:
@@ -1694,7 +1727,11 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                     else
                     {
                         eventType = wxEVT_COMMAND_LIST_KEY_DOWN;
-                        event.m_code = wxCharCodeMSWToWX(wVKey);
+
+                        // wxCharCodeMSWToWX() returns 0 if the key is an ASCII
+                        // value which should be used as is
+                        int code = wxCharCodeMSWToWX(wVKey);
+                        event.m_code = code ? code : wVKey;
                     }
 
                     event.m_itemIndex =
@@ -1833,7 +1870,6 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
     // process the event
     // -----------------
 
-    event.SetEventObject( this );
     event.SetEventType(eventType);
 
     if ( !GetEventHandler()->ProcessEvent(event) )