<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    動態菜單項、狀態條提示、工具條提示問題

    趙湘寧
    本文例子代碼
    問題的提出:
    一個應用程序想要動態改變菜單項。使用CCmdUI::SetText("Menu Text")可以改變菜單文本,但是如何動態改變工具條和狀態條的文本呢?

    有幾種策略,避免,欺騙,面對......?
    ??? 首先,避免:為什么你非要動態改變菜單項?一般說來,這是個壞主意,動態菜單容易把人搞糊涂。我正在使用你的產品,本來用得好好的突然菜單項變了。不管什么時候,每當我看到一個改變菜單的應用時,都要琢麼為什么他們需要這樣的用戶界面設計。

    ??? 然而,每一個規則都有例外,許多例子的動態改變菜單項都很酷。例如,在大多數面向文檔的應用程序中“文件”菜單的最后一項MRU(最近使用的文件列表)。但作為一個用戶,面對動態菜單項的弊端是顯而易見的。我把避免動態菜單提升為設計準則。即便是采用了動態菜單的設計,也要讓用戶注意不到菜單項是改變,否則,It's bad design。反之,如果用戶注意不到菜單項的改變,It's OK。

    ??? 但是動態改變狀態條提示又如何呢?在MRU菜單中,無論什么文件,狀態條一般都提示“打開選擇的文檔”。這是另一個要避免的策略。只有特別本位或任性的程序員會操心實現一個動態提示的菜單,如:“打開某某文件”,而不去用完全可行并且有效的提示“打開這個文檔”。你完全有權利不遵循這種慣例,也就是說,如果你非要改變狀態條提示的話,那就請往下繼續看吧,你會明白的。

    使用動態菜單的另一場合是當你想設置某個布爾狀態時。例如,隱藏或顯示工具條,當工具條可見時顯示“隱藏工具條”,反之顯示“顯示工具條”。更為普通的方法是用單個命令以校驗標記來實現,當工具條可見時顯示標記(如下圖)。

    ??? GUI的高手們常常爭論哪種方法更好。可能它沒有什么差別,但是即使你決定使用動態提示(如隱藏/顯示工具條),你也能使用單個的命令ID,ID_VIEW_TOOLBAR,和單個的提示“隱藏或顯示工具條”。我認為沒有必要去實現動態提示。

    ??? 在所有建議中,你要做的第一件事情是好好重新考慮用戶的界面。你確實需要動態菜單項嗎?以及你確實需要菜單的動態提示嗎?除非兩個問題的答案都是“是”。否則就止住,別再浪費時間。

    ??? 要改變菜單文本是容易的。只要實現ON_UPDATE_COMMAND_UI處理器并調用CCmdUI::SetText即可:

    void CFrameWnd::OnUpdateToolbar(CCmdUI* pCmdUI)?
    {
    ???? BOOL bVisible = IsToolbarVisible(...);
    ???? // Note same mnemonic (&T) for both cmds!
    ???? pCmdUI->SetText(bVisible ? "Hide &Toolbar" : "Show &Toolbar");?
    }?

    僅此而已。下一步是提示。當你創建了一個菜單提示,你給它一個ID號。MFC使用這個ID來查找資源串獲取命令提示。例如:

    STRINGTABLE DISCARDABLE?
    BEGIN
    ???? ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"?
    END?

    ??? 如果你的菜單命令也有工具條按鈕,MFC用“\n”(新行標記)后的文本作為工具條提示文本。因為MFC允許每個命令只能有一個串,如何動態改變提示呢?最簡單的方法是編寫一個提示在兩種情況下都工作,象前面討論的隱藏、顯示工具條的例子。但這種方法顯得很笨拙。

    ??? 獲得動態提示的一個方法是將命令分成幾個命令-例如,ID_HIDE_ TOOLBAR?和ID_SHOW_TOOLBAR,只是一種欺騙策略。這些命令的命令處理器最終要做的事情是改變菜單項的ID為其它命令項的ID。具體實現細節我就不講了,自己做吧。

    ??? 使用兩個ID可能是一種簡單的方法,但它不適用于所有情況。例如在MRU文件菜單中,對于每個可能的文件名字你會需要不同的ID。

    ??? 本文提供一個例子程序,DynPrompt,如下圖,

    狀態條采用了動態提示,為了理解DynPrompt是如何工作的,你必須對MFC的菜單提示有一些研究。當用戶的鼠標 移動到一個菜單項時,Windows發送WM_MENUSELECT和菜單項的ID。MFC的CFrameWnd處理如下:

    // much simplified?
    void CFrameWnd::OnMenuSelect(UINT nItemID,
    UINT nFlags, HMENU hSysMenu)
    {
    ???? SendMessage(WM_SETMESSAGESTRING, nItemID);?
    }?

    ??? 我做了一些簡化;函數的實際代碼超過了60行,但基本的意思是框架發送WM_SETMESSAGESTRING消息到自身,用WPARAM傳遞命令ID。SETMESSAGESTRING?是MFC的一個私有消息,它在afxpriv.h中定義。這個消息在狀態條窗格中設置 要顯示的文本。你可以用WPARAM傳遞資源串的ID,或者用LPARAM傳遞實際的串。

    // resource string ID?
    SendMessage(WM_SETMESSAGESTRING, ID_MYSTRING);

    // string?
    SendMessage(WM_SETMESSAGESTRING, 0, (LPARAM)_T("Hello, world"));?

    ??? 所以,如果要實現動態菜單提示,必須重載CFrameWnd::OnMenuSelect和 用提示串發送WM_SETMESSAGESTRIN消息。

    void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags,
    HMENU hSysMenu)?
    {?
    ???? if (/* nItemID has a dynamic prompt */) {
    ??????? CString sPrompt = // whatever you want?
    ??????? SendMessage(WM_SETMESSAGESTRING, 0,? (LPARAM)(LPCTSTR)sPrompt);?
    ??????? m_nIDTracking = nItemID;?
    ???? } else {?
    ??????? CFrameWnd::OnMenuSelect(nItemID,? nFlags, hSysMenu);?
    ???? }?
    }?

    ??? MainFrm.cpp文件中的OnMenuSelect實際代碼調用一連串函數從MRU菜單項來截獲 文件名并建立所要的文本提示。別忘了還要調用CFrameWnd::OnMenuSelect來處理 未改變的提示的命令。

    ??? 最后,對于如何動態改變工具提示文本的方法,CFrameWnd::OnToolTipText是MFC處理工具條通知的函數。其標準實現用匹配的命令ID加載資源串,截獲“\n”后的文本并將它拷貝調用者的TOOLTIPTEXT結構。你的任務是編寫自己的 代碼重載這個處理器。我把這個作為家庭作業。

    from: http://www.vckbase.com/vckbase/vckbase8/vc/ctrls/menu_07/0807002.htm

    posted on 2006-11-11 10:07 weidagang2046 閱讀(521) 評論(0)  編輯  收藏 所屬分類: Windows

    主站蜘蛛池模板: 亚洲人成色77777| 亚洲天然素人无码专区| 2020久久精品国产免费| 日韩亚洲翔田千里在线| 亚洲AV永久无码区成人网站| 国产成在线观看免费视频| kk4kk免费视频毛片| 亚洲黄色片免费看| 又粗又硬免费毛片| 久久国产精品成人片免费| 羞羞漫画小舞被黄漫免费| 亚洲视频在线观看一区| 国产在线ts人妖免费视频| 一区二区三区四区免费视频| 免费人成大片在线观看播放电影| 亚洲国产一区国产亚洲| 免费日韩在线视频| 最近免费中文字幕大全高清大全1 最近免费中文字幕mv在线电影 | 国产亚洲精品美女久久久久| 亚洲视频精品在线| 亚洲欧洲久久av| 天天摸夜夜摸成人免费视频 | 久久亚洲免费视频| 国产偷国产偷亚洲高清人| 久久亚洲AV无码精品色午夜麻豆 | 伊人亚洲综合青草青草久热| 无码人妻一区二区三区免费| 久久精品国产影库免费看| 亚洲AV无码一区二区三区牲色| 亚洲午夜视频在线观看| 亚洲Av无码乱码在线观看性色| 成人免费一级毛片在线播放视频| a级毛片在线免费看| 深夜免费在线视频| 亚洲乱码日产精品一二三| 亚洲精品美女视频| 亚洲国产精品久久久天堂| 亚洲国产一级在线观看| 成年丰满熟妇午夜免费视频| 日本免费网址大全在线观看| 免费A级毛片无码视频|