使用异或运算实现菜单项功能的启用与关闭

在MFC程序设计中,经常有这样的问题:点击一个菜单项启动某项功能,再点击一次取消该功能,再点击又启动该功能,再点击又取消该功能.......。尤其是有多个菜单项功能的时候,如何有效组织各个菜单项各自的状态,保证互不干扰,且实现简练。

 

本文以一个三维绘图程序为例,介绍使用异或状态运算实现菜单项功能的启用与关闭。假设在三维场景中有5种场景要素:天空、地面、房屋、道路、树木。程序要求实现这样的功能:控制各种场景要素的显示和不显示。

 

考虑使用菜单项来实现,创建五个菜单项: ViewSky(ID_VIEW_SKY)、 ViewGround(ID_VIEW_GROUND)、ViewBuilding(ID_VIEW_BUILDING)、ViewRoad  (ID_VIEW_ROAD)、ViewTree(ID_VIEW_TREE)。

 

通过添加事件处理程序创建菜单项的消息响应函数:

C3DView::OnViewSky()

C3DView::OnUpdateViewSky(CCmdUI *pCmdUI)

 

C3DView::ViewGround()

C3DView::OnUpdateViewGround(CCmdUI *pCmdUI)

 

C3DView::ViewBuilding()

C3DView::OnUpdateViewBuilding(CCmdUI *pCmdUI)

 

C3DView::ViewRoad  ()

C3DView::OnUpdateViewRoad(CCmdUI *pCmdUI)

 

C3DView::OnViewTree()

C3DView::OnUpdateViewTree(CCmdUI *pCmdUI)

 

 

在C3DView类的头文件中声明一个枚举类型的变量,并给每个变量付上十六进制的值:

enum EViewSettings

{

   VIEW_SKY  = 0x000001,
   VIEW_GROUND  = 0x000002,
   VIEW_BUILDING = 0x000004,
   VIEW_ROAD  = 0x000008,
   VIEW_TREE  = 0x000010
  };

 

声明一个int型变量m_iViewSettings用来记录当前渲染状态值。

 

在View类构造函数中,定义m_iViewSettings = VIEW_SKY|VIEW_GROUND|VIEW_BUILDING|VIEW_ROAD |VIEW_TREE ;m_iViewSettings 是枚举变量中各项的或运算值,表明初始场景绘制了所有要素。

 

下面以天空要素的控制为例说明:

//C3DView.cpp

 

void C3DView::OnViewSky()

{

//把当前记录的绘制状态赋给局部变量

 int vs = m_iViewSetttings;

 

//////////////将当前状态与枚举变量VIEW_SKY进行异或运算,如果当前状态中标识绘制天空的位为1,说明已经绘制了天空,异或运算后标识位变为0,表明此次消息响应将绘制状态中标识天空绘制的位置为0,表明不绘制天空;同理,如果当前状态中标识天空绘制的位为0,说明当前没有绘制天空,异或运算后标识为变为1,表明此次消息响应后将要绘制天空。

 

 vs ^= VIEW_SKY;

 m_iViewSetttings = vs;

 

/////////更新场景;
  Invalidate();

}

 

void C3DView::OnUpdateViewSky(CCmdUI *pCmdUI)

{

 //当天空绘制时,菜单项显示被选中

 int vs = m_iViewSetttings

 pCmdUI->SetCheck((vs & VIEW_SKY) != 0);

}

 

 

//////场景绘制

void C3DView::OnDraw()

{

 ....

 ...

 ....

 

if (m_iViewSettings & VIEW_SKY )
 {
  

   //绘制天空; 
 }

 

if (m_iViewSettings & VIEW_GROUND )
 {
  

   //绘制地面; 

 }

if (m_iViewSettings & VIEW_BUILDING )
 {
  

   //绘制房屋; 

 }

if (m_iViewSettings & VIEW_ROAD )
 {
  

   //绘制道路; 

 }

if (m_iViewSettings & VIEW_TREE )
 {
  

   //绘制树木; 

 }

 

 

 

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章