显示上下文菜单后为什么要SendMessage

antimatterworld 2008-03-24 05:25:02
void CMainWindow::OnContextMenu(CWnd* pWnd,CPoint point)
{
CRect rect;
GetClientRect(&rect);
ClientToScreen(&rect);
if(rect.PtInRect(point))
{
CMenu* pMenu = GetSystemMenu(FALSE);
UpdateSystemMenu(pMenu);

int nID = (int)pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|
TPM_RIGHTBUTTON|TPM_RETURNCMD,point.x,point.y,this);
if(nID > 0)
SendMessage(WM_SYSCOMMAND,nID,0);
return;
}
CFrameWnd::OnContextMenu(pWnd,point);
}


MSDN:
BOOL TrackPopupMenu(
UINT nFlags,
int x,
int y,
CWnd* pWnd,
LPCRECT lpRect = 0
);


Return Value
Nonzero if the function is successful; otherwise 0.

我觉得:
if(nID > 0)
SendMessage(WM_SYSCOMMAND,nID,0);


有错误,nID根本就不是什么真正的ID,只是个BOOL值,在说了,这段程序只是显示上下文菜单,具体发什么命令,那得看用户点哪个子菜单吧~~

这是MFC Windows程序设计第2版P733 - 734的一段代码.

是不是书上的代码写错了啊?听说这本书上有几处错误...
...全文
115 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
antimatterworld 2008-03-24
3Q
回复
cnzdgs 2008-03-24
我上面已经解释了,系统菜单消息是WM_SYSCOMMAND,而TrackPopupMenu就算不加TPM_RETURNCMD也只会产生WM_COMMAND消息,所以必须要自己来发WM_SYSCOMMAND消息。至于加了TPM_RETURNCMD之后会不会有WM_SYSCOMMAND,你可以重载OnCommand函数并设置断点调试来验证,这一点并不重要。
回复
antimatterworld 2008-03-24
这个菜单是从系统菜单上衔接来的,就是加了个全屏和置顶菜单。
现在问题的焦点是,如果加入了TPM_RETURNCMD是否在选中一个子菜单,如果不手动发送消息,系统就不会接收到消息?
回复
cnzdgs 2008-03-24
我现在用的是VS2005的MSDN,TPM_RETURNCMD标志不是新增加的,VS2003的MSDN中肯定也有说明,你要看的是TrackPopupMenu而不是TrackPopupMenu method。

有关TPM_RETURNCMD的说明:
TPM_RETURNCMD
If this flag is set, the function returns the menu item identifier of the user's selection in the return value.

TPM_RETURNCMD标志我也没用过,不过即使菜单向窗口发消息也是WM_COMMAND而不会是WM_SYSCOMMAND,所以要自己发这个消息。这种情况一般应该用PostMessage来发,SendMessage也可以。
回复
antimatterworld 2008-03-24
楼上2位大侠用的是哪个版本的MSDN?
我用的是VS2003的.
如果是指定了TPM_RETURNCMD ,那么是否程序运行到显示菜单的时候会等待,当用户选择了一个子菜单后,才给nID付值,并且只有用SendMessage才能发送消息,菜单自己并不会象顶层菜单那样自动发消息?
请达人再解释的具体点,我这里的MSDN是VS2003的,好象和以前的VS6有些出入.
回复
htlxiao 2008-03-24
If you specify TPM_RETURNCMD in the uFlags parameter, the return value is the menu-item identifier of the item that the user selected. If the user cancels the menu without making a selection, or if an error occurs, then the return value is zero.

If you do not specify TPM_RETURNCMD in the uFlags parameter, the return value is nonzero if the function succeeds and zero if it fails. To get extended error information, call GetLastError.
回复
cnzdgs 2008-03-24
没有错。
MSDN中对TrackPopupMenu返回值的解释:
If you specify TPM_RETURNCMD in the uFlags parameter, the return value is the menu-item identifier of the item that the user selected. If the user cancels the menu without making a selection, or if an error occurs, then the return value is zero.
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2008-03-24 05:25
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……