MFC菜单工具栏以及状态栏编程

1、 创建“图形”、“颜色”、“线的类型”、“线宽度”子菜单。
(1) 在新建的工程中“ResourceView”中打开Menu选项,在空白中添加这几项。
(2) 在“图形”下拉菜单中依次添加“椭圆”、“矩形”、“曲线”,并且依次设置ID分别为:ID_ELLIPSE,ID_RECTANGLE,ID_CURVES。
(3) 在“颜色”下拉菜单中依次添加“红色”,“绿色”,“蓝色”,“白色”和“黑色”。并设置其ID分别为ID_COLORRED,ID_COLORGREEN,ID_COLORBLUE,ID_COLORBLACK,ID_COLORWHITE。
(4) 在“线的类型”下拉菜单中依次添加“实线”和“虚线”。其ID分别是ID_LINESOLID,ID_LINEDOT
(5) 在“线宽度”下拉菜单中创建“1”和“2”,其ID分别设为ID_LINEWIDE1,ID_LINEWIDE2。
编译,运行后效果如下:

[img]http://dl.iteye.com/upload/attachment/471291/46af6ccc-5133-3310-a914-22d75be32e86.png[/img]

[img]http://dl.iteye.com/upload/attachment/471293/11b6158e-9702-37a3-8841-69db7926247f.png[/img]

[img]http://dl.iteye.com/upload/attachment/471295/34be40f0-0a67-3aec-b95f-997afd896e5b.png[/img]

[img]http://dl.iteye.com/upload/attachment/471297/240678d6-1a23-34c7-a907-e57e566f21b0.png[/img]

[img]http://dl.iteye.com/upload/attachment/471299/7c3fc56e-93a8-310c-ab03-e495535e5a2c.png[/img]
2、 响应菜单栏中的“图形”下拉子菜单的消息
响应椭圆(ID_ELLIPSE)矩形(ID_RECTANGLE)
(1)、首先在view类中添加变量

BOOL m_ISPointup; //鼠标左键弹起

BOOL m_ISPointdown; //鼠标左键按下

CPoint m_pointup; //鼠标左键弹起的位置

CPoint m_pointdown; //鼠标左键按下的位置

BOOL m_ClickRectangle; //判断是否画矩形
BOOL m_ClickEllipse; //判断是否画椭圆
Int flage;//菜单选项被标记的标志


(2)、在view类中对这些变量初始化

m_pointdown = 0; //原点
m_pointup = 0;
m_ISPointup = FALSE; //未按下
m_ISPointdown = FALSE;
flag = 0;


(3)、响应ID_ELLIPSE和ID_RECTANGLE的command和update消息

void CYangwei20090810229View::OnEllipse()
{
// TODO: Add your command handler code here
flag++;
m_ClickEllipse = TRUE;
m_ClickRectangle = FALSE;
m_ClickCurves = FALSE;
}
void CYangwei20090810229View::OnRectangle()
{
// TODO: Add your command handler code here
flag++;
m_ClickEllipse = FALSE;
m_ClickRectangle = TRUE;
m_ClickCurves = FALSE;
}
void CYangwei20090810229View::OnUpdateEllipse(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(flag%2==0);
if(255 == flag)
{
flag = 1;
}

void CYangwei20090810229View::OnUpdateRectangle(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(flag%2==1);
}


(3)、响应WM_LBUTTONDOWN消息,此时记下该点位置,并表示按下状态,添加代码:

void CYangwei20090810229View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_pointdown = point;
m_ISPointdown = TRUE;
m_ISPointup = FALSE;
CView::OnLButtonDown(nFlags, point);
}
(4)、响应WM_LBUTTONUP消息记下此点位置,虽然在此程序中未用到改点。
void CYangwei20090810229View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_pointup = point;
CDC *pDC=GetDC();
CBrush *pnew = CBrush::FromHandle((HBRUSH)GetStockObject(HOLLOW_BRUSH));//获得空画刷
CBrush *pold = pDC->SelectObject(pnew); //选择新建画刷

CPen newpen(m_penstyle,m_linewide,RGB(m_pen.red,m_pen.green,m_pen.blue));//创建自定义的画笔,这里的m_pen是自己写的结构
CPen *poldpen = pDC->SelectObject(&newpen); //选择自定义的画笔
if(m_ClickEllipse)
{
pDC->Ellipse(m_pointdown.x,m_pointdown.y,point.x,point.y);
}
if(m_ClickRectangle)
{
pDC->Rectangle(m_pointdown.x,m_pointdown.y,point.x,point.y);
}
pDC->SelectObject(poldpen);
pDC->SelectObject(pold);
m_ISPointup = TRUE;
m_ISPointdown = FALSE;

CView::OnLButtonUp(nFlags, point);
}


响应曲线(ID_CURVES)
(1)、响应ID_CURVES的command消息

void CYangwei20090810229View::OnCurves()
{
// TODO: Add your command handler code here
m_ClickCurves = TRUE; //代表曲线被选择
m_ClickEllipse = FALSE;
m_ClickRectangle = FALSE;
}
响应WM_MOUSEMOVE消息
void CYangwei20090810229View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_ISPointdown && m_ClickCurves)
{
CClientDC dc(this);
CPen pen(m_penstyle,m_linewide,RGB(m_pen.red,m_pen.green,m_pen.blue));
CPen *pold = dc.SelectObject(&pen);
dc.MoveTo(m_pointdown);
dc.LineTo(point);
m_pointdown = point;
dc.SelectObject(pold);
}
CView::OnMouseMove(nFlags, point);
}


对于颜色菜单,首先在view类中的头文件中定义一个结构体

struct myColor
{
int red;//红色
int green;//绿色
int blue;//蓝色
};


向view类中添加myColor m_pen; //画笔的颜色
初始化黑色

m_pen.red = 0;
m_pen.green = 0;
m_pen.blue = 0;

响应红色ID_COLORRED的command消息

void CYangwei20090810229View::OnColorred()
{
// TODO: Add your command handler code here
m_pen.red = 255;
m_pen.green = 0;
m_pen.blue = 0;
}


其他的颜色道理一样,只要知道各种颜色的三原色各自的值并且赋给他们即可,不再详述

对于线的类型:
在view类中添加变量m_penstyle并在构造函数中初始化
	
m_penstyle =PS_SOLID;//线类型实线

然后响应实线ID_LINESOLID的command消息

void CYangwei20090810229View::OnLinesolid()
{
// TODO: Add your command handler code here
m_penstyle = PS_SOLID;
}
对于虚线响应ID_LINEDOT消息
void CYangwei20090810229View::OnLinedot()
{
// TODO: Add your command handler code here
m_penstyle = PS_DOT;
}

对于线宽 1,2分别响应ID_LINEWIDE1和ID_LINEWIDE2的command消息
void CYangwei20090810229View::OnLinewide1()
{
// TODO: Add your command handler code here
m_linewide = 1;//线宽1
}

void CYangwei20090810229View::OnLinewide2()
{
// TODO: Add your command handler code here
m_linewide = 2;//线宽2
}



3、 响应工具栏的的各种图形消息
如椭圆
在ResourceView页面中,双击Toolbar文件夹,可以看到有一个ID位ID_MAINFRAME的工具栏。双击ID_MAINFRAME工具栏,在工具栏编辑框中出现如下图所示的工具栏。
[img]http://dl.iteye.com/upload/attachment/471301/b6171c98-ece6-3e54-9da1-bc6d320353ed.png[/img]
在工具栏的最右边有一空白按钮,双击该按钮,弹出对话框如下图,其中ID选择ID_ELLIPSE,即“椭圆”按钮。该按钮显示在编辑窗口中,可以通过Graphics和Colors工具箱及鼠标画自己的图标。(矩形工具栏图标同椭圆方法)

[img]http://dl.iteye.com/upload/attachment/471303/c198cafb-2390-36e0-88c4-45d1b0bf8921.png[/img]
其他图形一样。

4、 响应右击菜单消息
a) 在工作区的ResourceView选项卡中,右击Menu文件夹,在弹出菜单中选择插入菜单便可创建一个新的菜单资源,其ID为IDR_MENU1。右击IDR_MENU1,在弹出菜单中选择属性,修改其ID为IDR_POPMENU。双击IDR_POPMENU资源进入编辑对话框,对弹出式菜单进行编辑,,完成后的菜单资源如图:

[img]http://dl.iteye.com/upload/attachment/471307/3550f0a8-a362-3d25-8f37-824221021125.png[/img]
b) 添加代码,实现鼠标右键单击时显示弹出式菜单。在查看菜单项中选择建立类向导来添加右键单击弹出式菜单WM_CONTEXTMENU及消息处理函数,这时MFC会发现创建了一个新资源,将询问是否创建一个新类,取消后,弹出下图对话框,选择ID为CExyangwei20090810229View,Messages为WM_CONTEXTMENU,双击该消息或单击Add Function按钮,将为该消息添加默认处理函数,单击Edit Code按钮进入OnContextMenu()函数,对其进行编辑。
[img]http://dl.iteye.com/upload/attachment/471311/d0027a15-0ba6-32a4-b5a6-548c82885858.png[/img]

void CYangwei20090810229View::OnContextMenu(CWnd*, CPoint point)
{

// CG: This block was added by the Pop-up Menu component
{
if (point.x == -1 && point.y == -1){
//keystroke invocation
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);

point = rect.TopLeft();
point.Offset(5, 5);
}

CMenu menu;
VERIFY(menu.LoadMenu(CG_IDR_POPUP_YANGWEI20090810229_VIEW));

CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;

while (pWndPopupOwner->GetStyle() & WS_CHILD)
pWndPopupOwner = pWndPopupOwner->GetParent();

pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
pWndPopupOwner);
}
}


其中响应画各种图形的方法与工具栏中的做法差不多
对于清空消息ID_UPDATE

void CYangwei20090810229View::OnUpdate()
{
// TODO: Add your command handler code here
Invalidate();
UpdateWindow();
}


5、 下面美化状态栏
(1)、将状态栏的提示器改成自己的东西,在这里我改成了作者和日期
即2011-4-2 made by Veiker.其实就是在ResourseView中的StringTable中找到
AFX_IDS_IDLEMESSAGE 将其属性改下
(2)、修改状态栏中的提示器
让状态栏显示鼠标箭头的位置,CTRL键是否按下,时间、进度条
A、 在Stringtable中添加对应的ID
B、 在Frame类构造函数中的indicators数组中添加ID(对应ID如下显示)

static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_XY, //显示鼠标位置
ID_INDICATOR_CTRL,//显示CTRL键是否按下
ID_INDICATOR_TIME,//显示时间
ID_INDICATOR_PROG,//显示进度条
ID_INDICATOR_NUM,//显示数字
};


显示鼠标位置:
响应WM_MOUSEMOVE 由于前面响应过这里只要向里面添加代码

CString str;
str.Format("x=%d,y=%d",point.x,point.y);
CMainFrame*pMainFrame=(CMainFrame*)(AfxGetApp()->GetMainWnd());
pMainFrame->m_wndStatusBar.SetPaneText(1,str);


注意:包含MainFrm.h
显示CTRL键是否按下在View类中的消息注释宏中添加
ON_UPDATE_COMMAND_UI(ID_INDICATOR_CTRL,OnUpdateKeyCtrl)
然后响应函数

void CYangwei20090810229View::OnUpdateKeyCtrl(CCmdUI* pCmdUI)
{
pCmdUI->Enable(::GetKeyState(VK_CONTROL)<0); //更新状态指示器
}


显示时间
在frame类中OnCreate()中添加

SetTimer(1,1000,NULL);
CTime time = CTime::GetCurrentTime();
CString str = time.Format("%H:%M:%S");
m_wndStatusBar.SetPaneText(3,str);

响应WM_TIMER消息

void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CTime time = CTime::GetCurrentTime();
CString str = time.Format("%H:%M:%S");
m_wndStatusBar.SetPaneText(3,str);
CFrameWnd::OnTimer(nIDEvent);
}


显示进度条:
在frame类中添加变量CProgressCtrl m_Process;
响应WM_PAINT消息

void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CRect rect;
m_wndStatusBar.GetItemRect(4,&rect);
if(m_Process.m_hWnd)
{
m_Process.SetWindowPos(NULL,rect.left,rect.top,rect.Width(),rect.Height(),SWP_NOZORDER);
}
else{
m_Process.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,111);
}
// Do not call CFrameWnd::OnPaint() for painting messages
}


向OnTimer()中添加m_Process.StepIt();
三、 运行后总体效果:

[img]http://dl.iteye.com/upload/attachment/471316/e8d594d2-a3c6-3298-9403-82ddad23bb7e.png[/img]
源代码:见附件
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值