关于在MFC派生类中处理菜单消息(可能涉及到消息反射)

DDGG 2009-07-30 11:42:53
新建一个MFC对话框工程,在对话框里加入一棵树(CTreeCtrl)和一个菜单,然后新建一个MFC类CMyTreeCtrl继承自CTreeCtrl。
我想让菜单项点击的事件由树而不是对话框来处理,于是修改MyTreeCtrl.cpp如下:

// MyTree.cpp : implementation file
//

#include "stdafx.h"
#include "Test.h"
#include "MyTree.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyTree

CMyTree::CMyTree()
{
}

CMyTree::~CMyTree()
{
}


BEGIN_MESSAGE_MAP(CMyTree, CTreeCtrl)
//{{AFX_MSG_MAP(CMyTree)
ON_COMMAND(ID_MENUITEM32771, OnMenuitem32771) // 改成ON_CONTROL_REFLECT也没用
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyTree message handlers

void CMyTree::OnMenuitem32771()
{
AfxMessageBox("hi"); // 点击菜单项后此处没有执行

}


请问原因为何?网上说ON_COMMAND的消息反射应该是ON_CONTROL_REFLECT啊,可是仍然处理不了菜单点击。
...全文
201 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
捕鲸叉 2009-07-30
  • 打赏
  • 举报
回复
CMyDlg::OnCmdMsg(...)
捕鲸叉 2009-07-30
  • 打赏
  • 举报
回复
你的消息没有路由到你的控件上, 建议你看看虚函数CFrameWnd::OnCmdMsg,看明白它就知道怎么办了
DDGG 2009-07-30
  • 打赏
  • 举报
回复
是通过修改对话框属性,把那个菜单设置为对话框的主菜单了,那个菜单下有一项ID是ID_MENUITEM32771。
通过类向导对这个ID的ON_COMMAND在CMyTreeCtrl中进行了消息映射。
aa3000 2009-07-30
  • 打赏
  • 举报
回复
菜单怎么弹出的?

TrackPopupMenuEx ?

DDGG 2009-07-30
  • 打赏
  • 举报
回复
那ON_CONTROL_REFLECT呢?这个不是号称能反射对话框的ON_COMMAND给其下的子控件吗?
一开始的回忆 2009-07-30
  • 打赏
  • 举报
回复
ON_COMMAND 映射了一个消息。ID是ID_MENUITEM32771,
但是点击了Menu后就会给对话框产生消息,没有给Tree产生,所以,CMyTree就不会捕获到这个ID等于MENUITEM32771的消息,也不会产生CMyTree::OnMenuitem32771()事件。

我这样理解。
DDGG 2009-07-30
  • 打赏
  • 举报
回复
恩,谢谢togoblime,你的方法也不错!
DDGG 2009-07-30
  • 打赏
  • 举报
回复
哈哈,我发现不用这么麻烦,把

ON_COMMAND(ID_MENUITEM32771, OnMenuitem32771)

移到对话框的CPP里面,写成这样就行了:

ON_COMMAND(ID_MENUITEM32771, CMyTree::OnMenuitem32771)
togoblime 2009-07-30
  • 打赏
  • 举报
回复
菜单的消息默认是由它的父窗口来处理的,要让树控件接收到菜单消息只需将TrackPopupMenu的最后一个参数设为TreeCtrl指针即可
BOOL TrackPopupMenu(
UINT nFlags,
int x,
int y,
CWnd* pWnd,
LPCRECT lpRect = 0
);
pWnd
Identifies the window that owns the pop-up menu. This window receives all WM_COMMAND messages from the menu. In Windows versions 3.1 and later, the window does not receive WM_COMMAND messages until TrackPopupMenu returns. In Windows 3.0, the window receives WM_COMMAND messages before TrackPopupMenu returns.

wuqiangu 2009-07-30
  • 打赏
  • 举报
回复
可以自定义消息转发
在对话框中接收单击菜单的消息,在里面直接发送自定义消息,在树控件中接受该自定义消息,接受后就可以处理你想处理的东西了。
Conry 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ddgg 的回复:]
楼上的两位说得好像都有道理,那具体应该怎么做呢?
[/Quote]
在对话框处理,然后调用tree的方法就行了
DDGG 2009-07-30
  • 打赏
  • 举报
回复
楼上的两位说得好像都有道理,那具体应该怎么做呢?
Yofoo 2009-07-30
  • 打赏
  • 举报
回复
消息反射是子控件自己的消息, 与菜单的消息没有关系,
你的这个情况需要对话框做代理, 转发菜单消息到tree

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧