第十四篇:在SOUI中使用定时器
前言
定时器是win32编程中常用的制作动画效果的手段。在Win32编程中,可以使用::SetTimer来创建定时器,定时器消息会被会发到调用SetTimer时指定的HWND。
在SOUI中一般来说只有一个宿主窗口有HWND,所有的SWindow都属于一个宿主窗口,如此一来直接使用::SetTimer创建的定时器就难以直接分发到SWindow对象了。
在SOUI的控件中使用定时器
为了能够方便的在SWindow中使用定时器,在SOUI系统中,我们通过将定时器ID(共32位)按位进行分解:
class SOUI_EXP STimerID
{
public:
DWORD Swnd:; //窗口句柄,如果窗口句柄超过24位范围,则不能使用这种方式设置定时器
DWORD uTimerID:; //定时器ID,一个窗口最多支持128个定时器。
DWORD bSwndTimer:; //区别通用定时器的标志,标志为1时,表示该定时器为SWND定时器 STimerID(SWND hWnd,char id)
{
SASSERT(hWnd<0x00FFFFFF && id>=);
bSwndTimer=;
Swnd=hWnd;
uTimerID=id;
}
STimerID(DWORD dwID)
{
memcpy(this,&dwID,sizeof(DWORD));
}
operator DWORD &() const
{
return *(DWORD*)this;
}
};
低24位用来存储SWindow的窗口ID(swnd)。swnd是一个SWindow创建序号,在一个应用中,通常很难产生超过0xFFFFFF(16777215)个窗口对象,因此使用低24位来存储窗口ID在大部分情况下都是够用的了。
高8位中保留最高位设置为1,用来区别直接使用::SetTimer创建的定时器(不可以把最高位置1)。
剩下7位用于SWindow中作为定时器ID。因此在SOUI中,一个SWindow最多可以创建0-127个定时器。
创建定时器:
SWindow::SetTimer(0~127);
/**
* SWindow::SetTimer
* @brief 利用窗口定时器来设置一个ID为0-127的SWND定时器
* @param char id -- 定时器ID
* @param UINT uElapse -- 延时(MS)
* @return BOOL
*
* Describe 参考::SetTimer
*/
BOOL SWindow::SetTimer(char id,UINT uElapse);
销毁定时器:
SWindow::KillTimer;
/**
* KillTimer
* @brief 删除一个SWND定时器
* @param char id -- 定时器ID
* @return void
*
* Describe
*/
void KillTimer(char id);
响应定时器消息:
在消息映射表中使用MSG_WM_TIMER_EX。参见:SGifPlayer.h
SOUI_MSG_MAP_BEGIN()
MSG_WM_TIMER_EX(OnTimer) //定时器消息
MSG_WM_PAINT_EX(OnPaint) //窗口绘制消息
MSG_WM_SHOWWINDOW(OnShowWindow)//窗口显示状态消息
SOUI_MSG_MAP_END()
如果在一个窗口中必须要创建使用32位的定时器ID,在SOUI中可以使用另一个接口来实现:
/**
* SetTimer2
* @brief 利用函数定时器来模拟一个兼容窗口定时器
* @param UINT_PTR id -- 定时器ID
* @param UINT uElapse -- 延时(MS)
* @return BOOL
*
* Describe 由于SetTimer只支持0-127的定时器ID,SetTimer2提供设置其它timerid
* 能够使用SetTimer时尽量不用SetTimer2,在Kill时效率会比较低
*/
BOOL SetTimer2(UINT_PTR id,UINT uElapse); /**
* KillTimer2
* @brief 删除一个SetTimer2设置的定时器
* @param UINT_PTR id -- SetTimer2设置的定时器ID
* @return void
*
* Describe 需要枚举定时器列表
*/
void KillTimer2(UINT_PTR id);
响应定时器:
使用SWindow::SetTimer2创建的定时器,最后会通过一个消息:WM_TIMER2来分发到SWindow。
#define WM_TIMER2 (WM_USER+5432) //定义一个与HWND定时器兼容的SOUI定时器 #define MSG_WM_TIMER2(func) \
if (uMsg == WM_TIMER2) \
{ \
SetMsgHandled(TRUE); \
func(wParam); \
lResult = ; \
if(IsMsgHandled()) \
return TRUE; \
}
在应用程序中使用定时器
前面两种定时器都是在控件开发的时候使用定时器的方法。而在应用层,还可以为宿主窗口直接使用::SetTimer或者宿主窗口的基类:CSimpleWnd::SetTimer来创建定时器(注意最高位必须是0)。
在响应这类定时器时,一样可以在宿主窗口的消息映射表中使用MSG_WM_TIMER来响应定时器消息。但是需要注意的是,这个映射宏会截获所有分发给宿主窗口的定时器,如果不是自己创建的定时器,则需要继续交给基类处理。
可以调用:SetMsgHandled(FALSE); 或者:SHostWnd::OnTimer(UINT_PTR idEvent);实现。
第十四篇:在SOUI中使用定时器的更多相关文章
- Egret入门学习日记 --- 第十四篇(书中 5.4~5.6节 内容)
第十四篇(书中 5.4~5.6节 内容) 书中内容: 总结 5.4节 内容重点: 1.如何编写自定义组件? 跟着做: 重点1:如何编写自定义组件? 文中提到了重要的两点. 好,我们来试试看. 第一步, ...
- 第二十八篇:SOUI中自定义控件开发过程
在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件 ...
- 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)
解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...
- 第十四篇 Integration Services:项目转换
本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...
- 【译】第十四篇 Integration Services:项目转换
本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...
- 跟我学SpringCloud | 第十四篇:Spring Cloud Gateway高级应用
SpringCloud系列教程 | 第十四篇:Spring Cloud Gateway高级应用 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 ...
- SpringBoot第二十四篇:应用监控之Admin
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 前一章(S ...
- Egret入门学习日记 --- 第十五篇(书中 6.1~6.9节 内容)
第十五篇(书中 6.1~6.9节 内容) 好的,昨天完成了第五章. 今天来看第六章. 总结重点: 1.如何对组件进行分组? 跟着做: 重点1:如何对组件进行分组? 首先,选中你想要组合的组件. 然后点 ...
- Spring Cloud第十四篇 | Api网关Zuul
本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...
- Python之路【第十四篇】:AngularJS --暂无内容-待更新
Python之路[第十四篇]:AngularJS --暂无内容-待更新
随机推荐
- 【GoLang】golang 如何像Java 一样通过类名反射对象?
结论: golang不支持解析string然后执行. golang的反射机制只能存在于已经存在的对象上面. 不知道后续的版本有没有规划,现在只能先加载注册,然后实现类似Java工厂模式的反射. 代码示 ...
- Binary Tree Vertical Order Traversal
Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...
- select count(*)和select count(1)的区别
一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的 假如表沒有主键(Primary key), 那么count(1)比count(*)快, 如果有主键的話 ...
- zpf 获取表单等数据的用法
2015年4月12日 12:25:35 星期日 zpf框架中获取表单数据的方法 //获得get,post,url中的数据 private function setData() { $this-> ...
- 自定义ToolBar之一
其实已经有很多大神写过这方面的文章了,不过我比较蠢吧,老有一些地方看不懂的,翻了很多关于Toolbar方面的文章和视频,这儿总结一下. 参考资料:youtube:slidenerd 阶段一 自定义配 ...
- 在Win7下使用sphinx-build建立开源软件文档
最近想看看odoo的使用文档,在线看不方便,而且还没有提供离线文档下载,由于是开源项目,此项目托管在Github上,于是就有了想通过Github把文档git下来,可是git下来的文档是.rst文件,无 ...
- Please see the 'svn upgrade' command
svn: E155036: Please see the 'svn upgrade' command svn: E155036: Working copy '/home/easwy/dev' is t ...
- SQL Server 查询时间段内数据
方式一: ALTER Proc [dbo].[usp_Rpt_AcctTypeAudit] @FromDate datetime=null, -- yyyy-mm-dd (may change in ...
- IOS 去掉导航栏(UINavigationBar)下方的横线
这是导航栏的问题,将下边的代码放在 viewWillAppear 方法中就可以实现效果: - (void)viewWillAppear:(BOOL)animated{ // Called when ...
- September 7th 2016 Week 37th Wednesday
Patience is bitter, but its fruit is sweet. 忍耐是痛苦的,但它的果实却是甜蜜的. However, many may give up before they ...