Is there any way to make editable CTreeCtrl
items that are fit in exact condition, not all of tree items.
If I set TVS_EDITLABELS
, all tree items can be changed by right button click
CViewTree m_ModelTree; // CViewTree based on CTreeCtrl
const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TVS_EDITLABELS;
if (!m_ModelTree.Create(dwViewStyle, rectDummy, this, IDC_TREEMODEL))
{
TRACE0(_T("Failed to create Class View\n"));
return -1; // fail to create
}
And I need to edit only exact type of nodes. Something like this:
HTREEITEM item = m_ModelTree.GetSelectedItem();
auto it = theApp.TreeMap.find(item);
if (it == theApp.TreeMap.end()) return;
if(it->type == tree_node_type::indexes)
m_ModelTree.EditLabel(hItem);
else
//FORBID EDIT
Or maybe is there a way to forbid edit lable with TV_INSERTSTRUCT
on the InsertItem
step...?
TV_INSERTSTRUCT tvinsert;
m_ModelTree.InsertItem(&tvinsert);
The standard Tree View control with the TVS_EDITLABELS
style allows clients to control, at run time, whether any given item can be edited. This is offered in the form of a TVN_BEGINLABELEDIT
notification sent to the control's parent, where the return value determines whether editing should be canceled.
The MFC entry Tree Control Label Editing in the documentation provides details:
When label editing begins, a tree control sends a
TVN_BEGINLABELEDIT
notification message. By processing this notification, you can allow editing of some labels and prevent editing of others. Returning 0 allows editing, and returning nonzero prevents it.
To receive TVN_BEGINLABELEDIT
notifications, the control parent (presumably a dialog or regular window) must have an entry in its message map that wires the notification to a callback function. The ON_NOTIFY
macro is the most convenient way to go about this:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
// ...
ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_TREEMODEL, OnTCBeginLabelEdit)
END_MESSAGE_MAP()
The OnTCBeginLabelEdit
callback must have the following signature:
afx_msg void OnTCBeginLabelEdit(NMHDR* pNotifyStruct, LRESULT* result);
Its implementation is where the logic to decide whether editing should be canceled goes:
void CMyDialog::OnTCBeginLabelEdit(NMHDR* pNotifyStruct, LRESULT* result) {
// The TVN_BEGINLABELEDIT notification sends an NMTVDISPINFO structure
auto const& disp_info = *reinterpret_cast<NMTVDISPINFO*>(pNotifyStruct);
// Get the target item
auto const current_item = disp_info.item.hItem;
// Implement the logic here
bool do_cancel = ...;
// Pass the decision through result
*result = do_cancel;
}
The above assumes that the tree view control is a child of a dialog called CMyDialg
that derives from CDialogEx
. Those are the only parts that need to be adjusted accordingly.