最初的解决方法是为计算消息设定时间间隔:当一个计算消息到达时,开始计时,在一定时间间隔内,接受到的计算消息一概不处理。由于时间间隔没法给定,也没法进行预算。时间间隔设置长了,如果两次操作过快,就会漏算;设置时间短了,又无法解决计算此数过多的问题。所以这个解决方法只能算是延缓了问题,而不能算是解决问题。
后来,不知道什么时候灵机一动,想到了下面的方法,完美的解决了问题。这对于我这个菜鸟来说,还是有纪念意义的。
我的解决思想是:制作一个合并消息的类。利用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 > 1000
class 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<MERGE_MES_HEADER*, MERGE_MES_HEADER*> 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_FILE static 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<CFepMergeMessage> pDlgMergeMessage(NULL);
CFepMergeMessage::CFepMergeMessage() { m_bMessagePosted = FALSE; Create(); }
CFepMergeMessage::~CFepMergeMessage() { for(int i=0; i<m_rgMessage.GetSize(); ++i) { delete m_rgMessage.GetAt(i); } m_rgMessage.RemoveAll(); }
BEGIN_MESSAGE_MAP(CFepMergeMessage, CDialog) ON_MESSAGE(WM_MERGE_MESSAGE, OnMergeMessage) ON_MESSAGE(WM_PROCESS_MESSAGE, OnProcessMessage) END_MESSAGE_MAP()
//**************************************************************************** // Function CFepMergeMessage::Create // @mfunc // @rdesc TRUE if the function succeeds; otherwise, FALSE.(BOOL) // @xref <c CFepMergeMessage > //**************************************************************************** // @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 <c CFepMergeMessage > //**************************************************************************** // @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 <c CFepMergeMessage > //**************************************************************************** // @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; i<m_rgMessage.GetSize(); ++i) { MERGE_MES_HEADER* pMes = m_rgMessage.GetAt(i); if(pNewMes->IsKindOf(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 <c CFepMergeMessage > //**************************************************************************** // @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*)。
 
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
|