使用異或運算實現菜單項功能的啓用與關閉

在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 )
 {
  

   //繪製樹木; 

 }

 

 

 

}

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