MFC 對ListiControl實現編輯功能


最近用MFC實現一個簡單的權重設置工作,最簡便直接的方法是用ListControl控件進行編輯,但ListControl沒有直接編輯功能。查遍資料,主要參考的是如下兩篇文章。

https://blog.csdn.net/xianglifighter/article/details/17592209/

https://blog.csdn.net/cumirror/article/details/5183514

但是還是遇到兩個問題

第一個問題是pNMListView->iItem返回值是-1. 或者pos=m_list.GetFirstSelectedItemPosition();pos為空

 NM_LISTVIEW* pNMListView=(NM_LISTVIEW*)pNMHDR;  
 m_Row = pNMListView->iItem; //返回的值是-1

pos=m_list.GetFirstSelectedItemPosition(); //pos = NULL

發現pos為空,說明雙擊后無法獲得具體點的位置。

第二個問題是edit中的數據寫到之前點擊的位置中,但是沒有顯示。

解決上述兩個問題的關鍵有兩步

第一個是設置高亮風格。在OnInitDialog()函數中

dwStyle |= LVS_EX_FULLROWSELECT;//選中某行使整行高亮(只適用與report風格的listctrl) 

第二個是 添加在SetItemText之前添加InsertItem注意InsertItem添加的位置,是要在對ListControl編輯之前。只有添加InsertItem后pNMListView->iItem返回值才有意義,並且可以把edit數據顯示到ListControl中。

注意第二步是重中之重,尤其是InsertItem添加的位置,不可以直接添加到ListControl編輯操作之后(如雙擊之后再InsertItem)。沒有這步是不可以實現編輯的(我估計應該有其他方法,但我水平有限,還懇請各位大神不吝賜教,拜謝)。

詳細步驟及代碼如下。本人用的編譯器是VS2013,參考的是上面第一個鏈接的文章,但增加了一些細節並解決返回值為-1的問題:

第一步:添加edit控件。

添加一個edit控件到對話框的任意空白位置(實際上放到哪里效果都一樣,不過這樣可以方便管理)。

關聯edit控件變量如 CListCtrl m_srcEdit1; 

OnInitDialog()函數中寫入 m_srcEdit1.ShowWindow(SW_HIDE); 用於初始隱藏編輯框

第二步:添加ListControl控件並初始化。

添加一個CListCtrl控件,設置控件ID。關聯一個變量如:CListCtrl m_srcWList;

初始化CListCtrl控件風格,在OnInitDialog()函數中

LONG lStyle;
lStyle = GetWindowLong(m_srcWList.m_hWnd, GWL_STYLE);//獲取當前窗口style 
lStyle &= ~LVS_TYPEMASK; //清除顯示方式位 
lStyle |= LVS_REPORT; //設置style 
SetWindowLong(m_srcWList.m_hWnd, GWL_STYLE, lStyle);//設置style 
DWORD dwStyle = m_srcWList.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT;//選中某行使整行高亮(只適用與report風格的listctrl) 
dwStyle |= LVS_EX_GRIDLINES;
m_srcWList.SetExtendedStyle(dwStyle); //設置擴展風格

然后響應該控件的NM_DBLCLK消息,也就是雙擊事件處理消息。

NM_DBLCLK消息在類向導的“命令”,找到對象(ID)中該ListControl的ID,然后在右側的消息中找到NM_DBLCLK。

第三步:添加InsertItem。

用來解決返回值-1的問題以及ListControl不顯示結果。InsertItem可放到任意在第四步函數響應前的步驟里。如放到OnInitDialog()里。nNewCount為你要設置的默認的表格的行的數量(類似Excel最左側的行號)。

CString strListInfo;
for (int i = 0; i < nNewCount; i++)
{
    strListInfo.Format(_T("%d"), i + 1);
    LPCTSTR pStr = LPCTSTR(strListInfo);
		
    m_srcWList.InsertItem(i, _T(pStr));
}

第四步:添加NM_DBLCLK事件處理程序。

m_srcWList.SetExtendedStyle(m_srcWList.GetExtendedStyle() | LVS_EX_FULLROWSELECT); //設置選中整行

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CRect rc;
m_Row = pNMListView->iItem;//獲得選中的行  
m_Col = pNMListView->iSubItem;//獲得選中列

if (pNMListView->iSubItem != 0) //如果選擇的是子項;  
{
    m_srcWList.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc);//獲得子項的RECT;  
    m_srcEdit1.SetParent(&m_srcWList);//轉換坐標為列表框中的坐標  
    m_srcEdit1.MoveWindow(rc);//移動Edit到RECT坐在的位置;  
    m_srcEdit1.SetWindowText(m_srcWList.GetItemText(m_Row, m_Col));//將該子項中的值放在Edit控件中;  
    m_srcEdit1.ShowWindow(SW_SHOW);//顯示Edit控件;  
    m_srcEdit1.SetFocus();//設置Edit焦點  
    m_srcEdit1.ShowCaret();//顯示光標  
    m_srcEdit1.SetSel(-1);//將光標移動到最后  
}
*pResult = 0;

注意,m_Row和m_Col在頭文件中定義為int類型。

第五步:響應Edit控件m_srcEdit1的EN_KILLFOCUS消息。

是失去編輯框焦點時的消息處理。用於把Edit數據傳到ListControl中。EN_KILLFOCUS消息創建方法與ListControl的NM_DBLCLK消息創建方法一樣。響應該消息。

UpdateData();
CString tem, strListInfo;
m_srcEdit1.GetWindowText(tem);    //得到用戶輸入的新的內容  
m_srcWList.SetItemText(m_Row, m_Col, tem);   //設置編輯框的新內容  
m_srcEdit1.ShowWindow(SW_HIDE);                //隱藏編輯框  

最后結果輸出如下:

    







注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com