C++的console使用windows的消息机制,定时器等

C++的console使用windows的消息。

大家在编写console中,估计需要使用windows消息机制 差不多是 定时器。

因此,在网上可以搜索到相关的内容。

youyulangzi的专栏 天行健,君子以自强不息

http://blog.csdn.net/youyulangzi/article/details/5841199 
 

转自博客:http://www.cnblogs.com/phinecos/archive/2008/03/08/1096691.html

作者:洞庭散人

我现在项目是一个控制台程序,用到的Win32API都是与界面无关的,今天需要加入定时器刷新的功能,由于没有消息循环,所以WM_TIMER消息应该如何处理呢?综合了下网上找到的资料,写了个简单的demo,个人以为这种在一个线程中创建定时器,再通过指定的回调函数来处理定时器触发的模式是比较好的。

感谢楼上的两位的工作,为了进一步方便后来者更好的使用。我在楼上的基础上进一步进行了封装。
可以除了定时器外,可以使用其他的消息,比如:WSAAsyncSelect 等消息。
使用定时器的代码例子为:
UINT myProcTimer(UINT _message, MSG* _data, void* _userdata)
{
	printf("WM_TIMER in work thread count/n");
	return 1;
}
int main(int argc, char* argv[])
{
	CWindowsMessageHelper* pThread = new CWindowsMessageHelper;
        ///开启线程
	pThread->start();
	///printf("start ...");
	UINT timerId = pThread->start_timer(10);
        ///用户自己增加消息处理
	pThread->addMessageHanler(WM_TIMER,  myProcTimer, NULL, timerId);
	Sleep(100);
        ///移除我们的TimerId. (如果不移除timerId, 只移除我们的消息处理函数,后面框架会自动将没有处理timer进行停止掉)
        pThread->stop_timer(timerId);
pThread->removeMessageHandler(WM_TIMER,myProcTimer);
	_getch();
        ///停止当前的线程.
	pThread->stop();
	_getch();
	delete pThread;
	return 0;
}
 
如果需要在此线程中处理业务逻辑,借用ruby 中 的 Celluloid里面的思想。
我们尽量将此逻辑放到此线程中来调用。因此我们可以用 	UINT doBusiness(WPFP_Do_Business _callbck, void* _data, UINT _bSync = 0);
来处理逻辑,其中_callback的回调函数是在新的线程中来调用的。 可以参考我们写的 start_timer 和 stop_timer 的函数。
_bSync 默认是0,意味着我们不等待_callback函数调用就返回。 如果为1,则意味着,我们需要在调用_callback之后,才返回。
希望下面的代码,能够给你带来方便。^_^ :)
 
代码:
/// CWindowsMessageHelper.hpp
#pragma warning(disable: 4786)
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <vector>
#include <map>


typedef void (*WPFP_Do_Business)(void* _data);


#define WM_DO_CHORE    (WM_USER + 200)
#define WM_DO_STOP_TIMER  (WM_DO_CHORE+1)


///处理返回非0,0表明其他handler可以继续处理.
typedef UINT (*WPFP_Process_Message)(UINT _message,MSG* _data,void* _userdata);
class CWindowsMessageHelper
{
public:
	CWindowsMessageHelper();
	~CWindowsMessageHelper();


	void start();
	void stop();
	
	UINT doBusiness(WPFP_Do_Business _callbck, void* _data);
	
	///_wParam 如果为0. 则将匹配_messageId都转发,否则只有_wParam匹配相等才转发.
	void addMessageHanler(UINT _messageId,WPFP_Process_Message _handler,void* _data, WPARAM _wParam = 0);
	void removeMessageHandler(UINT _messageId, WPFP_Process_Message _handler);


	UINT start_timer(UINT _elaseInMilliseconds);
	void stop_timer(UINT _timerId);

private:
	static DWORD CALLBACK mainThread(PVOID pvoid);
	static void  CALLBACK timeProc(HWND hWnd,UINT uMsg,UINT  idEvent,DWORD dwTime);
        static void start_timer_chore(void* _data);
	static void stop_timer_chore(void* _data);


	UINT processMessage(UINT _message, MSG* _data);


	static UINT  doChores_Callback(UINT _message,MSG* _data, void* _userdata);
	static UINT do_stop_timerCallback(UINT _messge, MSG* _data, void* _userdata);
	UINT  doChores(UINT _message,MSG* _data);


	void stop_timer_imp(UINT _timerId);
	 
private:  
	WPFP_Do_Business m_do_business;
	void* m_do_business_data;
	HANDLE m_thread;
	DWORD m_threadId;
	struct InnerData
	{
		WPARAM m_wParam;
		WPFP_Process_Message m_process;
		void* m_pUserData;
	};	
	std::map<UINT, std::vector<InnerData> > m_handleMessage;
	HANDLE m_event;
};
 
 
 
/// CWindowsMessageHelper.cpp
#include "CWindowsMessageHelper.hpp"
CWindowsMessageHelper::CWindowsMessageHelper()
{
	m_do_business = NULL;
	m_thread = NULL;
	m_threadId = 0;
	addMessageHanler(WM_DO_CHORE, doChores_Callback,this);
	addMessageHanler(WM_DO_STOP_TIMER, do_stop_timerCallback,this);
	m_event = CreateEvent(NULL,TRUE,FALSE,NULL);
}


CWindowsMessageHelper::~CWindowsMessageHelper()
{
  CloseHandle(m_event);
}





UINT CWindowsMessageHelper::doBusiness(WPFP_Do_Business _callbck,void* _data,UINT _bSync)
{
	if(m_do_business) return 0;
	if(!_callbck) return 0;


	m_do_business = _callbck;
	m_do_business_data = _data;
	PostThreadMessage(m_threadId,WM_DO_CHORE, 0,0);


	if(_bSync)
	{
	  WaitForSingleObject(m_event,INFINITE);
	  ResetEvent(m_event);
	}
	return 1;
}
UINT  CWindowsMessageHelper::doChores_Callback(UINT _message, MSG* _data, void* _userdata)
{
	CWindowsMessageHelper* pThis = (CWindowsMessageHelper*) _userdata;
	return pThis->doChores(_message,_data);
}
UINT CWindowsMessageHelper::do_stop_timerCallback(UINT _messge, MSG* _data, void* _userdata)
{
	CWindowsMessageHelper* pThis = (CWindowsMessageHelper*) _userdata;
	pThis->stop_timer_imp(_data->wParam);
	return 1;
}


UINT  CWindowsMessageHelper::doChores(UINT _message, MSG* _data)
{
	WPFP_Do_Business callback = m_do_business;
	void* userData = m_do_business_data;
	m_do_business_data = NULL;
	m_do_business = NULL;
	if(callback)
	{
	 callback(userData);
	 SetEvent(m_event);
	}
	return 1;
}
struct CData_Timer
{
	CWindowsMessageHelper* m_pThis;
	UINT m_timerId;
	UINT m_idEvent;
	UINT m_elapse;


};
void CWindowsMessageHelper::start_timer_chore(void* _data)
{
	CData_Timer* pData = (CData_Timer*)_data;
	
    UINT timerId = SetTimer(NULL,pData->m_idEvent, pData->m_elapse,CWindowsMessageHelper::timeProc);
	pData->m_timerId = timerId;
}


void CWindowsMessageHelper::stop_timer_chore(void* _data)
{
	CData_Timer* pData = (CData_Timer*)_data;
	pData->m_pThis->stop_timer_imp(pData->m_timerId);
}
UINT CWindowsMessageHelper::start_timer(UINT _elaseInMilliseconds)
{
	CData_Timer timerData;
	timerData.m_elapse = _elaseInMilliseconds;
	timerData.m_idEvent = WM_USER+1;
	timerData.m_pThis = this;
	UINT timerId = 0;
	doBusiness(start_timer_chore, &timerData, 1);
	timerId = timerData.m_timerId;
	return timerId;
}


void CWindowsMessageHelper::stop_timer(UINT _timerId)
{
	CData_Timer timerData;
	timerData.m_pThis = this;
	timerData.m_timerId = _timerId;
	doBusiness(stop_timer_chore, &_timerId,1);
}
void CWindowsMessageHelper::stop_timer_imp(UINT _timerId)
{
  KillTimer(NULL,_timerId);
}
void CWindowsMessageHelper::start()
{
	HANDLE hand = CreateThread(NULL,0,CWindowsMessageHelper::mainThread, this,0,&m_threadId);
	WaitForSingleObject(m_event,INFINITE);
	ResetEvent(m_event);
	m_thread = hand;
}
void CWindowsMessageHelper::stop()
{
  PostThreadMessage(m_threadId, WM_QUIT,0,0);
}
void CWindowsMessageHelper::timeProc(HWND hWnd,UINT uMsg,UINT  idEvent,DWORD dwTime)
{
	DWORD threadId = GetCurrentThreadId();
	///用户没有截获此消息,我们停止此定时器.
	PostThreadMessage(threadId, WM_DO_STOP_TIMER, idEvent,dwTime);
}




void CWindowsMessageHelper::addMessageHanler(UINT _messageId,WPFP_Process_Message _handler, void* _data, WPARAM _wParam)
{
	InnerData innerData = {_wParam, _handler, _data};
	if(_handler == NULL) return;
	std::vector<InnerData>& vec = m_handleMessage[_messageId];
	std::vector<InnerData>::iterator iter = vec.begin();
	std::vector<InnerData>::iterator iterEnd = vec.end();
	while(iter != iterEnd)
	{
	  if(iter->m_process == _handler)
	  {
		///替换.
		*iter = innerData;
		return;
	  }
	  iter++;
	}
	vec.push_back(innerData);
}
void CWindowsMessageHelper::removeMessageHandler(UINT _messageId, WPFP_Process_Message _handler)
{
	std::vector<InnerData>& vec = m_handleMessage[_messageId];
	std::vector<InnerData>::iterator iter = vec.begin();
	std::vector<InnerData>::iterator iterEnd = vec.end();
	while(iter != iterEnd)
	{
		if(iter->m_process == _handler)
		{
			vec.erase(iter);
			return;
		}
		iter++;
	}
}
UINT CWindowsMessageHelper::processMessage(UINT _messageId, MSG* _data)
{
	UINT ret = 0;
	
	std::vector<InnerData>& vec = m_handleMessage[_messageId];
	std::vector<InnerData>::iterator iter = vec.begin();
	std::vector<InnerData>::iterator iterEnd = vec.end();
	while(iter != iterEnd)
	{
		WPFP_Process_Message& call = iter->m_process;
		if(_data->wParam == iter->m_wParam || iter->m_wParam == 0)
		{
			ret = call(_messageId, _data,iter->m_pUserData);		
		}
		if(ret != 0 ) break;
		iter++;
	}
	return ret;
}


DWORD CALLBACK CWindowsMessageHelper::mainThread(PVOID pvoid)
{
	CWindowsMessageHelper* pThread = (CWindowsMessageHelper*)pvoid;
	MSG msg;
	SetEvent(pThread->m_event);
	
	//PeekMessage(&msg,NULL,WM_USER,WM_USER,PM_NOREMOVE);
	BOOL bRet;
	while ((bRet = GetMessage(&msg,NULL,0,0))!=0)
	{
		if (bRet == -1)
		{
			printf("Error:the thread will quit,error id is %d/n",GetLastError());
			break;
		}
		else
		{
			TranslateMessage(&msg);
			if(pThread->processMessage(msg.message,&msg) == 0)
			{
			  DispatchMessage(&msg);
			}
		}
	}
	printf("thread end here/n");
	return 0;
}

如果需要转帖,请注明原始链接: http://blog.csdn.net/wu4long/article/details/7324965 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值