重写list

//.cpp

 

// TortoiseSVN - a Windows shell extension for easy version control

// Copyright (C) 2003-2008 - TortoiseSVN

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#include "stdafx.h"
#include "MyMemDC.h"
#include "HintListCtrl.h"

CHintListCtrl::CHintListCtrl() : CListCtrl()
 , pProvider(NULL)
{
}

CHintListCtrl::~CHintListCtrl()
{
}

void CHintListCtrl::ShowText(const CString& sText, bool forceupdate /* = false*/)
{
 m_sText = sText;
 Invalidate();
 if (forceupdate)
  UpdateWindow();
}

void CHintListCtrl::ClearText()
{
 m_sText.Empty();
 Invalidate();
}

BEGIN_MESSAGE_MAP(CHintListCtrl, CListCtrl)
 ON_WM_PAINT()
 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, &CHintListCtrl::OnToolTipText)
 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, &CHintListCtrl::OnToolTipText)
END_MESSAGE_MAP()

void CHintListCtrl::OnPaint()
{
 Default();
 if (!m_sText.IsEmpty())
 {
  COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);
  COLORREF clrTextBk;
  if (IsWindowEnabled())
   clrTextBk = ::GetSysColor(COLOR_WINDOW);
  else
   clrTextBk = ::GetSysColor(COLOR_3DFACE);

  CRect rc;
  GetClientRect(&rc);
  CHeaderCtrl* pHC;
  pHC = GetHeaderCtrl();
  if (pHC != NULL)
  {
   CRect rcH;
   rcH.SetRectEmpty();
   pHC->GetItemRect(0, &rcH);
   rc.top += rcH.bottom;
  }
  CDC* pDC = GetDC();
  {
   CMyMemDC memDC(pDC, &rc);

   memDC.SetTextColor(clrText);
   memDC.SetBkColor(clrTextBk);
   memDC.FillSolidRect(rc, clrTextBk);
   rc.top += 10;
   CGdiObject * oldfont = memDC.SelectStockObject(DEFAULT_GUI_FONT);
   memDC.DrawText(m_sText, rc, DT_CENTER | DT_VCENTER |
    DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
   memDC.SelectObject(oldfont);
  }
  ReleaseDC(pDC);
 }
}

INT_PTR CHintListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
{
 if (pProvider == NULL)
  return -1;

 LVHITTESTINFO lvhitTestInfo;

 lvhitTestInfo.pt = point;

 int nItem = ListView_SubItemHitTest(
  this->m_hWnd,
  &lvhitTestInfo);
 int nSubItem = lvhitTestInfo.iSubItem;

 UINT nFlags =   lvhitTestInfo.flags;

 //nFlags is 0 if the SubItemHitTest fails
 //Therefore, 0 & <anything> will equal false
 if (nFlags & LVHT_ONITEM)
 {
  //If it did fall on a list item,
  //and it was also hit one of the
  //item specific sub-areas we wish to show tool tips for

  //Get the client (area occupied by this control
  RECT rcClient;
  GetClientRect( &rcClient );

  //Fill in the TOOLINFO structure
  pTI->hwnd = m_hWnd;
  pTI->uId = (UINT)((nItem<<10)+(nSubItem&0x3ff)+1);
  pTI->lpszText = LPSTR_TEXTCALLBACK;
  pTI->rect = rcClient;

  return pTI->uId; //By returning a unique value per listItem,
  //we ensure that when the mouse moves over another list item,
  //the tooltip will change
 }
 else
 {
  //Otherwise, we aren't interested, so let the message propagate
  return -1;
 }
}

BOOL CHintListCtrl::OnToolTipText(UINT /*id*/, NMHDR * pNMHDR, LRESULT * pResult)
{
 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;

 if (pProvider == NULL)
  return FALSE;

 // Ignore messages from the built in tooltip, we are processing them internally
 if( (pNMHDR->idFrom == (UINT)m_hWnd) &&
  ( ((pNMHDR->code == TTN_NEEDTEXTA) && (pTTTA->uFlags & TTF_IDISHWND)) ||
  ((pNMHDR->code == TTN_NEEDTEXTW) && (pTTTW->uFlags & TTF_IDISHWND)) ) )
 {
   return FALSE;
 }

 *pResult = 0;

 //Get the mouse position
 const MSG* pMessage;
 pMessage = GetCurrentMessage();

 CPoint pt;
 pt = pMessage->pt;
 ScreenToClient(&pt);

 // Check if the point falls onto a list item
 LVHITTESTINFO lvhitTestInfo;
 lvhitTestInfo.pt = pt;

 int nItem = SubItemHitTest(&lvhitTestInfo);

 if (lvhitTestInfo.flags & LVHT_ONITEM)
 {
  // we want multiline tooltips
  ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, INT_MAX);
  CString strTipText = pProvider->GetToolTipText(nItem, lvhitTestInfo.iSubItem);

  //Deal with UNICODE
#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
  return TRUE;    //We found a tool tip,
  //tell the framework this message has been handled
 }

 return FALSE; //We didn't handle the message,
 //let the framework continue propagating the message
}

 

 

 

///.h

 

// TortoiseSVN - a Windows shell extension for easy version control

// Copyright (C) 2003-2008 - TortoiseSVN

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
#pragma once

class IListCtrlTooltipProvider
{
public:
 virtual CString GetToolTipText(int nItem, int nSubItem) = 0;
};

/**
 * /ingroup Utils
 * Allows to show a hint text on a list control, basically hiding the list control
 * content. Can be used for example during lengthy operations (showing "please wait")
 * or to indicate why the list control is empty (showing "no data available").
 */
class CHintListCtrl : public CListCtrl
{
public:
 CHintListCtrl();
 ~CHintListCtrl();

 void ShowText(const CString& sText, bool forceupdate = false);
 void ClearText();
 bool HasText() const {return !m_sText.IsEmpty();}
 void SetTooltipProvider(IListCtrlTooltipProvider * provider) {pProvider = provider;}


protected:
 DECLARE_MESSAGE_MAP()
 afx_msg void OnPaint();
 virtual afx_msg BOOL OnToolTipText(UINT id, NMHDR * pNMHDR, LRESULT * pResult);
 virtual INT_PTR OnToolHitTest(CPoint point, TOOLINFO * pTI) const;

private:
 CString   m_sText;
 IListCtrlTooltipProvider * pProvider;
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值