程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 用Windows消息循環實現消息延遲和合並

用Windows消息循環實現消息延遲和合並

編輯:關於VC++

最初的解決方法是為計算消息設定時間間隔:當一個計算消息到達時,開始計時,在一定時間間隔內,接受到的計算消息一概不處理。由於時間間隔沒法給定,也沒法進行預算。時間間隔設置長了,如果兩次操作過快,就會漏算;設置時間短了,又無法解決計算此數過多的問題。所以這個解決方法只能算是延緩了問題,而不能算是解決問題。

後來,不知道什麼時候靈機一動,想到了下面的方法,完美的解決了問題。這對於我這個菜鳥來說,還是有紀念意義的。

我的解決思想是:制作一個合並消息的類。利用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*)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved