IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> WTL 自绘控件库 (CQsHyperLink) -> 正文阅读

[C++知识库]WTL 自绘控件库 (CQsHyperLink)

概述:

CQsHyperLink 继承与 CHyperLinkImpl,通过自绘来透明背景。已经访问颜色转变。

代码实现如下:

#pragma once
#include "QsInclude.h"

/**
*@brief    透明HyperLink(超链接)控件类
*/
class CQsHyperLink :
	public CImageMgrCtrlBase< CQsHyperLink>,
	public CHyperLinkImpl<CQsHyperLink>,
	public COwnerDraw<CQsHyperLink>
{
	
	typedef CHyperLinkImpl< CQsHyperLink > theBaseClass;
	typedef CImageMgrCtrlBase< CQsHyperLink > theImageCtrlBaseClass;

	volatile UINT	m_uCurState;			//当前按钮状态
	volatile bool	m_bMouseDown;			//鼠标左键按下
	BOOL			m_bTransBKGnd;			//是否使用透明背景
	volatile bool	m_bMouseTrack;			//鼠标是否进入
	int m_uFirstPos;
	int m_uLastPos;
	Color m_color;                         //设置默认字体的颜色
	Color m_Visitedcolor;                  //设置访问后字体的颜色
    HFONT m_hFont;
public:
    BEGIN_MSG_MAP(CQsHyperLink)
		MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )
		MESSAGE_HANDLER( WM_LBUTTONUP, OnLButtonUp )
		MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
		MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
        CHAIN_MSG_MAP_ALT( COwnerDraw<CQsHyperLink>, 1)
		CHAIN_MSG_MAP( theBaseClass )
		CHAIN_MSG_MAP( theImageCtrlBaseClass )
        DEFAULT_REFLECTION_HANDLER()
    END_MSG_MAP()

	CQsHyperLink():
		m_bMouseDown( false ),
		m_uCurState( CONTROL_HLINK_NORMAL ),
		m_bTransBKGnd( FALSE ),
		m_bMouseTrack( TRUE )
	{
		m_uFirstPos = CONTROL_HLINK_FIRST;
		m_uLastPos = CONTROL_HLINK_LAST;
		m_color = Color(255, 60, 36, 118);
		m_Visitedcolor = Color(255, 255, 13, 192);
	}
		/*! \fn HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
		DWORD dwStyle = 0, DWORD dwExStyle = 0, ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
		* \param hWndParent parent window
		* \param rect create window rect
		* \param szWindowName the window name
		* \param dwStyle base window style
		* \param dwExStyle extended window style
		* \param MenuOrID menu or ID
		* \param lpCreateParam create param
		* \return BOOL success return TRUE, failed return FALSE
		* \exception nothrow exception
		* \brief Use this function to subclass one window
		*/
		HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
		{
			return theBaseClass::Create( hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
		}
    /**
    *@brief		子类化函数
    *@param		hWnd HWND,要子类化的控件的句柄
    *@return    BOOL, 执行成功为TRUE,失败为FALSE
    */
    BOOL SubclassWindow( HWND hWnd )
    {
        DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
        dwStyle |= SS_OWNERDRAW;
        ::SetWindowLong( hWnd, GWL_STYLE, dwStyle );
        return theBaseClass::SubclassWindow( hWnd );
    }

	/**
	*@method   OnLButtonDown
	*@brief    鼠标左键被按下消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnLButtonDown( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		m_bMouseDown = true;
		Invalidate();
		bHandled = FALSE;
		return 0;
	}

	/**
	*@method   SetNormalColor
	*@brief     设置通用状态下的字体颜色
	*    
	*@param    Color color
	*@return   void
	*/
	void SetNormalColor(Color color)
	{
		m_color = color;

	}
	/**
	*@method   SetVisitedColor
	*@brief    访问后字体的颜色  
	*    
	*@param    Color color
	*@return   void
	*/
	void SetVisitedColor(Color color)
	{
		m_Visitedcolor = color;

	}

	/**
	*@method   OnMouseMove
	*@brief    鼠标进入消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnMouseMove( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		if( m_uCurState != CONTROL_HLINK_MOUSEIN || m_bMouseTrack)
		{
			Invalidate();

			// 启动鼠标离开时间
			TRACKMOUSEEVENT tme;
			tme.cbSize  = sizeof(tme);
			tme.hwndTrack = m_hWnd;
			tme.dwFlags = TME_LEAVE|TME_HOVER;
			TrackMouseEvent(&tme);
			m_bMouseTrack = FALSE;
		}

		bHandled = FALSE;
		return 0;
	}


	/**
	*@method   OnMouseLeave
	*@brief    鼠标离开消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnMouseLeave( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		if(!m_bMouseTrack)
		{
			Invalidate();
			bHandled = FALSE;
			m_bMouseTrack = TRUE;
		}
		return 0;
	}


	/**
	*@method   OnLButtonUp
	*@brief    鼠标左键被放开消息响应函数
	*    
	*@param    UINT uMsg    消息类型
	*@param    WPARAM wParam    未被使用
	*@param    LPARAM lParam    详见MSDN
	*@param    BOOL& bHandled   未被使用
	*@return   LRESULT  详见MSDN
	*/
	LRESULT OnLButtonUp( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled )
	{
		m_bMouseDown = false;
		Invalidate();
		bHandled = FALSE;
		return 0;
	}

    /**
    *@brief		自绘函数,由COwnerDraw调用
    *@param		lpDrawItemStruct LPDRAWITEMSTRUCT,参见MSDN
    *@return    void
    */
    void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
        //采用双缓存
        int width = lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left;
        int height = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;

        //创建内存作图对象
        WTL::CDC memDC;
        memDC.CreateCompatibleDC( lpDrawItemStruct->hDC );
        WTL::CBitmap memBitmap;
        memBitmap.CreateCompatibleBitmap( lpDrawItemStruct->hDC, width, height );
        HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );

        memDC.SetBkMode( TRANSPARENT );
        ::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )lpDrawItemStruct->hwndItem );

        // get label part rects
        RECT rcClient = { 0 };
        GetClientRect(&rcClient);
        //memDC.SetBkMode(TRANSPARENT);
        //SetBkMode( lpDrawItemStruct->hDC, TRANSPARENT );
        //Graphics gra(lpDrawItemStruct->hDC);
        Graphics gra(memDC);
        StringFormat fmt;
        fmt.SetAlignment(StringAlignmentNear);
        fmt.SetLineAlignment(StringAlignmentCenter);

        SolidBrush brush(Color( 255, 60, 36, 118 ) );
        if ( IsWindowEnabled() )
        {
            if ( m_bVisited )
            {
                brush.SetColor( Color(m_Visitedcolor.GetA(), m_Visitedcolor.GetR(), m_Visitedcolor.GetG(), m_Visitedcolor.GetB()) );
            }
            else
            {
                brush.SetColor(Color(m_color.GetA(), m_color.GetR(), m_color.GetG(), m_color.GetB()));
            }
        }
        else
        {
            BYTE a, r, g, b;
            DWORD dwGray = ::GetSysColor(COLOR_GRAYTEXT);
            a = 255;
            b = BYTE(( dwGray >> 16 ) & 0xff);
            g = BYTE(( dwGray >> 8 ) & 0xff);
            r = BYTE(( dwGray ) & 0xff);
            brush.SetColor( Color( a, r, g, b ) );
        }
        

        //UINT uFontState = CONTROL_HLINK_NORMAL;
        CRect rc;
        GetWindowRect( rc );

        //POINT pt;
        //GetCursorPos( &pt );
        //BOOL bMouseIn = rc.PtInRect( pt );
        BOOL bIsDisabled = !IsWindowEnabled();//( ( lStyle & WS_DISABLED ) != 0 ); //是否被禁止
        //BOOL bIsFocused = ( ::GetFocus() == m_hWnd );

        //如果当前处于失效状态
        //if( !IsWindowEnabled() )
        //{
        //	//if( GetCtrlIcon( CONTROL_HLINK_DISABLED ) )
        //	uFontState = CONTROL_HLINK_DISABLED;
        //}
        //else if( bMouseIn )  //如果当前鼠标在按钮上
        //{
        //	if( m_bMouseDown )
        //	{
        //		//if( GetCtrlIcon( CONTROL_HLINK_MOUSEDOWN ) )
        //			
        //		uFontState = CONTROL_HLINK_MOUSEDOWN;
        //	}
        //	else
        //	{
        //		//if( GetCtrlIcon( CONTROL_HLINK_MOUSEIN ) )
        //			
        //		uFontState = CONTROL_HLINK_MOUSEIN;
        //	}
        //}
        //else if( bIsFocused )
        //{
        //	//if( GetCtrlIcon( CONTROL_HLINK_FOCUS ) )
        //		
        //	uFontState = CONTROL_HLINK_FOCUS;
        //}
        UINT uFontState = CONTROL_HLINK_NORMAL;

        HFONT hFont = GetStateFont( uFontState );
        /
        //Font fnt(lpDrawItemStruct->hDC,hFont);
        Font fnt(memDC,hFont);
        //Font fntUnderLine(lpDrawItemStruct->hDC,hFont);
        Font fntUnderLine(memDC,hFont);

        RectF rtf( REAL(rcClient.left), REAL(rcClient.top-3),REAL(rcClient.right - rcClient.left), REAL(rcClient.bottom - rcClient.top) ); 

        if(IsUsingTags())
        {
            // find tags and label parts
            LPTSTR lpstrLeft = NULL;
            int cchLeft = 0;
            LPTSTR lpstrLink = NULL;
            int cchLink = 0;
            LPTSTR lpstrRight = NULL;
            int cchRight = 0;

            CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);

            if(lpstrLeft != NULL)
            {
                if ((m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) )
                {
                    gra.DrawString( lpstrLeft, cchLeft,&fnt, rtf, &fmt, &brush );

                }
                else
                {
                    gra.DrawString( lpstrLeft, cchLeft,&fntUnderLine, rtf, &fmt, &brush );

                }
            }

            //Font fntNormal( lpDrawItemStruct->hDC, m_hFontNormal);
            Font fntNormal(memDC,m_hFontNormal);
            if(lpstrRight != NULL)
            {
                gra.DrawString( lpstrRight, cchRight, &fnt, rtf, &fmt, &brush );
            }
            if(GetFocus() == m_hWnd)
            {
                //::DrawFocusRect( lpDrawItemStruct->hDC, &m_rcLink );
                ::DrawFocusRect(memDC,&m_rcLink);
            }
        }
        else
        {
            LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;

            if(lpstrText != NULL)
            {
                if ((m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) )
                {
                    gra.DrawString( lpstrText, (INT)_tcslen(lpstrText),
                        &fnt, rtf, &fmt, &brush );
                }
                else
                {
                    gra.DrawString( lpstrText, (INT)_tcslen(lpstrText),
                        &fntUnderLine, rtf, &fmt, &brush );
                }
            }

            if(GetFocus() == m_hWnd)
            {
                ::DrawFocusRect( memDC.m_hDC, &m_rcLink );

            }

        }
        ::DeleteObject( hFont );
        //提交图像
        ::BitBlt( lpDrawItemStruct->hDC, 0, 0, width, height, memDC.m_hDC, 0, 0, SRCCOPY );

        memDC.SelectBitmap( hOldBmp );
    }
};


  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:24:29  更:2022-04-26 11:27:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:19:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码