没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2004-11-15 14:11:00.000|阅读 1786 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
在Window编程中,我们经常要依靠定时器来定时触发某些代码的执行。但在ATL 的ActiveX 编程中,定时器的使用受到了一定限制,下面,我就根据开发经验谈谈如何在ATL 的 ActiveX编程中使用定时器这一资源。
首先,为了优化的性能,当前ActiveX 控件 分两种有窗口和无窗口控件。
在有窗口控件中你所获得的编程资源几乎和普通的Windows编程没有两样,而定时器的使用也一样。在ATL中你只要在控件的构造函数中指定控件基类CComControlBase 的成员m_bWindowOnly 为 true 就可以创建一个有窗口的ActiveX控件。示例如下:
myControl : myControl(){
m_bWindowOnly = true;
}
这样就可以在程序中用 SetTimer/KillTimer 和 响应 WM_TIMER消息来设置并使用定时器。
当作为一个ATL程序员,我们当然不会放弃每一个优化程序性能的机会,下面我就来介绍一下在ATL中的无窗口ActiveX控件中使用定时器的几种方法:
第一种:使用回调函数。在VC中,由于MFC和ATL了包装,我们可以忽略窗口句柄参数,直接创建一个和窗口关联的定时器。当无窗口控件由于没有窗口句柄,直接调用CWindow的SetTimer函数会给你抛出一个ASSERT对话框来。这时候我们只好回到API来寻求帮助, 由于 API SetTimer在创建一个定时器时除了窗口句柄,还为我们提供了通过回调函数来响应定时事件,这样,我们就可以绕过无窗口控件的约束使用定时器了。
首先,定义一个定时器的回调函数:
VOID CALLBACK TimerProc(
HWND hwnd, // 定时器消息的窗口句柄
UINT message, // WM_TIMER 消息
UINT idTimer, // 定时器标志
DWORD dwTime) // 当前系统启动计时
{
//这里添加你的定时器处理代码
}
接下来,就可以使用SetTimer来使用定时器了
uResult = SetTimer(NULL, // handle to main window
ID_TIMER, // 定时器标识
1000, // 1 秒间隔
(TIMERPROC)TimerProc); // 回调函数
第二种:通常我们在使用定时器时,往往希望在定时事件出发时可以通知自己的ActiveX 控件,虽然上面方法可以,但在参数的传递上有些不便,这里我使用多线程来模拟实习之,作为ATL中的编程风格,在向实现类添加某些功能,通常使用模板基类来扩充,故首先定义如下基类:
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// 多线程模拟定时器
// 因 无窗口ATICVX 控件不能直接使用Timer, 而且为了保证定时的准确和精度,所以使用之
// 无窗口还可以通过 回调过程方式使用 Timer 但精度不能保证,所以此处排出
//
template <class Derived, class T, const IID* piid>
class CTimer
{
public:
CTimer()
{
m_bTimerOn = FALSE;
}
HRESULT TimerOn(DWORD dwTimerInterval)
{
Derived* pDerived = ((Derived*)this);
m_dwTimerInterval = dwTimerInterval;
if (m_bTimerOn) // 已经启动,仅仅调整定时间隔
return S_OK;
m_bTimerOn = TRUE;
m_dwTimerInterval = dwTimerInterval;
m_pStream = NULL;
HRESULT hRes;
// 接口列集
hRes = CoMarshalInterThreadInterfaceInStream(*piid, (T*)pDerived, &m_pStream);
// 创建线程并传递 this 指针
m_hThread = CreateThread(NULL, 0, &_Apartment, (void*)this, 0, &m_dwThreadID);
return S_OK;
}
void TimerOff()
{
if (m_bTimerOn)
{
m_bTimerOn = FALSE;
AtlWaitWithMessageLoop(m_hThread);
}
}
// 实现函数
private:
static DWORD WINAPI _Apartment(void* pv)
{
CTimer<Derived, T, piid>* pThis = (CTimer<Derived, T, piid>*) pv;
pThis->Apartment();
return 0;
}
DWORD Apartment()
{
CoInitialize(NULL);
HRESULT hRes;
m_spT.Release();
//接口散集
if (m_pStream)
hRes = CoGetInterfaceAndReleaseStream(m_pStream, *piid, void**)&m_spT);
while(m_bTimerOn)
{
Sleep(m_dwTimerInterval);
if (!m_bTimerOn)
break;
m_spT->OnTimer();
}
m_spT.Release();
CoUninitialize();
return 0;
}
// 属性
public:
DWORD m_dwTimerInterval;
// 实现属性
private:
HANDLE m_hThread;
DWORD m_dwThreadID;
LPSTREAM m_pStream;
CComPtr<T> m_spT;
BOOL m_bTimerOn;
};
从基类中可以看到,在线程函数中定时调用子类的OnTimer接口函数。这样我们只要从CTimer 中派生,并在子类接口中定义OnTimer接口,并实现该接口函数,就可以获得定时的调用,而TimerOn则用来开始并指定定时间隔,而TimerOff则用来关闭定时器。子类的代码如下:
////////////////////////////////////////////////////////////////////////////
//
// 类: CMyControl
// 功能: 示例 ActiveX 控件实现
//
class ATL_NO_VTABLE CMyControl :
// ... 其他接口
// 模拟定时器的支持
public CTimer<CMyControl , IMyControl, &IID_IMyControl>
{
public:
STDMETHOD(OnTimer)(void);
};
// 实现
STDMETHODIMP CCFuelWatchObj::OnTimer(void)
{
//定时响应代码
}
声明:方法二参考了MSDN中相关资料。
后记:实际上,在无窗口ActiveX控件中使用定时器的方法是很多,在这里只概述了两种。原本想就ATL中使用定时器这一功能进行比较详细描述,但由于中间工作原因间断,现在思源枯竭,只能写这些勒,如果这篇文章对于初次接触 ATL ActiveX 控件编程朋友有所参考,那在下就很感激了。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号