仿酷狗音乐播放器开发日志二十——换肤功能背景图片控件的制作(附源码)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 转载请说明原出处,谢谢~~           《仿酷狗音乐播放器开发日志二十》里做了换肤功能的一部分,今天完成其他的部分。酷狗的换肤窗口里的背景图可以让用户选择来换图,原酷狗的背景图的小图标,有normal、hover、down等多种状态,鼠标移动上去便会发生变化。

转载请说明原出处,谢谢~~

 

        《仿酷狗音乐播放器开发日志二十》里做了换肤功能的一部分,今天完成其他的部分。酷狗的换肤窗口里的背景图可以让用户选择来换图,原酷狗的背景图的小图标,有normal、hover、down等种状态,鼠标移动上去便会发生变化。如图


       当鼠标经过时会有个黑色图片覆盖,边框变为浅蓝色。并且在他上面显示出作者的一些信息。要实现这个效果应该另外开发一个控件来支持动态的信息展示效果。我把这个小控件的开发过程和源码发一下,给学习做duilib控件的新手朋友做个例子,控件的整体代码很少,熟悉duilib的朋友就不用看这篇博客了。

      我继承CButtonUI类来做这个控件,起名为CSkinPikerPictureItemUI,这个控件的行为和Button是相似的,唯一的区别就是鼠标移动和单击他的时候会显示出额外的信息的图片样式。

      我本来想通过写一个布局,利用多个控件的组合来完成这个效果,但是回头一想,这个控件的效果并不复杂,使用布局去添加多个控件实在是杀鸡用牛刀,而且浪费资源。所以还是觉得直接把这个效果绘制出来。想要改变控件在hot和down状态下的显示效果,只要重写CButtonUI类的PaintStatusImage函数就可以了,编程的方法可以参考CButtonUI类的代码。

       另外,由于这个控件上要显示出这个图片的名字和作者的名字,所以就应该为这个控件增加两个属性,用来在xml文件中设置这两个值,为此需要重写SetAttribute函数。先声明两个成员变量保存这两个值:

	CDuiString m_BkName;
	CDuiString m_Author;

      SetAttribute函数的代码

void CSkinPikerPictureItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
	if( _tcscmp(pstrName, _T("bkname")) == 0 ) m_BkName = pstrValue;
	else if( _tcscmp(pstrName, _T("author")) == 0 ) m_Author += pstrValue;
	CButtonUI::SetAttribute(pstrName, pstrValue);
}


        PaintStatusImage函数的代码

void CSkinPikerPictureItemUI::PaintStatusImage(HDC hDC)
{
	CButtonUI::PaintStatusImage(hDC);

	if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
	else m_uButtonState &= ~ UISTATE_FOCUSED;
	if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
	else m_uButtonState &= ~ UISTATE_DISABLED;

	if( (m_uButtonState & UISTATE_PUSHED) != 0 || (m_uButtonState & UISTATE_HOT) != 0) {

		DrawImage(hDC, kSkinPickerPictureItemForeImage) ;

		//计算作者信息文字和背景图片名字文字的显示位置,这里是用了硬编码,请使用者自己修改
		RECT rcBkName = m_rcItem;
		LONG nTextPadding = (m_rcItem.right - m_rcItem.left  - CRenderEngine::GetTextSize(hDC, GetManager(),\
			m_BkName.GetData(), m_iFont, m_uTextStyle).cx) / 2;
		rcBkName.left += nTextPadding;
		rcBkName.right -= nTextPadding;
		rcBkName.top += 15;
		rcBkName.bottom = rcBkName.top + 20;

		RECT rcAuthor = m_rcItem;
		nTextPadding = (m_rcItem.right - m_rcItem.left - CRenderEngine::GetTextSize(hDC, GetManager(),\
			m_Author.GetData(), m_iFont, m_uTextStyle).cx) / 2;
		rcAuthor.left += nTextPadding;
		rcAuthor.right -= nTextPadding;
		rcAuthor.top += 40;
		rcAuthor.bottom = rcAuthor.top + 20;

		CRenderEngine::DrawText(hDC, m_pManager, rcBkName, m_BkName, kBkNameColor, m_iFont, m_uTextStyle);
		CRenderEngine::DrawText(hDC, m_pManager, rcAuthor, m_Author, kAuthorColor, m_iFont, m_uTextStyle);
		CRenderEngine::DrawRect(hDC, m_rcItem, 2, kBorderColor);

	
	}
}

       这个控件的编写非常简单,我也就不多说什么了,不知道让duilib调用自定义控件的可以看看duilib自带的360demo和QQDemo,我这里给写出CreateControl的代码:

CControlUI* CSkinPicker::CreateControl(LPCTSTR pstrClass) 
{
	if (_tcsicmp(pstrClass, kSkinPickerPictureItemInterface) == 0)
		return	new CSkinPikerPictureItemUI();

	return NULL;
}

        效果图:


  

            有朋友在和我聊天中提起我博客里一些原理写的多,但是发的代码不够,我以后尽量多发布源代码出来~~

        这个控件的源码:点击打开链接



     Redrain  2014.8.7  18:15

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
Rust 前端开发 JavaScript
Tauri 开发实践 — Tauri 日志记录功能开发
本文介绍了如何为 Tauri 应用配置日志记录。Tauri 是一个利用 Web 技术构建桌面应用的框架。文章详细说明了如何在 Rust 和 JavaScript 代码中设置和集成日志记录,并控制日志输出。通过添加 `log` crate 和 Tauri 日志插件,可以轻松实现多平台日志记录,包括控制台输出、Webview 控制台和日志文件。文章还展示了如何调整日志级别以优化输出内容。配置完成后,日志记录功能将显著提升开发体验和程序稳定性。
80 1
Tauri 开发实践 — Tauri 日志记录功能开发
|
16天前
|
监控 开发者
鸿蒙5.0版开发:使用HiLog打印日志(ArkTS)
在HarmonyOS 5.0中,HiLog是系统提供的日志系统,支持DEBUG、INFO、WARN、ERROR、FATAL五种日志级别。本文介绍如何在ArkTS中使用HiLog打印日志,并提供示例代码。通过合理使用HiLog,开发者可以更好地调试和监控应用。
62 16
|
1月前
|
开发框架 缓存 安全
开发日志:IIS安全配置
开发日志:IIS安全配置
开发日志:IIS安全配置
|
1月前
|
开发工具 git
git显示开发日志+WinSW——将.exe文件注册为服务的一个工具+图床PicGo+kubeconfig 多个集群配置 如何切换
git显示开发日志+WinSW——将.exe文件注册为服务的一个工具+图床PicGo+kubeconfig 多个集群配置 如何切换
39 1
|
2月前
|
存储 监控 数据可视化
SLS 虽然不是直接使用 OSS 作为底层存储,但它凭借自身独特的存储架构和功能,为用户提供了一种专业、高效的日志服务解决方案。
【9月更文挑战第2天】SLS 虽然不是直接使用 OSS 作为底层存储,但它凭借自身独特的存储架构和功能,为用户提供了一种专业、高效的日志服务解决方案。
158 9
|
19天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
154 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
1月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
244 3
|
3月前
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
136 3
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1642 14
|
1月前
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
35 0
下一篇
无影云桌面