?? teach_road_33.htm
字號:
<html><head><meta http-equiv="Content-Type"content="text/html; charset=gb_2312-80"><title>VC Road</title><style type="text/css" MEDIA="screen"><!--a {text-decoration: underline;}a:hover {color:red; text-decoration:underline}small {color: navy; font-size: 12px ; line-height:16px;}h1 {color: navy; font-size: 12px ; line-height:16px;}
big {color: navy; font-size: 22px ; line-height:26px;}
td {color: navy; font-size: 12px ; line-height:16px;bgcolor="#FFCFA3";}--></style></head>
<body background="../img/ground.gif">
<p align="center"><a
HREF="http://www.0828.com/pay/cgi-bin/random.cgi?job=go&id=820"
target="_blank">
<img SRC="http://www.0828.com/pay/cgi-bin/random.cgi?id=820" BORDER="0"
width="468" height="60"></a><br>
<font size="2"><a href="http://www.0828.com/pay/index.html" target=_blank><img border="0"
src="http://www.0828.com/pay/code.gif" width="468" height="15"></a><br><small>你每點一下上面的廣告我就能有更多的上網時間為大家尋找資料</small></font>
</p>
<p align=center><big>3.3 使用菜單</big></p><table border=0 align=center width=80%>
<tr><td>
<small>
<p>利用菜單接受用戶命令是一中很簡單的交互方法,同時也是一種很有效的方法。通常菜單作為一中資源存儲在文件中,因此我們可以在設計時就利用資源編輯器設計好一個菜單。關于使用VC設計菜單我就不再多講了,但你在編寫菜單時應該盡量在屬性對話框的底部提示(Prompt)處輸入文字,這雖然不是必要的,但MFC在有狀態欄和工具條的情況下會使用該文字,文字的格式為“狀態欄出說明\n工具條提示”。<a href=33_g1.gif target=img>圖33_g1</a></p>
<p>我們要面臨的任務是如何知道用戶何時選擇了菜單,他選的是什么菜單項。當用戶選擇了一個有效的菜單項時系統會向應用發送一個WM_COMMAND消息,在消息的參數中表明來源。在MFC中我們只需要進行一次映射,將某一菜單ID映射到一處理函數,<a href=33_g2.gif target=img>圖33_g2</a>。在這里我們在CView的派生類中處理菜單消息,同時我對同一ID設置兩個消息映射,接下來將這兩種映射的作用。</p>
<p><b>ON_COMMAND</b> 映射的作用為在用戶選擇該菜單時調用指定的處理函數。如:ON_COMMAND(IDM_COMMAND1, OnCommand1)會使菜單被選擇時調用OnCommand1成員函數。</p>
<p><b>ON_UPDATE_COMMAND_UI(IDM_COMMAND1, OnUpdateCommand1)</b> 映射的作用是在菜單被顯示時通過調用指定的函數來進行確定其狀態。在這個處理函數中你可以設置菜單的允許/禁止狀態,其顯示字符串是什么,是否在前面打鉤。函數的參數為CCmdUI* pCmdUI,CCmdUI是MFC專門為更新命令提供的一個類,你可以調用<ul>
<li>Enable 設置允許/禁止狀態</li>
<li>SetCheck 設置是否在前面打鉤</li>
<li>SetText 設置文字</li>
</ul>
</p>
<p>下面我講解一個例子:我在CView派生類中有一個變量m_fSelected,并且在視中處理兩個菜單的消息,當IDM_COMMAND1被選時,對m_fSelected進行邏輯非操作,當IDM_COMMAND2被選中時出一提示;同時IDM_COMMAND1根據m_fSelected決定菜單顯示的文字和是否在前面打上檢查符號,IDM_COMMAND2根據m_fSelected的值決定菜單的允許/禁止狀態。下面是代碼和說明:<a href=33_s1.zip>下載示例代碼 17K</a><pre>
void CMenuDView::OnCommand1()
{
m_fSelected=!m_fSelected;
TRACE("command1 selected\n");
}
void CMenuDView::OnUpdateCommand1(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_fSelected);//決定檢查狀態
pCmdUI->SetText(m_fSelected?"當前被選中":"當前未被選中");//決定所顯示的文字
}
void CMenuDView::OnUpdateCommand2(CCmdUI* pCmdUI)
{//決定是否為允許
pCmdUI->Enable(m_fSelected);
}
void CMenuDView::OnCommand2()
{//選中時給出提示
AfxMessageBox("你選了command2");
}
</pre></p>
<p>接下來再講一些通過代碼操縱菜單的方法,在MFC中有一個類CMenu用來處理和菜單有關的功能。在生成一個CMenu對象時你需要從資源中裝如菜單,通過調用BOOL CMenu::LoadMenu( UINT nIDResource )進行裝入,然后你就可以對菜單進行動態的修改,所涉及到的函數有:<ul>
<li>CMenu* GetSubMenu( int nPos ) 一位置得到子菜單的指針,因為一個CMenu對象只能表示一個彈出菜單,如果菜單中的某一項也為彈出菜單,就需要通過該函數獲取指針。</li>
<li>BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ) 在末尾添加一項,nFlag為MF_SEPARATOR表示增加一個分隔條,這樣其他兩個參數將會被忽略;為MF_STRING表示添加一個菜單項uIDNewItem為該菜單的ID命令值;為MF_POPUP表示添加一個彈出菜單項,這時uIDNewItem為另一菜單的句柄HMENU。lpszNewItem為菜單文字說明。</li>
<li>BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于在指定位置插入一菜單,位置由變量nPosition指明。如果nFlags包含MF_BYPOSITION則表明插入在nPosition位置,如果包含MF_BYCOMMAND表示插入在命令ID為nPosition的菜單處。</li>
<li>BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于修改某一位置的菜單,如果nFlags包含MF_BYPOSITION則表明修改nPosition位置的菜單,如果包含MF_BYCOMMAND表示修改命令ID為nPosition處的菜單。</li>
<li>BOOL RemoveMenu( UINT nPosition, UINT nFlags )用于刪除某一位置的菜單。如果nFlags包含MF_BYPOSITION則表明刪除nPosition位置的菜單,如果包含MF_BYCOMMAND表示刪除命令ID為nPosition處的菜單。</li>
<li>BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ) 和 BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp )可以添加一位圖菜單,但這樣的菜單在選中時只是反色顯示,并不美觀。(關于使用自繪OwnerDraw菜單請參考我翻譯的一篇文章<a href=http://vchelp.163.net/refer/odmenu.htm>自繪菜單類</a>)</li>
</ul></p>
<p>視圖中是沒有菜單的,在框架窗口中才有,所以只有用AfxGetApp()->m_pMainWnd->GetMenu()才能得到應用的菜單指針。</p>
<p>最后我講一下如何在程序中彈出一個菜單,你必須先裝入一個菜單資源,你必需得到一個彈出菜單的指針然后調用BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL )彈出菜單,你需要指定(x,y)為菜單彈出的位置,pWnd為接收命令消息的窗口指針。下面有一段代碼說明方法,<a href=33_s2.zip>下載示例代碼 17K</a>。當然為了處理消息你應該在pWnd指明的窗口中對菜單命令消息進行映射。<pre>
CMenu menu;
menu.LoadMenu(IDR_POPUP);
CMenu* pM=menu.GetSubMenu(0);
CPoint pt;
GetCursorPos(&pt);
pM->TrackPopupMenu(TPM_LEFTALIGN,pt.x,pt.y,this);
</pre></p>
<p>另一種做法是通過CMenu::CreatePopupMenu()建立一個彈出菜單,然后使用TrackPopupMenu彈出菜單。使用CreatePopupMenu創建的菜單也可以將其作為一個彈出項添加另一個菜單中。下面的偽代碼演示了如何創建一個彈出菜單并進行修改后彈出:<pre>
CMenu menu1,menu2;
menu1.CreatePopupMenu
menu1.InsertMenu(1)
menu1.InsertMenu(2)
menu1.InsertMenu(3)
menu2.CreatePopupMenu
menu2.AppendMenu(MF_POPUP,1,menu1.Detach()) 將彈出菜單加入 or InsertMenu...
menu2.InsertMenu("string desc");
menu.TrackPopupMenu(...)
</pre>
</p>
<p align=center><a href=teach_first.htm#charpter3>返回</a></p>
</td></tr>
</table>
<p align=center><small>版權所有 聞怡洋 <a href=http://vchelp.163.net/>http://vchelp.163.net/</a></small></p>
<!-- 耐特付費廣告代碼開始 不得修改. -->
<center><script language="javascript">
<!--
var date = new Date();
var ra = date.getTime() % 1000;
var ua = document.URL;
document.write("<iframe src='http://www.china-free.com/cgi-bin/ad/random.cgi?id=560' width=468 height=60 scrolling=no marginwidth=0 marginheight=0 frameborder=0 vspace=0 hspace=0 >");
document.write("<a href='http://www.china-free.com/cgi-bin/ad/random.cgi?id=560' target='_blank'>");
document.write("<img src='http://www.china-free.com/cgi-bin/ad/random.cgi?job=go&id=560' width=468 height=60 border=0></a>");
document.write("</iframe>");
//-->
</script>
<noscript>
<a target="_blank" href="http://www.china-free.com/cgi-bin/ad/random.cgi?id=560">
<img src="http://www.china-free.com/cgi-bin/ad/random.cgi?job=go&id=560" width="468" height="60" border="0"></a>
</noscript>
<br><a HREF="http://www.china-free.com/ad" target="_blank"><img SRC="http://www.china-free.com/ad/bd.gif" BORDER="0" ></a></center>
<!-- 耐特付費廣告代碼結尾. -->
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -