1. 程式人生 > >ToolTip用法及例項

ToolTip用法及例項

正文:

我們經常在一些軟體中看到類似的功能:滑鼠移動到一個按鈕(或其他控制元件)上的時候,自動彈出一些提示(不是彈出對話方塊),以提醒使用者該控制元件的作用或注意事項。這種提示就是所說的Tooltip(如圖1所示)。關於Tooltip,網上已經有很多資料了,我在這裡只是給大家提供一些連結,讓沒有做過的朋友能在最短的時間內實現這個功能。

圖1

Codeproject已經有許多現成的Tooltip類,並且有的功能非常之強,可以直接拿來用,這會為你節省許多時間!具體連結及說明如下:

說明:這是一個功能相當強大的Tooltip類,它實現了Office 2007風格的Tooltip

,當然,初次接觸它的話,你肯定要花更多的時間去學習怎麼用,我沒有用過這個類,因為它所實現的效果遠遠超過了我軟體中的需求,所以,這個類適合那些想讓自己的軟體Tooltip非常炫的朋友。

說明:這個類同樣強大,你可以看一下上面連結中它的圖例,我也沒有去仔細看,因為它花哨的功能我也用不了這麼多。

說明:這個類是本文介紹的重點,它實現了我的要求,上面的圖1就是我用它做出來的效果。

 說一下這個類的使用(非常簡單):

VC.NET 2003為例,新建一個基於對話方塊的MFC應用程式,在該工程中新增XInfoTip.cppXInfoTip.h檔案(這兩個檔案在上面的Codeproject

連結中你可以找到)。然後在你需要實現Tooltip的對話方塊類中新增CXInfoTip成員變數(如果有多個Tooltip,請依次新增)m_tip1,然後在OnInitDialog()函式中(如果是子視窗,則需過載子對話方塊類的該函式,否則看不到這個函式——這是基礎知識)新增以下兩句程式碼:

     m_tip1.Create(this);

     m_tip1.AddTool(GetDlgItem(IDC_COMBO_COMPORT),
                 _T("
串列埠未正確連線的話/n/n將導致系統不能運作!"),   //Tooltip的內容
                ::LoadIcon(NULL, IDI_WARNING));

 //載入一個警告圖示

AddTool()的第一個引數意思是:當滑鼠移動到哪一個控制元件上的時候彈出Tooltip,這裡用GetDlgItem來獲取控制代碼就可以了,上面的程式碼寫得非常明白,一看就懂吧?第二個引數是設定彈出的Tooltip中的內容,其中/n是換行符(地球人都知道)。關於第三個引數,可用LoadIcon()函式來載入一個圖示顯示在Tooltip中(如圖1所示),可查MSDN,用法非常簡單。

這樣做之後,你就差最後一步就可以完成了,即:過載你用到Tooltip的對話方塊類的PreTranslateMessage()函式(別告訴我你不知道怎麼過載喲~),然後將裡面的程式碼改成如下所示:

{

      // TODO: 在此新增專用程式碼和/或呼叫基類

m_tip1.RelayEvent(pMsg);    //新增這一句

      return CDialog::PreTranslateMessage(pMsg);

}

好了,大功告成!編譯一下試試看,再把滑鼠移動到控制元件上,是不是彈出了很酷的Tooltip

本文只涉及到了該類的很簡單的功能使用,關於改變Tooltip中文字的字型、控制Tooltip顯示時間等操作,請參閱Codeproject連結中作者的文章以及Demo

還有幾個類似的,在此一併給出連結:

=============================

方法2:

我用VC做TOOL TIP很多次了,但每次都要再研究一遍.雖然說學而時習,應該的,但主要還是由於自己懶.今天一定要記下來.以後再用的時候,就是參考.也請閱讀此文的朋友記下來,將來查閱用.

用VC實現TOOL TIP.比較複雜,其實也簡單,但MFC幫助一些視窗實現,而另一些視窗又不實現,倒搞得複雜了.最開始我用WM_MOUSEMOVE訊息,然後用CToolTipCtrl::Pop,這個方法太笨.不建議用.除非需要自定義.

MFC對TOOL TIP的支援不錯的.預設情況CFrameWnd支援很好.然後是CWnd.主要體現在TTN_NEEDTEXT訊息的支援和OnToolHitTest的支援.TTN_NEEDTEXT是在CFrameWnd中支援的.OnToolHitTest是在CWnd中支援的.有了這些支援,可以在框架視窗中很好實現ToolBar的TIP.和在一個對話方塊中很好實現一個控制元件的TOOL TIP.

舉例.在對話方塊中實現TOOL TIP.

1.EnableToolTips( TRUE )是不可少的.建議在:CDialog::OnInitDialog 呼叫吧.

2.ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnNeedText ).OnNeedText實現了TOOL TIP的文字.傳入的引數idFrom是控制元件的ID,根據控制元件ID得到相應的TIP文字

就這麼簡單的兩步,就實現了對話方塊中的TOOL TIP.其實不只對話方塊,任何視窗都可以用上面的方法實現自己的子視窗控制元件的TIP.但前提是必須是CWnd的派生類.

這就看出了MFC對TOOL TIP的支援很厲害

但這一切都是MFC實現的我們簡單描述一下它的實現原理,這樣看得更清楚

CWnd本身就帶有一個CToolTipCtrl物件,是放在pThreadState中的這個不說了,知道CWnd有就行了

CWnd負責建立它,然後在PreTranslateMessage中呼叫了FilterToolTipMessage,這個函式的作用是處理WM_MOUSEMOVE,WM_NCMOUSEMOVE等訊息,給CToolTipCtrl一個機會,判斷滑鼠是否在需要顯示TIP的視窗上,如果是,就顯示.FilterToolTipMessage先從CWnd::OnToolHitTest得到TOOLINFO:中的資料,比如哪個控制元件需要TIP等資訊,然後利用ADDTOOL訊息把這個需要TIP的控制加入到CToolTipCtrl的TOOL列表中,然後將滑鼠移動的訊息轉給CToolTipCtrl處理.如果這個TIP的文字需要用回撥函式來獲得,就用WM_NOTIFY的TTN_NEEDTEXT從CToolTipCtrl的父視窗獲取.這個過程就是CToolTipCtrl判斷是否要顯示TIP,到獲得文字並顯示TIP的全過程

這樣一分析,就知道原來CWnd幫助實現了控制元件子視窗的TIP其實就是實現了OnToolHitTest這個函式,然後在PreTranslateMessage中轉發訊息,幫助CToolTipCtrl正確顯示TIP.

而CFrameWnd是實現了TTN_NEEDTEXT的響應,幫助子視窗實現TIP.

其實我們也可以不要這些預設實現,自己用CToolTipCtrl搞定,做法一樣:

1.CToolTipCtrl::Create建立Tool Tip

2.AddTool增加一個TOOL,這裡的TOOL就是需要顯示TIP的一個區域或一個子視窗.如果對AddTool使用有不清楚的地方,建議檢視源程式.可能會覺得直接使用TTM_ADDTOOL更方便.

3.在PreTranslateMessage中呼叫CToolTipCtrl::RelayMessage

4.如果在AddTool中,文字是用回撥函式實現,那就要處理TTN_NEEDTEXT訊息.

其實自己建立CToolTipCtrl和MFC做的一樣.只是不需要在OnToolHitTest中給出需要顯示TIP的視窗或者區域.

如果給子視窗用TIP.就用MFC最簡單.如果給自己呢?

設定TOOLINFO中的uFlags = TTF_IDISHWND,然後設定uId為視窗控制代碼,hWnd為視窗控制代碼就可以了.

寫了這麼多,有不對的地方還請和我聯絡一下,幫助我改正錯誤.

只是有個問題還沒搞明白.就是為什麼MFC把CToolTipCtrl放在了pThreadState中.難道是為了用一個TOOL TIP為該執行緒的所有視窗服務嗎?難道是一種節約資源的表現.這點還需要研究.如果哪位朋友知道答案,還希望能不吝賜教.謝謝.