问题是这样的,偶做了一个 TreeCtrl 在工具条上,现在需要对当用户选择 TreeCtrl 中的条目后按下回车键做出相应反应,添加了 NM_RETURN 的消息映射宏及响应函数,但没有反应,何故?偶用 spy 看了 TreeCtrl 的消息,在 TreeCtrl 中按下回车键后并没有 WM_NOTIFY 消息发出.这就牵扯到另外一个问题, 偶做一个 TreeCtrl 在对话框上, 当 TreeCtrl 拥有输入焦点的时候, 按下回车键, 却会触发对话框的 OnOK 函数导致对话框关闭?为何, 明明是 TreeCtrl 拥有输入焦点呀?
或者自己从CTreeCtrl继承一个CMyTreeCtrl,然后在CMyTreeCtrl里定义消息响应函数NO_NOTIFY()
对于你的程序来说:工具条类就是TreeCtrl的父窗口,如果你自己从CTreeCtrl继承一个CMyTreeCtrl,并在工具条里面使用这个CMyTreeCtrl,这时,也可以把消息处理函数放到CMyTreeCtrl中进行
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);
}
{
// 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);
}