问题是这样的,偶做了一个 TreeCtrl 在工具条上,现在需要对当用户选择 TreeCtrl 中的条目后按下回车键做出相应反应,添加了 NM_RETURN 的消息映射宏及响应函数,但没有反应,何故?偶用 spy 看了 TreeCtrl 的消息,在 TreeCtrl 中按下回车键后并没有 WM_NOTIFY 消息发出.这就牵扯到另外一个问题, 偶做一个 TreeCtrl 在对话框上, 当 TreeCtrl 拥有输入焦点的时候, 按下回车键, 却会触发对话框的 OnOK 函数导致对话框关闭?为何, 明明是 TreeCtrl 拥有输入焦点呀?

解决方案 »

  1.   

    CDialog::PretranslateMessage call OnOK when enter key is pressed. override it and call CWnd::PretranslateMessage in this case
      

  2.   

    感谢楼上这个可以解释在对话框中出现的情况,但是偶的 TreeCtrl 是在工具条上动态创建的,当 TreeCtrl 拥有输入焦点并且按下回车键时,仍然没有发出 WM_NOTIFY 消息, 这是怎么会事, 如何解决?
      

  3.   

    在你的PretranslateMessage里面处理WM_KEYDOWN,判断是不是按键VK_RETURN和焦点在不在TreeCtrl 上,然后做你的事情!屏蔽掉回车退出是见很简单的事,在OnOK函数中去掉CDialog::OnOK()函数就可以
      

  4.   

    在你的工具条类文件上响应TreeCtrl的消息处理函数NO_NOTIFY()
    或者自己从CTreeCtrl继承一个CMyTreeCtrl,然后在CMyTreeCtrl里定义消息响应函数NO_NOTIFY()
      

  5.   

    控件的消息响应是要传递给他的父窗口,所以相应的消息处理函数就要在他的父窗口里面定义和实现
    对于你的程序来说:工具条类就是TreeCtrl的父窗口,如果你自己从CTreeCtrl继承一个CMyTreeCtrl,并在工具条里面使用这个CMyTreeCtrl,这时,也可以把消息处理函数放到CMyTreeCtrl中进行
      

  6.   

    这个问题我已经解决了。但是我觉得楼上所说的在工具条中响应 ON_NOTIFY 消息的方法不能捕获到在 Tree 控件中按下回车键。我在工具条类中重载 OnNotify() 函数,并在其中添加代码,如下所示:
    BOOL CClassifyWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
    {
    // TODO: Add your specialized code here and/or call the base class
    NMHDR *pnMhdr;

    pnMhdr = (NMHDR *) lParam; TRACE("\r\n\r\n***************************\r\nNM_FIRST = %d", (int) NM_FIRST);

    TRACE("\r\n OnNotify wParam = %d, lParam = %d\r\n pnMhdr -> code = %d", 
    (int) wParam, (int) lParam, (int) pnMhdr -> code); if((int) pnMhdr -> code == NM_RETURN)
    {
    TRACE("Press return !");
    }
    else if((int) pnMhdr -> code == NM_DBLCLK)
    {
    TRACE("\r\n-------------- Double Click !");
    }
    else if((int) pnMhdr -> code == NM_CLICK)
    {
    TRACE("\r\n-------------- Click !");
    }
    else if((int) pnMhdr -> code == NM_KEYDOWN)
    {
    TRACE("\r\n-------------- Key Down !");
    }
    else if((int) pnMhdr -> code == NM_RCLICK)
    {
    TRACE("\r\n-------------- Right Click!");
    }
    else if((int) pnMhdr -> code == NM_CHAR)
    {
    TRACE("\r\n-------------- Char!");
    }
    else if((int) pnMhdr -> code == TVN_KEYDOWN)
    {
    TRACE("\r\n-------------- TVN_KEYDOWN!");
    }

    return CWnd::OnNotify(wParam, lParam, pResult);
    }通过运行,可以看到,当在 Tree 控件中单击/双击/单击右键 Tree 控件都会向工具条发送WM_NOTIFY 消息,并且在 OnNotify 函数中都可以得到相应的 Notification code 如 NM_CLICK, NM_DBLCLK, NM_RCLICK. 但是当 TREE 空间拥有输入焦点并且按下键时,在该函数当中确却不到 NM_CHAR,更看不到 NM_RETURN。能够看到的只有 TVN_KEYDOWN,同样按下 BackSpace、ESC 键后也不会触发 OnNotify 函数。
    偶现在就不明白 Windows 为什么要像这样做,它又是如何实现的呢?
    偶现在的解决办法是按照  所说,在工具条类当中重载 PreTranslateMessage() 函数。代码如下:
    BOOL CClassifyWnd::PreTranslateMessage(MSG* pMsg) 
    {
    int VKCode;

    VKCode = (int) pMsg ->wParam;  if(VKCode == 13 && pMsg ->message == WM_KEYDOWN)
    {

    // =============================
    //            ...... 
    // 按下回车键后实现功能的代码
    //            ......
    // ============================= ::SendMessage(hWndRichEditView, WM_SETFOCUS, NULL, NULL); // hWndRichEditView 为程序视图窗口的句柄
    ::SendMessage(hWndRichEditView, WM_ACTIVATE, (WPARAM) WA_ACTIVE, NULL);   return TRUE; } return CWnd::PreTranslateMessage(pMsg);
    }
      

  7.   

    呵呵!^_^可能微软开发MFC的工具条时就只认为用户在工具条上的操作就只有鼠标点击和激活Tab时的按键等响应消息真是这样的话,楼主就只能再重载PreTranslateMessage() 函数消息处理函数了或者楼主用我第二个方法试试,从CTreeCtrl继承一个自己的CMyTreeCtrl类,再在CMyTreeCtrl类中响应你所需要的消息不过不知道成不成功啊,我功力有限,帮不上什么忙啊!^_^
      

  8.   

    BOOL CMyTreeView::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class
    if(pMsg->message==WM_KEYDOWN)
    {
    if(pMsg->wParam==VK_RETURN)
    {
    m_TreeView.SetFocus();
    return TRUE;
    }
    }
    return CDialog::PreTranslateMessage(pMsg);
    }