WTL怎么让View来响应菜单事件

 我来答
神话梦碎
2017-05-18 · TA获得超过8800个赞
知道大有可为答主
回答量:6699
采纳率:0%
帮助的人:3283万
展开全部
先要改View里面的消息循环,把它写成如下形式:
程序代码
BEGIN_MSG_MAP(CGameView)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_Create, OnCreate)
ALT_MSG_MAP(1) // Handle notify message.
COMMAND_ID_HANDLER(ID_GAME_START_NEW, OnGameStartNew)
END_MSG_MAP()

然后在CMainFrame的消息循环中加入CHAIN_MSG_MAP_ALT_MEMBER():
程序代码
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_Create, OnCreate)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
CHAIN_MSG_MAP_ALT_MEMBER(m_view, 1)
END_MSG_MAP()
匿名用户
2017-05-18
展开全部
在WTL里面,CMainFrame的消息循环是这样的:
程序代码
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_Create, OnCreate)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()

而View里面的消息循环是这样的:
程序代码
BEGIN_MSG_MAP(CGameView)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_Create, OnCreate)
COMMAND_ID_HANDLER(ID_GAME_START_NEW, OnGameStartNew)
END_MSG_MAP()

虽然我明明写了一个OnGameStartNew来响应菜单项ID_GAME_START_NEW,但是通过实验可以确定,CMainFrame并没有将这个消息转交过来,而是自己截获认为是无用的消息扔掉了。那么,如何让CMainFrame将消息交给View就是我要解决的问题了。

首先我想到的是在PreTranslateMessage这个函数上做文章,因为CMainFrame的PreTranslateMessage确实调用了 View的PreTranslateMessage函数,所以要想截获这个消息还是蛮容易的,但是由于自己要写一个显式的消息循环,写出来的代码极为丑 陋,不爽,只把它作为最后保底的方案。

接着我想到的是向消息循环注册Message Filter的方法,也就是在View的OnCreate中加入以下代码:
程序代码
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);

并且,要让View派生自CMessageFilter,如下所示:
程序代码
class CGameView
: public CScrollWindowImpl<CGameView>
, public CMessageFilter
{
// ...
};

但是很可惜,只有FrameWindow才能享用Message Filter带来的灵活性,View不可以。

再接着,我尝试使用CHAIN_MSG_MAP_MEMBER(),直接在CMainFrame的消息循环里面把View的消息循环给插进来:
程序代码
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_Create, OnCreate)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
CHAIN_MSG_MAP_MEMBER(m_view)
END_MSG_MAP()

不过让我十分沮丧的是,这样可以捕捉菜单消息了,也非常的简洁明了,但是View截获了很多本来不应该收到的消息,使得整个CMainFrame的显示等等都乱了!这可不行!

最后,我找到了CHAIN_MSG_MAP_ALT_MEMBER()和ALT_MSG_MAP(),用它们一起配合,终于让事情变得简洁好用了!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式