+ case NM_RCLICK:
+ {
+ eventType = wxEVT_COMMAND_LIST_COL_RIGHT_CLICK;
+ event.m_col = -1;
+
+ // find the column clicked: we have to search for it
+ // ourselves as the notification message doesn't provide
+ // this info
+
+ // where did the click occur?
+ POINT ptClick;
+ if ( !::GetCursorPos(&ptClick) )
+ {
+ wxLogLastError(_T("GetCursorPos"));
+ }
+
+ if ( !::ScreenToClient(hwndHdr, &ptClick) )
+ {
+ wxLogLastError(_T("ScreenToClient(listctrl header)"));
+ }
+
+ event.m_pointDrag.x = ptClick.x;
+ event.m_pointDrag.y = ptClick.y;
+
+ int colCount = Header_GetItemCount(hwndHdr);
+
+ RECT rect;
+ for ( int col = 0; col < colCount; col++ )
+ {
+ if ( Header_GetItemRect(hwndHdr, col, &rect) )
+ {
+ if ( ::PtInRect(&rect, ptClick) )
+ {
+ event.m_col = col;
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case HDN_GETDISPINFOW:
+ {
+ LPNMHDDISPINFOW info = (LPNMHDDISPINFOW) lParam;
+ // This is a fix for a strange bug under XP.
+ // Normally, info->iItem is a valid index, but
+ // sometimes this is a silly (large) number
+ // and when we return FALSE via wxControl::MSWOnNotify
+ // to indicate that it hasn't yet been processed,
+ // there's a GPF in Windows.
+ // By returning TRUE here, we avoid further processing
+ // of this strange message.
+ if ( info->iItem >= GetColumnCount() )
+ return TRUE;
+ }
+ // fall through
+
+ default:
+ return wxControl::MSWOnNotify(idCtrl, lParam, result);
+ }
+ }
+ else
+#endif // defined(HDN_BEGINTRACKA)
+ if ( nmhdr->hwndFrom == GetHwnd() )
+ {
+ // almost all messages use NM_LISTVIEW
+ NM_LISTVIEW *nmLV = (NM_LISTVIEW *)nmhdr;
+
+ const int iItem = nmLV->iItem;
+
+ // set the data event field for all messages for which the system gives
+ // us a valid NM_LISTVIEW::lParam
+ switch ( nmLV->hdr.code )
+ {
+ case LVN_BEGINDRAG:
+ case LVN_BEGINRDRAG:
+ case LVN_COLUMNCLICK:
+ case LVN_ITEMCHANGED:
+ case LVN_ITEMCHANGING:
+ if ( iItem != -1 )
+ {
+ if ( iItem >= GetItemCount() )
+ {
+ // there is apparently a bug in comctl32.dll version
+ // 5.50.4704.1100 (note that the MS DLL database
+ // doesn't say what this version is, it's not the one
+ // shipped with W2K although the bug was reported under
+ // that system) and it sends us LVN_ITEMCHANGING
+ // notifications with the item out of range -- and as
+ // we access the items client data, we crash below
+ //
+ // see
+ //
+ // http://lists.wxwindows.org/cgi-bin/ezmlm-cgi?8:mss:29852:knlihdmadhaljafjajei
+ //
+ // and the thread continuation for more details
+ // (although note that the bug may be present in other
+ // versions of comctl32.dll as well as it has been
+ // reported quite a few times)
+ //
+ // to fix this, simply ignore these "bad" events (as
+ // above with HDN_GETDISPINFOW)
+ return TRUE;
+ }
+
+ wxListItemInternalData *internaldata =
+ (wxListItemInternalData *) nmLV->lParam;
+
+ if ( internaldata )
+ event.m_item.m_data = internaldata->lParam;
+ }
+
+ default:
+ // fall through
+ ;
+ }
+
+ switch ( nmhdr->code )
+ {
+ case LVN_BEGINRDRAG:
+ eventType = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
+ // fall through
+
+ case LVN_BEGINDRAG:
+ if ( eventType == wxEVT_NULL )
+ {
+ eventType = wxEVT_COMMAND_LIST_BEGIN_DRAG;
+ }
+
+ event.m_itemIndex = iItem;
+ event.m_pointDrag.x = nmLV->ptAction.x;
+ event.m_pointDrag.y = nmLV->ptAction.y;
+ break;
+
+ // NB: we have to handle both *A and *W versions here because some
+ // versions of comctl32.dll send ANSI message to an Unicode app
+ case LVN_BEGINLABELEDITA:
+ {
+ eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT;
+ wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item);
+ wxConvertFromMSWListItem(GetHwnd(), event.m_item, item);
+ event.m_itemIndex = event.m_item.m_itemId;
+ }
+ break;
+ case LVN_BEGINLABELEDITW:
+ {
+ eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT;
+ wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item);
+ wxConvertFromMSWListItem(GetHwnd(), event.m_item, item);
+ event.m_itemIndex = event.m_item.m_itemId;
+ }
+ break;
+
+ case LVN_ENDLABELEDITA:
+ {
+ eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
+ wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item);
+ wxConvertFromMSWListItem(NULL, event.m_item, item);
+ if ( ((LV_ITEM)item).pszText == NULL ||
+ ((LV_ITEM)item).iItem == -1 )
+ return FALSE;
+
+ event.m_itemIndex = event.m_item.m_itemId;
+ }
+ break;
+ case LVN_ENDLABELEDITW:
+ {
+ eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
+ wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item);
+ wxConvertFromMSWListItem(NULL, event.m_item, item);
+ if ( ((LV_ITEM)item).pszText == NULL ||
+ ((LV_ITEM)item).iItem == -1 )
+ return FALSE;
+
+ event.m_itemIndex = event.m_item.m_itemId;
+ }
+ break;
+
+ case LVN_COLUMNCLICK: