这算是一个演示程序吧,想不到上下文菜单也是採用ON_COMMAND宏来进行消息映射,在这里,我发现一个问题:从CWnd派生的类ON_UPDATE_COMMAND_UI_RANGE似乎没有效果,不知道应该再加点什么,可是从CFrameWnd派生出来问题就不会发生,真是奇怪……

看看从CWnd派生出来的效果:

contextMenuDemo.h

#pragma once
class CMyApp : public CWinApp {
virtual BOOL InitInstance();
};
class CMainWindow : public CWnd {
public:
CMainWindow();
protected:
int m_nShape;
void PostNcDestroy();
int OnCreate(LPCREATESTRUCT lpCreateStruct);
void OnPaint();
void OnContextMenu(CWnd* pWnd, CPoint point);
void OnShape(UINT nID);
void OnUpdateShape(CCmdUI* pCmdUI);
DECLARE_MESSAGE_MAP()
};

contextMenuDemo.cpp:

#include <afxwin.h>
#include "contextMenuDemo.h"
#include "resource.h"
CMyApp myApp;
BOOL CMyApp::InitInstance() {
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow, CWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_CONTEXTMENU()
ON_COMMAND_RANGE(ID_SHAPE_RECT, ID_SHAPE_CIRCLE, OnShape)
ON_UPDATE_COMMAND_UI_RANGE(ID_SHAPE_RECT, ID_SHAPE_CIRCLE, OnUpdateShape)
END_MESSAGE_MAP()
CMainWindow::CMainWindow() {
CString strWndClass = AfxRegisterWndClass(0,
AfxGetApp()->LoadStandardCursor(IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),
AfxGetApp()->LoadStandardIcon(IDI_WINLOGO));
CreateEx(0,
strWndClass,
_T("玩玩了"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL);
m_nShape = ID_SHAPE_RECT;
}
void CMainWindow::PostNcDestroy() {
delete this;
}
int CMainWindow::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if(CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void CMainWindow::OnContextMenu(CWnd* pWnd, CPoint point) {
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CPoint pt = point;
ScreenToClient(&pt);
CRect rc;
GetClientRect(&rc);
CMenu* pMenu = menu.GetSubMenu(0);
if(rc.PtInRect(pt)) {
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x,
point.y, AfxGetMainWnd());
return;
}
CWnd::OnContextMenu(pWnd, point);
}
void CMainWindow::OnShape(UINT nID) {
m_nShape = nID;
Invalidate();
}
void CMainWindow::OnPaint() {
CPaintDC dc(this);
switch(m_nShape) {
case ID_SHAPE_RECT:
dc.Rectangle(100, 100, 500, 500);
break;
case ID_SHAPE_CIRCLE:
dc.Ellipse(100, 100, 500, 500);
break;
}
}
void CMainWindow::OnUpdateShape(CCmdUI* pCmdUI) {
pCmdUI->SetCheck(pCmdUI->m_nID == m_nShape);
}

执行效果没有太大的问题,就是SetCheck没有效果……

我们从CFrameWnd派生出来的话,问题就好了:

头文件:
#pragma once
class CMyApp : public CWinApp {
virtual BOOL InitInstance();
};
class CMainWindow : public CFrameWnd {
public:
CMainWindow();
protected:
int m_nShape;
//void PostNcDestroy();
//int OnCreate(LPCREATESTRUCT lpCreateStruct);
void OnPaint();
void OnContextMenu(CWnd* pWnd, CPoint point);
void OnShape(UINT nID);
void OnUpdateShape(CCmdUI* pCmdUI);
DECLARE_MESSAGE_MAP()
};

实现文件:
#include <afxwin.h>
#include "contextMenuDemo.h"
#include "resource.h"
CMyApp myApp;
BOOL CMyApp::InitInstance() {
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_CONTEXTMENU()
ON_COMMAND_RANGE(ID_SHAPE_RECT, ID_SHAPE_CIRCLE, OnShape)
ON_UPDATE_COMMAND_UI_RANGE(ID_SHAPE_RECT, ID_SHAPE_CIRCLE, OnUpdateShape)
END_MESSAGE_MAP()
CMainWindow::CMainWindow() {
Create(NULL, _T("玩玩"));
m_nShape = ID_SHAPE_RECT;
}
void CMainWindow::OnContextMenu(CWnd* pWnd, CPoint point) {
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CPoint pt = point;
ScreenToClient(&pt);
CRect rc;
GetClientRect(&rc);
CMenu* pMenu = menu.GetSubMenu(0);
if(rc.PtInRect(pt)) {
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x,
point.y, AfxGetMainWnd());
return;
}
CWnd::OnContextMenu(pWnd, point);
}
void CMainWindow::OnShape(UINT nID) {
m_nShape = nID;
Invalidate();
}
void CMainWindow::OnPaint() {
CPaintDC dc(this);
switch(m_nShape) {
case ID_SHAPE_RECT:
dc.Rectangle(100, 100, 500, 500);
break;
case ID_SHAPE_CIRCLE:
dc.Ellipse(100, 100, 500, 500);
break;
}
}
void CMainWindow::OnUpdateShape(CCmdUI* pCmdUI) {
pCmdUI->SetCheck(pCmdUI->m_nID == m_nShape);
}

上下文菜单与TrackPopupMenu的更多相关文章

  1. (C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单

    原文 (C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单 接上一节:(C#)Windows Shell 编程系列2 - 解释,从“桌面”开始展开这 ...

  2. (C#)Windows Shell 外壳编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单

    (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:(C#)Windows Shell 外壳编程系列2 - 解释,从“桌面”开始展开 这里解释上一节中获取名称的方法 GetD ...

  3. 不得不吐槽的Android PopupWindow的几个痛点(实现带箭头的上下文菜单遇到的坑)

    说到PopupWindow,我个人感觉是又爱又恨,没有深入使用之前总觉得这个东西应该很简单,很好用,但是真正使用PopupWindow实现一些效果的时候总会遇到一些问题,但是即便是人家的api有问题, ...

  4. android上下文菜单

    XML: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmln ...

  5. RCP:为指定的导航器添加上下文菜单

    可以参考Eclipse的Help->Help Content下的: Platform Plug-in Developer Guide > Programmer's Guide > P ...

  6. 【WP 8.1开发】上下文菜单

    在桌面系统中,别说是开发者,相信有资格考得过计算机一级的人都知道什么叫一下文菜单,或者叫右键菜单. 为了让操作更方便,在手机应用程序中,也应当有这样的菜单.上下文菜单之所以有”上下文“之说,是因为通常 ...

  7. Android成长日记-ContextMenu实现上下文菜单

    一. ContextMenu的组成 标题以及标题图标 菜单内容 菜单内容的点击事件 二. ContextMenu与OptionMenu的区别 OptionMenu对应的是activity,一个acti ...

  8. Java基础之扩展GUI——高亮元素、上下文菜单、移动旋转元素、自定义颜色(Sketcher 10)

    窗口应用程序. 本例在上一版的基础上实现了高亮元素.移动元素.上下文菜单.旋转元素.设置自定义颜色. 1.自定义常量包: // Defines application wide constants p ...

  9. 安卓开发_浅谈ContextMenu(上下文菜单)

    长下文菜单,即长按view显示一个菜单栏 与OptionMenu的区别OptionMenu对应的是activity,一个activity只能拥有一个选项菜单ContextMenu对应的是View,每个 ...

随机推荐

  1. Java学习笔记九(泛型)

    1.介绍 所谓的泛型就是将类型作为一种參数来传递.有了泛型后类型不再是一成不变的.能够通过泛型參数来指定. 能够提供程序开发的灵活性. 2.泛型类或接口的使用 泛型类声明时.与普通类没有太大的差别,仅 ...

  2. 原码、反码、补码和移码事实上非常easy

    近期在备战软考,复习到计算机组成原理的时候,看到书中关于原码.反码.补码和移码的定义例如以下(n是机器字长): 原码: 反码: 补码: 移码: 看完这些定义以后,我的脑袋瞬间膨胀到原来的二倍!这样变态 ...

  3. EasyUI - Dialog 对话框

    效果: html代码: 其中有class加载方式和Javascript加载方式. <!--class加载方式--> <%--<div id="dd" cla ...

  4. .Net有许多Office,PDF,Email,HTML的控件

    比如: Aspose.Total for .NET includes the following components: Aspose.Words for .NET 16.3.0 (4/13/2016 ...

  5. Javascript做模糊查询

    <html> <head> <title>Javascript模糊查找</title> </head> <body> <l ...

  6. 翻转整数 Reverse digits of a number

    两种方法翻转一个整数.顺序翻转和递归翻转 这里没考虑overflow的情况 递归的作用是使得反向处理.即从递归栈的最低端開始处理.通过绘图可得. 假设是rec(num/10): 12345 1234 ...

  7. shell telnet 路由器

    #!/usr/bin/expect -f spawn telnet 172.16.1.80 expect "login" { send "admin\n" ex ...

  8. 待机状态下,服务类型 WCDMA Service type in Idle mode

    Services aredistinguished into categories defined in [7]; also the categorisation of cellsaccording ...

  9. Swift - 项目部署配置(支持的系统,设备和状态条样式等)

    点击项目,在General选项卡中的“Deployment Info”栏目中可以进行一些项目的配置 Deployment Target:支持的iOS SDK的最低版本 Device:所支持的设备(iP ...

  10. C++ - Operator Precedence

    The following table lists the precedence and associativity of C++ operators. Operators are listed to ...