Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14523492
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:03:12

下载本文示例代码
  最初的解决方法是为计算消息设定时间间隔:当一个计算消息到达时,开始计时,在一定时间间隔内,接受到的计算消息一概不处理。由于时间间隔没法给定,也没法进行预算。时间间隔设置长了,如果两次操作过快,就会漏算;设置时间短了,又无法解决计算此数过多的问题。所以这个解决方法只能算是延缓了问题,而不能算是解决问题。   后来,不知道什么时候灵机一动,想到了下面的方法,完美的解决了问题。这对于我这个菜鸟来说,还是有纪念意义的。  我的解决思想是:制作一个合并消息的类。利用Window消息循环,当消息到达时,并不立即处理,只是将参数存起来。如果是第一个消息,则向自己Post一个处理消息。当Post的处理消息到达时采取真正的调用应该调用的函数。  后来,要求使用这种功能的模块增加,我就将它实现为能容纳多个需要合并消息的工具类。代码如下:  //****************************************************************************// D L G C S O F T W A R E C O.//****************************************************************************// Filename: FepMergeMessage.h // Project: FEP V4 6.0 // Module: // Programmer: Ma Nan // Version: Version 1.00 // Revision Date: 2006/12/04 //****************************************************************************// Description: Declaration of class CFepMergeMessage //****************************************************************************// Revision history: // 2006/12/04 - First implementation //****************************************************************************// Bugs: ........ //****************************************************************************// @doc //****************************************************************************// FepMergeMessage.h: interface for the CFepMergeMessage class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_FEPMERGEMESSAGE_H__D60309AA_9DA0_4474_9DC0_EDFF72E7165C__INCLUDED_)#define AFX_FEPMERGEMESSAGE_H__D60309AA_9DA0_4474_9DC0_EDFF72E7165C__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class MERGE_MES_HEADER;typedef void (*MergeMesCallBack)(const MERGE_MES_HEADER* lpMergMes);class MERGE_MES_HEADER : public CObject{ DECLARE_DYNAMIC(MERGE_MES_HEADER); MergeMesCallBack pfnCallBack; virtual MERGE_MES_HEADER* Clone() const = 0; virtual BOOL IsSameMes(const MERGE_MES_HEADER* pMes) const = 0;};//****************************************************************************// @class CFepMergeMessage | // CFepMergeMessage is used to // // @base CDialog//****************************************************************************// @ex// This shows how to call CFepMergeMessage : |// // // //****************************************************************************// @prog // Ma Nan// @revs // 2006/12/04 - First implementation//****************************************************************************// @todo //****************************************************************************class CFepMergeMessage : public CDialog{ public:  CFepMergeMessage();  virtual ~CFepMergeMessage();  static BOOL Excute(const MERGE_MES_HEADER* pParam); protected:  //create the dialog to deal the message  BOOL Create(); protected:  afx_msg LRESULT OnMergeMessage(WPARAM wParam, LPARAM lParam);  afx_msg LRESULT OnProcessMessage(WPARAM wParam, LPARAM lParam);  DECLARE_MESSAGE_MAP() protected:  CArray m_rgMessage;  BOOL m_bMessagePosted;};#endif // !defined(AFX_FEPMERGEMESSAGE_H__D60309AA_9DA0_4474_9DC0_EDFF72E7165C__INCLUDED_)///////////////////////////////FepMergeMessage.cpp////////////////////////////#include "StdAfx.h"#include "FepMergeMessage.h"#include "../Include/FepPtr.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif#define WM_MERGE_MESSAGE WM_USER 100#define WM_PROCESS_MESSAGE WM_USER 200////////////////////////////////////////////////////////////////////////////struct MERGE_MES_HEADER//////////////////////////////////////////////////////////////////////////IMPLEMENT_DYNAMIC(MERGE_MES_HEADER, CObject)//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////static CFepPtr pDlgMergeMessage(NULL);CFepMergeMessage::CFepMergeMessage(){ m_bMessagePosted = FALSE; Create();}CFepMergeMessage::~CFepMergeMessage(){ for(int i=0; i //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************BOOL CFepMergeMessage::Create(){ if(GetSafeHwnd() != NULL) {  return TRUE; } DWORD dwDlgTempl[100]; ZeroMemory(dwDlgTempl, sizeof(DWORD)*100); DLGTEMPLATE* pDlgTmp = (DLGTEMPLATE*)dwDlgTempl; pDlgTmp->style = WS_POPUP | DS_CONTROL; pDlgTmp->cx = 1; pDlgTmp->cy = 1; return CDialog::CreateIndirect(pDlgTmp);}//****************************************************************************// Function CFepMergeMessage::Excute // @mfunc // @rdesc TRUE if the function succeeds; otherwise, FALSE.(BOOL) // @parm const MERGE_MES_HEADER* | pParam | a pointer to const MERGE_MES_HEADER // @xref //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************BOOL CFepMergeMessage::Excute(const MERGE_MES_HEADER* pParam){ // dlgMergeMes.SendMessage(WM_MERGE_MESSAGE, (WPARAM)pParam, 0); if(pDlgMergeMessage.m_pPtr == NULL) {  pDlgMergeMessage.m_pPtr = new CFepMergeMessage; } if(pDlgMergeMessage->GetSafeHwnd() == NULL) {  return FALSE; } pDlgMergeMessage->SendMessage(WM_MERGE_MESSAGE, (WPARAM)pParam, 0); return TRUE;}//****************************************************************************// Function CFepMergeMessage::OnMergeMessage // @mfunc // @rdesc (LRESULT) // @parm WPARAM | wParam | // @parm | LPARAM | // @xref //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************LRESULT CFepMergeMessage::OnMergeMessage(WPARAM wParam, LPARAM){ const MERGE_MES_HEADER* pNewMes = (const MERGE_MES_HEADER*)wParam; for(int i=0; iIsKindOf(pMes->GetRuntimeClass()) && pNewMes->IsSameMes(pMes))  {   delete pMes;   m_rgMessage.RemoveAt(i);   --i;  } } m_rgMessage.Add(pNewMes->Clone()); if(!m_bMessagePosted) {  PostMessage(WM_PROCESS_MESSAGE, 0, 0);  m_bMessagePosted = TRUE; } return 0L;}//****************************************************************************// Function CFepMergeMessage::OnProcessMessage // @mfunc // @rdesc (LRESULT) // @parm | WPARAM | // @parm | LPARAM | // @xref //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************LRESULT CFepMergeMessage::OnProcessMessage(WPARAM, LPARAM){ while(m_rgMessage.GetSize() > 0) {  MERGE_MES_HEADER* pHeader = m_rgMessage.GetAt(0);  pHeader->pfnCallBack(pHeader);  delete pHeader;  m_rgMessage.RemoveAt(0); } m_bMessagePosted = FALSE; return 0L;}  说明:  MERGE_MES_HEADER是一个参数类,每一个要使用这个工具类的都需要自己派生一个参数类。  参数类需要完成的任务有:  1. 执行函数。  2. 是否是同一消息的ID。  这个参数类由以下部分组成:  1. pfnCallBack。回调函数,真正要执行的函数。  2. Clone()。这是一个虚函数,因为这个参数需要存起来,使用这个函数可以实现参数复制。  3. IsSameMes()。这是一个虚函数,在CFepMergeMessage调用这个函数时,已经为其判断了类型。重写这个函数判断传入的参数是否为同一参数。  这三个变量/虚函数在派生类中一定要进行复制或重写。  使用时很简单,生命一个参数对象,调用CFepMergeMessage::Excute(const MERGE_MES_HEADER*)。  查看关于 Windows消息 的全部文档  相关技术:黑客之旅初始篇:原始套接字透析 ·VC入门专区 ·VC高级技术专区 E夏Java轻松行 JBuilder 2005全接触 从老虎到野马 Java 6.0新功能观察 ·VC网络通讯编程 ·VC图像编程 ·轻松玩转MFC文档视图架构编程 ·深入浅出Win32多线程程序设计 ·深入浅出Visual C 动态链接库编程   最初的解决方法是为计算消息设定时间间隔:当一个计算消息到达时,开始计时,在一定时间间隔内,接受到的计算消息一概不处理。由于时间间隔没法给定,也没法进行预算。时间间隔设置长了,如果两次操作过快,就会漏算;设置时间短了,又无法解决计算此数过多的问题。所以这个解决方法只能算是延缓了问题,而不能算是解决问题。   后来,不知道什么时候灵机一动,想到了下面的方法,完美的解决了问题。这对于我这个菜鸟来说,还是有纪念意义的。  我的解决思想是:制作一个合并消息的类。利用Window消息循环,当消息到达时,并不立即处理,只是将参数存起来。如果是第一个消息,则向自己Post一个处理消息。当Post的处理消息到达时采取真正的调用应该调用的函数。  后来,要求使用这种功能的模块增加,我就将它实现为能容纳多个需要合并消息的工具类。代码如下:  //****************************************************************************// D L G C S O F T W A R E C O.//****************************************************************************// Filename: FepMergeMessage.h // Project: FEP V4 6.0 // Module: // Programmer: Ma Nan // Version: Version 1.00 // Revision Date: 2006/12/04 //****************************************************************************// Description: Declaration of class CFepMergeMessage //****************************************************************************// Revision history: // 2006/12/04 - First implementation //****************************************************************************// Bugs: ........ //****************************************************************************// @doc //****************************************************************************// FepMergeMessage.h: interface for the CFepMergeMessage class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_FEPMERGEMESSAGE_H__D60309AA_9DA0_4474_9DC0_EDFF72E7165C__INCLUDED_)#define AFX_FEPMERGEMESSAGE_H__D60309AA_9DA0_4474_9DC0_EDFF72E7165C__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class MERGE_MES_HEADER;typedef void (*MergeMesCallBack)(const MERGE_MES_HEADER* lpMergMes);class MERGE_MES_HEADER : public CObject{ DECLARE_DYNAMIC(MERGE_MES_HEADER); MergeMesCallBack pfnCallBack; virtual MERGE_MES_HEADER* Clone() const = 0; virtual BOOL IsSameMes(const MERGE_MES_HEADER* pMes) const = 0;};//****************************************************************************// @class CFepMergeMessage | // CFepMergeMessage is used to // // @base CDialog//****************************************************************************// @ex// This shows how to call CFepMergeMessage : |// // // //****************************************************************************// @prog // Ma Nan// @revs // 2006/12/04 - First implementation//****************************************************************************// @todo //****************************************************************************class CFepMergeMessage : public CDialog{ public:  CFepMergeMessage();  virtual ~CFepMergeMessage();  static BOOL Excute(const MERGE_MES_HEADER* pParam); protected:  //create the dialog to deal the message  BOOL Create(); protected:  afx_msg LRESULT OnMergeMessage(WPARAM wParam, LPARAM lParam);  afx_msg LRESULT OnProcessMessage(WPARAM wParam, LPARAM lParam);  DECLARE_MESSAGE_MAP() protected:  CArray m_rgMessage;  BOOL m_bMessagePosted;};#endif // !defined(AFX_FEPMERGEMESSAGE_H__D60309AA_9DA0_4474_9DC0_EDFF72E7165C__INCLUDED_)///////////////////////////////FepMergeMessage.cpp////////////////////////////#include "StdAfx.h"#include "FepMergeMessage.h"#include "../Include/FepPtr.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif#define WM_MERGE_MESSAGE WM_USER 100#define WM_PROCESS_MESSAGE WM_USER 200////////////////////////////////////////////////////////////////////////////struct MERGE_MES_HEADER//////////////////////////////////////////////////////////////////////////IMPLEMENT_DYNAMIC(MERGE_MES_HEADER, CObject)//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////static CFepPtr pDlgMergeMessage(NULL);CFepMergeMessage::CFepMergeMessage(){ m_bMessagePosted = FALSE; Create();}CFepMergeMessage::~CFepMergeMessage(){ for(int i=0; i //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************BOOL CFepMergeMessage::Create(){ if(GetSafeHwnd() != NULL) {  return TRUE; } DWORD dwDlgTempl[100]; ZeroMemory(dwDlgTempl, sizeof(DWORD)*100); DLGTEMPLATE* pDlgTmp = (DLGTEMPLATE*)dwDlgTempl; pDlgTmp->style = WS_POPUP | DS_CONTROL; pDlgTmp->cx = 1; pDlgTmp->cy = 1; return CDialog::CreateIndirect(pDlgTmp);}//****************************************************************************// Function CFepMergeMessage::Excute // @mfunc // @rdesc TRUE if the function succeeds; otherwise, FALSE.(BOOL) // @parm const MERGE_MES_HEADER* | pParam | a pointer to const MERGE_MES_HEADER // @xref //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************BOOL CFepMergeMessage::Excute(const MERGE_MES_HEADER* pParam){ // dlgMergeMes.SendMessage(WM_MERGE_MESSAGE, (WPARAM)pParam, 0); if(pDlgMergeMessage.m_pPtr == NULL) {  pDlgMergeMessage.m_pPtr = new CFepMergeMessage; } if(pDlgMergeMessage->GetSafeHwnd() == NULL) {  return FALSE; } pDlgMergeMessage->SendMessage(WM_MERGE_MESSAGE, (WPARAM)pParam, 0); return TRUE;}//****************************************************************************// Function CFepMergeMessage::OnMergeMessage // @mfunc // @rdesc (LRESULT) // @parm WPARAM | wParam | // @parm | LPARAM | // @xref //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************LRESULT CFepMergeMessage::OnMergeMessage(WPARAM wParam, LPARAM){ const MERGE_MES_HEADER* pNewMes = (const MERGE_MES_HEADER*)wParam; for(int i=0; iIsKindOf(pMes->GetRuntimeClass()) && pNewMes->IsSameMes(pMes))  {   delete pMes;   m_rgMessage.RemoveAt(i);   --i;  } } m_rgMessage.Add(pNewMes->Clone()); if(!m_bMessagePosted) {  PostMessage(WM_PROCESS_MESSAGE, 0, 0);  m_bMessagePosted = TRUE; } return 0L;}//****************************************************************************// Function CFepMergeMessage::OnProcessMessage // @mfunc // @rdesc (LRESULT) // @parm | WPARAM | // @parm | LPARAM | // @xref //****************************************************************************// @prog // Ma Nan // @revs // 2006/12/04 First implementation//****************************************************************************// @todo // //****************************************************************************LRESULT CFepMergeMessage::OnProcessMessage(WPARAM, LPARAM){ while(m_rgMessage.GetSize() > 0) {  MERGE_MES_HEADER* pHeader = m_rgMessage.GetAt(0);  pHeader->pfnCallBack(pHeader);  delete pHeader;  m_rgMessage.RemoveAt(0); } m_bMessagePosted = FALSE; return 0L;}  说明:  MERGE_MES_HEADER是一个参数类,每一个要使用这个工具类的都需要自己派生一个参数类。  参数类需要完成的任务有:  1. 执行函数。  2. 是否是同一消息的ID。  这个参数类由以下部分组成:  1. pfnCallBack。回调函数,真正要执行的函数。  2. Clone()。这是一个虚函数,因为这个参数需要存起来,使用这个函数可以实现参数复制。  3. IsSameMes()。这是一个虚函数,在CFepMergeMessage调用这个函数时,已经为其判断了类型。重写这个函数判断传入的参数是否为同一参数。  这三个变量/虚函数在派生类中一定要进行复制或重写。  使用时很简单,生命一个参数对象,调用CFepMergeMessage::Excute(const MERGE_MES_HEADER*)。  查看关于 Windows消息 的全部文档  相关技术:黑客之旅初始篇:原始套接字透析 ·VC入门专区 ·VC高级技术专区 E夏Java轻松行 JBuilder 2005全接触 从老虎到野马 Java 6.0新功能观察 ·VC网络通讯编程 ·VC图像编程 ·轻松玩转MFC文档视图架构编程 ·深入浅出Win32多线程程序设计 ·深入浅出Visual C 动态链接库编程 下载本文示例代码


用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并用Windows消息循环实现消息延迟和合并
阅读(184) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~