MFC中點擊ListControl時,第一次點擊不響應NM_CLICK消息,第二次才響應的問題

這個問題困擾了我三天,先描述一下問題所在。

我創建了一個ListControl,並將這個控件放在了一個對話框上面。具體的創建代碼如下:

m_meshlistctrl.Create(WS_CHILD|WS_BORDER|LVS_REPORT|LVS_SINGLESELC,Rect(1,1,300,400), this, IDC_LIST1);    //  IDC_LIST1是我綁定的ListControl資源

m_meshlistctrl.SetWindowPos(this,1,1,300,tabRect.bottom/2-1,SWP_SHOWWINDOW |SWP_NOACTIVATE | SWP_NOZORDER );

m_meshlistctrl.ShowWindow(SW_SHOW);

DWORDdwExStyle = GetExtendedStyle();

        SetExtendedStyle( dwExStyle |LVS_EX_ONECLICKACTIVATE| LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES ); 

我創建完這個ListControl以後 想通過NM_CLICK消息來響應左擊ListControl時產生的操作。添加消息響應函數如下:

afx_msg void OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult);//在頭文件中添加

ON_NOTIFY(NM_CLICK, IDC_LIST1, &CSimMeshProDlg::OnNMClickList1)   //關聯處理單擊左鍵函數

然後問題出現了,當我在ListControl中插入幾列數據時,點擊ListControl中非數據處時,會默認選中幾列數據爲藍色高亮顯示。而我並沒有設置其爲高亮狀態(此問題原因已經發現:我在插入數據時這樣做的:m_meshlistctrl.InsertItem(LVIF_TEXT | LVIF_STATE, i,"", (i % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED, 0, 0);//導致偶數行默認爲選中狀態)。並且第一次點擊ListControl控件非數據部分時,NM_CLICK消息不會得到觸發。而當我第二次點擊ListControl控件非數據部位時,NM_CLICK消息纔會得到觸發。我糾結了兩三天,這個問題還是沒得到解決,但是由於項目需要,我將ListControl的第一行數據設置爲默認選中狀態,方法如下:

m_meshlistctrl.SetItemState(0, LVIS_SELECTED|LVIS_FOCUSED,/*LVIS_DROPHILITED|*/LVIS_SELECTED|LVIS_FOCUSED);

這樣,儘管點擊ListControl非數據部位時,仍需要兩次才能觸發NM_CLICK消息,但是可以將藍色高亮顯示在第一行。勉強算達到要求。MFC博大精深,還需耐住性子,好好研究。在這裏記錄一下,有大神如果能夠幫我解惑,甚爲感激。

下面貼出ListControl的一些常規使用的風格:

         一:設置ListControl的風格

 LONG lStyle;
       lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//獲取當前窗口style
      lStyle &= ~LVS_TYPEMASK; //清除顯示方式位
      lStyle |= LVS_REPORT; //設置style
       SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//設置style
 
      DWORD dwStyle = m_list.GetExtendedStyle();
       dwStyle |= LVS_EX_FULLROWSELECT;//選中某行使整行高亮(只適用與report風格的listctrl)
       dwStyle |= LVS_EX_GRIDLINES;//網格線(只適用與report風格的listctrl)
       dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
       m_list.SetExtendedStyle(dwStyle); //設置擴展風格
       注:listview的style請查閱msdn
    

二:選中和取消選中一行

     int nIndex = 0;
     //選中
     m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
     //取消選中
     m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);

三:失去焦點後仍然高亮顯示一行或熄滅一行

//獲得選中行的索引
m_SecCount = (int)m_lc.GetFirstSelectedItemPosition()-1;
//設置選中行一直高亮顯示
m_lc.SetItemState(m_SecCount,LVIS_DROPHILITED,LVIF_STATE);
//取消在失去高亮時候選中行的高亮顯示
m_lc.SetItemState(m_SecCount,FALSE,LVIF_STATE);

具體更詳細的可以參考:http://blog.sina.com.cn/s/blog_635ff3050101luqx.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章