仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)

简介: 转载请说明原出处,谢谢~~          整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果很不理想。

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


         整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果很不理想。在源码中可以知道(属性列表中列的不全面)Option提供了8种显示状态,分别为

<Attribute name="normalimage" default="" type="STRING" comment="普通状态图片"/>
<Attribute name="hotimage" default="" type="STRING" comment="鼠标悬浮的状态图片"/>
<Attribute name="pushedimage" default="" type="STRING" comment="鼠标按下的状态图片"/>
<Attribute name="focusedimage" default="" type="STRING" comment="获得焦点时的状态图片"/>
<Attribute name="disabledimage" default="" type="STRING" comment="禁用的状态图片"/>
<Attribute name="selectedimage" default="" type="STRING" comment="选中的状态图片"/>
<Attribute name="selectedhotimage" default="" type="STRING" comment="选中的鼠标悬浮的的状态图片"/>
<Attribute name="foreimage" default="" type="STRING" comment="前景图片"/>

        这些属性可以大致模仿出check控件分别在选中和非选中状态下的一些效果,我设置了其中的normalimage、hotimage、pushedimage、disabledimage、selectedimage、selectedhotimage属性,但是在测试时发现,只有 pushedimage 属性没有效果,也就是check控件和option控件没有被按下的状态的效果,同时也注意到原控件没有提供选中的鼠标按下的的状态图片,这就让Option控件和Check控件的效果很不好。查看源码后发现问题。原代码如下:

	void COptionUI::PaintStatusImage(HDC hDC)
	{
		m_uButtonState &= ~UISTATE_PUSHED;

		if( (m_uButtonState & UISTATE_HOT) != 0 && IsSelected() && !m_sSelectedHotImage.IsEmpty()) {
			if( !DrawImage(hDC, (LPCTSTR)m_sSelectedHotImage) )
				m_sSelectedHotImage.Empty();
			else goto Label_ForeImage;
		}
		else if( (m_uButtonState & UISTATE_SELECTED) != 0 ) {
			if( !m_sSelectedImage.IsEmpty() ) {
				if( !DrawImage(hDC, (LPCTSTR)m_sSelectedImage) ) m_sSelectedImage.Empty();
				else goto Label_ForeImage;
			}
			else if(m_dwSelectedBkColor != 0) {
				CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwSelectedBkColor));
				return;
			}	
		}

		CButtonUI::PaintStatusImage(hDC);

Label_ForeImage:
		if( !m_sForeImage.IsEmpty() ) {
			if( !DrawImage(hDC, (LPCTSTR)m_sForeImage) ) m_sForeImage.Empty();
		}
	}
        可以看到,代码的第一句就把按下状态给去掉了,虽然不知道作者这样写的意图,但我觉得这是不对的,去掉这句代码后Option控件在非选中状态下就可以显示鼠标按下的状态了。

        随后我给Option控件增加了一个selectedpushedimage属性,用来设置选中的鼠标按下的的状态图片,让Option的显示状态更加完全,为了使用这个属性,需要修改SetAttribute函数,另外增加了两个函数SetSelectedPushedImage和GetSelectedPushedImage,这是修改后的PaintStatusImage函数:

		if( (m_uButtonState & UISTATE_PUSHED) != 0 && IsSelected() && !m_sSelectedPushedImage.IsEmpty()) {
			if( !DrawImage(hDC, (LPCTSTR)m_sSelectedPushedImage) )
				m_sSelectedPushedImage.Empty();
			else goto Label_ForeImage;
		}
		else if( (m_uButtonState & UISTATE_HOT) != 0 && IsSelected() && !m_sSelectedHotImage.IsEmpty()) {
			if( !DrawImage(hDC, (LPCTSTR)m_sSelectedHotImage) )
				m_sSelectedHotImage.Empty();
			else goto Label_ForeImage;
		}
		else if( (m_uButtonState & UISTATE_SELECTED) != 0 ) {
			if( !m_sSelectedImage.IsEmpty() ) {
				if( !DrawImage(hDC, (LPCTSTR)m_sSelectedImage) ) m_sSelectedImage.Empty();
				else goto Label_ForeImage;
			}
			else if(m_dwSelectedBkColor != 0) {
				CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwSelectedBkColor));
				return;
			}	
		}

		CButtonUI::PaintStatusImage(hDC);

Label_ForeImage:
		if( !m_sForeImage.IsEmpty() ) {
			if( !DrawImage(hDC, (LPCTSTR)m_sForeImage) ) m_sForeImage.Empty();
		}
          这样就可以让Option控件显示出9种状态了,完全可以模仿出真正的Option控件的样子,这是我做的一部分的设置窗体的样子:




           这里给出完整的状态属性列表:

<Attribute name="normalimage" default="" type="STRING" comment="普通状态图片"/>
<Attribute name="hotimage" default="" type="STRING" comment="鼠标悬浮的状态图片"/>
<Attribute name="pushedimage" default="" type="STRING" comment="鼠标按下的状态图片"/>
<Attribute name="focusedimage" default="" type="STRING" comment="获得焦点时的状态图片"/>
<Attribute name="disabledimage" default="" type="STRING" comment="禁用的状态图片"/>
<Attribute name="selectedimage" default="" type="STRING" comment="选中的状态图片"/>
<Attribute name="selectedhotimage" default="" type="STRING" comment="选中的鼠标悬浮的的状态图片"/>
<Attribute name="selectedpushedimage" default="" type="STRING" comment="选中的鼠标按下的的状态图片"/>
<Attribute name="foreimage" default="" type="STRING" comment="前景图片"/>

        另外因为需要大量重复使用Option控件,为了避免重复设置属性,我这里给出我的仿酷狗设置窗体的Default标签,方便大家用,大家根据自己的情况再去修改:

<Default name="CheckBox" value="textcolor="#FF454545" disabledtextcolor="#FF454545" width="10" height="14" textpadding="16,1,0,0" align="left" normalimage="file='UI\setting\check_normal.png' dest='0,0,14,14'" hotimage="file='UI\setting\check_hover.png' dest='0,0,14,14'" pushedimage="file='UI\setting\check_down.png' dest='0,0,14,14'" disabledimage="file='UI\setting\check_disable.png' dest='0,0,14,14'" selectedimage="file='UI\setting\checked_normal.png' dest='0,0,14,14'" selectedhotimage="file='UI\setting\checked_hover.png' dest='0,0,14,14'" selectedpushedimage="file='UI\setting\checked_down.png' dest='0,0,14,14'" autocalcwidth="true""/>

总结:

        其实还可以在写一个selecteddisabledimage属性,用来给选中状态下的Option控件设置禁用效果,这个代码我目前不需要,就不写了,留给大家自己写吧,很简单的。

        修改好的OPtion控件下载地址:点击打开链接

Redrain 2014.8.25

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
小程序 前端开发 API
微信小程序全栈开发中的异常处理与日志记录
【4月更文挑战第12天】本文探讨了微信小程序全栈开发中的异常处理和日志记录,强调其对确保应用稳定性和用户体验的重要性。异常处理涵盖前端(网络、页面跳转、用户输入、逻辑异常)和后端(数据库、API、业务逻辑)方面;日志记录则关注关键操作和异常情况的追踪。实践中,前端可利用try-catch处理异常,后端借助日志框架记录异常,同时采用集中式日志管理工具提升分析效率。开发者应注意安全性、性能和团队协作,以优化异常处理与日志记录流程。
|
3月前
|
数据库
什么是计算机软件开发领域的 verbose 代码和日志
什么是计算机软件开发领域的 verbose 代码和日志
33 0
|
4月前
|
调度
kettle开发篇-写日志
kettle开发篇-写日志
99 0
|
25天前
|
JavaScript Java 测试技术
基于Java的公司员工工作日志办公系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的公司员工工作日志办公系统的设计与实现(源码+lw+部署文档+讲解等)
141 3
|
2月前
|
XML Java 开发者
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging
45 1
|
3月前
|
供应链 Java 测试技术
开发Java应用时如何用好Log
开发Java应用时如何用好Log
78 3
|
6天前
|
C++
JNI Log 日志输出
JNI Log 日志输出
14 1
|
6天前
|
存储 运维 大数据
聊聊日志硬扫描,阿里 Log Scan 的设计与实践
泛日志(Log/Trace/Metric)是大数据的重要组成,伴随着每一年业务峰值的新脉冲,日志数据量在快速增长。同时,业务数字化运营、软件可观测性等浪潮又在对日志的存储、计算提出更高的要求。
|
13天前
|
XML Java Maven
Springboot整合与使用log4j2日志框架【详解版】
该文介绍了如何在Spring Boot中切换默认的LogBack日志系统至Log4j2。首先,需要在Maven依赖中排除`spring-boot-starter-logging`并引入`spring-boot-starter-log4j2`。其次,创建`log4j2-spring.xml`配置文件放在`src/main/resources`下,配置包括控制台和文件的日志输出、日志格式和文件切分策略。此外,可通过在不同环境的`application.yml`中指定不同的log4j2配置文件。最后,文章提到通过示例代码解释了日志格式中的各种占位符含义。
|
13天前
|
运维 监控 Go
Golang深入浅出之-Go语言中的日志记录:log与logrus库
【4月更文挑战第27天】本文比较了Go语言中标准库`log`与第三方库`logrus`的日志功能。`log`简单但不支持日志级别配置和多样化格式,而`logrus`提供更丰富的功能,如日志级别控制、自定义格式和钩子。文章指出了使用`logrus`时可能遇到的问题,如全局logger滥用、日志级别设置不当和过度依赖字段,并给出了避免错误的建议,强调理解日志级别、合理利用结构化日志、模块化日志管理和定期审查日志配置的重要性。通过这些实践,开发者能提高应用监控和故障排查能力。
88 1