A Class To Encapsulate MultiMedia Timers

多媒体定时器的封装与使用
本文介绍了一个简单的多媒体定时器类的实现,包括如何在项目中包含该类的头文件和实现文件,如何通过继承自定义定时器类并覆盖成员函数来控制定时器的行为,以及如何设置和启动定时器,同时提供了源代码示例。
This simple class encapsulates the multimedia timers. To use the class include mmTimers.cpp and mmTimers.h in your project. Link with winmm.lib. To use a timer derive a class from CMMTimers and override member timerProc. timerProc will be called when the timer goes off. Instantiate a variable of the new class. The parameter to the constructor is the timer resolution in ms. To start a timer call startTimer. The first parameter specifies the period of the timer in ms. The second parameter specifies whether the timer is a one shot or periodic timer. To stop a periodic timer call stopTimer.

This code was developed with Visual C++ 5.0 and has been tested on NT 4.0.

The source follows:

The header file, mmTimers.h

#ifndef ___multimedia_timers___
#define ___multimedia_timers___


#include 

 

class CMMTimers
{
public:
 CMMTimers(UINT resolution);
 virtual ~CMMTimers();

 UINT getTimerRes() { return timerRes; };

 bool startTimer(UINT period,bool oneShot);
 bool stopTimer();

 virtual void timerProc() {};

protected:
 UINT timerRes;
 UINT timerId;
};


#endif 

The source file, mmTimers.cpp

#include "StdAfx.h"
#include "mmTimers.h"


CMMTimers::CMMTimers(UINT resolution) : timerRes(0), timerId(0)
{
 TIMECAPS tc;

 if (TIMERR_NOERROR == timeGetDevCaps(&tc,sizeof(TIMECAPS)))
 {
  timerRes = min(max(tc.wPeriodMin,resolution),tc.wPeriodMax);
  timeBeginPeriod(timerRes);
 }
}


CMMTimers::~CMMTimers()
{
 stopTimer();
 if (0 != timerRes)
 {
  timeEndPeriod(timerRes);
  timerRes = 0;
 }
}


extern "C"
void CALLBACK internalTimerProc(UINT id, UINT msg,
DWORD dwUser, DWORD dw1, DWORD dw2)
{
 CMMTimers * timer = (CMMTimers *)dwUser;

 timer->timerProc();
}


bool CMMTimers::startTimer(UINT period,bool oneShot)
{
 bool  res = false;
 MMRESULT result;

 result = timeSetEvent(period, timerRes, internalTimerProc,
 (DWORD)this,oneShot ? TIME_ONESHOT : TIME_PERIODIC);
 if (NULL != result)
 {
  timerId = (UINT)result;
  res = true;
 }

 return res;
}


bool CMMTimers::stopTimer()
{
 MMRESULT result;

 result = timeKillEvent(timerId);
 if (TIMERR_NOERROR == result)
  timerId = 0;

 return TIMERR_NOERROR == result;

DownLoad Source - 1KB

在编程和面向对象设计中,**encapsulate(封装)** 是指将数据(属性)和行为(方法)包装在一个类中,并控制对这些成员的访问。这种机制允许隐藏内部实现细节,仅暴露必要的接口供外部使用,从而提高代码的安全性、可维护性和模块化程度。 ### 封装的核心特性 1. **信息隐藏**:通过访问修饰符(如 `private`、`protected`、`public`)限制对类成员的直接访问。 2. **数据抽象**:只展示必要的接口,隐藏复杂实现。 3. **增强控制**:可以在访问或修改数据时加入验证逻辑,防止非法操作。 ### 示例说明 以下是一个使用封装的简单示例,展示如何通过 `private` 字段和 `public` 方法来控制对内部状态的访问: ```java public class BankAccount { private double balance; public BankAccount(double initialBalance) { if (initialBalance >= 0) { this.balance = initialBalance; } } public void deposit(double amount) { if (amount > 0) { balance += amount; } } public void withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; } } public double getBalance() { return balance; } } ``` 在这个例子中,`balance` 被声明为 `private`,因此外部无法直接修改其值。只能通过 `deposit()`、`withdraw()` 和 `getBalance()` 这些公共方法进行操作,这样可以确保余额不会被非法更改[^3]。 ### 使用封装的优势 - **安全性提升**:防止外部直接访问和修改敏感数据。 - **易于维护**:如果需要更改内部实现,只需调整类的方法,而无需修改调用方代码。 - **模块化设计**:不同模块之间通过接口通信,降低了耦合度。 ### 其他语言中的封装支持 在 Python 中,虽然没有严格的访问控制关键字,但可以通过命名约定(如 `_variable` 表示受保护变量,`__variable` 触发名称改写)来实现类似效果: ```python class Person: def __init__(self, name): self.__name = name # 私有变量 def get_name(self): return self.__name def set_name(self, name): if isinstance(name, str): self.__name = name ``` 此例中,`__name` 变量对外不可见,只能通过 `get_name()` 和 `set_name()` 方法安全地访问和修改[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值