精通 VC++ 实效编程280例 - 02 菜单和光标

菜单和关闭时重要的 Windows 资源之一。SDK 中,用 HCURSOR 和 HMENU 分别表示菜单和光标的句柄。MFC 中,CMenu 类封装了菜单的功能。

23 动态添加和删除菜单项

添加菜单项可以调用 CMenu::AppendMenu 或 CMenu::InserMenu 函数,删除菜单项可以调用 CMenu::RemoveMenu 或 CMenu::DeleteMenu 函数,最后调用 CWnd::DrawMenuBar 函数重画菜单。

  • CMenu::AppendMenu:在菜单末端添加菜单项。
  • CMenu::InserMenu:在菜单指定位置添加菜单项。
  • CMenu::RemoveMenu:移动菜单项,如果菜单项与弹出菜单相关联,将不将销毁弹出菜单的句柄,因此菜单可重用。
  • CMenu::DeleteMenu:删除菜单项,如果菜单项与弹出菜单相关联,将销毁弹出菜单的句柄,并释放其占用的内存。
#define ID_TEST_MENU                    10000
void CMainFrame::OnAppendMenu() 
{//获得主菜单CMenu* pMenu = GetMenu();//获得子菜单CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 4){//在菜单末端添加菜单项pSubMenu->AppendMenu(MF_STRING,ID_TEST_MENU,_T("New Menu"));//重画菜单DrawMenuBar();}
}void CMainFrame::OnInsertMenu() 
{//获得主菜单CMenu* pMenu = GetMenu();//获得子菜单CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 4){//在菜单指定位置添加菜单项pSubMenu->InsertMenu(4,MF_BYPOSITION,ID_TEST_MENU,_T("New Menu"));//重画菜单DrawMenuBar();}	
}void CMainFrame::OnRemoveMenu() 
{//获得主菜单CMenu* pMenu = GetMenu();//获得子菜单CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 5){//删除菜单项pSubMenu->RemoveMenu(4,MF_BYPOSITION);//重画菜单DrawMenuBar();}
}void CMainFrame::OnDeleteMenu() 
{//获得主菜单CMenu* pMenu = GetMenu();//获得子菜单CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 5){//删除菜单项pSubMenu->DeleteMenu(4,MF_BYPOSITION);//重画菜单DrawMenuBar();}
}
void CMainFrame::OnTestMenu() 
{AfxMessageBox(_T("测试菜单项命令"));	
}

24 在系统菜单中添加和删除菜单项

在系统菜单中添加和删除菜单项,首先调用 CWnd::GetSystemMenu 函数获得系统菜单的指针,然后调用 CMenu::AppendMenu 或 CMenu::InsertMenu,CMenu::RemoveMenu 或 CMenu::DeleteMenu 函数添加和删除菜单项,最后调用 CWnd::DrawMenuBar 函数重画菜单。对于添加的菜单项,可以在 CWnd::OnSysCommand 重载函数中处理菜单命令。

//在resource.h文件中添加宏定义
#define ID_TEST_MENU					10000
BOOL CDemoDlg::OnInitDialog()
{CDialog::OnInitDialog();//...//获得系统菜单CMenu* pMenu = GetSystemMenu(FALSE);//删除系统菜单项pMenu->RemoveMenu(SC_MOVE,MF_STRING);//添加菜单项pMenu->InsertMenu(0,MF_BYPOSITION,ID_TEST_MENU,_T("New Menu"));//重画菜单DrawMenuBar();return TRUE; 
}
void CDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else if(nID == ID_TEST_MENU){AfxMessageBox(_T("测试菜单项命令"));}else{CDialog::OnSysCommand(nID, lParam);}
}

25 禁用关闭按钮

禁用关闭按钮可以调用 CMenu::EnableMenuItem 函数。

BOOL CDemoDlg::OnInitDialog()
{CDialog::OnInitDialog();//...//获得系统菜单CMenu* pMenu = GetSystemMenu(FALSE);//禁用关闭按钮pMenu->EnableMenuItem(SC_CLOSE,MF_BYCOMMAND | MF_GRAYED);return TRUE;
}

26 启用和禁用菜单项

可以在类的 UPDATE_COMMAND_UI 消息处理函数中调用 CCmdUI::Enable 函数,启用和禁用菜单项。

//在CMainFrame类中添加成员变量
public:BOOL m_bEnable1;BOOL m_bEnable2;
//在CMainFrame类的构造函数中初始化成员变量
CMainFrame::CMainFrame()
{m_bEnable1 = TRUE;m_bEnable2 = FALSE;
}
//在CMainFrame类中为菜单项添加命令处理函数void CMainFrame::OnTestMenu1() 
{m_bEnable1 = FALSE;m_bEnable2 = TRUE;	
}void CMainFrame::OnUpdateTestMenu1(CCmdUI* pCmdUI) 
{//启动或禁用菜单1pCmdUI->Enable(m_bEnable1);
}void CMainFrame::OnTestMenu2() 
{m_bEnable1 = TRUE;m_bEnable2 = FALSE;
}void CMainFrame::OnUpdateTestMenu2(CCmdUI* pCmdUI) 
{//启动或禁用菜单2pCmdUI->Enable(m_bEnable2);
}

27 设置菜单项的检查状态

可以在类的 UPDATE_COMMAND_UI 消息处理函数中调用 CCmdUI::SetCheck 函数设置菜单项的检查状态(选中/不选中状态)。

//在CMainFrame类中添加成员变量
public:int m_nCheck;
//在CMainFrame类的构造函数中初始化成员变量
CMainFrame::CMainFrame()
{m_nCheck = 0;
}
//在CMainFrame类中为菜单项添加命令处理函数
void CMainFrame::OnTestMenu() 
{if (m_nCheck == 0){m_nCheck = 1;}else{m_nCheck = 0;}}void CMainFrame::OnUpdateTestMenu(CCmdUI* pCmdUI) 
{//设置菜单项检查状态pCmdUI->SetCheck(m_nCheck);
}

28 快捷菜单

实现快捷菜单可以在 CWnd::OnContextMenu 重载函数中调用 CMenu::TrackPopupMenu 函数。

在资源中添加1个菜单资源,ID 为 IDR_MENU。在菜单资源中添加1个子菜单,并添加菜单项。

//在CDemoView类中重载CWnd::OnContextMenu函数
void CDemoView::OnContextMenu(CWnd* pWnd, CPoint point) 
{CMenu menu;//加载菜单if (!menu.LoadMenu(IDR_MENU)){return;}//获得子菜单CMenu* pPopupMenu = menu.GetSubMenu(0);//弹出菜单pPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,pWnd);
}
void CDemoView::OnTestMenu1() 
{AfxMessageBox(_T("快捷菜单项1命令"));
}void CDemoView::OnTestMenu2() 
{AfxMessageBox(_T("快捷菜单项2命令"));
}

29 获取光标的坐标

可以在 WM_MOUSEMOVE 消息处理函数中获得光标的位置。

//在CDemoView类中添加成员变量
public:CPoint m_Point;
//在类中添加WM_MOUSEMOVE消息处理函数
void CDemoView::OnMouseMove(UINT nFlags, CPoint point) 
{//保存光标坐标m_Point = point;//刷新客户区Invalidate();CView::OnMouseMove(nFlags, point);
}
//在类中重载CView::OnDraw函数
void CDemoView::OnDraw(CDC* pDC)
{//获得客户区坐标CRect rect;GetClientRect(rect);//绘制十字光标pDC->MoveTo(0,m_Point.y);pDC->LineTo(rect.Width(),m_Point.y);pDC->MoveTo(m_Point.x,0);pDC->LineTo(m_Point.x,rect.Height());//输出光标坐标CString strText = _T("");strText.Format(_T("%d,%d"),m_Point.x,m_Point.y);pDC->SetBkMode(TRANSPARENT);pDC->SetTextAlign(TA_RIGHT | TA_BOTTOM);pDC->TextOut(m_Point.x,m_Point.y,strText);
}

30 限制光标的移动范围

限制光标的范围可以调用 SDK 的 ClipCursor 函数。

//在CDemoView类中重载CView::OnDraw函数
void CDemoView::OnDraw(CDC* pDC)
{//获得客户区坐标CRect rect;GetClientRect(rect);rect.left = rect.left + rect.Width() / 4;rect.right = rect.right - rect.Width() / 4;rect.top = rect.top + rect.Height() / 4;rect.bottom = rect.bottom -rect.Height() / 4;//绘制光标移动范围pDC->Rectangle(rect);
}
//在CDemoView类中分别添加WM_LBUTTONDOWN和WM_LBUTTONUP消息处理函数
void CDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
{//获得客户区坐标CRect rect;GetClientRect(rect);rect.left = rect.left + rect.Width() / 4;rect.right = rect.right - rect.Width() / 4;rect.top = rect.top + rect.Height() / 4;rect.bottom = rect.bottom - rect.Height() /4;//映射屏幕坐标ClientToScreen(rect);//限制光标移动范围ClipCursor(&rect);CView::OnLButtonDown(nFlags, point);
}void CDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
{//光标自由移动ClipCursor(NULL);CView::OnLButtonUp(nFlags, point);
}

31 自定义光标

使用自定义光标,首先调用 CWinApp::LoadCursor函数加载光标,然后调用SDK的SetCursor函数设置光标。

//创建1个单文档的应用程序,并添加2个光标资源,在CDemoView类中添加成员变量
public:HCURSOR m_hCursor;
//在CDemoView类中重载CView::OnInitialUpdate函数
void CDemo2View::OnInitialUpdate() 
{CView::OnInitialUpdate();//加载光标m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);
}
//在CDemoView类中添加WM_SETCURSOR消息处理函数
BOOL CDemo2View::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{//设置光标::SetCursor(m_hCursor);return TRUE;
}
//在CDemoView类中分别添加WM_LBUTTONDOWN和WM_LBUTTONUP消息处理函数
void CDemo2View::OnLButtonDown(UINT nFlags, CPoint point) 
{//加载光标m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR2);//设置光标::SetCursor(m_hCursor);CView::OnLButtonDown(nFlags, point);
}void CDemo2View::OnLButtonUp(UINT nFlags, CPoint point) 
{//加载光标m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);//设置光标::SetCursor(m_hCursor);CView::OnLButtonUp(nFlags, point);
}

32 等待光标

启动等待光标可以调用 CCmdTarget::BeginWaitCursor函数,结束等待光标可以调用CCmdTarget::EndWaitCursor函数。

void CDemo2View::OnLButtonUp(UINT nFlags, CPoint point) 
{//启动等待光标BeginWaitCursor();//休眠Sleep(5000);//结束等待光标EndWaitCursor();CView::OnLButtonDown(nFlags,point);
}

  

 

转载于:https://www.cnblogs.com/iwanc/archive/2013/06/09/2987866.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的osu游戏程序设计(oo)

osu是一款社区元素为主旨的音乐游戏,由澳大利亚人Dean Herbert (peppy)独立制作并运行. 游戏的方法简单,就是 1. 圈圈(Circle):圈圈(Circle) 50。没打中显示X,并减少生命值。圈中序号的最后一个的300、100会显示为激300、喝100。2.滑条(Slider) : 在开始端点击按住不…

Android programming on Mac 之安装Eclipse

1.安装包在此链接下载&#xff1a; http://developer.android.com/sdk/index.html google GoAgent翻墙不好用&#xff0c;更新了host文件也不行&#xff0c;整了半天&#xff0c;还是一怒之下续签了vpn账号。早知如此&#xff0c;何必折腾。~~~~(>_<)~~~~ 更新文件时…

c++关于虚表的一些笔记

文章目录1、虚函数表指针2、多态构成的条件3、重载、重写、重定义 三者区别4、继承与虚函数5、单继承中的虚函数表无虚函数覆盖有虚函数覆盖6、单继承中的虚函数表无虚函数覆盖有虚函数覆盖参考看《深度探索c对象模型》的时候对虚表有了点疑惑&#xff0c;正好网上有些文章解除…

C语言技巧:把单一元素的数组放在末尾,struct可以拥有可变大小的数组

《C 对象模型》第19页有这样一句话 C程序员的巧计有时候却成为c程序员的陷阱。例如把单一元素的数组放在一个struct的末尾&#xff0c;于是每个struct objects可以拥有可变数组的数组&#xff1a; struct mumble {/* stuff */char pc[1]; };//从文件或标准输入装置中取得一个…

探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别(二)...

看此文&#xff0c;务必需要先了解本文讨论的背景&#xff0c;不多说&#xff0c;给出链接&#xff1a; 探讨C 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别&#xff08;一&#xff09; 本文会以此问题作为讨论的实例&#xff0c;来具体讨论以下四个问题&a…

后台系统可扩展性学习笔记(一)概要

文章目录系统大致架构可扩展性负载均衡器与会话保持引入冗余增强系统可用性缓存减轻数据库压力异步处理参考系统大致架构 当一个用户请求从客户端出发&#xff0c;经过网络传输&#xff0c;达到 Web 服务层&#xff0c;接着进入应用层&#xff0c;最后抵达数据层&#xff0c;它…

后台系统可扩展性学习笔记(二)权衡取舍

文章目录性能与可扩展性延迟与吞吐量可用性与一致性一致性模式可用性模式可用性衡量参考系统设计中也面临许多权衡取舍&#xff1a;性能与可扩展性延迟与吞吐量可用性与一致性 性能与可扩展性 可扩展&#xff0c;意味着服务能以加资源的方式成比例地提升性能&#xff0c;性能…

后台系统可扩展性学习笔记(三)DNS机制原理

文章目录DNS概念梳理域名基本概念资源记录基本概念路由策略DNS 域空间结构实现原理复制机制查询机制缓存机制参考DNS概念梳理 DNS&#xff08;Domain Name System&#xff09;相当于互联网的通讯录&#xff0c;能够把域名翻译成 IP 地址。 从技术角度来讲&#xff0c;DNS 是个…

后台系统可扩展性学习笔记(四)CDN机制原理

文章目录概念梳理CDN拓扑结构CDN内容分发方式架构原理工作原理实现原理概念梳理 CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是由分布在不同地理位置的代理服务器及其数据中心组成的网络&#xff0c;希望在空间距离上为用户就近提供服务&am…

后台系统可扩展性学习笔记(五)负载均衡

文章目录Load balancer(负载均衡器)请求传输拆解DNS 负载均衡客户端负载均衡OSI 七层模型回顾2 层、3 层负载均衡3/4 层负载均衡7 层负载均衡在 第一节谈到了系统的横向扩展在于从单机扩展到多机&#xff0c;那么面临的第一个问题就是这些机器如何协同工作&#xff0c;即如何调…

Struts2第一个工程helloStruts极其基本配置

前面已经准备好了Struts-2.3.15&#xff0c;现在就可以直接搭建Struts2的工程了。前面http://blog.csdn.net/huangchnegdada/article/details/9179041有对Struts-2.3.15的准备工作的详述。 首先打开MyEclispe新建一个Web Project&#xff0c;名字就叫Struts2_0100_Introduction…

后台系统可扩展性学习笔记(六)反向代理

文章目录Web代理服务反向代理反向代理作用Web代理服务 Web 代理服务指的是在客户端资源请求和提供这些资源的 Web 服务之间充当中介的角色&#xff0c;代理服务可以实现在客户端&#xff0c;或者从客户端到目标服务器中间的任意环节。 例如&#xff0c;客户端不直接向提供目标…

实验:sigsuspend(),sigprocmask()

实验&#xff1a;sigsuspend(),sigprocmask()源代码&#xff1a;/* * Program: pause_suspend.c * To test the difference between sigsuspend() and paus(). * Author: zsl * Date: 2014-10-17 * First release. * 参见网页&#xff1a;http://blog.csdn.net/liwentao1091/ar…

后台系统可扩展性学习笔记(七)Service Discovery与微服务

文章目录应用层微服务架构服务注册查询 Service Discovery客户端 Service DiscoveryDNS-SD DNS-based Service Discovery服务端 Service Discovery服务注册与注销自注册模式第三方注册模式总结参考应用层 在简单的 3 层结构中&#xff0c;Web 服务层既要处理请求&#xff0c;又…

很久没写代码了,这(那)几天真是累死了。。。先写一个幻方的程序吧

1 #include <stdio.h>2 #include <stdlib.h>3 #include <windows.h>4 5 #define EVEN_DOUBLE_4 4 //双偶的最基本类型&#xff0c;4阶双偶6 #define SCREEN_SIZE 19 //屏幕显示不变形的最大尺寸&#xff08;主要是因为窗口大小限制&#xff09;7 #defi…

后台系统可扩展性学习笔记(八)Service Mesh

文章目录网络传输可靠性将微服务控制下沉到网络栈&#xff1f;Sidecar从 Sidecar 到 Service MeshService Mesh 部署平台参考网络传输可靠性 从计网的学习过程中我们可以知道数据在网络传输中可能会出现一些异常状况&#xff1a; 数据丢失&#xff1a;数据包可能会到达一个缓…

关于Spring batch的学习之CSV2DB

最近在学习Spring batch相关的内容&#xff0c;网上也有不少Spring Batch相关的知识&#xff0c;不过大多都是使用xml进行配置的。这里是我用注解的方式进行相关的学习心得。 首先我们来看如何将一个文本文件中的内容导入到数据库中。 我们先来看一下我们所需要的环境。我们这里…

后台系统可扩展性学习笔记(九)Database Replication

文章目录数据库扩展一致性问题Replication &#xff08;复制&#xff09;异步复制同步复制半同步复制拓扑结构单主结构多主结构无主结构复制具体措施参考数据库扩展 之前在第一章后台系统可扩展性学习笔记&#xff08;一&#xff09;概要谈到&#xff1a;理论上&#xff0c;有…

python中的sum函数.sum(axis=1)

看起来挺简单的样子&#xff0c;但是在给sum函数中加入参数。sum&#xff08;a&#xff0c;axis0&#xff09;或者是.sum(axis1) 就有点不解了 在我实验以后发现 我们平时用的sum应该是默认的axis0 就是普通的相加 而当加入axis1以后就是将一个矩阵的每一行向量相加 例如&…

后台系统可扩展性学习笔记(十)Database Partitioning

为了提升数据库的处理能力&#xff0c;我们把单库扩展成多库&#xff0c;并通过更新同步机制&#xff08;即Replication&#xff09;来保证多份数据的一致性。然而&#xff0c;在 各种复制方案下&#xff0c;每个数据库都持有一份完整数据&#xff0c;基于全量数据提供增删改查…