用MFC的訊息映像實現動態選單

2021-04-12 15:31:18 字數 3473 閱讀 2330

---- 首先,我們簡要說說vc 中mfc 的訊息映像。每個windows 程式設計師大概都對以前使用的視窗函式windowproc 記憶猶新,當我們面對各種訊息時,我們別無他方,只能使用龐大而機械的switch-case 語句來實現不同的分支選擇。在vc5.0 中使用v4.2 版的mfc 基本類庫,你將告別switch-case 語句,代之以透明的訊息映像。要在乙個類中使用訊息映像,在類宣告中,必須顯式的加入巨集declare_message_map:

class cmyclass: public cbaseclass

---- 在類實現中,必須使用兩個巨集begin_message_map 和end_message_map,begin_message_map 帶兩個引數:當前類和直接父類:

---- begin_message_map(cmyclass, cbaseclass)

---- // 訊息映像項

---- // 訊息映像項

---- end_message_map()

---- 訊息映像項使用下列基本語法:

---- on_messagename(id, clas**ethod)

---- messagename 是需要處理的訊息,id 是傳送訊息的識別符號,而clas**ethod 為處理此訊息的類方法名。messagename 是mfc 預定義的,可分為以下三種:

---- 命令訊息

---- 子視窗通知訊息

---- windows 訊息

---- 共一百多個,使用者不必記住它們,因為訊息映像可以很簡單的利用classwizard 加入。處理乙個訊息的類方法clas**ethod 必須在類定義中宣告,且有實現**。其原型為:

---- afx_msg return_type clas**ethod(paras table)

---- 類ccmdui 專門(且僅僅)與on_update_command_ui 訊息映像巨集配套使用,用於管理選單(還有工具欄按扭等)的實時狀態,如是否變灰,是否加選中標記等。

---- on_update_command_ui 訊息映像巨集原型為:

---- on_update_command_ui(menu_item_id, menu_proc)

---- on_update_command_ui 訊息映像巨集將乙個選單項(命令項)和乙個更新處理過程聯結,從而在適當的時機自動呼叫此更新處理過程來完成對選單項狀態的更新。

---- menu_item_id 為選單項的id 號,menu_proc 為此選單項的更新處理函式,? 為:

---- afx_msg void menu_proc (ccmdui* pcmdui)

---- 它帶有乙個ccmdui 類指標,使用它可呼叫ccmdui 的類方法。與選單有關的類方法有:

enable(bool) 使選單項有效或無效

settext(lpctstr) 設定選單項的文字

setcheck(int) 加上或去掉選中標記「x」

setradio(bool) 加上或去掉選中標記「.」

---- menuproc 被呼叫的時機有以下幾種情況:

---- 用滑鼠選中包含該選單項的選單條

---- 用熱鍵選中包含該選單項的選單條

---- 用快捷鍵選中與該選單項在同一選單條下的任一選單項

---- 我們以下面選單結構為例:

test menu

item one id_item_one ctrl+1

item two id_item_two ctrl+2

popup popup one id_popup_one ctrl+3

popup two id_popup_two ctrl+4

---- 當用滑鼠左鍵點按test menu 選單條或按alt+t 或按ctrl+1/2/3/4 時,四個選單項的更新處理過程menuproc 都將被呼叫。

---- 當我們考察上面這個具有巢狀結構的選單時,我們面臨這樣乙個問題:選單項item one/item two 的更新函式和popup one/popup two 的更新函式形式上是否一致?當popup one 和popup two 都變灰時popup 是否自動變灰?

---- 根據mfc 的內部機制,僅僅彈出選單的第一項應附加一些**,其餘項的形式基本是一致的。也就是說在上例中,除選單項popup one 外,其他選單項更新函式的**基本一致,即根據條件,簡單呼叫ccmdui 類方法即可。選單項popup one 由於是彈出式選單popup 的第一項,它的更新函式在以下兩種情況下都會被呼叫:

---- 當彈出式選單(popup)的選單項(popup one 和popup two)要被繪出時

---- 當此彈出式選單即popup 本身要被繪出時

---- 第一種情況很好理解,正如我們選中test menu 而item one 和item two 的更新函式會自動執行一樣。第二種情況其實也很自然,因為popup 和item one/item two 不一樣,它沒有id 號,不能新增訊息映像項,那麼它的狀態如何更新呢?於是它的第一項的更新函式被呼叫,為了區分是不同的呼叫,它將ccmdui 的類成員變數m_psubmenu 設定為不同的值。在第一種情況下,m_psubmenu 等於null, 第二種情況下,m_psubmenu 不等於null。

---- 以下我們給出乙個實際的程式設計範例。由於篇幅關係,我們僅僅給出一些關鍵的語句,其餘的則一併略去。

---- 在標頭檔案的類宣告中:

bool m_bitemone, m_bitemtwo, m_bpopupone, m_bpopuptwo;

//用於決定各個選單項的狀態

protected:

afx_msg void onupdatemenuitemone(ccmdui* pcmdui);

afx_msg void onupdatemenuitemtwo(ccmdui* pcmdui);

afx_msg void onupdatepopupone(ccmdui* pcmdui);

afx_msg void onupdatepopuptwo(ccmdui* pcmdui);

//各選單項的更新函式

declare_message_map()

在原始檔中:

begin_message_map(cmydoc, cdocument)

on_update_command_ui (id_item_one,

onupdatemenuitemone)

on_update_command_ui (id_item_two,

onupdatemenuitemtwo)

on_update_command_ui (id_popup_one,

onupdatepopupone)

on_update_command_ui (id_ popup_two,

onupdatepopuptwo)

end_message_map()

pcmdui->enable(m_bpopupone); }

MFC 訊息對映的實現

訊息對映的實現 windows訊息概述 windows應用程式的輸入由windows系統以訊息的形式傳送給應用程式的視窗。這些視窗通過視窗過程來接收和處理訊息,然後把控制返還給windows。訊息的分類 佇列訊息和非佇列訊息 從訊息的傳送途徑上看,訊息分兩種 佇列訊息和非佇列訊息。佇列訊息送到系統訊...

實現動態選單的技巧

我的小軟體想實現這樣乙個功能 登陸前,我希望只有 帳戶 幫助 這兩個選單項,帳戶選單有註冊和登陸兩個彈出選單 登陸以後,其他選單才全部出來。但是這樣生成的選單並沒有命令處理機制,解決的辦法是過載oncmdmsg函式 然後根據選單id用switch方式選擇執行函式。總是感覺這種方法很別拗。當然可以一開...

Delphi的動態選單實現

這裡所謂的動態選單是指選單項是變化的,它隨程式的操作變化而變化。例如在很多應用程式的 檔案 選單下列出了最近多少次曾經使用過的檔名,這是最常見的動態選單用法,microsoft word 的 檔案 選單就是一例。動態選單的使用為操作應用程式提供了極大的方便。用 delphi 編寫應用程式我們也可以實...