使用一个Clistctrl控件显示了一些数据,现在想实现点击列头排序功能,因为需要点击不同的列头实现多种方式排序,请问怎样得到所点击的列头的内容以区分不同排序!~~~~

解决方案 »

  1.   

    OnColumnclickList1函数的第一个参数NMHDR* pNMHDR其实是一个NM_LISTVIEW的指针,该结构中的iSubItem表明是第几列,你传递给你的排序函数加以区分。
      

  2.   

    //m_List是一个CListCtrl,现在取第0列的列名:CHeaderCtrl* pmyHeaderCtrl = m_List.GetHeaderCtrl;
    if(!pmyHeaderCtrl)
       return;
       
    HDITEM hdi;
    TCHAR  lpBuffer[256];hdi.mask = HDI_TEXT;
    hdi.pszText = lpBuffer;
    hdi.cchTextMax = 256;pmyHeaderCtrl->GetItem(0, &hdi);
    //hdi.pszText放的就是列名
      

  3.   

    请问楼上这行是做什么用的CHeaderCtrl* pmyHeaderCtrl = m_result.GetHeaderCtrl;我编译后提示error C2440: 'initializing' : cannot convert from 'class CHeaderCtrl *(__thiscall CListCtrl::*)(void)' to 'class CHeaderCtrl *'错误
      

  4.   

    //////////////////////////enable sort of the listctrl
    void CViewPorts::OnLvnColumnclickProcList(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMLISTVIEW pnmv = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    if( pnmv->iSubItem == nSortedCol )
    bSortAscending = !bSortAscending;
    else
    bSortAscending = TRUE;
    nSortedCol = pnmv->iSubItem;
    SortTextItems( nSortedCol, bSortAscending );
    // bHandled = 0;
    *pResult = 0;
    }
    BOOL CViewPorts::SortTextItems( int nCol, BOOL bAscending,int low , int high )
    {
    HWND hHeaderCtrl = ListView_GetHeader(hwndListView);
    if (!hHeaderCtrl) return -1;
    int nColCount =(int)::SendMessage(hHeaderCtrl, HDM_GETITEMCOUNT, 0L, 0L);  
    #ifdef _DEBUG
    TCHAR tmp_msg[1024];
    if(bAscending)
    wsprintf(tmp_msg,"SortTextItems(%d,TRUE,%d,%d), nColCount:%d",nCol,low,high,nColCount);
    else
    wsprintf(tmp_msg,"SortTextItems(%d,FALSE,%d,%d), nColCount:%d",nCol,low,high,nColCount);
    OutputDebugString(tmp_msg);
    #endif
    if(nCol>=nColCount)
    return FALSE; int itemcount=ListView_GetItemCount(hwndListView);
    if( high == -1 ) 
    high = itemcount - 1;
    int lo = low;
    int hi = high;
    if( hi <= lo ) return FALSE;
    std::basic_string<TCHAR> midItem=GetItemText( (lo+hi)/2, nCol );
    // loop through the list until indices cross
    while( lo <= hi )
    {
    // rowText will hold all column text for one row
    std::vector<std::basic_string<TCHAR> > rowText;
    // find the first element that is greater than or equal to 
    // the partition element starting from the left Index.
    if( bAscending )
    //while( ( lo < high ) && ( GetItemText(lo, nCol) < midItem ) )
    while( ( lo < high ) && CompareItem( midItem,GetItemText(lo, nCol)  ) )
    ++lo;
    else
    while( ( lo < high ) && CompareItem( GetItemText(lo, nCol) , midItem ) )
    //while( ( lo < high ) && ( GetItemText(lo, nCol) > midItem ) )
    ++lo;
    // find an element that is smaller than or equal to 
    // the partition element starting from the right Index.
    if( bAscending )
    while( ( hi > low ) && CompareItem( GetItemText(hi, nCol) , midItem ) )
    //while( ( hi > low ) && ( GetItemText(hi, nCol) > midItem ) )
    --hi;
    else
    while( ( hi > low ) && CompareItem( midItem,GetItemText(hi, nCol)) )
    //while( ( hi > low ) && ( GetItemText(hi, nCol) < midItem ) )
    --hi;
    // if the indexes have not crossed, swap
    // and if the items are not equal
    if( lo <= hi )
    {
    // swap only if the items are not equal
    if( GetItemText(lo, nCol) != GetItemText(hi, nCol))
    {
    // swap the rows
    LV_ITEM lvitemlo, lvitemhi;
    rowText.resize( nColCount );
    int i;
    for( i=0; i<nColCount; i++)
    rowText[i] = GetItemText(lo, i);
    lvitemlo.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
    lvitemlo.iItem = lo;
    lvitemlo.iSubItem = 0;
    lvitemlo.stateMask = LVIS_CUT | LVIS_DROPHILITED | 
    LVIS_FOCUSED |  LVIS_SELECTED | LVIS_OVERLAYMASK | LVIS_STATEIMAGEMASK; lvitemhi = lvitemlo;
    lvitemhi.iItem = hi;
    ListView_GetItem(hwndListView,&lvitemlo);
    ListView_GetItem(hwndListView,&lvitemhi);
    for( i=0; i<nColCount; i++)
    SetItemText(lo, i, GetItemText(hi, i));
    lvitemhi.iItem = lo;
    ListView_SetItem(hwndListView,&lvitemhi); for( i=0; i<nColCount; i++)
    SetItemText(hi, i, rowText[i]);
    lvitemlo.iItem = hi;
    ListView_SetItem(hwndListView,&lvitemlo);
    }
    ++lo;
    --hi;
    }
    }
    // If the right index has not reached the left side of array
    // must now sort the left partition.
    if( low < hi )
    SortTextItems( nCol, bAscending , low, hi);
    // If the left index has not reached the right side of array
    // must now sort the right partition.
    if( lo < high )
    SortTextItems( nCol, bAscending , lo, high );
    return TRUE;
    }std::basic_string<TCHAR> CViewPorts::GetItemText(int nItem, int nSubItem)
    {
    TCHAR itembuf[256];
    memset(itembuf,0,sizeof(itembuf));
    ListView_GetItemText(hwndListView,nItem,nSubItem,itembuf,sizeof(itembuf)-1);
    return std::basic_string<TCHAR>(itembuf);
    }void CViewPorts::SetItemText(int item, int subitem, std::basic_string<TCHAR> sdata)
    {
    TCHAR tmpbuf[256];
    ZeroMemory(tmpbuf,sizeof(tmpbuf));
    wsprintf(tmpbuf,_T("%s"),sdata.c_str());
    ListView_SetItemText(hwndListView,item,subitem,tmpbuf);
    }bool CViewPorts::CompareItem(std::basic_string<TCHAR> &str1, std::basic_string<TCHAR> &str2)
    {
    if(IsNumberString(str1)&&IsNumberString(str2))
    {
    return _ttoi(str1.c_str()) > _ttoi(str2.c_str());
    }
    else
    return str1>str2;
    }bool CViewPorts::IsNumberString(std::basic_string<TCHAR> &s_param)
    {
    int str_len = s_param.length();
    if(str_len<1)
    return false;
    for(int i=0;i<str_len;i++)
    {
    if(!_istdigit(s_param.at(i)))
    return false;
    }
    return true;
    }