带 Web 链接的 CListCtrl
扩展的ListCtrl类,支持网页链接。
引言
随着桌面端Web应用程序的兴起,人们自然会期望CListCtrl
能够更加友好地支持Web,并像支持图片一样支持URL链接。通过使用一些额外的参数(例如LVS_EX_ONECLICKACTIVATE
、LVS_EX_UNDERLINECOLD
和LVS_EX_UNDERLINEHOT
)调用SetExtendedStyle
,确实可以使CListCtrl
的条目看起来像URL链接。不幸的是,这种控件样式的改变会强制所有条目都看起来像网页链接,而实际上控件中可能只有一部分条目需要(甚至有意义)成为网页链接。为了克服这个问题,我创建了CListCtrlLink
,这是一个CListCtrl
的派生类,允许你在列表视图控件中为某些条目包含URL链接,如页面顶部的图片所示。
CListCtrlLink
中的URL链接使用ShellExecute
API调用来实现。这使得链接能够处理系统上所有已知的协议(HTTP、FTP、MAILTO、CALLTO…),通过调用系统默认应用程序来处理操作。换句话说,如果你点击一个HTTP链接,默认的Web浏览器将被调用来打开相应的页面。如果你点击一个电子邮件地址,默认的邮件阅读器应用程序将被调用。
如何使用CListCtrlLink
假设你已经有了一个带有列表控件的应用程序(其view
属性设置为report
,并且类中有一个CListCtrl
成员变量),那么你只需4个步骤即可在你的应用程序中使用CListCtrl
。
- 将以下文件添加到你的项目中:LinkItem.cpp、LinkProperties.cpp和ListCtrlLink.cpp以及它们各自的头文件。
- 将你当前的
CListCtrl
成员变量替换为CListCtrlLink
成员变量。不要忘记在包含列表控件的类中插入#include "ListCtrlLink.h"
。 - 在你的
OnInitDialog()
中添加对Init()
的调用以正确初始化控件,如下面的代码片段所示。BOOL CListCtrlLinkTestDlg::OnInitDialog() { CDialog::OnInitDialog(); . . . //Initializes CListCtrlLink. If you don’t call //this method you won’t get links in your list control. m_listCtrl.Init(); . . . }
CListCtrl
方法InsertItem
和SetItemText
已被重写,以支持URL链接而增加了一个额外的参数。如果你没有向这些调用传递任何参数,则不会显示任何链接。下面的代码是从示例项目中提取的,通过查看页面顶部图片中的前两行,你可以看到结果的样子。m_listCtrl.InsertItem( 0, _T("Ana")); m_listCtrl.SetItemText(0, 1, _T("26")); m_listCtrl.SetItemText(0, 2, _T("Stanford"), _T("http://www.stanford.edu/")); m_listCtrl.SetItemText(0, 3, _T("Unpublished")); m_listCtrl.InsertItem( 1, _T("John")); m_listCtrl.SetItemText(1, 1, _T("21")); m_listCtrl.SetItemText(1, 2, _T("Yahoo"), _T("http://www.yahoo.com/")); m_listCtrl.SetItemText(1, 3, _T("john@ficticious.edu"), _T("mailto:john@ficticious.edu"));
组件结构
即使“东西能工作”,了解组件的工作原理也很不错。让我们从查看图1中的CListCtrlLink
URL类图开始我们的简短旅程。
图1:CListCtrlLink
的UML图
CListCtrlLink
派生自MFC的CListCtrl
,并且只增加了3个新的成员函数:Init
以及扩展的InsertItem
和SetItem
。该类有两个类型为CLinkProperties
的成员变量,稍后将解释。CListCtrlLink
使用自定义绘制技术使某些条目看起来像链接,而其他条目看起来像普通的列表控件项。Michael Dunn的Neat Stuff to do in List Controls Using Custom Draw详细解释了自定义绘制。一旦用户点击链接,OnItemchanging
就会被调用并处理URL处理。
CLinkProperties
负责链接的外观。如果你想将已访问的链接更改为黄色,未访问的链接更改为绿色,这就是你需要修改的地方。请注意,没有链接的条目实际上是黑色的链接,没有下划线,也没有关联的URL。
最后,CLinkItem
存储URL、链接是否已被访问以及指向CLinkProperties
的指针。通过指向m_link
或m_noLink
,可以最大限度地减少每个链接的内存需求,并且链接设置会同时影响所有链接。CListCtrlLink
负责维护所有正在使用的CLinkItems
的列表,包括创建和删除。