?? hyperlink.cpp
字號:
// HyperLink.cpp : implementation file
#include "stdafx.h"
#include "HyperLink.h"
//Win2000定義
//#define IDC_HAND MAKEINTRESOURCE(32649)
#ifdef _DEBUG
#define new DEBUm_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TOOLTIP_ID 1
//設置風格位操作
#define SETBITS(dw, bits) (dw |= bits)
//去掉風格位操作
#define CLEARBITS(dw, bits) (dw &= ~(bits))
//判斷風格位操作
#define BITSET(dw, bit) (((dw) & (bit)) != 0L)
/////////////////////////////////////////////////////////////////////////////
// CHyperLink
const DWORD CHyperLink::STYLEUNDERLINE = 0x00000001; // 下劃線
const DWORD CHyperLink::STYLEUSEHOVER = 0x00000002; // 鼠標的掠過顏色風格
const DWORD CHyperLink::STYLEAUTOSIZE = 0x00000004; // 自動調整大小
const DWORD CHyperLink::STYLEDOWNCLICK = 0x00000008; // 鼠標按下代表單擊風格
const DWORD CHyperLink::STYLEGETFOCUSONCLICK = 0x00000010; // 單擊時候得到光標
const DWORD CHyperLink::STYLENOHANDCURSOR = 0x00000020; // 沒有設置光標
const DWORD CHyperLink::STYLENOACTIVECOLOR = 0x00000040; // 沒有活動時設置顏色
//默認的顏色
COLORREF CHyperLink::m_crLinkColor = RGB(0, 0, 255);
COLORREF CHyperLink::m_crActiveColor = RGB(0, 128, 128);
COLORREF CHyperLink::m_crVisitedColor = RGB(128, 0, 128);
COLORREF CHyperLink::m_crHoverColor = RGB(255, 0, 0 );
HCURSOR CHyperLink::m_hLinkCursor = NULL;
CHyperLink::CHyperLink()
{
m_bOverControl = FALSE; // 光標不在控件上
m_bVisited = FALSE; // 可見
m_bLinkActive = FALSE; // 活動
m_strURL.Empty(); // URL
// 設置默認的風格
m_dwStyle = STYLEUNDERLINE|STYLEAUTOSIZE|STYLEGETFOCUSONCLICK;
}
CHyperLink::~CHyperLink()
{
m_Font.DeleteObject();
}
IMPLEMENT_DYNAMIC(CHyperLink, CStatic)
BEGIN_MESSAGE_MAP(CHyperLink, CStatic)
//{{AFX_MSm_MAP(CHyperLink)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_KEYDOWN()
ON_WM_NCHITTEST()
ON_WM_LBUTTONDOWN()
//}}AFX_MSm_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHyperLink message handlers
BOOL CHyperLink::PreTranslateMessage(MSG* pMsg)
{
m_ToolTip.RelayEvent(pMsg);
return CStatic::PreTranslateMessage(pMsg);
}
void CHyperLink::PreSubclassWindow()
{
// 如果URL為空,以顯示文本為連接對象
if (m_strURL.IsEmpty())
GetWindowText(m_strURL);
//檢查是否為空
CString strWndText;
GetWindowText(strWndText);
if (strWndText.IsEmpty())
{
//ASSERT(!m_strURL.IsEmpty());
CStatic::SetWindowText(m_strURL);
}
//得到字體
CFont* pFont = GetFont();
if (pFont != NULL)
{
LOGFONT lf;
pFont->GetLogFont(&lf);
lf.lfUnderline = BITSET(m_dwStyle, STYLEUNDERLINE);
if (m_Font.CreateFontIndirect(&lf))
CStatic::SetFont(&m_Font);
//調整窗口的大小,以適應字體的全部可見
AdjustWindow();
}
else
{
//如果沒有得到字體,說明本控件不是一個Text類型的,
//把其設置成自動伸縮
CLEARBITS(m_dwStyle,STYLEAUTOSIZE);
}
if (!BITSET(m_dwStyle,STYLENOHANDCURSOR))
SetDefaultCursor();
//提示
CRect rect;
GetClientRect(rect);
m_ToolTip.Create(this);
m_ToolTip.AddTool(this, m_strURL, rect, TOOLTIP_ID);
CStatic::PreSubclassWindow();
}
//設置字體和顏色
HBRUSH CHyperLink::CtlColor(CDC* pDC, UINT nCtlColor)
{
ASSERT(nCtlColor == CTLCOLOR_STATIC);
if (m_bOverControl && BITSET(m_dwStyle,STYLEUSEHOVER))
{
pDC->SetTextColor(m_crHoverColor);
}
else if (!BITSET(m_dwStyle,STYLENOACTIVECOLOR) && m_bLinkActive)
{
pDC->SetTextColor(m_crActiveColor);
}
else if (m_bVisited)
{
pDC->SetTextColor(m_crVisitedColor);
}
else
{
pDC->SetTextColor(m_crLinkColor);
}
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
void CHyperLink::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bOverControl) // 當前在
{
CRect rect;
GetClientRect(rect);
if (!rect.PtInRect(point))
{
m_bOverControl = FALSE;
ReleaseCapture();
Invalidate();
return;
}
}
else // 光標已經離開
{
m_bOverControl = TRUE;
Invalidate();
SetCapture();
}
}
//通常,如果沒有SS_NOTIFY,Static控件得不到到鼠標事件,
//本函數完成了與SS_NOTIFY
//的效果,但在調用OnCtlColor時打開SS_NOTIFY更可靠,因為在Bitamap風格的Static中沒有
//發送WM_CTLCOLOR的消息
UINT CHyperLink::OnNcHitTest(CPoint point)
{
return HTCLIENT;
}
void CHyperLink::OnLButtonDown(UINT nFlags, CPoint point)
{
if (BITSET(m_dwStyle,STYLEGETFOCUSONCLICK))
{
SetFocus();
}
if (BITSET(m_dwStyle,STYLEDOWNCLICK))
{
FollowLink();
}
m_bLinkActive = TRUE;
}
void CHyperLink::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bLinkActive && !BITSET(m_dwStyle,STYLEDOWNCLICK))
FollowLink();
}
BOOL CHyperLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_hLinkCursor)
{
::SetCursor(m_hLinkCursor);
return TRUE;
}
return FALSE;
}
void CHyperLink::OnSetFocus(CWnd* pOldWnd)
{
m_bLinkActive = TRUE;
Invalidate(); // Repaint to set the focus
}
void CHyperLink::OnKillFocus(CWnd* pNewWnd)
{
// Assume that control lost focus = mouse out
// this avoid troubles with the Hover color
m_bOverControl = FALSE;
m_bLinkActive = FALSE;
Invalidate(); // Repaint to unset the focus
}
void CHyperLink::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
//空格
if (nChar == VK_SPACE)
{
FollowLink();
}
else
{
CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
}
}
/////////////////////////////////////////////////////////////////////////////
// CHyperLink operations
void CHyperLink::SetColors( COLORREF crLinkColor,
COLORREF crActiveColor,
COLORREF crVisitedColor,
COLORREF crHoverColor /* = -1 */)
{
m_crLinkColor = crLinkColor;
m_crActiveColor = crActiveColor;
m_crVisitedColor = crVisitedColor;
if (crHoverColor == -1)
m_crHoverColor = ::GetSysColor(COLOR_HIGHLIGHT);
else
m_crHoverColor = crHoverColor;
}
void CHyperLink::GetColors(COLORREF &crLink,COLORREF &crActive,COLORREF &crVisited,COLORREF &crHover)
{
crLink=m_crLinkColor;
crActive = m_crActiveColor;
crVisited = m_crVisitedColor;
crHover = m_crHoverColor;
}
void CHyperLink::SetLinkCursor(HCURSOR hCursor) {
ASSERT(hCursor != NULL);
m_hLinkCursor = hCursor;
if (m_hLinkCursor == NULL)
SetDefaultCursor();
}
HCURSOR CHyperLink::GetLinkCursor() {
return m_hLinkCursor;
}
BOOL CHyperLink:: ModifyLinkStyle(DWORD dwRemove, DWORD dwAdd,
BOOL bApply /* =TRUE */)
{
if ((dwRemove & dwAdd) != 0L)
return FALSE;
CLEARBITS(m_dwStyle, dwRemove);
SETBITS(m_dwStyle, dwAdd);
if (bApply && ::IsWindow(GetSafeHwnd()))
{
if (BITSET(dwAdd,STYLEUNDERLINE) || BITSET(dwRemove,STYLEUNDERLINE))
SwitchUnderline();
if (BITSET(dwAdd,STYLEAUTOSIZE))
AdjustWindow();
if (BITSET(dwRemove,STYLEUSEHOVER))
Invalidate();
}
return TRUE;
}
DWORD CHyperLink::GetLinkStyle() const {
return m_dwStyle;
}
void CHyperLink::SetURL(CString strURL)
{
m_strURL = strURL;
if (::IsWindow(GetSafeHwnd()))
{
ShowWindow(SW_HIDE);
AdjustWindow();
m_ToolTip.UpdateTipText(strURL, this, TOOLTIP_ID);
ShowWindow(SW_SHOW);
}
}
CString CHyperLink::GetURL() const
{
return m_strURL;
}
void CHyperLink::SetWindowText(LPCTSTR lpszText)
{
ASSERT(lpszText != NULL);
if (::IsWindow(GetSafeHwnd()))
{
ShowWindow(SW_HIDE);
CStatic::SetWindowText(lpszText);
AdjustWindow();
ShowWindow(SW_SHOW);
}
}
void CHyperLink::SetFont(CFont* pFont)
{
ASSERT(::IsWindow(GetSafeHwnd()));
ASSERT(pFont != NULL);
ShowWindow(SW_HIDE);
LOGFONT lf;
pFont->GetLogFont(&lf);
m_Font.DeleteObject();
m_Font.CreateFontIndirect(&lf);
CStatic::SetFont(&m_Font);
AdjustWindow();
ShowWindow(SW_SHOW);
}
void CHyperLink::SwitchUnderline()
{
LOGFONT lf;
CFont* pFont = GetFont();
if (pFont != NULL)
{
pFont->GetLogFont(&lf);
lf.lfUnderline = BITSET(m_dwStyle,STYLEUNDERLINE);
m_Font.DeleteObject();
m_Font.CreateFontIndirect(&lf);
SetFont(&m_Font);
}
}
//調整窗口的大小,以適應文字的大小
void CHyperLink::AdjustWindow()
{
ASSERT(::IsWindow(GetSafeHwnd()));
if (!BITSET(m_dwStyle,STYLEAUTOSIZE))
return;
CRect rcWnd;
GetWindowRect(rcWnd);
//父窗口先轉換
CWnd* pParent = GetParent();
if (pParent)
pParent->ScreenToClient(rcWnd);
CRect rcClient;
GetClientRect(rcClient);
// 計算邊框
int borderWidth = rcWnd.Width() - rcClient.Width();
int borderHeight = rcWnd.Height() - rcClient.Height();
// 得到字體的尺寸
CString strWndText;
GetWindowText(strWndText);
CDC* pDC = GetDC();
CFont* pOldFont = pDC->SelectObject(&m_Font);
CSize Extent = pDC->GetTextExtent(strWndText);
pDC->SelectObject(pOldFont);
ReleaseDC(pDC);
//得到字體的對方式
DWORD dwStyle = GetStyle();
if (BITSET(dwStyle, SS_CENTERIMAGE))
{
rcWnd.DeflateRect(0, (rcWnd.Height() - Extent.cy) / 2);
}
else
{
rcWnd.bottom = rcWnd.top + Extent.cy;
}
if (BITSET(dwStyle, SS_CENTER))
{
rcWnd.DeflateRect((rcWnd.Width() - Extent.cx) / 2, 0);
}
else if (BITSET(dwStyle,SS_RIGHT))
{
rcWnd.left = rcWnd.right - Extent.cx;
}
else // SS_LEFT
{
rcWnd.right = rcWnd.left + Extent.cx;
}
MoveWindow(rcWnd.left, rcWnd.top, rcWnd.Width() + borderWidth,
rcWnd.Height() + borderHeight);
}
void CHyperLink::SetVisited(BOOL bVisited /* = TRUE */) {
m_bVisited = bVisited;
}
BOOL CHyperLink::IsVisited() const {
return m_bVisited;
}
/////////////////////////////////////////////////////////////////////////////
// CHyperLink implementation
// 從WIn32hlp中得到默認的手形光標
void CHyperLink::SetDefaultCursor()
{
//如果僅在Win2000中可以用
//HCURSOR hHandCursor=::LoadCursor(NULL,IDC_HAND);
//m_hLinkCursor = CopyCursor(hHandCursor);
//return;
//否則用
if (m_hLinkCursor == NULL)
{
CString strWndDir;
GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
strWndDir.ReleaseBuffer();
strWndDir += _T("\\winhlp32.exe");
HMODULE hModule = LoadLibrary(strWndDir);
if (hModule)
{
HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
if (hHandCursor)
m_hLinkCursor = CopyCursor(hHandCursor);
}
FreeLibrary(hModule);
}
}
HINSTANCE CHyperLink::GotoURL(LPCTSTR url, int showcmd)
{
HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, showcmd);
return result;
}
// 激活連接控件
void CHyperLink::FollowLink()
{
int result = (int) GotoURL(m_strURL, SW_SHOW);
if (result <= HINSTANCE_ERROR)
{
MessageBeep(MB_ICONEXCLAMATION);
}
else
{
m_bVisited = TRUE;
Invalidate();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -