CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  进程/线程/DLL

如何创建一个具有消息循环 但是没有界面的子线程啊? 可以响应计时器消息

楼主AntonlioX(做人要厚道)2005-05-23 10:00:18 在 VC/MFC / 进程/线程/DLL 提问

如何创建一个具有消息循环   但是没有界面的子线程啊?   可以响应计时器消息 问题点数:20、回复次数:22Top

1 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:02:29 得分 0

是不是需要创建一个窗口才行啊?Top

2 楼etre(林荃)回复于 2005-05-23 10:06:06 得分 8

class   CThreadBase  
  {  
  public:  
  CThreadBase();  
   
  protected:  
  virtual   ~CThreadBase();  
   
  //   Operationen  
  public:  
  DWORD   m_dwThreadId;  
  HANDLE   m_hThread;  
  BOOL   Create(int   nPriority   =   THREAD_PRIORITY_NORMAL,   DWORD   dwCreateFlags   =   0);  
  DWORD   SuspendThread();  
  DWORD   ResumeThread();  
  BOOL   PostThreadMessage(   UINT   message   ,   WPARAM   wParam,   LPARAM   lParam   );  
  BOOL   SetPriority(int   nPriority);  
   
  protected:  
  virtual   int   OnThreadMessage(UINT   Msg,   WPARAM   wParam,   LPARAM   lParam);  
  virtual   BOOL   InitInstance();  
  virtual   DWORD   ExitInstance();  
  DWORD   Run();  
  static   DWORD   WINAPI   ThreadProc(LPVOID   lpParameter);  
  HANDLE   m_hEventStarted;  
  bool   m_started;;  
  };  
   
  Top

3 楼etre(林荃)回复于 2005-05-23 10:06:26 得分 0

 
   
  CThreadBase::CThreadBase()  
  {  
  m_hThread   =   0;  
  m_dwThreadId   =   NULL;  
  m_hEventStarted   =   CreateEvent(0,   FALSE,   FALSE,   NULL);  
  m_started   =   false;  
  }  
   
  CThreadBase::~CThreadBase()  
  {  
  CloseHandle(m_hEventStarted);  
  CloseHandle(m_hThread);  
  }  
   
  BOOL   CThreadBase::Create(int   nPriority   /*=THREAD_PRIORITY_NORMAL*/,   DWORD   dwCreateFlags   /*=0*/)  
  {  
  m_hThread=CreateThread(0,   0,   ThreadProc,   this,   dwCreateFlags,   &m_dwThreadId);  
  if   (!m_hThread)  
  {  
  delete   this;  
  return   FALSE;  
  }  
  ::SetThreadPriority(m_hThread,   nPriority);  
  return   TRUE;  
  }  
   
  BOOL   CThreadBase::PostThreadMessage(UINT   message,   WPARAM   wParam,   LPARAM   lParam)  
  {  
  BOOL   res=::PostThreadMessage(m_dwThreadId,   message,   wParam,   lParam);;  
  ASSERT(res);  
  return   res;  
  }  
   
  DWORD   CThreadBase::ResumeThread()  
  {  
  DWORD   res=::ResumeThread(m_hThread);  
  if   (!m_started)  
  {  
  WaitForSingleObject(m_hEventStarted,   INFINITE);  
  }  
  return   res;  
  }  
   
  DWORD   CThreadBase::SuspendThread()  
  {  
  return   ::SuspendThread(m_hThread);  
  }  
   
  DWORD   WINAPI   CThreadBase::ThreadProc(LPVOID   lpParameter)  
  {  
  return   ((CThreadBase   *)lpParameter)->Run();  
  }  
   
  DWORD   CThreadBase::Run()  
  {  
  InitInstance();  
  SetEvent(m_hEventStarted);  
  m_started   =   true;  
  MSG   msg;  
  while   (GetMessage(&msg,   0,   0,   0))  
  {  
  TranslateMessage(&msg);  
  if   (!msg.hwnd)  
  OnThreadMessage(msg.message,   msg.wParam,   msg.lParam);  
  DispatchMessage(&msg);  
  }  
  DWORD   res=ExitInstance();  
  delete   this;  
  return   res;  
  }  
   
  int   CThreadBase::OnThreadMessage(UINT   Msg,   WPARAM   wParam,   LPARAM   lParam)  
  {  
  return   0;  
  }  
   
  BOOL   CThreadBase::InitInstance()  
  {  
  return   TRUE;  
  }  
   
  DWORD   CThreadBase::ExitInstance()  
  {  
  return   0;  
  }  
   
  BOOL   CThreadBase::SetPriority(int   nPriority)  
  {  
  if   (!m_hThread)  
  return   false;  
   
  return   ::SetThreadPriority(m_hThread,   nPriority);  
  }Top

4 楼etre(林荃)回复于 2005-05-23 10:07:52 得分 0

在OnThreadMessage中实现if   (Msg   ==   WM_TIMER)  
  OnTimer(wParam,   lParam);Top

5 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:21:58 得分 0

CThreadBase   不是MFC的类   啊?Top

6 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:23:01 得分 0

如何使用啊?Top

7 楼etre(林荃)回复于 2005-05-23 10:40:51 得分 0

CThreadBase   是的啊.你继承他就行了Top

8 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:53:08 得分 0

thanksTop

9 楼AntonlioX(做人要厚道)回复于 2005-05-23 10:54:48 得分 0

从你的给的类的定义中,CThreadBase不是从CWinThread派生的啊  
   
  class   CThreadBase  
  {  
  public:  
  CThreadBase();  
   
  protected:  
  virtual   ~CThreadBase();  
   
  //   Operationen  
  public:  
  DWORD   m_dwThreadId;  
  HANDLE   m_hThread;Top

10 楼idAnts(此广告位招租)回复于 2005-05-23 10:56:15 得分 0

给你个简单的例子,线程设定时器:  
  UINT_PTR   hTimer   =   0;  
  VOID   __stdcall   TimerProc(HWND   hwnd,UINT   uMsg,UINT_PTR   idEvent,DWORD   dwTime)  
  {  
  KillTimer(NULL,hTimer);  
  MessageBox(NULL,"Speak   in   Timer!",":)",MB_OK);  
  }  
   
  DWORD   __stdcall   ThreadFun(void   *)  
  {  
  MSG   msg;  
  PeekMessage(&msg,   NULL,   NULL,   NULL,   PM_NOREMOVE);  
  hTimer   =   SetTimer(NULL,0,10,(TIMERPROC)TimerProc);  
  while(!PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_NOREMOVE))  
  {  
  OutputDebugString("Not   peek   message\r\n");  
  Sleep(100);  
  }  
  if(msg.message   ==   (WM_TIMER))  
  {  
  DispatchMessage(&msg);  
  }  
  return   0;  
  }Top

11 楼etre(林荃)回复于 2005-05-23 10:59:32 得分 0

不是很好用的.我们在项目中都用Top

12 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:19:08 得分 0

idAnts(你才无聊呢)   (   )    
   
  你给的例子怎么用啊?Top

13 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:22:21 得分 0

顺便问个问题     如何主窗口传递消息给用户界面线程的窗口啊?是不是使用PostThreadMessage()  
  当子线程得到了消息再进行处理啊   比如传递参数给它的窗口。   也就是说  
   
      主线程--》(PostThreadMessage)子线程--》子线程的窗口对象     ???  
  Top

14 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:27:33 得分 0

是不是可以直接PostMessage()给子线程中的对话框啊?     到底消息循环需不需要窗口啊?我现在有点糊涂了Top

15 楼idAnts(此广告位招租)回复于 2005-05-23 11:29:14 得分 0

我的例子你只要直接用那个线程函数创建线程就可以了啊。  
  加上PostThreadMessage再给你个例子吧!Top

16 楼idAnts(此广告位招租)回复于 2005-05-23 11:33:25 得分 7

UINT_PTR   hTimer   =   0;  
  //定时器消息处理函数  
  VOID   __stdcall   TimerProc(HWND   hwnd,UINT   uMsg,UINT_PTR   idEvent,DWORD   dwTime)  
  {  
  KillTimer(NULL,hTimer);  
  MessageBox(NULL,"Speak   in   Timer!",":)",MB_OK);  
  }  
   
  //线程函数  
  DWORD   __stdcall   ThreadFun(void   *)  
  {  
  MSG   msg;  
  PeekMessage(&msg,   NULL,   NULL,   NULL,   PM_NOREMOVE);  
  hTimer   =   SetTimer(NULL,0,10,(TIMERPROC)TimerProc);  
  while(!PeekMessage(&msg,NULL,WM_TIMER,WM_USER+1,PM_NOREMOVE))  
  {  
  OutputDebugString("Not   peek   message\r\n");  
  Sleep(100);  
  }  
  if(msg.message   ==   (WM_USER+1))  
  {  
                                      //收到主线程发来的消息  
  OutputDebugString("Rec   message\r\n");  
  }  
  else  
  {  
                                      //收到定时器消息,派送之  
  OutputDebugString("what   message\r\n");  
  DispatchMessage(&msg);  
  }  
  return   0;  
  }  
   
   
  //创建线程代码:  
  DWORD   dwThreadId;    
          HANDLE   hThread   =   NULL;  
  hThread   =   CreateThread(NULL,0,ThreadFun,NULL,0,&dwThreadId);  
  if   (hThread   ==   NULL)    
  {  
  MessageBox("CreateThread   failed.",   "main",   MB_OK   );  
  }  
  else    
  {  
  OutputDebugString("prepare   post   message\r\n");  
  Sleep(1000);//等待线程创建好了  
  PostThreadMessage(dwThreadId,WM_USER+1,0,0);//给线程发消息  
  OutputDebugString("Post   message   ok\r\n");  
  CloseHandle(   hThread   );  
  }  
  Top

17 楼idAnts(此广告位招租)回复于 2005-05-23 11:35:16 得分 0

你把PostThreadMessage(dwThreadId,WM_USER+1,0,0);注释掉就可以收到定时器消息了,或者是你在线程里循环的接收消息,否则只能接收到一条。Top

18 楼AntonlioX(做人要厚道)回复于 2005-05-23 11:39:35 得分 0

谢谢以上各位   啊       我先试试啊Top

19 楼younggle(洋溢)回复于 2005-05-23 12:28:01 得分 5

这是MFC的CWinThread类的实现。我提供更好的给你:  
  首先创建一个线程   _beginthread(MainThread,   DEFAULT_STACK_SIZE,   NULL);  
  然后在MainThread中创建一个看不见的窗口(伪窗口):  
  WNDCLASS   wcl;  
  HWND   hWnd   =   NULL;  
   
  memset(&wcl,0,sizeof(wcl));  
   
  if   (lpfnWndProc   ==   NULL)  
  {  
  return     NULL;   /*失败*/  
  }  
   
  /*register   class*/    
   
  wcl.cbClsExtra   =   0;  
  wcl.cbWndExtra   =   0;  
  wcl.hbrBackground   =   NULL;  
  wcl.hCursor   =   NULL;  
  wcl.hIcon   =   NULL;  
  wcl.hInstance   =   NULL;  
  wcl.lpfnWndProc   =   MainWindowProc;  
  wcl.lpszClassName   =   szWndName;  
  wcl.lpszMenuName   =   NULL;  
  wcl.style   =   CS_VREDRAW;  
  if   (RegisterClass(&wcl)   ==   0)  
  {  
  return   NULL;  
  }  
   
  /*create   window*/  
  hWnd   =   CreateWindow(szWndName,NULL,WS_POPUP,0,0,  
  CW_USEDEFAULT,CW_USEDEFAULT,  
  NULL,NULL,NULL,NULL);  
   
  /*进入消息循环*/  
          do  
          {  
                  ret   =   GetMessage(&msg,NULL,0,0);  
                  if   (ret   >   0)  
                  {  
                          DispatchMessage(&msg);  
                  }  
   
          }while(ret   >   0);  
   
   
  DestroySTUNServerWindow(szWndName,   s_hSTUNServerWnd);  
  最后可以在MainWindowProc中处理你的消息了:  
  LRESULT   CALLBACK   MainWindowProc(HWND   hWnd,  
        UINT   uMsg,      
        WPARAM     wParam,  
        LPARAM   lParam)  
  {  
  switch(uMsg)  
          {  
  default:  
  return   DefWindowProc(hWnd,uMsg,wParam,lParam);  
  }  
   
  return   0;  
  }  
  Top

20 楼AntonlioX(做人要厚道)回复于 2005-05-23 16:57:58 得分 0

我的可用分不多了   所以实现不好意思阿   谢谢各位的支持阿Top

21 楼AntonlioX(做人要厚道)回复于 2005-05-23 17:07:37 得分 0

结贴了   分数大家分分了拉     不好意思啊Top

22 楼AntonlioX(做人要厚道)回复于 2005-05-23 17:07:59 得分 0

结贴了   分数大家分分了拉     不好意思啊Top

相关问题

  • 一个用户界面线程怎样响应WM_TIMER消息?
  • 为使界面较快响应的线程问题请教
  • 线程函数中如何实现计时器?
  • 一个简单的线程问题,类似计时器
  • 请问进行网络连接时,操作界面无响应,怎么用线程来解决?
  • 计时器
  • 计时器
  • 线程问题(WinForm界面)
  • 请教各位大侠:运算量大的子线程开始后,主界面控件不能响应。请问该如何解决
  • 多线程程序无响应问题

关键词

  • 线程
  • 消息
  • 循环
  • 函数
  • wcl
  • cthreadbase
  • htimer
  • timerproc
  • 子线程
  • hthread

得分解答快速导航

  • 帖主:AntonlioX
  • etre
  • idAnts
  • younggle

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo