WTL::CListViewCtrl动态显示Tooltip的实现

在WTL::CListViewCtrl控件实现Tooltip显示的实例:

1. 从CListViewCtrl类重载,创建CTooltipCtrl控件,处理鼠标事件。

重载类头文件:
class CListViewCtrlTip : public CWindowImpl<CListViewCtrlTip, CListViewCtrl>
{
public:
 CListViewCtrlTip()
 {
  m_nCurItem = -1;
  m_dwCurItemData = 0;
 }

 BEGIN_MSG_MAP(CListViewCtrlTip)
  MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
  MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
 END_MSG_MAP()

 LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
 LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

 void Attach(HWND hWnd);
 void Detach();
 void DeactivateTip();
 int GetCurItem()
 {
  return m_nCurItem;
 }

 DWORD GetCurItemData()
 {
  return m_dwCurItemData;
 }

private:
 CToolTipCtrl m_ctrlTip;
 int m_nCurItem;
 DWORD m_dwCurItemData;
};

重载类实现:
void CListViewCtrlTip::Attach(HWND hWnd)
{
 // Use subclass window to support message event instead of attach
 if (CWindowImpl<CListViewCtrlTip, CListViewCtrl>::SubclassWindow(hWnd))
 {
  m_ctrlTip.Create(m_hWnd);
  m_ctrlTip.Activate(FALSE);
  m_ctrlTip.AddTool(m_hWnd);
  m_ctrlTip.SetMaxTipWidth(260); // Set the max tip width to 260 characters
  m_ctrlTip.SetDelayTime(TTDT_AUTOPOP, 10000); // Set auto pop delay time to 10s
 }
}

void CListViewCtrlTip::Detach()
{
 if (::IsWindow(m_hWnd))
 {
  m_ctrlTip.Activate(FALSE);
  m_ctrlTip.DelTool(m_hWnd);
  CWindowImpl<CListViewCtrlTip, CListViewCtrl>::UnsubclassWindow(TRUE);
 }
}

void CListViewCtrlTip::DeactivateTip()
{
 m_nCurItem = -1;
 m_dwCurItemData = 0;
 m_ctrlTip.Activate(FALSE);
}

LRESULT CListViewCtrlTip::OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
 MSG msg = { m_hWnd, uMsg, wParam, lParam };

 if (m_ctrlTip.IsWindow())
 {
  m_ctrlTip.RelayEvent(&msg);
 }
 bHandled = FALSE; // Leave the message to next case

 return 0;
}

LRESULT CListViewCtrlTip::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
 int xPos = GET_X_LPARAM(lParam);
 int yPos = GET_Y_LPARAM(lParam);
 POINT pt = { xPos, yPos };
 int nCurItem = HitTest(pt, NULL);
 
 // Check and active the tool tip control
 if (nCurItem >= 0)
 {
  if (m_nCurItem != nCurItem)
  {
   m_ctrlTip.Activate(FALSE); // Deactivate first
   m_nCurItem = nCurItem;
   m_dwCurItemData = (ULONG)GetItemData(m_nCurItem);
   m_ctrlTip.Activate(TRUE);
  }
 }
 else
 {
  DeactivateTip();
 }
 bHandled = FALSE; // Leave the message to next case

 return 0;
}

2. 修改调用类中CListViewCtrl类型为重载的类型,在初始化函数中调用Attach方法,在OnDestroy调用Detach方法。

CListViewCtrlTip m_lvw;

m_lvw.Attach(GetDlgItem(IDC_IST));

m_lvw.Detach();

3. 调用类处理TTN_GETDISPINFO通知,更新Tooltip的数据。

char m_szCurToolTip[MAX_TOOLTIP_LEN];

LRESULT CTestDlg::OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam,
          BOOL& /*bHandled*/)
{
 switch (((LPNMHDR)lParam)->code)
 {
 case TTN_GETDISPINFO: // Notify event from list view control to get the tool tip string
  LPNMTTDISPINFO pInfo = (LPNMTTDISPINFO)lParam;
  // Make dynamic tool tip string here
  pInfo->lpszText = m_szCurToolTip;

  break;
 }

 return 0;
}

Tags:

Leave a Reply