2017-01-03 69 views
0

我使用WinApi創建了一個樹視圖控件。我想捕獲鼠標點擊複選框。通知消息NM_CLICK包含NMHDR,它沒有關於被點擊的節點的信息。由於點擊的節點可能與選定的節點不同,因此應該找到一種方法來查找哪個節點已被選中或未選中,可能是HTREEITEM,或者在將項添加到樹視圖時插入lParam。我想要實時捕獲/取消選中。我如何指定哪個節點被選中/取消選中?任何幫助或鏈接表示讚賞。 mr.abzadeh如何捕獲點擊哪個treeview節點

回答

0

您可以發送TVM_HITTEST消息(或使用TreeView_HitTest宏)找到樹型視圖項目,給予客戶相對座標。

要在生成NM_CLICK消息時獲取光標位置,請使用GetMessagePos API。

這使您可以監視控件客戶區中的任何鼠標點擊。如果您對標準樹視圖控件實現的結果感興趣,則可以改爲處理TVN_ITEMCHANGINGTVN_ITEMCHANGED通知。兩者都提供NMTVITEMCHANGE結構,其中hItem標識要更改的項目,而lParam則攜帶應用程序特定數據。

+0

downvote作爲壞的和OP問題的有效解決方案 - 「我怎樣才能指定哪些節點被檢查/未選中? – RbMm

+0

您在**之後已經添加了有關'TVN_ITEMCHANGING'和'TVN_ITEMCHANGED'通知**的信息我用自己的答案編寫了自己的答案 - 編輯歷史記錄可以看到這個答案。這是如何最低限度不好:) – RbMm

+0

@RbMm:因爲你還沒有完全掌握,這個地方是如何工作的,請參加[遊覽]並訪問[幫助]。納入來自反饋意見的建議**是正確的做法。 – IInspectable

1

我想捕獲實時檢查/取消選中。我如何 指定哪個節點被選中/取消選中?

這個存在通知TVN_ITEMCHANGINGTVN_ITEMCHANGED - 尋找的NMTVITEMCHANGEuStateNewuStateOld成員 - 當樹視圖具有複選框(TVS_CHECKBOXES風格),它使用狀態圖像列表2個圖像 - uncheckedchecked

所以state & TVIS_STATEIMAGEMASK0當沒有複選框,INDEXTOSTATEIMAGEMASK(1)爲未選中和INDEXTOSTATEIMAGEMASK(2)爲檢查。基於這個信息,我們可以捕獲鼠標點擊複選框

通過使用TVN_ITEMCHANGING您還可以防止當您爲此通知返回TRUE時的更改。如果你只需要通知 - 使用TVN_ITEMCHANGED

case WM_NOTIFY: 
     { 
      union { 
       LPARAM lp; 
       NMTVITEMCHANGE *pnm; 
       NMHDR* phdr; 
      }; 
      lp = lParam; 

      switch (phdr->code) 
      { 
      case TVN_ITEMCHANGING: 
       { 
        UINT CheckStateOld = pnm->uStateOld & TVIS_STATEIMAGEMASK; 
        UINT CheckStateNew = pnm->uStateNew & TVIS_STATEIMAGEMASK; 

        if (CheckStateNew != CheckStateOld) 
        { 
         PCSTR szstate = "??"; 
         switch (CheckStateNew) 
         { 
         case INDEXTOSTATEIMAGEMASK(1): 
          szstate = "uncheck"; 
          break; 
         case INDEXTOSTATEIMAGEMASK(2): 
          szstate = "check"; 
          break; 
         } 
         DbgPrint("%p>%s\n", pnm->lParam, szstate); 
        } 
       } 
       return FALSE; 
      } 
     } 

也讀How to Work With State Image Indexes

// Image 1 in the tree-view check box image list is the unchecked box. 
    // Image 2 is the checked box. 

    tvItem.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1)); 

通知TVN_ITEMCHANGINGTVN_ITEMCHANGED從Windows Vista的可用開始。如果你還需要XP的支持 - 在xp只有選項使用@IInspectable solution

+0

重要的是要提到TVN_ITEMCHANGING從Vista開始可用,否則OP必須使用hittesting。 – AlwaysLearningNewStuff

+0

@AlwaysLearningNewStuff是的..,我想念這個。我的錯誤 – RbMm

+0

不是一個錯誤,只是重要的一點。我已經提出了你的答案。 – AlwaysLearningNewStuff