• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 47, 文章 - 10, 評(píng)論 - 8, 引用 - 0
            數(shù)據(jù)加載中……

            孫鑫VC++講座筆記-(6)菜單編程

            1,彈出菜單(Pop-up)是不能用來作命令響應(yīng)的。

            2,MFC中菜單項(xiàng)消息如果利用ClassWizard來對(duì)菜單項(xiàng)消息分別在上述四個(gè)類中進(jìn)行響應(yīng),則菜單消息傳遞順序:View類--Doc類--CMainFrame類--App類。菜單消息一旦在其中一個(gè)類中響應(yīng)則不再在其它類中查找響應(yīng)函數(shù)。
            具體:
            當(dāng)點(diǎn)擊一個(gè)菜單項(xiàng)的時(shí)候,最先接受到菜單項(xiàng)消息的是CMainFrame框架類,CMainFrame框架類將會(huì)把菜單項(xiàng)消息交給它的子窗口View類,由View類首先進(jìn)行處理;如果View類檢測(cè)到?jīng)]對(duì)該菜單項(xiàng)消息做響應(yīng),則View類把菜單項(xiàng)消息交由文檔類Doc類進(jìn)行處理;如果Doc類檢測(cè)到Doc類中也沒對(duì)該菜單項(xiàng)消息做響應(yīng),則Doc類又把該菜單項(xiàng)消息交還給View類,由View類再交還給CMainFrame類處理。如果CMainFrame類查看到CMainFrame類中也沒對(duì)該消息做響應(yīng),則最終交給App類進(jìn)行處理。

            3,消息的分類:標(biāo)準(zhǔn)消息,命令消息,通告消息。
            [標(biāo)準(zhǔn)消息]:除WM_COMMAND之外,所有以WM_開頭的消息。
            [命令消息]:來自菜單、加速鍵或工具欄按鈕的消息。這類消息都以WM_COMMAND呈現(xiàn)。
            在MFC中,通過菜單項(xiàng)的標(biāo)識(shí)(ID)來區(qū)分不同的命令消息;在SDK中,通過消息的wParam參數(shù)識(shí)別。
            [通告消息]:由控件產(chǎn)生的消息,例如,按鈕的單擊,列表框的選擇等均產(chǎn)生此類消息,為的是向其父窗口(通常是對(duì)話框)通知事件的發(fā)生。這類消息也是以WM_COMMAND形式呈現(xiàn)。
            說明:
            1)從CWnd派生的類,都可以接收到[標(biāo)準(zhǔn)消息]。
            2)從CCmdTarget派生的類,都可以接收到[命令消息]和[通告消息]。

            4,一個(gè)菜單攔可以有若干個(gè)子菜單,一個(gè)子菜單又可以有若干個(gè)菜單項(xiàng)等。對(duì)菜單欄的子菜單由左至右建立從0開始的索引。對(duì)特定子菜單的菜單項(xiàng)由上至下建立了從0開始的索引。訪問子菜單和菜單項(xiàng)均可以通過其索引或標(biāo)識(shí)(如果有標(biāo)識(shí)的話)進(jìn)行。
            相關(guān)重要函數(shù):

            1 CMenu * ?GetMenu(?)?; // CWnd::GetMenu得到窗口菜單欄對(duì)象指針。
            2 CMenu * ?GetSubMenu(??)?; // CMenu::GetSubMenu獲得指向彈出菜單對(duì)象指針
            3 UINT?CheckMenuItem(?); // CMenu::CheckMenuItem?Adds?check?marks?to?or?removes?check?marks?from?menu?items?in?the?pop-up?menu.?
            4 BOOL?SetDefaultItem(); // CMenu::SetDefaultItem?Sets?the?default?menu?item?for?the?specified?menu.
            5 BOOL?SetMenuItemBitmaps(?); // CMenu::SetMenuItemBitmaps?設(shè)置位圖標(biāo)題菜單。
            6 UINT?EnableMenuItem(); // CMenu::EnableMenuItem使菜單項(xiàng)有效,無效,或變灰。
            7 BOOL?SetMenu(?CMenu * ?pMenu?); // CWnd::SetMenu在當(dāng)前窗口上設(shè)置新菜單或移除菜單。
            8 HMENU?Detach(?); // CMenu::Detach?Detaches?a?Windows?menu?from?a?CMenu?object?and?returns?the?handle.?
            9

            說明:
            1)在計(jì)算子菜單菜單項(xiàng)的索引的時(shí)候,分隔欄符也算索引的。
            2)int GetSystemMetrics()獲取系統(tǒng)信息度量。可以用它來獲取菜單標(biāo)題的尺寸從而設(shè)置位圖標(biāo)題菜單中位圖的大小。
            3)在MFC中MFC為我們提供了一套命令更新機(jī)制,所有菜單項(xiàng)的更新都是由這套機(jī)制來完成的。所以要想利用CMenu::EnableMenuItem來自己控制菜單使用或不使用變灰等,必須要在CMainFrame的構(gòu)造函數(shù)中將變量m_bAutoMenuEnable設(shè)置為FALSE。
            4)Create a CMenu object on the stack frame as a local, then call CMenu’s member functions to manipulate the new menu as needed. Next, call CWnd::SetMenu to set the menu to a window, followed immediately by a call to the CMenu object’s Detach member function. The CWnd::SetMenu member function sets the window’s menu to the new menu, causes the window to be redrawn to reflect the menu change, and also passes ownership of the menu to the window. The call to Detach detaches the HMENU from the CMenu object, so that when the local CMenu variable passes out of scope, the CMenu object destructor does not attempt to destroy a menu it no longer owns. The menu itself is automatically destroyed when the window is destroyed.
            5)You can use the LoadMenuIndirect member function to create a menu from a template in memory, but a menu created from a resource by a call to LoadMenu is more easily maintained, and the menu resource itself can be created and modified by the menu editor.
            6)EXAMPLE:
            1CMenu?menu;//定義為局部對(duì)象
            2menu.LoadMenu(IDR_MAINFRAME);
            3SetMenu(&menu);
            4menu.Detach();//?這里menu對(duì)象作為一個(gè)局部對(duì)象。使用Detach()從menu對(duì)象中分離窗口菜單句柄,從而當(dāng)menu對(duì)象析構(gòu)的時(shí)候窗口菜單資源不隨之銷毀。
            5

            5,命令更新機(jī)制:
            菜單項(xiàng)狀態(tài)的維護(hù)是依賴于CN_UPDATE_COMMAND_UI消息,誰捕獲CN_UPDATE_COMMAND_UI消息,MFC就在其中創(chuàng)建一個(gè)CCmdUI對(duì)象。
            在后臺(tái)操作系統(tǒng)發(fā)出WM_INITMENUPOPUP消息,然后由MFC的基類如CFrameWnd接管并創(chuàng)建一個(gè)CCmdUI對(duì)象和第一個(gè)菜單項(xiàng)相關(guān)聯(lián),調(diào)用對(duì)象成員函數(shù)DoUpdate()(注:這個(gè)函數(shù)在MSDN中沒有找到說明)發(fā)出CN_UPDATE_COMMAND_UI消息,這條消息帶有指向CCmdUI對(duì)象的指針。此后同一個(gè)CCmdUI對(duì)象又設(shè)置為與第二個(gè)菜單項(xiàng)相關(guān)聯(lián),這樣順序進(jìn)行,直到完成所有菜單項(xiàng)。
            更新命令UI處理程序僅應(yīng)用于彈出式菜單項(xiàng)上的項(xiàng)目,不能應(yīng)用于永久顯示的頂級(jí)菜單項(xiàng)目。
            說明:
            1)可以手工或用ClassWizard來給菜單項(xiàng)添加UPDATE_COMMAND_UI消息響應(yīng),利用響應(yīng)函數(shù)中傳進(jìn)來的CCmdUI對(duì)象指針可完成設(shè)置菜單項(xiàng)可使用,不可使用,變灰,設(shè)置標(biāo)記菜單等操作。

            6,如果要想讓工具欄上的某個(gè)圖標(biāo)與菜單項(xiàng)的某個(gè)菜單相關(guān)聯(lián),只需要將圖標(biāo)的ID設(shè)置為該菜單項(xiàng)的ID。
            工具欄圖標(biāo)的索引記數(shù)順序是:從做至右從0開始,分隔符也算索引號(hào)。

            7,利用向項(xiàng)目中添加VC的POPMENU控件:Project->Add to Project->Components and Controls..
            系統(tǒng)增加的內(nèi)容:A,一個(gè)菜單資源;B,在派生View類中增加了OnContextMenu()函數(shù)
            說明:
            1)CWnd::OnContextMenu Called by the framework when the user has clicked the right mouse button (right clicked) in the window. You can process this message by displaying a context menu using the TrackPopupMenu.
            2)BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL );
            //CMenu::TrackPopupMenu Displays a floating pop-up menu at the specified location and tracks the selection of items on the pop-up menu. A floating pop-up menu can appear anywhere on the screen.

            8,利用調(diào)用TrackPopupMenu函數(shù),手工添加彈出菜單:
            1)用資源管理器添加一個(gè)菜單資源
            2)在鼠標(biāo)右鍵消息響應(yīng)函數(shù)中,加載菜單資源,并獲得要顯示的子菜單指針,并用該指針調(diào)用TrackPopupMenu函數(shù)便完成任務(wù)(但要注意:鼠標(biāo)響應(yīng)函數(shù)傳進(jìn)來的坐標(biāo)是客戶區(qū)坐標(biāo),而TrackPopupMenu函數(shù)中使用的是屏幕坐標(biāo),在調(diào)用TrackPopupMenu前要調(diào)用ClientToScreen客戶區(qū)坐標(biāo)到屏幕坐標(biāo)的轉(zhuǎn)換)
            事例代碼:

            ?1CMenu?menu;
            ?2menu.LoadMenu(IDR_MENU1);
            ?3CMenu?*pPopup=menu.GetSubMenu(0);
            ?4ClientToScreen(&point);
            ?5pPopup->TrackPopupMenu(TPM_LEFTALIGN?|?TPM_RIGHTBUTTON,?point.x,?point.y,this);
            ?6//說明:
            ?7CWnd::ClientToScreen(..);//將一個(gè)坐標(biāo)點(diǎn)或一個(gè)矩形區(qū)域坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)。
            ?8CMenu::TrackPopupMenu(..);//在指定位置以指定的方式顯示彈出菜單。
            ?9CWnd::ScreenToClient(..);
            10//Converts?the?screen?coordinates?of?a?given?point?or?rectangle?on?the?display?to?client?coordinates.?
            11

            9,當(dāng)彈出菜單屬于框架窗口的時(shí)候(可在TrackPopupMenu函數(shù)參數(shù)中設(shè)置),彈出菜單上的消息,在路由的時(shí)候,仍然遵循View-DOC-MainFrame-APP的響應(yīng)順序。

            10,動(dòng)態(tài)菜單編程:
            所有的資源對(duì)象都有一個(gè)數(shù)據(jù)成員保存了資源的句柄。

            1CMenu::AppendMenu?//Appends?a?new?item?to?the?end?of?a?menu.
            2CMenu::CreatePopupMenu?//Creates?an?empty?pop-up?menu?and?attaches?it?to?a?CMenu?object.
            3CMenu::InsertMenu?
            4//Inserts?a?new?menu?item?at?the?position?specified?by?nPosition?and?moves?other?items?down?the?menu.?
            5CMenu::GetSubMenu?//Retrieves?a?pointer?to?a?pop-up?menu.
            6CWnd::GetMenu?//Retrieves?a?pointer?to?the?menu?for?this?window.
            7CMenu::DeleteMenu?//Deletes?an?item?from?the?menu.?
            8

            11,手動(dòng)給動(dòng)態(tài)菜單項(xiàng)添加響應(yīng)函數(shù):
            在Resource.h中可以添加資源的ID
            在頭文件中寫消息函數(shù)原型
            在代碼文件中添加消息映射和添加消息響應(yīng)函數(shù)
            說明:
            可以先創(chuàng)建一個(gè)臨時(shí)的菜單項(xiàng),設(shè)置它的ID和動(dòng)態(tài)菜單項(xiàng)的一致,然后對(duì)它用向?qū)нM(jìn)行消息響應(yīng),然后刪除臨時(shí)菜單。
            再在代碼文件中把消息映射放到宏外(注意一定要放到宏外面,因?yàn)镃LASSWIZARD發(fā)現(xiàn)菜單刪除了,同時(shí)要把其宏對(duì)里的消息映射也刪除掉的)

            12,CWnd::DrawMenuBar

            1//Redraws?the?menu?bar.?If?a?menu?bar?is?changed?after?Windows?has?created?the?window,?call?this?function?to?draw?the?changed?menu?bar
            2
            3CWnd::GetParent?//get?a?pointer?to?a?child?window’s?parent?window?(if?any).?
            4CWnd::Invalidate?//注意其參數(shù)的作用
            5

            13,集合類:
            CStringArray,CStringArray,CDWordArray,CPtrArray,CStringArray,CUIntArray,CWordArray
            其中成員函數(shù):
            CArray::GetAt
            CArray::Add

            14,命令消息是到OnCommand函數(shù)的時(shí)候完成路由的。
            由于CWnd::OnCommand 是個(gè)虛函數(shù),可以在框架類中重寫OnCommand函數(shù),從而可以截獲菜單消息使它不再往下(VIEW類)路由。
            例:

            ?1BOOL?CMainFrame::OnCommand(WPARAM?wParam,?LPARAM?lParam)?
            ?2{
            ?3?//?TODO:?Add?your?specialized?code?here?and/or?call?the?base?class
            ?4?int?MenuCmdId=LOWORD(wParam);//取命令I(lǐng)D
            ?5?CMenu2View?*pView=(CMenu2View*)GetActiveView();//獲取當(dāng)前VIEW類指針
            ?6?if(MenuCmdId>=IDM_PHONE1?&&?MenuCmdId<IDM_PHONE1+pView->m_strArray.GetSize())//消息范圍判斷
            ?7?{
            ?8??CClientDC?dc(pView);
            ?9??dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdId-IDM_PHONE1));
            10??return?TRUE;?
            11???//函數(shù)返回,避免調(diào)用CFrameWnd::OnCommand函數(shù),在CFrameWnd::OnCommand中截獲的消息會(huì)交由VIEW類處理
            12?}

            13?return?CFrameWnd::OnCommand(wParam,?lParam);
            14??//調(diào)用基類OnCommand函數(shù),在CFrameWnd::OnCommand中截獲的消息會(huì)交由VIEW類處理
            15}

            16

            MSDN說明:
            virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );
            //The framework calls this member function when the user selects an item from a menu, when a child control sends a notification message, or when an accelerator keystroke is translated.
            OnCommand processes the message map for control notification and ON_COMMAND entries, and calls the appropriate member function.
            Override this member function in your derived class to handle the WM_COMMAND message. An override will not process the message map unless the base class OnCommand is called.

            15,LOWORD與HIWORD宏

            ?1WORD?LOWORD(
            ?2??DWORD?dwValue??//?value?from?which?low-order?word?is?retrieved
            ?3);
            ?4WORD?HIWORD(
            ?5??DWORD?dwValue??//?value?from?which?high-order?word?is?retrieved
            ?6);
            ?7
            ?8//The?LOWORD?macro?retrieves?the?low-order?word?from?the?given?32-bit?value.?
            ?9//The?HIWORD?macro?retrieves?the?high-order?word?from?the?given?32-bit?value.?
            10
            11
            16,CFrameWnd::GetActiveView
            CView* GetActiveView( ) const;//獲取當(dāng)前視窗口指針(單文檔框架中)

            17,源文件是單獨(dú)參與編譯的。

            posted on 2006-04-04 11:09 編程之道 閱讀(246) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

            奇米影视7777久久精品人人爽| 97久久精品人妻人人搡人人玩| 精品国际久久久久999波多野| 国产精品无码久久综合网| 久久中文骚妇内射| 996久久国产精品线观看| 久久综合香蕉国产蜜臀AV| 欧美日韩久久中文字幕| 亚洲乱码精品久久久久.. | 久久强奷乱码老熟女网站| 无码任你躁久久久久久老妇| 国内精品久久久久久久亚洲| 国产精品日韩深夜福利久久| 久久精品中文字幕有码| 思思久久99热免费精品6| 久久久无码精品亚洲日韩京东传媒 | 一本色道久久88综合日韩精品| 久久亚洲AV无码西西人体| 久久久久无码国产精品不卡| 国产精品久久久香蕉| 亚洲人成精品久久久久| 久久棈精品久久久久久噜噜| 99久久久精品免费观看国产| 国产一区二区三精品久久久无广告| 香蕉久久永久视频| 精品久久久久久成人AV| 久久精品国产99久久丝袜| 久久精品国产免费观看| 久久99精品久久久久久久久久| 国产成人精品久久亚洲高清不卡 | 久久人人爽人人精品视频| 亚洲人成伊人成综合网久久久| 久久亚洲高清观看| 国产69精品久久久久久人妻精品| 久久精品中文字幕无码绿巨人| 岛国搬运www久久| 午夜人妻久久久久久久久| 精品水蜜桃久久久久久久| 久久精品中文字幕无码绿巨人| 亚洲国产小视频精品久久久三级| 九九精品99久久久香蕉|