VC++学习(6)——菜单编程,消息捕获机制和顺序;创建标记、缺省、图形、不可用等菜单;命令更新模式;右键的弹出菜单
目录
- 引出
- 第6讲 菜单编程
- 在CMainFrame中捕获
- 消息响应捕获顺序
- 插曲:删除函数的方法
- 消息分类
- 菜单的结构
- 创建标记菜单
- 创建缺省菜单
- 创建图形菜单
- 菜单项不允许使用
- 如何整个菜单取消
- 命令更新模式
- 右键弹出菜单功能
- 添加方式
- 显示位置
- 定义事件
- 动态添加
- 定义响应
- 总结
- 第五讲 文本编程
- 新建项目
- 输入线的初始化
- 根据字体大小定义插入符大小
- 创建图形插入符
- 文字始终保存在窗口中
- CString类
- 通过字符串资源
- 路径层
- 字符输入的功能
- 键盘输入消息
- 鼠标左键消息
- 保存点击位置的坐标
- 输入回车键的处理
- 删除文字的实现
- 字符输入功能代码
- 字体的修改
- 模拟卡拉ok变色字体
- 第四讲 简单绘图
- 加入点击弹窗
- 划线的实现1
- 划线实现2
- 划线的实现3,CClient
- GetParent()
- 划线的实现4
- 不同的颜色画笔
- 不同颜色画刷
- 位图
- 空的矩形
- 画笔实现
- 画个扇形
引出
VC++学习(6)——菜单编程,消息捕获机制和顺序;创建标记、缺省、图形、不可用等菜单;命令更新模式;右键的弹出菜单
第6讲 菜单编程
在CMainFrame中捕获
消息响应捕获顺序
插曲:删除函数的方法
消息捕获顺序
消息分类
CWnd派生的类既可以接收命令消息,也可以接收标准消息
菜单的结构
文件下的整个部分是一个子菜单
创建标记菜单
比如在文件下面加一个标记菜单
指向整个菜单的指针
指向子菜单的指针
// 获取指向CMenu对象的指针 // 1.按照索引访问 GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED); // 2.按照id号访问 ID_FILE_NEW GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_CHECKED);
创建缺省菜单
加粗显示
// setDefaultItem // 通过索引设置粗体 GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN); // 通过 id号 设置粗体 GetMenu()->GetSubMenu(0)->SetDefaultItem(1,TRUE);
创建图形菜单
// 定义一个位图菜单 m_bitmap.LoadBitmap(IDB_BITMAP1); GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);
图形标记的尺寸,17x17
CString str; str.Format("x= %d, y= %d", GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK)); MessageBox(str); // 定义一个位图菜单 m_bitmap.LoadBitmap(IDB_BITMAP1); GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);
菜单项不允许使用
没有生效
表示自己决定
这时所有菜单项是否可以使用,都要由自己来决定
/ // CMainFrame construction/destruction CMainFrame::CMainFrame() { // TODO: add member initialization code here // 设置enable m_bAutoMenuEnable = FALSE; }
GetMenu()->GetSubMenu(0)->EnableMenuItem(3,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
如何整个菜单取消
调用Detach,将句柄和C++对象断开
命令更新模式
如果用索引可能会出现问题,最好采用id号设置
右键弹出菜单功能
添加方式
方式一:通过 工程—增加到工程— , 进行添加
方式二:自己手动添加
显示位置
捕获鼠标右键点击事件
位置不对的原因是:坐标体系不一样,获取的是用户view窗口,而显示的屏幕坐标
void CMenuView::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // menu对象,加载资源 CMenu menu; menu.LoadMenu(IDR_MENU1); CMenu *pPopup = menu.GetSubMenu(0); // 坐标转换 ClientToScreen(&point); pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); CView::OnRButtonDown(nFlags, point); }
定义事件
分别在CMainFrame和 CMainView中添加command
删除view类中的函数,右键没有反应,是因为
void CMenuView::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // menu对象,加载资源 CMenu menu; menu.LoadMenu(IDR_MENU1); CMenu *pPopup = menu.GetSubMenu(0); // 坐标转换 ClientToScreen(&point); pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, GetParent()); // 用框架类指针 CView::OnRButtonDown(nFlags, point); }
动态添加
中间插入
添加菜单项
在原有的最后增加
在原有的中间插入
删除菜单
删除菜单里面的项
定义响应
不会写就先添加一个,然后照猫画虎写
总结
VC++学习(6)——菜单编程,消息捕获机制和顺序;创建标记、缺省、图形、不可用等菜单;命令更新模式;右键的弹出菜单
其他
第五讲 文本编程
新建项目
输入线的初始化
输入的竖直线,一闪一闪的输入
增加Windows消息处理
根据字体大小定义插入符大小
int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here // 确定符号大小 CClientDC dc(this); // 当前设备描述表describe TEXTMETRIC tm; dc.GetTextMetrics(&tm); // 取地址符 // 创建一个插入符号 CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight); ShowCaret(); // 显示出来 return 0; }
创建图形插入符
文字始终保存在窗口中
CString类
/ // CTextView drawing void CTextView::OnDraw(CDC* pDC) { CTextDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here // CString CString str("pet"); pDC->TextOut(50,50,str); }
通过字符串资源
/ // CTextView drawing void CTextView::OnDraw(CDC* pDC) { CTextDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here // CString CString str("pet"); pDC->TextOut(50,50,str); // 使用字符串资源 str.LoadString(IDS_PET); pDC->TextOut(0,200,str); }
路径层
字符输入的功能
键盘输入消息
鼠标左键消息
void CTextView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 移动插入符到这里 SetCaretPos(point); m_strLine.Empty(); // 将cstring中保存的内容情空 CView::OnLButtonDown(nFlags, point); }
保存点击位置的坐标
输入回车键的处理
删除文字的实现
将文本的颜色设置成和背景色一样
字符输入功能代码
1.鼠标左键定位插入字符位置;
2.特殊字符的处理,回车键,删除键;
3.光标随着输入的字符移动;
void CTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default // 字体的高度 CClientDC dc(this); TEXTMETRIC tm; dc.GetTextMetrics(&tm); printf("%u\n", nChar); if(0x0d==nChar) // 输入的是回车 { m_strLine.Empty(); // 清空 m_ptOrig.y += tm.tmHeight; // 到下一行 }else if(0x08==nChar) // 输入的是删除 { // 获取背景色,文本颜色设置成背景色 COLORREF clr = dc.SetTextColor(dc.GetBkColor()); // 然后输出 dc.TextOut(m_ptOrig.x,m_ptOrig.y,m_strLine); // 减少字符,再次输出 m_strLine = m_strLine.Left(m_strLine.GetLength()-1); dc.SetTextColor(clr); }else // 输入其他 { m_strLine += nChar; } // 插入符随着输入移动 CSize sz = dc.GetTextExtent(m_strLine); CPoint pt; pt.x = m_ptOrig.x + sz.cx; pt.y = m_ptOrig.y; SetCaretPos(pt); dc.TextOut(m_ptOrig.x,m_ptOrig.y,m_strLine); CView::OnChar(nChar, nRepCnt, nFlags); } void CTextView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 移动插入符到这里 SetCaretPos(point); m_strLine.Empty(); // 将cstring中保存的内容情空 m_ptOrig = point; // 保存坐标值 CView::OnLButtonDown(nFlags, point); }
字体的修改
vc++6.0中的字体
Windows系统中的字体
// 定义字体 CFont font; font.CreatePointFont(300, "华文行楷", NULL); CFont *pOldFont = dc.SelectObject(&font);
模拟卡拉ok变色字体
void CTextView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default // 显示大小按5个像素增加 m_nWidth += 5; CClientDC dc(this); // 字体的高度 TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rect; rect.left = 0; rect.top = 200; rect.right = m_nWidth; rect.bottom = rect.top + tm.tmHeight; // 改变文本颜色 dc.SetTextColor(RGB(255,0,0)); CString str; str.LoadString(IDS_PET); dc.DrawText(str,rect,DT_LEFT); rect.top=150; rect.bottom = rect.top + tm.tmHeight; dc.DrawText(str,rect,DT_RIGHT); // 判断一下,走到哪里了 CSize sz = dc.GetTextExtent(str); if(m_nWidth>sz.cx) { m_nWidth = 0; dc.SetTextColor(RGB(0,255,0)); dc.TextOut(0,200,str); } CView::OnTimer(nIDEvent); }
第四讲 简单绘图
加入点击弹窗
框架类CMainFrame中加入不生效,需要在CDrawView中加入
编写代码,加入一个消息框
在头文件中,自动加入了注释宏
源文件中加入了宏,加入了消息响应函数的宏
划线的实现1
鼠标的抬起与放下的事件定义
/ // CDrawView message handlers void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 点击的时候,拿到了点 m_ptOrigin=point; // 获取起点 // MessageBox("view click"); CView::OnLButtonDown(nFlags, point); } void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default HDC hdc; hdc=::GetDC(m_hWnd); // 起点 MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL); // 划线 LineTo(hdc,point.x,point.y); // 释放dc ::ReleaseDC(m_hWnd,hdc); CView::OnLButtonUp(nFlags, point); }
划线实现2
用cdc实现
划线的实现3,CClient
GetParent()
划线的实现4
CWindowDC dc(GetParent()); dc.MoveTo(m_ptOrigin); dc.LineTo(point);
不同的颜色画笔
// 创建画笔 CPen pen(PS_DOT,1,RGB(255,0,0)); CClientDC dc(this); CPen *pOldPen=dc.SelectObject(&pen); dc.MoveTo(m_ptOrigin); dc.LineTo(point); dc.SelectObject(pOldPen); // 先前的画笔选择回设备描述表
不同颜色画刷
// 创建画刷 CBrush brush(RGB(255,0,0)); CClientDC dc(this); dc.FillRect(CRect(m_ptOrigin,point),&brush);
位图
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(m_ptOrigin,point),&brush);
空的矩形
画笔实现
构造函数初始化为false
鼠标按下时,设置为真,True
鼠标抬起,设置为false
画出连续的线条
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 判断鼠标状态 CClientDC dc(this); if(m_bDraw==TRUE) { // 开始划线 dc.MoveTo(m_ptOrigin); dc.LineTo(point); m_ptOrigin=point; // 终点设置为起点 } CView::OnMouseMove(nFlags, point); }
换个红色的画笔
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); // 换个颜色 CPen pen(PS_SOLID,1,RGB(255,0,0)); CPen *pOldPen=dc.SelectObject(&pen); // 之前的画笔 // 判断鼠标状态 if(m_bDraw==TRUE) { // 开始划线 dc.MoveTo(m_ptOrigin); dc.LineTo(point); m_ptOrigin=point; // 终点设置为起点 } dc.SelectObject(pOldPen); //设置回之前的画笔 CView::OnMouseMove(nFlags, point); }
画个扇形
先画出一个点,再到另一个点画出一条线,终点变化,重新划线
画出边线
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); // 换个颜色 CPen pen(PS_SOLID,1,RGB(255,0,0)); CPen *pOldPen=dc.SelectObject(&pen); // 之前的画笔 // 判断鼠标状态 if(m_bDraw==TRUE) { // 开始划线 dc.MoveTo(m_ptOrigin); dc.LineTo(m_ptOld); // 画出一个点 // dc.MoveTo(m_ptOrigin); // 线性的扇形 dc.MoveTo(m_ptOld); // 画出边线 dc.LineTo(point); m_ptOld=point; } dc.SelectObject(pOldPen); //设置回之前的画笔 CView::OnMouseMove(nFlags, point); }