• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • VC中給樹形控件的圖標加上工具提示

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    我從沒有在任何一個應用程序中看到過圖標的工具提示。有時候查遍了整個幫助 文檔也沒有明白某個圖標是什么意思。如果能在自己的程序中為圖標加上工具提 示,一定會使界面的友好性大大增加。本文中以樹形控件為例,詳細介紹了在VC 中使用MFC提供的機制來實現
    我從沒有在任何一個應用程序中看到過圖標的工具提示。有時候查遍了整個幫助
    文檔也沒有明白某個圖標是什么意思。如果能在自己的程序中為圖標加上工具提
    示,一定會使界面的友好性大大增加。本文中以樹形控件為例,詳細介紹了在VC
    中使用MFC提供的機制來實現圖標工具提示的方法。

    ---- 第一步:使控件可以顯示工具提示

    ---- 調用EnableToolTips(TRUE)使一個窗口可以顯示工具提示。在什么地方插入
    這條代碼最好呢?在類的PreSubclassWindow()中。因為不管一個控件如何被創建
    ,MFC都會調用此函數。而其他的函數則不一定會被調用。以OnCreate()為例,如
    果調用Create()或CreateEx()創建一個控件,OnCreate()會被調用,而如果一個
    控件是從對話框資源創建,OnCreate()就不會被調用。

    實現代碼如下:
    void CTreeCtrlX::PreSubclassWindow()
    {
    CTreeCtrl::PreSubclassWindow();

    EnableToolTips(TRUE);
    }

    ---- 第二步:重載虛函數OnToolHitTest()
    ---- MFC調用函數來確定在某個點是否應該顯示工具提示。MSDN建議如果鼠標落
    在應該顯示工具提示的點上,返回值1。這并不完全正確。這個函數應該返回不同
    的值來區分窗口中不同的應該顯示提示的區域。

    ---- 在這個函數中,本文只處理鼠標落在節點圖標或節點狀態圖標上的情況。讀
    者可以按照自己的情況向樹的其他元素上添加工具提示。在兩種情況下,都要計
    算圖標的區域,并且把TOOLINFO的uID設為鼠標所在點的樹節點的句柄。注意,盡
    管對于節點圖標和節點狀態圖標,使用了相同的id,但返回值并不相同。不同的
    返回值迫使MFC更新工具提示。

    ---- 雖然我們可以在此函數中給出工具提示,但因為鼠標的每次移動都會調用此
    函數,太多的處理并不是一個好注意,所以我們在其他的函數中處理應該顯示什
    么提示的問題。

    類聲明中的代碼如下所示:
    // Overrides
    // ClassWizard generated
    virtual function overrides
    //{{AFX_VIRTUAL(CTreeCtrlX)
    protected:

    virtual int OnToolHitTest
    ( CPoint point, TOOLINFO* pTI ) const;
    //}}AFX_VIRTUAL

    實現代碼如下所示:
    int CTreeCtrlX::OnToolHitTest
    (CPoint point, TOOLINFO * pTI) const
    {
    RECT rect;

    UINT nFlags;
    HTREEITEM hitem = HitTest( point, &nFlags );
    if( nFlags & TVHT_ONITEMICON )
    {
    CImageList *pImg = GetImageList( TVSIL_NORMAL );
    IMAGEINFO imageinfo;
    pImg- >GetImageInfo( 0, &imageinfo );

    GetItemRect( hitem, &rect, TRUE );
    rect.right = rect.left - 2;
    rect.left -= (imageinfo.rcImage.right + 2);

    pTI- >hwnd = m_hWnd;
    pTI- >uId = (UINT)hitem;
    pTI- >lpszText = LPSTR_TEXTCALLBACK;
    pTI- >rect = rect;
    return pTI- >uId;
    }
    else if( nFlags & TVHT_ONITEMSTATEICON )
    {
    CImageList *pImg = GetImageList( TVSIL_NORMAL );
    IMAGEINFO imageinfo;
    pImg- >GetImageInfo( 0, &imageinfo );

    GetItemRect( hitem, &rect, TRUE );
    rect.right = rect.left -
    (imageinfo.rcImage.right + 2);

    pImg = GetImageList( TVSIL_STATE );
    rect.left = rect.right - imageinfo.rcImage.right ;

    pTI- >hwnd = m_hWnd;
    pTI- >uId = (UINT)hitem;
    pTI- >lpszText = LPSTR_TEXTCALLBACK;
    pTI- >rect = rect;

    // 返回與節點圖標不同的值
    return pTI- >uId*2;
    }
    return -1;
    }

    ---- 第三步:處理TTN_NEEDTEXT消息;
    ---- 加入一個函數處理TTN_NEEDTEXT消息通知。當工具處理控制需要知道應該顯
    示什么信息時,這條消息被發出。由于上一步中我們給TOOLINFO的lpszText賦值
    為LPSTR_TEXTCALLBACK,所以我們要處理這個消息VC的ClassWizard并不支持這條
    消息被映射,所以只有我們自己加入這條消息的映射機制加入到MESSAGE_MAP中去
    。我們不得不處理這個消息的兩個版本,TTN_NEEDTEXTA和TTN_NEEDTEXTA。消息
    映射的代碼如下所示:

    BEGIN_MESSAGE_MAP(CTreeCtrlX, CTreeCtrl)
    //{{AFX_MSG_MAP(CTreeCtrlX)

    //}}AFX_MSG_MAP
    ON_NOTIFY_EX_RANGE
    (TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
    ON_NOTIFY_EX_RANGE
    (TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
    END_MESSAGE_MAP()

    下面的代碼是加到類聲明中:
    protected:
    //{{AFX_MSG(CTreeCtrlX)

    //}}AFX_MSG
    afx_msg BOOL OnToolTipText
    ( UINT id, NMHDR * pNMHDR, LRESULT * pResult );
    DECLARE_MESSAGE_MAP()

    ---- 現在討論這個函數本身的實現。為了適應不同的語言字符集,ANSI字符集和
    UNICODE字符集都必須被處理,處理過程會有些不同。此處對樹形控件的本身產生
    的ToolTip消息不予處理,過濾掉上述消息的原則是樹形控件本身產生的消息的ID
    是樹形控件窗口的句柄,并且有TTF_IDISHWND標志。根據鼠標位置可以確定應該
    給出節點圖標還是狀態圖標的工具提示。本文根據筆者畫的圖顯示了一些無關緊
    要的提示,讀者做這一步時應該加入一些有意義的提示。當然,本文假定控件包
    含節點圖標和狀態圖標。如不包含,計算鼠標位置時要注意 不要計算錯誤。

    BOOL CTreeCtrlX::OnToolTipText
    ( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
    {
    // 需要處理ANSI和UNICODE兩種格式
    TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
    TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
    CString strTipText;
    UINT nID = pNMHDR- >idFrom;

    // 不必處理樹自己發出的ToolTip消息
    if( nID == (UINT)m_hWnd &&
    (( pNMHDR- >code == TTN_NEEDTEXTA &&
    pTTTA- >uFlags & TTF_IDISHWND ) ||
    ( pNMHDR- >code == TTN_NEEDTEXTW &&
    pTTTW- >uFlags & TTF_IDISHWND ) ) )
    return FALSE;

    // 得到鼠標位置
    const MSG* pMessage;
    CPoint pt;
    pMessage = GetCurrentMessage();
    ASSERT ( pMessage );
    pt = pMessage- >pt;
    ScreenToClient( &pt );

    UINT nFlags;
    HTREEITEM hitem = HitTest( pt, &nFlags );
    if( nFlags & TVHT_ONITEMICON )
    {
    int nImage, nSelImage;
    GetItemImage( (HTREEITEM ) nID, nImage, nSelImage );
    switch(nImage)
    {
    case 0:
    strTipText = "叉";
    break;
    case 1:
    strTipText = "加號";
    break;
    case 2:
    strTipText = "菱形";
    break;
    }
    }
    else
    {
    if( (GetItemState( (HTREEITEM ) nID,
    TVIS_STATEIMAGEMASK ) > >12 ) == 2 )
    strTipText.Format( "此節點被選中" );
    else
    strTipText.Format( "此節點未被選中" );
    }

    #ifndef _UNICODE
    if (pNMHDR- >code == TTN_NEEDTEXTA)
    lstrcpyn(pTTTA- >szText, strTipText, 80);
    else
    _mbstowcsz(pTTTW- >szText, strTipText, 80);
    #else
    if (pNMHDR- >code == TTN_NEEDTEXTA)
    _wcstombsz(pTTTA- >szText, strTipText, 80);
    else
    lstrcpyn(pTTTW- >szText, strTipText, 80);
    #endif
    *pResult = 0;

    return TRUE; // 消息處理完畢
    }

    ---- 本文程序在Win9x,VC6.0下調試通過。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>