前言

定时器是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中使用定时器的更多相关文章

  1. Egret入门学习日记 --- 第十四篇(书中 5.4~5.6节 内容)

    第十四篇(书中 5.4~5.6节 内容) 书中内容: 总结 5.4节 内容重点: 1.如何编写自定义组件? 跟着做: 重点1:如何编写自定义组件? 文中提到了重要的两点. 好,我们来试试看. 第一步, ...

  2. 第二十八篇:SOUI中自定义控件开发过程

    在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件 ...

  3. 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)

    解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...

  4. 第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  5. 【译】第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  6. 跟我学SpringCloud | 第十四篇:Spring Cloud Gateway高级应用

    SpringCloud系列教程 | 第十四篇:Spring Cloud Gateway高级应用 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 ...

  7. SpringBoot第二十四篇:应用监控之Admin

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   前一章(S ...

  8. Egret入门学习日记 --- 第十五篇(书中 6.1~6.9节 内容)

    第十五篇(书中 6.1~6.9节 内容) 好的,昨天完成了第五章. 今天来看第六章. 总结重点: 1.如何对组件进行分组? 跟着做: 重点1:如何对组件进行分组? 首先,选中你想要组合的组件. 然后点 ...

  9. Spring Cloud第十四篇 | Api网关Zuul

    ​ 本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...

  10. Python之路【第十四篇】:AngularJS --暂无内容-待更新

    Python之路[第十四篇]:AngularJS --暂无内容-待更新

随机推荐

  1. 【GoLang】golang 中可变参数的 定义、传递 示例

    支持可变长参数列表的函数可以支持任意个传入参数,比如fmt.Println函数就是一个支持可变长参数列表的函数. package main import "fmt" // 这个函数 ...

  2. 如何查看Git对象

    原文:http://gitbook.liuhui998.com/7_2.html 如果在阅读本文之前,你还不知道git是如何进行存储的,请先阅读<Git是如何存储对象的>. 我们可以使用c ...

  3. static cross compile gtk-2.16.6+gtk-directfb+arm-linux (arm-linux-gcc-3.4.4+glib-2.3.5)

    ----------------------------------------------------------------------- In Ubuntu 10.4 Desktop and & ...

  4. form、iframe实现异步上传文件

    转载自:http://blog.csdn.net/sunjing21/article/details/4779321 实现主要功能: 页面提供一个上传图片的input file选择框,用于上传某一类型 ...

  5. 【python】类中的self

    在python的类中,经常会写self,代表对象自己.如下例: #coding=utf-8 class Foo: def __init__(self, name): self.name = name ...

  6. SQL Server 2008 R2 安装出错:Could not open key

    安装Sql Server 2008 R2 企业版出现错误提示无法继续安装,错误提示为: Could not open key: UNKNOWN\Components\7ABFE44842C12B390 ...

  7. tableView滚到最后一行

    dispatch_async(dispatch_get_main_queue(), ^{ [_tableview scrollToRowAtIndexPath:[NSIndexPath indexPa ...

  8. eclipse svn设置忽略文件

  9. 零基础十分钟学会用git在coding.net上传(pull)和push

    ---恢复内容开始--- 对于入门者来说,特别是刚刚接触计算机的人来说,模仿是最快的学习方式了,先能够会使用(对于初学者来说,这种使用新事物的感觉很能爽的)至于原理,以后再说.下面先让初学者快速的学会 ...

  10. volatile和const

    volatile可理解为“编译器警告指示字” volatile用于告诉编译器必须每次去内存中取变量值 volatile主要修饰可能被多个线程访问的变量 volatile也可以修饰可能被未知因数更改的变 ...