CTreeCtrl编辑节点时enter和escape不生效的bug

原创 2004年08月03日 16:05:00
Microsoft Knowledge Base Article - 167960 Content_subban.gif

BUG: ESC/ENTER Keys Do Not Work When Editing CTreeCtrl Labels

适用于
This article was previously published under Q167960

SYMPTOMS

When you edit labels in a CTreeCtrl, you are allowed to press the ESC key to cancel the changes or press the ENTER key to accept the changes. However, when the CTreeCtrl is a child window of a dialog box (CDialog), a formview window (CFormView), or a property page (CPropertyPage), the ESC or ENTER keys do not function as expected.

CAUSE

IsDialogMessage() function is called in the PreTranslateInput() function which in turn is called in the PreTranslateMessage() function of all CFormView or CDialog derived classes mentioned above. The ESC and ENTER keys are processed in IsDialogMessage() but are not passed on to the edit control created by the tree-view control. Thus, these keystrokes have no effect.

RESOLUTION

For Visual C++ 4.xx and later, we can trap the ESC and ENTER keystroke messages in the PreTranslateMessage() function for all CFormView, CDialog (modal or modeless) and CPropertyPage (either in modal or modeless CPropertySheet) derived classes.

In the code below, m_TreeCtrl is a member variable of those derived classes and it is of CTreeCtrl data type, and CMyXxx can be any CFormView, CDialog, or CPropertyPage derived class.
 BOOL CMyXxx::PreTranslateMessage(MSG* pMsg) { // If edit control is visible in tree view control, when you send a // WM_KEYDOWN message to the edit control it will dismiss the edit // control. When the ENTER key was sent to the edit control, the // parent window of the tree view control is responsible for updating // the item's label in TVN_ENDLABELEDIT notification code. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) { CEdit* edit = m_TreeCtrl.GetEditControl(); if (edit) { edit->SendMessage(WM_KEYDOWN, pMsg->wParam, pMsg->lParam); return TRUE; } } // CXxxx can be a CFormView, Cdialog, or CPropertyPage class. return CXxxx::PreTranslateMessage(pMsg); } 
For Visual C++ 2.xx, since PreTranslateMessage() is not called for modal CDialog-derived classes, the sample code above does not apply to the modal dialog and property page in a modal CPropertySheet derived class. In this situation, those keystroke messages can be trapped in the overridden OnOK() (for Enter key) and OnCancel() (for Esc key) functions in either CDialog or CPropertySheet derived-class. The sample code works fine even in the absence of both the OK and Cancel buttons from the dialog resource template.

NOTE: It is too late to trap those keystroke messages in CPropertyPage's OnOK() and OnCancel() functions. Therefore, we have to do it in CPropertySheet-derived class.

A new member function called IsTreeCtrlEditMessage() is added to the CDialog or CPropertySheet derived-class. This function sends a WM_KEYDOWN message to the tree-view's edit control when it is the window with focus. And it is being called in both overridden OnOK() and OnCancel() functions. The CMyDxxx in the sample code below can either be a CDialog or a CPropertySheet derived-class. Note that the MODAL_PROPERTYSHEET constant is declared and used in IsTreeCtrlEditMessage() so the same code can be applied to both CDialog and CPropertySheet derived-classes.
 // Set MODAL_PROPERTYSHEET to 1 for modal CPropertySheet-derived class // and 0 for CDialog-derived class. #define MODAL_PROPERTYSHEET 1 BOOL CMyDxxx::IsTreeCtrlEditMessage(WPARAM KeyCode) { BOOL rvalue = FALSE; // pWnd is a pointer to either an active CPropertyPage of the modal // CPropertySheet or a modal CDialog object. CWnd* pWnd = this; #if MODAL_PROPERTYSHEET pWnd = GetActivePage(); #endif // IDC_TREECTRL is the ID of the tree view control. CTreeCtrl *treectrl = (CTreeCtrl *) pWnd->GetDlgItem(IDC_TREECTRL); if (!treectrl) return rvalue; // If the edit control of the tree view control has the input focus, // sending a WM_KEYDOWN message to the edit control will dismiss the // edit control. When ENTER key was sent to the edit control, the // parentwindow of the tree view control is responsible for updating // the item's label in TVN_ENDLABELEDIT notification code. CWnd* focus = GetFocus(); CEdit* edit = treectrl->GetEditControl(); if ((CEdit *) focus == edit) { edit->SendMessage(WM_KEYDOWN, KeyCode); rvalue = TRUE; } return rvalue; } void CMyDxxx::OnOK() { // Do not dismiss the dialog object if ENTER key was sent to the tree // view's edit control. You may call the CDialog::OnOK() function if // this is for CDialog. if (!IsTreeCtrlEditMessage(VK_RETURN)) EndDialog(IDOK); } void CMyDxxx::OnCancel() { // Do not dismiss the dialog object if ESC key was sent to the tree // view's edit control. You might call the CDialog::Cancel() // function if this is for CDialog. if (!IsTreeCtrlEditMessage(VK_ESCAPE)) EndDialog(IDCANCEL); } 

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.

MFC CTreeCtrl 设置每一项Item颜色

1.CTreeCtrlXX继承CTreeCtrl,在CTreeCtrlXX里添加SetItemColor方法和重载OnPaint方法 2.添加消息yings 3.重载树控件#define CTre...
  • u011056389
  • u011056389
  • 2013年11月26日 11:28
  • 3109

CTreeCtrl利用TV_ITEM插入节点与遍历节点

插入树节点 TV_ITEM tvItem; tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_HANDLE | TVIF_SEL...
  • CNHK1225
  • CNHK1225
  • 2015年07月30日 11:22
  • 1047

mfc CTreeCtrl 添加节点 和绑定图标

1、添加控件并绑定变量 1、修改属性Line At Root为True Has Bootons改成True 3、初始化函数中如下: TVINSERTSTRUCT tvInsert; tvInsert....
  • woquNOKIA
  • woquNOKIA
  • 2016年11月24日 20:07
  • 545

CTreeCtrl点击节点左边的按钮或者图标等处理

问题引出:在CTreeCtrl 上点击节点,使用GetItemText 直接获取到了该节点的文本值,在树创建时是TVS_HASBUTTONS的时候,节点左边还会存在  +/-按钮,我想在点击 +/-按...
  • modyaj
  • modyaj
  • 2015年02月11日 16:19
  • 823

CTreeCtrl展开、收起子节点下所有的节点

转载自:http://blog.csdn.net/zmaojun/article/details/4006681
  • xiong_mao_1
  • xiong_mao_1
  • 2014年05月06日 03:10
  • 1873

选中CTreeCtrl的节点,弹出对话框嵌入到客户区中

前言在Outlookbar工具栏中,有CTreeCtrl树控件,点击一个节点,弹出的对话框会嵌入到客户区中。本文的样例涉及到BCGControlBar V22.1控件库,使用的是该库的自带例子BCGP...
  • u010670734
  • u010670734
  • 2017年04月24日 16:04
  • 140

CTreeCtrl的用法

树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点。MFC中使用CTreeCtrl类来封装树形控件的各种操作。通过调用 BOO...
  • Louis_815
  • Louis_815
  • 2016年12月05日 13:42
  • 269

CTreeCtrl之排序

 在实际开发中,我们往往需要对树控件(CTreeCtrl)的节点进行排序。事实上,大部分的排序工作可以用CTreeCtrl::SortChildren来实现,不过CTreeCtrl::SortC...
  • wangdong770909027
  • wangdong770909027
  • 2015年07月21日 13:30
  • 747

MFC制作一个可自由添加删除节点的树(CTreeCtrl)类

微软的MFC提供了强大的界面设计功能,但因为其很多函数过于繁琐,对初学者来说不好上手,而我自己在学习过程中也碰到了很多问题,查了很多文章,在此要特地感谢鸡琢米以及各位在CSDN上些小教程的各位前辈大佬...
  • zhuzexujiaxing
  • zhuzexujiaxing
  • 2017年04月23日 10:01
  • 1445

MFC——CTreeCtrl数据的处理:如何将数据和逻辑分开?

MFC——CTreeCtrl数据的处理:如何将数据和逻辑分开?
  • u011729265
  • u011729265
  • 2013年10月27日 23:07
  • 1935
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CTreeCtrl编辑节点时enter和escape不生效的bug
举报原因:
原因补充:

(最多只允许输入30个字)