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