LinkList CListCtrl里显示多个链接

头文件:

#pragma once

// CLinkList
#define  WM_LIST_BTN_CLICK WM_USER + 500

class CLinkList : public CListCtrl
{
DECLARE_DYNAMIC(CLinkList)

public:
CLinkList();
virtual ~CLinkList();

int InsertItem(int nItem, LPCTSTR lpszItem, LPCTSTR lpctszUrl = NULL);

BOOL SetItemText(int nItem, int nSubItem, LPCTSTR lpszText, LPCTSTR lpctszUrl = NULL);

void DeleteAllGridData();

CString GetLinkText(){ return m_curUrl;}

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

protected:
DECLARE_MESSAGE_MAP()

void GetCurLinkIndex();
BOOL HasLink(int row, int col);

private:
CMapStringToOb m_gridMap;
CMapStringToString m_linkMap;
int m_row;  // 鼠标当前所在行
int m_col; // 鼠标当前所在列
CString m_curUrl;
int m_nItemHeight;
public:
afx_msg void OnNMClick(NMHDR *pNMHDR, LRESULT *pResult);
//设置行高
void SetItemHeight(UINT nHeight);

afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
};

///

源文件:

// LinkList.cpp : 实现文件
//

#include "stdafx.h"
#include "LinkList.h"

// CLinkList

IMPLEMENT_DYNAMIC(CLinkList, CListCtrl)

CLinkList::CLinkList()
{

}

CLinkList::~CLinkList()
{
DeleteAllGridData();
}

BEGIN_MESSAGE_MAP(CLinkList, CListCtrl)
ON_NOTIFY_REFLECT(NM_CLICK, &CLinkList::OnNMClick)
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()

// CLinkList 消息处理程序

int CLinkList::InsertItem(int nItem, LPCTSTR lpctszItem,
       LPCTSTR lpctszUrl /*= NULL*/)
{
CString strIndex;
strIndex.Format(_T("%d-%d"), nItem, 0);
CStringArray* pArrText = (CStringArray*)m_gridMap[strIndex];
if (pArrText == NULL)
{
  pArrText = new CStringArray;
  m_gridMap[strIndex] = (CObject*)pArrText;
}
pArrText->Add(lpctszItem);

if (lpctszUrl)
{
  strIndex.Format(_T("%d-%d-%s"), nItem, 0, lpctszItem);
  m_linkMap[strIndex] = lpctszUrl;

strIndex.Empty();
int count = pArrText->GetCount();
for (int i(0); i < count; ++i)
{
  strIndex += CString(_T(" ")) + CString(pArrText->GetAt(i));
}
strIndex.TrimLeft();

return CListCtrl::InsertItem(nItem, strIndex);
}

BOOL CLinkList::SetItemText(int nItem, int nSubItem, LPCTSTR lpctszText,
        LPCTSTR lpctszUrl /*= NULL*/)
{

CString strIndex;
strIndex.Format(_T("%d-%d"), nItem, nSubItem);
CStringArray* pArrText = (CStringArray*)m_gridMap[strIndex];
if (pArrText == NULL)
{
  pArrText = new CStringArray;  
  m_gridMap[strIndex] = (CObject*)pArrText;
}
pArrText->Add(lpctszText);

int count = pArrText->GetCount();
if (lpctszUrl)
{
  strIndex.Format(_T("%d-%d-%d"), nItem, nSubItem, count - 1);
  m_linkMap[strIndex] = lpctszUrl;

strIndex.Empty(); 
for (int i(0); i < count; ++i)
{
  strIndex += CString(_T(" ")) + CString(pArrText->GetAt(i));
}
strIndex.TrimLeft();

return CListCtrl::SetItemText(nItem, nSubItem, strIndex);
}

void CLinkList::DeleteAllGridData()
{
POSITION pos;
CString strKey;
CStringArray *pGridItem;

//Delete the entire list
for (pos = m_gridMap.GetStartPosition(); pos != NULL; )
{
  m_gridMap.GetNextAssoc( pos, strKey, (CObject*&)pGridItem);
  if (pGridItem)
  {
   CStringArray* pArr = pGridItem;
   pArr->RemoveAll();

   delete pGridItem;
   pGridItem = NULL;
  }
}
m_gridMap.RemoveAll();

m_linkMap.RemoveAll();
}

void CLinkList::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
CWnd* pWnd = GetParent();
if (pWnd && !m_curUrl.IsEmpty())
{
  NMHDR nmhdr;
  nmhdr.hwndFrom = m_hWnd;
  nmhdr.idFrom = GetDlgCtrlID();
  nmhdr.code = WM_LIST_BTN_CLICK;  // 用户自定义消息
  pWnd->SendMessage(WM_NOTIFY, (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
*pResult = 0;
}

void CLinkList::GetCurLinkIndex()
{
DWORD   dwPos   =   GetMessagePos();
CPoint   point(   LOWORD(dwPos),   HIWORD(dwPos)   );
ScreenToClient(&point);  

LVHITTESTINFO   lvinfo;
lvinfo.pt   =   point;
lvinfo.flags   =   LVHT_ABOVE;

int   nItem   =   SubItemHitTest(&lvinfo);
if (nItem == -1)
{
  return ;
}

m_row = lvinfo.iItem;
m_col = lvinfo.iSubItem;

int start(5);
for (int i(0); i < lvinfo.iSubItem; ++i)
{
  start += GetColumnWidth(i);
}

CString strIndex;
strIndex.Format(_T("%d-%d"), lvinfo.iItem,   lvinfo.iSubItem);
CStringArray* pArrText = (CStringArray*)m_gridMap[strIndex];
if (pArrText)
{
  int cnt = pArrText->GetCount();
  for (int i(0); i < cnt; ++i)
  {
   int txtLen = GetStringWidth(pArrText->GetAt(i));

   if (point.x > start && point.x < start + txtLen)
   {
    CString strIndex;
    strIndex.Format(_T("%d-%d-%d"), m_row, m_col, i);
    m_curUrl = m_linkMap[strIndex];

    break;
   }
   else
   {
    start += txtLen + 5;
   }
  }
}
}

void CLinkList::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
GetCurLinkIndex();

if (!m_curUrl.IsEmpty())
{
  ::SetCursor(::LoadCursor(NULL, IDC_HAND));
}

CListCtrl::OnMouseMove(nFlags, point);
}

BOOL CLinkList::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{

return CListCtrl::OnSetCursor(pWnd, nHitTest, message);
}

BOOL CLinkList::HasLink(int row, int col)
{
BOOL has(FALSE);

CString strIndex;
strIndex.Format(_T("%d-%d"), row, col);
CStringArray* pArrText = (CStringArray*)m_gridMap[strIndex];
if (pArrText)
{
  int cnt = pArrText->GetCount();
  for (int i(0); i < cnt; ++i)
  {
   strIndex.Format(_T("%d-%d-%d"), m_row, m_col, i);
   CString str(m_linkMap[strIndex]);
   if (!str.IsEmpty())
   {
    has = TRUE;
    break;
   }
  }
}

return has;
}

void CLinkList::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item 
ASSERT(lpDrawItemStruct->CtlType == ODT_LISTVIEW); 
CDC dc;  
dc.Attach(lpDrawItemStruct->hDC); 
ASSERT(NULL != dc.GetSafeHdc()); 

//dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT));

// Save these value to restore them when done drawing. 
COLORREF crOldTextColor = dc.GetTextColor(); 
COLORREF crOldBkColor = dc.GetBkColor(); 

CFont * pOldFont = NULL;

// If this item is selected, set the background color  
// and the text color to appropriate values. Also, erase 
// rect by filling it with the background color. 
//if ((lpDrawItemStruct->itemAction | ODA_SELECT) && 
// (lpDrawItemStruct->itemState & ODS_SELECTED)) 
//{ 
// dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); 
// dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); 
// dc.FillSolidRect(&lpDrawItemStruct->rcItem,  
//  ::GetSysColor(COLOR_HIGHLIGHT)); 
//} 
//else 
//{ 
// if(lpDrawItemStruct->itemID%2) 
//  dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(128,128,128)); 
// else 
//  dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,128,255)); 
//} 

// If this item has the focus, draw a red frame around the 
// item's rect. 
/*if ((lpDrawItemStruct->itemAction | ODA_FOCUS) && 
  (lpDrawItemStruct->itemState & ODS_FOCUS)) 

  CBrush br(RGB(128, 128, 128)); 
  dc.FrameRect(&lpDrawItemStruct->rcItem, &br); 
}  */

// Draw the text. 
CString strText(_T("")); 
CRect rcItem; 

for(int i=0; i GetItemCount(); i++) 

  strText = GetItemText(lpDrawItemStruct->itemID, i); 
  GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem);    
  rcItem.left += 5; 

  bool has(false);
  CString strIndex;
  strIndex.Format(_T("%d-%d"), lpDrawItemStruct->itemID, i);
  CStringArray* pArrText = (CStringArray*)m_gridMap[strIndex];
  if (pArrText)
  {
   int cnt = pArrText->GetCount();
   for (int j(0); j < cnt; ++j)
   {
    strIndex.Format(_T("%d-%d-%d"),lpDrawItemStruct->itemID, i, j);
    CString str(m_linkMap[strIndex]);
    if (!str.IsEmpty())
    {
     has = true;
     break;
    }
   }
  }

  if (has)
  {
   int cnt = pArrText->GetCount();
   int start = rcItem.left;
   for (int j(0); j < cnt; ++j)
   {
    int txtLen = GetStringWidth(pArrText->GetAt(j));
    CRect rcTxt(rcItem);
    rcTxt.left = start;
    rcTxt.right = start + txtLen;
    strIndex.Format(_T("%d-%d-%d"), lpDrawItemStruct->itemID, i, j);
    CString str(m_linkMap[strIndex]);
    if (!str.IsEmpty())
    {     
     dc.SetTextColor(RGB(0,0,255));

     CFont * pFont = GetFont();
     ASSERT(pFont);
     LOGFONT lf;
     pFont->GetLogFont(&lf);
     lf.lfUnderline = TRUE;
     CFont fUnderline;
     fUnderline.CreateFontIndirect(&lf);  
     pOldFont = dc.SelectObject(&fUnderline);

     dc.DrawText( 
      pArrText->GetAt(j), 
      pArrText->GetAt(j).GetLength(), 
      &rcTxt, 
      DT_LEFT|DT_SINGLELINE|DT_VCENTER);
     if (pOldFont) dc.SelectObject(pOldFont);
    }
    else
    {
     dc.SetTextColor(RGB(0,0,0));
     dc.DrawText( 
      pArrText->GetAt(j), 
      pArrText->GetAt(j).GetLength(), 
      &rcTxt, 
      DT_LEFT|DT_SINGLELINE|DT_VCENTER); 
    }

    start += txtLen +5;
   }

  }
  else
  {
   dc.SetTextColor(RGB(0,0,0));
   dc.DrawText( 
    strText, 
    strText.GetLength(), 
    &rcItem, 
    DT_LEFT|DT_SINGLELINE|DT_VCENTER); 
  }

// Reset the background color and the text color back to their 
// original values. 
dc.SetTextColor(crOldTextColor); 
dc.SetBkColor(crOldBkColor); 

dc.Detach(); 
}

void CLinkList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if( m_nItemHeight > 0 )
  lpMeasureItemStruct->itemHeight = m_nItemHeight;
}

//设置行高
void CLinkList::SetItemHeight(UINT nHeight)
{
m_nItemHeight = nHeight;

CRect rcWin;
GetWindowRect(&rcWin);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rcWin.Width();
wp.cy = rcWin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;

SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值