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

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

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

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評(píng)論 - 101, 引用 - 0
    數(shù)據(jù)加載中……

    動(dòng)態(tài)菜單項(xiàng)、狀態(tài)條提示、工具條提示問(wèn)題

    趙湘寧
    本文例子代碼
    問(wèn)題的提出:
    一個(gè)應(yīng)用程序想要?jiǎng)討B(tài)改變菜單項(xiàng)。使用CCmdUI::SetText("Menu Text")可以改變菜單文本,但是如何動(dòng)態(tài)改變工具條和狀態(tài)條的文本呢?

    有幾種策略,避免,欺騙,面對(duì)......?
    ??? 首先,避免:為什么你非要?jiǎng)討B(tài)改變菜單項(xiàng)?一般說(shuō)來(lái),這是個(gè)壞主意,動(dòng)態(tài)菜單容易把人搞糊涂。我正在使用你的產(chǎn)品,本來(lái)用得好好的突然菜單項(xiàng)變了。不管什么時(shí)候,每當(dāng)我看到一個(gè)改變菜單的應(yīng)用時(shí),都要琢麼為什么他們需要這樣的用戶界面設(shè)計(jì)。

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

    ??? 但是動(dòng)態(tài)改變狀態(tài)條提示又如何呢?在MRU菜單中,無(wú)論什么文件,狀態(tài)條一般都提示“打開(kāi)選擇的文檔”。這是另一個(gè)要避免的策略。只有特別本位或任性的程序員會(huì)操心實(shí)現(xiàn)一個(gè)動(dòng)態(tài)提示的菜單,如:“打開(kāi)某某文件”,而不去用完全可行并且有效的提示“打開(kāi)這個(gè)文檔”。你完全有權(quán)利不遵循這種慣例,也就是說(shuō),如果你非要改變狀態(tài)條提示的話,那就請(qǐng)往下繼續(xù)看吧,你會(huì)明白的。

    使用動(dòng)態(tài)菜單的另一場(chǎng)合是當(dāng)你想設(shè)置某個(gè)布爾狀態(tài)時(shí)。例如,隱藏或顯示工具條,當(dāng)工具條可見(jiàn)時(shí)顯示“隱藏工具條”,反之顯示“顯示工具條”。更為普通的方法是用單個(gè)命令以校驗(yàn)標(biāo)記來(lái)實(shí)現(xiàn),當(dāng)工具條可見(jiàn)時(shí)顯示標(biāo)記(如下圖)。

    ??? GUI的高手們常常爭(zhēng)論哪種方法更好。可能它沒(méi)有什么差別,但是即使你決定使用動(dòng)態(tài)提示(如隱藏/顯示工具條),你也能使用單個(gè)的命令I(lǐng)D,ID_VIEW_TOOLBAR,和單個(gè)的提示“隱藏或顯示工具條”。我認(rèn)為沒(méi)有必要去實(shí)現(xiàn)動(dòng)態(tài)提示。

    ??? 在所有建議中,你要做的第一件事情是好好重新考慮用戶的界面。你確實(shí)需要?jiǎng)討B(tài)菜單項(xiàng)嗎?以及你確實(shí)需要菜單的動(dòng)態(tài)提示嗎?除非兩個(gè)問(wèn)題的答案都是“是”。否則就止住,別再浪費(fèi)時(shí)間。

    ??? 要改變菜單文本是容易的。只要實(shí)現(xiàn)ON_UPDATE_COMMAND_UI處理器并調(diào)用CCmdUI::SetText即可:

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

    僅此而已。下一步是提示。當(dāng)你創(chuàng)建了一個(gè)菜單提示,你給它一個(gè)ID號(hào)。MFC使用這個(gè)ID來(lái)查找資源串獲取命令提示。例如:

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

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

    ??? 獲得動(dòng)態(tài)提示的一個(gè)方法是將命令分成幾個(gè)命令-例如,ID_HIDE_ TOOLBAR?和ID_SHOW_TOOLBAR,只是一種欺騙策略。這些命令的命令處理器最終要做的事情是改變菜單項(xiàng)的ID為其它命令項(xiàng)的ID。具體實(shí)現(xiàn)細(xì)節(jié)我就不講了,自己做吧。

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

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

    狀態(tài)條采用了動(dòng)態(tài)提示,為了理解DynPrompt是如何工作的,你必須對(duì)MFC的菜單提示有一些研究。當(dāng)用戶的鼠標(biāo) 移動(dòng)到一個(gè)菜單項(xiàng)時(shí),Windows發(fā)送WM_MENUSELECT和菜單項(xiàng)的ID。MFC的CFrameWnd處理如下:

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

    ??? 我做了一些簡(jiǎn)化;函數(shù)的實(shí)際代碼超過(guò)了60行,但基本的意思是框架發(fā)送WM_SETMESSAGESTRING消息到自身,用WPARAM傳遞命令I(lǐng)D。SETMESSAGESTRING?是MFC的一個(gè)私有消息,它在afxpriv.h中定義。這個(gè)消息在狀態(tài)條窗格中設(shè)置 要顯示的文本。你可以用WPARAM傳遞資源串的ID,或者用LPARAM傳遞實(shí)際的串。

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

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

    ??? 所以,如果要實(shí)現(xiàn)動(dòng)態(tài)菜單提示,必須重載CFrameWnd::OnMenuSelect和 用提示串發(fā)送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實(shí)際代碼調(diào)用一連串函數(shù)從MRU菜單項(xiàng)來(lái)截獲 文件名并建立所要的文本提示。別忘了還要調(diào)用CFrameWnd::OnMenuSelect來(lái)處理 未改變的提示的命令。

    ??? 最后,對(duì)于如何動(dòng)態(tài)改變工具提示文本的方法,CFrameWnd::OnToolTipText是MFC處理工具條通知的函數(shù)。其標(biāo)準(zhǔn)實(shí)現(xiàn)用匹配的命令I(lǐng)D加載資源串,截獲“\n”后的文本并將它拷貝調(diào)用者的TOOLTIPTEXT結(jié)構(gòu)。你的任務(wù)是編寫自己的 代碼重載這個(gè)處理器。我把這個(gè)作為家庭作業(yè)。

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

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

    主站蜘蛛池模板: 亚洲中文字幕无码专区| 亚洲一级大黄大色毛片| **一级毛片免费完整视| 精品国产日韩久久亚洲| 四虎永久在线精品免费观看地址 | 成人爽a毛片免费| 亚洲人精品亚洲人成在线| 亚洲精品国产V片在线观看| 6080午夜一级毛片免费看| 风间由美在线亚洲一区| 亚洲AV日韩AV鸥美在线观看| 免费羞羞视频网站| 国产婷婷成人久久Av免费高清| 四虎亚洲精品高清在线观看| 亚洲人成在线播放网站| 最新中文字幕电影免费观看| 999zyz**站免费毛片| 亚洲国产精品无码观看久久| 亚洲AV永久无码精品水牛影视| 日韩中文字幕免费| 99精品免费观看| jyzzjyzz国产免费观看| 中文字幕在线观看亚洲日韩| 亚洲s色大片在线观看| 又粗又硬又黄又爽的免费视频| xxxx日本免费| 精品成人免费自拍视频| 免费激情网站国产高清第一页| 亚洲国产精品成人久久久| 亚洲色婷婷六月亚洲婷婷6月| 日日AV拍夜夜添久久免费| 120秒男女动态视频免费| 香蕉免费一级视频在线观看| 亚洲av中文无码乱人伦在线观看| 亚洲伊人tv综合网色| 亚洲伊人色欲综合网| 免费人妻无码不卡中文字幕18禁| 久久电影网午夜鲁丝片免费| 最好看最新的中文字幕免费 | 久久不见久久见中文字幕免费| 免费国产99久久久香蕉|