m_bR.x=0; m_bR.y=0; //圆上的点 m_ist=0; //圆心与圆上的点区别 }
第四步:在视图类的OnDraw()函数中加入下列代码,实现视图绘图。 void CMouseSpringView::OnDraw(CDC* pDC) { CMouseSpringDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->SelectStockObject(NULL_BRUSH); DrawCircle(pDC,m_bO,m_bR); // 调用自定义的成员函数画圆 }
第五步:向视图类中添加两个鼠标消息响应函数,并输入鼠标处理程序代码。
具体操作方法与鼠标示例1方法相同。一个是OnLButtonDown()函数,另一个是OnMouseMove()函数。程序如下:
void CMouseSpringView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC *pDC=GetDC();
pDC->SelectStockObject(NULL_BRUSH); if (!m_ist) //绘制圆 { m_bO=m_bR=point; //纪录第一次单击鼠标位置,定圆心 m_ist++; } else { m_bR=point; //记录第二次单击鼠标的位置,定圆周上的点 m_ist--; // 为新绘图作准备 DrawCircle(pDC,m_bO,m_bR); //绘制新圆 } ReleaseDC(pDC); //释放设备环境 CView::OnLButtonDown(nFlags, point); }
void CMouseSpringView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC *pDC=GetDC();
int nDrawmode=pDC->SetROP2(R2_NOT); //设置异或绘图模式,并保存原来绘图模式 pDC->SelectStockObject(NULL_BRUSH); if(m_ist==1)
-- 22
{ CPoint prePnt,curPnt; prePnt=m_bR; //获得鼠标所在的前一位置 curPnt=point; //绘制橡皮筋线 DrawCircle(pDC,m_bO,prePnt); //用异或模式重复画圆,擦出所画的圆 DrawCircle(pDC,m_bO,curPnt); //用当前位置作为圆周上的点画圆 m_bR=point; } pDC->SetROP2(nDrawmode); //恢复原绘图模式 ReleaseDC(pDC); //释放设备环境 CView::OnMouseMove(nFlags, point); }
第六步:添加成员函数的程序代码。
分别为两个成员函数DrawCircle()和ComputeRadius()添加程序代码,程序如下: void CMouseSpringView::DrawCircle(CDC *pDC, CPoint cenp, CPoint ardp) {
int radius=ComputeRadius(cenp,ardp); // 由圆心确定所画圆的外切区域
CRect rc(cenp.x-radius,cenp.y-radius,cenp.x+radius,cenp.y+radius); pDC->Ellipse(rc); //画出一个整圆 }
int CMouseSpringView::ComputeRadius(CPoint cenp, CPoint ardp) {
int dx=cenp.x-ardp.x; int dy=cenp.y-ardp.y;
//sqrt()函数的调用,在头文件中加入#include \ return (int)sqrt(dx*dx+dy*dy); }
第七步:编译运行程序,验证运行结果。
3.4 菜单程序设计
在Windows应用程序设计中,菜单是重要的用户界面对象和交互手段。Windows支持三种类型的菜单,他们分别是菜单栏(主菜单)、弹出式菜单和上下文菜单(单击鼠标右键弹出的浮动菜单)。本节主要介绍如何对菜单进行编辑、如何响应菜单的消息、如何运用菜单的UI机制、如何动态地改变菜单以及如何处理上下文菜单。
-- 23
3.4.1 菜单编辑器
菜单编辑器用来创建并编辑菜单资源,是一个可视化设计工具。对于MDI应用程序(多文档应用程序),AppWizard自动生成两个菜单资源:IDR_MAINFRAME和IDR_PrjNameTYPE (PrjName是应用程序工程名)。在MDI子窗口打开之前系统显示IDR_MAINFRAME菜单,在MDI子窗口打开之后系统显示IDR_ PrjNameTYPE菜单。对于SDI应用程序,AppWizard只生成一个菜单资源:IDR_MAINFRAME。
在一个SDI文档工程项目中,在工作区窗口中选择ResourceView标签,列出工程项目的所有资源,选择Menu,双击IDR_MAINFRAME,弹出菜单编辑器窗口,如图3-15所示。
图3-15 菜单编辑器 (1)创建菜单和菜单选项
在图3-15中,可以创建主菜单,也可以创建菜单选项。可以通过Tab键(向右移)、Shift+Tab键(向左移),或鼠标定位,通过Ins键在某一菜单前插入新的菜单。另外,用鼠标拖动菜单方框可以改变菜单项的相对位置。例如,在查看菜单前插入一个“绘图”菜单,包括直线、圆、矩形和颜色四个菜单项。
步骤1:定位到“查看”菜单,按下Ins键或Insert键,插入一个空菜单项;通过Delete
键删除一个菜单项;
步骤2:双击空菜单项,弹出菜单项对话框,并输入菜单信息,如图3-16所示。
图3-16 菜单对话框
-- 24
步骤3:添加菜单项条目。
双击“绘图”菜单下的空菜单项,弹出菜单项对话框。如图3-17所示。
图3-17 菜单项对话框
步骤4:重复第3步,完成菜单设计。
在菜单设计中,可以为菜单或菜单项定义助记符,方法是在响应的字符前加符号&。菜单项的ID号,可以选取已有的ID号,也可以自定义ID号,如果不输入ID号,则系统自动生成一个ID号。另外,在菜单项对话框中还可以为菜单项指定风格。另外,还可以为菜单项定义快捷键,方法是在标题后直接输入,转义符\\t表示快捷键左对齐。
(2) 弹出菜单的设计
弹出菜单就是主菜单项的子菜单,也称为级联菜单。
创建级联菜单的方法如下:选择级联菜单项,在该菜单项属性对话框中选中“弹出”(Pop-up)复选项,于是该项便被标记级联菜单符(?),且在该项的右侧出现新的菜单项空方框。添加级联菜单项的方法与上述方法相同。如图3-18所示。
图3-18 级联菜单设计
(3)上下文菜单
单击鼠标右键将弹出相应的上下文菜单。为了在应用程序中使用上下文菜单,首先要创建菜单本身,然后将其与应用程序代码链接。创建上下文菜单的步骤如下:
步骤1:创建带空标题的菜单栏。右击Menu,选择“Insert”,创建一个空的菜单栏; 步骤2:输入菜单标题和菜单项,并保存菜单资源,默认为IDR_MENI1,创建其级联菜单用于显示;
步骤3:在源文件中添加下列程序代码: CMenu menu;
// 装载并验证菜单资源;
VERIFY(menu.LoadMenu(IDR_MENU1));
-- 25
CMenu *pPopup=menu.GetSubMenu(0); ASSERT(pPopup!=NULL);
//显示菜单内容
pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
x,y,AfxGetMainWnd());
在创建上下文菜单资源后,应用程序代码装载菜单资源并使用函数TrackPopupMenu()来显示菜单内容。
3.4.2 菜单消息响应
Windows应用程序是通过消息传递机制运行的。为菜单项添加相应功能函数的方法步骤:
步骤1:右击所选菜单项,从弹出的菜单中选择“建立类向导…”,弹出类向导对话框,如图3-19所示;
图3-19 建立类向导对话框 步骤2:选择工程名(Project:),并在类名(Class name:)中选择视图类,在Object IDs:列表中选择菜单项的ID号,在Messages:列表中选择COMMAND; 步骤3:单击“Add Function…”,添加成员函数;
步骤4:选择该成员函数,单击“Edit Code”输入或编辑程序代码。
3.4.3 综合示例
利用菜单资源编辑器在默认的菜单中添加“字体”菜单项。在程序运行过程中改变菜单项的显示状态。
步骤1:创建Mymenu应用程序工程文件,选择单文档应程序; 步骤2:利用Resource View设计菜单,如图3-20所示;
-- 26