在MFC应用程序中,经常需要在表格控件中显示超链接。为了实现这个功能,可以创建一个自定义的单元格类,该类继承自标准的网格单元格类,并添加了URL识别和处理的功能。以下是实现这个自定义URL单元格类的步骤和关键代码。
首先,需要从CGridCell
类派生出一个新的类,命名为CGridURLCell
。这个新类将继承标准单元格的所有功能,并添加对URL的支持。
为了存储URL的颜色,在CGridURLCell
类中添加了一个COLORREF
类型的变量m_clrUrl
。这个变量可以存储由SetUrlColor(COLORREF clr)
方法设置的颜色,或者使用系统高亮颜色GetSysColor(COLOR_HIGHLIGHT)
作为默认颜色。
接下来,需要重写Draw
函数,以便在绘制单元格时检查文本中是否包含URL。如果包含URL,则使用高亮颜色绘制单元格;否则,按照正常方式绘制单元格。
BOOL CGridURLCell::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd)
{
if (HasUrl(GetText()))
SetTextClr(m_clrUrl);
m_Rect = rect;
return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
}
为了检查单元格文本中是否包含URL,定义了一个HasUrl
函数。这个函数会在单元格文本中搜索已知的URL前缀。如果找到URL前缀,则返回TRUE
;否则,继续搜索,直到所有前缀都被检查完毕,如果没有找到URL前缀,则返回FALSE
。
BOOL CGridURLCell::HasUrl(CString str)
{
static URLStruct g_szURIprefixes[] = {
{ _T("www."), _tcslen(_T("www.")) },
{ _T("http:"), _tcslen(_T("http:")) },
// ... 更多前缀
};
int nNumPrefixes = sizeof(g_szURIprefixes) / sizeof(g_szURIprefixes[0]);
for (int i = 0; i < nNumPrefixes; i++)
if (str.Find(g_szURIprefixes[i].szURLPrefix) >= 0)
return TRUE;
return FALSE;
}
为了在鼠标悬停在URL上时显示手形光标,需要重写OnSetCursor
函数。在这个函数中,首先获取鼠标的位置,然后调用OverURL
函数来判断鼠标是否在URL上。如果是,则显示手形光标;否则,显示普通光标。
BOOL CGridURLCell::OnSetCursor()
{
CString strURL;
CPoint pt(GetMessagePos());
GetGrid()->ScreenToClient(&pt);
pt = pt - m_Rect.TopLeft();
if (OverURL(pt, strURL))
{
SetCursor(g_hLinkCursor);
return TRUE;
}
return CGridCell::OnSetCursor();
}
在OnClick
函数中,需要检查是否应该自动打开URL。如果是,则调用OverURL
函数获取URL,然后使用ShellExecute
函数打开默认浏览器。
void CGridURLCell::OnClick(CPoint PointCellRelative)
{
CString strURL;
if (GetAutoLaunchUrl() && OverURL(PointCellRelative, strURL))
ShellExecute(NULL, _T("open"), strURL, NULL, NULL, SW_SHOW);
}
// 设置单元格类型
m_Grid.SetCellType(1, 1, RUNTIME_CLASS(CGridURLCell));
// 获取单元格并设置属性
CGridURLCell* cell = (CGridURLCell *)m_Grid.GetCell(1, 1);
cell->...