LinkBox : 一个控件多个超链接

 

程序设计中HyperLink控件经常用到,vs2010 自带了HeperLink控件,可以直接在设计器中使用,相当方便.即便用的vc6.0这样的老古董也可以从网上找到一大把HyperLink控件的实现代码.codeproject上的实现的都挺漂亮的.

 

此次项目开发中需要在一个地方放好几个链接,它们排列密集-------这没有关系,多拖几次鼠标就行了-------但是他们的父窗口在运行的过程中需要改变大小,这些链接控件也要相应的改变其在窗口中的位置. 使用EasySize的话就要多写十多行代码,这挺麻烦的,于是我多写了好几百行代码来消除这个烦恼,这就是LinkBox,继承自CListCtrl。没有继承自CListBox的主要原因是我觉得CListCtrlHitTest用起来很爽,而ListBox中压根找不到HitTest

 

它的功能需求应该是:

1.  一个控件内可以写多个连接

2.  背景全透明

3.  MouseHover的时候光标变化

4.  自定义颜色

 

它的效果是这样的:

 LinkBox : 一个控件多个超链接_第1张图片

这份代码中并没有实现背景全透明,(添加背景全透明的话可以参考这个文章http://www.codeproject.com/KB/dialog/transparent-control.aspx),也没有写自定义颜色,但写到这儿就已经完全满足我的要求了,所以它的代码就是这样的,没啥技术含量,主要就是自绘,响应MouseLeave消息可以消除本代码中的一个不足,这不足你一用就知道,但对于我来说,恰好是个额外的功能,所以不做修改了:

#pragma once // LinkBox typedef struct LinkData { CString sUrlOrCmd; BOOL bIsCommand; BOOL bMouseHove; }*LPLINKDATA; DECLARE_USER_MESSAGE(QLINKBOX_ITEMCLICK); class LinkBox : public CListCtrl { DECLARE_DYNAMIC(LinkBox) public: LinkBox(); virtual ~LinkBox(); void AddLink(LPCTSTR lpText,LPCTSTR lpLink,BOOL bIsCommd=FALSE); void AddLink(LPCTSTR lpText,LPLINKDATA pData); void InsertLink(int idx,LPCTSTR lpText,LPLINKDATA pData); void InsertLink(int idx,LPCTSTR lpText,LPCTSTR lpLink,BOOL bIsCommd=FALSE); void Init(); inline void SetCallbackWnd(HWND hWndCallback) {m_hWndCallback = hWndCallback;}; protected: void FreeRes(); DECLARE_MESSAGE_MAP() virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnDestroy(); void RedrawItem(int nItem); private: CImageList m_ImageList; HWND m_hWndCallback; HCURSOR m_hCurHand; CFont m_Font; int m_iLastHoverItem; }; 

 

cpp文件:

// H:/Project/QMarket/cmnctl/LinkBox.cpp : 实现文件 // #include "stdafx.h" #include "LinkBox.h" // LinkBox IMPLEMENT_DYNAMIC(LinkBox, CListCtrl) LinkBox::LinkBox() { m_Font.CreateFont(12,6,0,0,FW_REGULAR,0,1,0,CHINESEBIG5_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,0,DEFAULT_PITCH,_T("宋体")); m_hCurHand = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(IDC_HAND)); m_iLastHoverItem = -1; } LinkBox::~LinkBox() { } void LinkBox::FreeRes() { m_Font.DeleteObject(); DeleteObject(m_hCurHand); for (int i = 0; i < GetItemCount(); i++) { delete ((LPLINKDATA)(GetItemData(i))); } } void LinkBox::OnDestroy() { FreeRes(); } BEGIN_MESSAGE_MAP(LinkBox, CListCtrl) ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_DESTROY() END_MESSAGE_MAP() void LinkBox::AddLink(LPCTSTR lpText,LPCTSTR lpLink,BOOL bIsCommd/*=FALSE*/) { InsertLink(-1,lpText,lpLink,bIsCommd); } void LinkBox::AddLink(LPCTSTR lpText,LPLINKDATA pData) { InsertLink(-1,lpText,pData); } void LinkBox::InsertLink(int idx,LPCTSTR lpText,LPLINKDATA pData) { if (idx == -1) { idx = GetItemCount(); } int item = InsertItem(idx,lpText); SetItemData(item,(DWORD_PTR)pData); } void LinkBox::InsertLink(int idx,LPCTSTR lpText,LPCTSTR lpLink,BOOL bIsCommd) { LPLINKDATA pData = new LinkData; pData->bIsCommand = bIsCommd; pData->sUrlOrCmd = lpLink; pData->bMouseHove = FALSE; InsertLink(idx,lpText,pData); } void LinkBox::Init() { ModifyStyle(WS_BORDER,LVS_NOCOLUMNHEADER|LVS_NOSCROLL|LVS_REPORT); if (m_ImageList.m_hImageList == NULL) { m_ImageList.Create(32,32,ILC_COLOR32|ILC_MASK,0,0); } SetImageList(&m_ImageList,LVSIL_NORMAL); CRect rect; GetClientRect(&rect); InsertColumn(0,_T("NON-VISIABLE"),LVCFMT_LEFT,rect.Width() - 1); } // LinkBox 消息处理程序 void LinkBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { int item = lpDrawItemStruct->itemID; if (item < 0) return; CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CFont *pOldFont = pDC->SelectObject(&m_Font); pDC->SetBkMode(TRANSPARENT); LPLINKDATA pData = (LPLINKDATA)(GetItemData(item)); ASSERT(pData != NULL); if (pData->bMouseHove) pDC->SetTextColor(RGB(255,0,0)); else pDC->SetTextColor(RGB(0,0,255)); CString str = GetItemText(lpDrawItemStruct->itemID,0); pDC->DrawText(str,&(lpDrawItemStruct->rcItem),DT_LEFT); pDC->SelectObject(pOldFont); } void LinkBox::OnMouseMove(UINT nFlags, CPoint point) { LVHITTESTINFO NowHti; NowHti.pt = point; int nItem = HitTest(&NowHti); if (nItem != -1) { SetCursor(m_hCurHand); } if ((nItem == -1) || (nItem != -1 && m_iLastHoverItem == nItem)) return; if (m_iLastHoverItem != -1) { LPLINKDATA pData = (LPLINKDATA)GetItemData(m_iLastHoverItem); ASSERT(pData != NULL); pData->bMouseHove = FALSE; RedrawItem(m_iLastHoverItem); } if (nItem != -1) { SetCursor(m_hCurHand); LPLINKDATA pData = (LPLINKDATA)GetItemData(nItem); ASSERT(pData != NULL); pData->bMouseHove = TRUE; m_iLastHoverItem = nItem; } RedrawItem(nItem); } void LinkBox::OnLButtonDown(UINT nFlags, CPoint point) { LVHITTESTINFO NowHti; NowHti.pt = point; int nItem = HitTest(&NowHti); if (-1 != nItem) { LPLINKDATA pData = (LPLINKDATA)GetItemData(nItem); ASSERT(pData != NULL); pData->bMouseHove = TRUE; if (!(pData->bIsCommand)) ::ShellExecute(m_hWnd,NULL,pData->sUrlOrCmd,NULL,NULL,SW_SHOWNORMAL); else if(NULL != m_hWndCallback) { ::SendMessage(m_hWndCallback,QLINKBOX_ITEMCLICK,0,(LPARAM)((LPCTSTR)(pData->sUrlOrCmd))); } } } void LinkBox::RedrawItem(int nItem) { CRect rect; GetSubItemRect(nItem,0, LVIR_LABEL, rect); rect.left = 0; RedrawWindow(&rect); } 


 

你可能感兴趣的:(report,null,delete,border,imagelist,Hyperlink)