用CreateThread创建的线程能不能通过发消息方式通讯?就像SendMessage能给其他HWND发消息一样
如果能,用什么函数?
谢谢

解决方案 »

  1.   


    m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL); ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);==============================
    http://blog.ednchina.com/opencv2008/216706/message.aspx
      

  2.   

    //转载完整的例子  /*   
        *   Worker.cpp   
        *   
        *   Sample   code   for   "Multithreading   Applications   in   Win32"   
        *   This   is   from   Chapter   14,   Listing   14-3   
        *   
        *   Demonstrate   using   worker   threads   that   have   
        *   their   own   message   queue   but   no   window.   
        */   
          
      #define   WIN32_LEAN_AND_MEAN   
      #include   <stdio.h>   
      #include   <stdlib.h>   
      #include   <windows.h>   
      #include   <process.h>   
      #include   <string.h>   
      #include   "MtVerify.h"   
        
      unsigned   WINAPI   ThreadFunc(void*   p);   
        
      HANDLE   ghEvent;   
        
      #define   WM_JOB_PRINT_AS_IS                     WM_APP   +   0x0001   
      #define   WM_JOB_PRINT_REVERSE                 WM_APP   +   0x0002   
      #define   WM_JOB_PRINT_LOWER                     WM_APP   +   0x0003   
        
      int   main(VOID)     
      {     
              HANDLE   hThread;   
              unsigned   tid;   
        
              //   Give   the   new   thread   something   to   talk   
              //   to   us   with.   
              ghEvent   =   CreateEvent(NULL,   TRUE,   FALSE,   NULL);   
          
              hThread   =   (HANDLE)_beginthreadex(NULL,   
                                                  0,   
                                                  ThreadFunc,   
                                                  0,   
                                                  0,   
                                                  &tid   );   
              MTVERIFY(hThread);   
        
              //   This   thread   has   to   wait   for   the   new   thread   
              //   to   init   its   globals   and   msg   queue.   
              WaitForSingleObject(ghEvent,   INFINITE);   
        
              //   The   only   place   in   the   book   we   get   to   use   
              //   the   thread   ID!   
              char   *szText   =   strdup("Thank   you   for   buying   this   book.\n");   
              PostThreadMessage(tid,   WM_JOB_PRINT_AS_IS,   NULL,   (LPARAM)szText);   
        
              szText   =   strdup("Text   is   easier   to   read   forward.\n");   
              PostThreadMessage(tid,   WM_JOB_PRINT_REVERSE,   NULL,   (LPARAM)szText);   
        
              szText   =   strdup("\nLOWER   CASE   IS   FOR   WHISPERING.\n");   
              PostThreadMessage(tid,   WM_JOB_PRINT_LOWER,   NULL,   (LPARAM)szText);   
        
              WaitForSingleObject(hThread,   INFINITE);   
        
              CloseHandle(hThread);   
        
              return   0;   
      }   
          
      VOID   CALLBACK   TimerFunc(   
              HWND   hwnd,     //   handle   of   window   for   timer   messages     
              UINT   uMsg,     //   WM_TIMER   message   
              UINT   idEvent,       //   timer   identifier   
              DWORD   dwTime   )     //   current   system   time   
      {   
              UNREFERENCED_PARAMETER(hwnd);   
              UNREFERENCED_PARAMETER(uMsg);   
        
              PostThreadMessage(GetCurrentThreadId(),   WM_QUIT,0,0);   
      }   
          
      /*   
        *   Call   a   function   to   do   something   that   terminates   
        *   the   thread   with   ExitThread   instead   of   returning.   
        */   
      unsigned   WINAPI   ThreadFunc(LPVOID   n)   
      {   
              UNREFERENCED_PARAMETER(n);   
        
              MSG   msg;   
        
              //   This   creates   the   message   queue.   
              PeekMessage(&msg,   NULL,   0,   0,   PM_NOREMOVE);   
        
              SetEvent(ghEvent);   
        
              //   We'll   run   for   two   seconds   
              SetTimer(NULL,   NULL,   2000,   (TIMERPROC)TimerFunc);   
        
              while   (GetMessage(&msg,   NULL,   0,   0))   
              {   
                      char   *psz   =   (char   *)msg.lParam;   
                      switch(msg.message)   
                      {   
                      case   WM_JOB_PRINT_AS_IS:   
                              printf("%s",   psz);   
                              free(psz);   
                              break;   
                      case   WM_JOB_PRINT_REVERSE:   
                              printf("%s",   strrev(psz));   
                              free(psz);   
                              break;   
                      case   WM_JOB_PRINT_LOWER:   
                              printf("%s",   _strlwr(psz));   
                              free(psz);   
                              break;   
                      default:   
                              DispatchMessage(&msg);   
                      }   
              }   
        
              return   0;   
      }   
        
      下面是这个例子中用到的一个用于断言的头文件   
      /*   
        *   MtVerify.h   
        *   
        *   Error   handling   for   applications   in   
        *   "Multitheading   Applications   in   Win32"   
        *   
        *   The   function   PrintError()   is   ed   as   __inline   so   that   it   can   be   
        *   included   from   one   or   more   C   or   C++   files   without   multiple   definition   
        *   errors.   For   the   examples   in   this   book,   this   works   fine.   
        *   To   use   the   PrintError()   in   an   application,   it   should   be   taken   out,   
        *   placed   in   its   own   source   file,   and   the   "__inline"   declaration   removed   
        *   so   the   function   will   be   globally   available.   
        */   
        
      #pragma   comment(   lib,   "USER32"   )   
        
      #include   <crtdbg.h>   
      #define   MTASSERT(a)   _ASSERTE(a)   
        
        
      #define   MTVERIFY(a)   if   (!(a))   PrintError(#a,__FILE__,__LINE__,GetLastError())   
        
      __inline   void   PrintError(LPSTR   linedesc,   LPSTR   filename,   int   lineno,   DWORD   errnum)   
      {   
      LPSTR   lpBuffer;   
      char   errbuf[256];   
      #ifdef   _WINDOWS   
      char   modulename[MAX_PATH];   
      #else   //   _WINDOWS   
      DWORD   numread;   
      #endif   //   _WINDOWS   
        
      FormatMessage(   FORMAT_MESSAGE_ALLOCATE_BUFFER   
      |   FORMAT_MESSAGE_FROM_SYSTEM,   
      NULL,   
      errnum,   
      LANG_NEUTRAL,   
      (LPTSTR)&lpBuffer,   
      0,   
      NULL   );   
        
      wsprintf(errbuf,   "\nThe   following   call   failed   at   line   %d   in   %s:\n\n"   
                                    "         %s\n\nReason:   %s\n",   lineno,   filename,   linedesc,   lpBuffer);   
      #ifndef   _WINDOWS   
      WriteFile(GetStdHandle(STD_ERROR_HANDLE),   errbuf,   strlen(errbuf),   &numread,   FALSE   );   
      Sleep(3000);   
      #else   
      GetModuleFileName(NULL,   modulename,   MAX_PATH);   
      MessageBox(NULL,   errbuf,   modulename,   MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);   
      #endif   
      exit(EXIT_FAILURE);   
      }   
      

  3.   

    自己定义一个WM_USER,如:#define WM_USER_MSG WM_USER+102HANDLE m_hTHread1=CreateThread(...);PostThreadMessage(m_hThread1,WM_USER_MSG,0,0);在另一个线程用:
    MSG msg;
    GetMessage(&msg,0,0,0);
    switch(msg.message)
    {
    case WM_USER_MSG:
       ....
       break;
    default:
       break;
    }
      

  4.   

    #include "IocpTest.h"
    #pragma comment(lib,"LIBCMT.LIB")
    #pragma comment(lib,"ws2_32.lib")
    HANDLE m_hEvent;
    HANDLE m_h1;
    unsigned long  ThreadID1;
    #define WM_USERMSG WM_USER+101
    struct TagMsg
    {
    int ID;
    char buf[100];

    };
    DWORD WINAPI ProcThread(void* lpParam)
    {
    SOCKET* s=(SOCKET*)lpParam;
            TagMsg *Tmsg=new TagMsg;
    memset(Tmsg,0,sizeof(TagMsg));
    while(true)
    {
    char buf[100]={0};
    strcpy(buf,"123sssssssss");
    send(*s,buf,strlen(buf)+1,0);
    Sleep(1000);
    memcpy(Tmsg->buf,"1111111111hhh",sizeof(Tmsg->buf));
    Tmsg->ID=100101;
    ::PostThreadMessage(ThreadID1,WM_USERMSG,0,(LPARAM)Tmsg);//*************//
    }
    }
    DWORD WINAPI PrintThread(void* lpParam)
    { MSG msg;
    TagMsg *pMsg=new TagMsg;
    char *buf=new char[100];
    while(true)
    {

    ::GetMessage(&msg,0,0,0);//***************************//
    switch(msg.message)
    {
    case WM_USERMSG:
    {

    memset(pMsg,0,sizeof(pMsg));
    memcpy(pMsg,(TagMsg*)msg.lParam,sizeof(TagMsg));
    printf("%d   %s\n",pMsg->ID,pMsg->buf);
    }
                break;
    default:
    break;
    }
    }}
    void main()
    {
            WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD( 2, 2 ); WSAStartup( wVersionRequested, &wsaData ); SOCKET s=socket(AF_INET,SOCK_STREAM,0);

    sockaddr_in si;
    si.sin_port=::htons(4567);
    si.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    si.sin_family=AF_INET; connect(s,(sockaddr*)&si,sizeof(sockaddr));
    unsigned long  ThreadID;

            m_h1=CreateThread(NULL,0,PrintThread,NULL,0,&ThreadID1);
            HANDLE m_h=CreateThread(NULL,0,ProcThread,(void*)&s,NULL,&ThreadID);
            CloseHandle(m_h);
    m_hEvent=CreateEvent(NULL,FALSE,FALSE,"sdd");

    ::WaitForSingleObject(m_hEvent,INFINITE);
    closesocket(s);
    WSACleanup();
    }这是我自己今天才写的,你参考一下.
      

  5.   

    可以的 别的线程中用postthreadmessage就可以给指定线程发消息,在此线程中用while   (GetMessage(&msg,   NULL,   0,   0))从线程的消息队列中获取消息
      

  6.   

    代码都整理好了。/* 
      * Worker.cpp 
      * 
      * Sample code for "Multithreading Applications in Win32" 
      * This is from Chapter 14, Listing 14-3 
      * 
      * Demonstrate using worker threads that have 
      * their own message queue but no window. 
      */ 
      
      #define WIN32_LEAN_AND_MEAN 
      #include <stdio.h> 
      #include <stdlib.h> 
      #include <windows.h> 
      #include <process.h> 
      #include <string.h> 
      #include "MtVerify.h" 
      
      unsigned WINAPI ThreadFunc(void* p); 
      
      HANDLE ghEvent; 
      
      #define WM_JOB_PRINT_AS_IS       WM_APP + 0x0001 
      #define WM_JOB_PRINT_REVERSE     WM_APP + 0x0002 
      #define WM_JOB_PRINT_LOWER       WM_APP + 0x0003 
      
      int main(VOID)   
      {   
      HANDLE hThread; 
      unsigned tid;    // Give the new thread something to talk 
      // to us with. 
      ghEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
      
      hThread = (HANDLE)_beginthreadex(NULL, 
      0, 
      ThreadFunc, 
      0, 
      0, 
      &tid); 
      MTVERIFY(hThread);    // This thread has to wait for the new thread 
      // to init its globals and msg queue. 
      WaitForSingleObject(ghEvent, INFINITE);    // The only place in the book we get to use 
      // the thread ID! 
      char *szText = strdup("Thank you for buying this book.\n"); 
      PostThreadMessage(tid, WM_JOB_PRINT_AS_IS,  NULL,(LPARAM)szText);    szText = strdup("Text is easier to read forward.\n"); 
      PostThreadMessage(tid, WM_JOB_PRINT_REVERSE, NULL, (LPARAM)szText);    szText = strdup("\nLOWER CASE IS FOR WHISPERING.\n"); 
      PostThreadMessage(tid, WM_JOB_PRINT_LOWER, NULL, (LPARAM)szText);    WaitForSingleObject(hThread, INFINITE);    CloseHandle(hThread);    return 0; 
      } 
      
      VOID CALLBACK TimerFunc( 
        HWND hwnd,   // handle of window for timer messages   
        UINT uMsg,   // WM_TIMER message 
        UINT idEvent,   // timer identifier 
        DWORD dwTime )   // current system time 
      { 
        UNREFERENCED_PARAMETER(hwnd); 
        UNREFERENCED_PARAMETER(uMsg); 
      
        PostThreadMessage(GetCurrentThreadId(), WM_QUIT,0,0); 
      } 
      
      /* 
      * Call a function to do something that terminates 
      * the thread with ExitThread instead of returning. 
      */ 
      unsigned WINAPI ThreadFunc(LPVOID n) 
      { 
        UNREFERENCED_PARAMETER(n); 
      
        MSG msg; 
      
        // This creates the message queue. 
        PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); 
      
        SetEvent(ghEvent); 
      
        // We'll run for two seconds 
        SetTimer(NULL, NULL, 2000, (TIMERPROC)TimerFunc); 
      
        while (GetMessage(&msg, NULL, 0, 0)) 
        { 
          char *psz = (char *)msg.lParam; 
          switch(msg.message) 
          { 
          case WM_JOB_PRINT_AS_IS: 
              printf("%s", psz); 
              free(psz); 
              break; 
          case WM_JOB_PRINT_REVERSE: 
              printf("%s", strrev(psz)); 
              free(psz); 
              break; 
          case WM_JOB_PRINT_LOWER: 
              printf("%s", _strlwr(psz)); 
              free(psz); 
              break; 
          default: 
              DispatchMessage(&msg); 
          } 
        } 
      
        return 0; 
      } 
      
      下面是这个例子中用到的一个用于断言的头文件 
      /* 
      * MtVerify.h 
      * 
      * Error handling for applications in 
      * "Multitheading Applications in Win32" 
      * 
      * The function PrintError() is ed as __inline so that it can be 
      * included from one or more C or C++ files without multiple definition 
      * errors. For the examples in this book, this works fine. 
      * To use the PrintError() in an application, it should be taken out, 
      * placed in its own source file, and the "__inline" declaration removed 
      * so the function will be globally available. 
      */ 
      
      #pragma comment( lib, "USER32" ) 
      
      #include <crtdbg.h> 
      #define MTASSERT(a) _ASSERTE(a) 
      
      
      #define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError()) 
      
      __inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum) 
      { 
      LPSTR lpBuffer; 
      char errbuf[256]; 
      #ifdef _WINDOWS 
      char modulename[MAX_PATH]; 
      #else // _WINDOWS 
      DWORD numread; 
      #endif // _WINDOWS 
      
      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER 
      | FORMAT_MESSAGE_FROM_SYSTEM, 
      NULL, 
      errnum, 
      LANG_NEUTRAL, 
      (LPTSTR)&lpBuffer, 
      0, 
      NULL ); 
      
      wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n" 
    "   %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer); 
      #ifndef _WINDOWS 
      WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE ); 
      Sleep(3000); 
      #else 
      GetModuleFileName(NULL, modulename, MAX_PATH); 
      MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND); 
      #endif 
      exit(EXIT_FAILURE); 
      } 
      

  7.   


    这段代码中涉及了线程之间控制的消息和事件的使用,比如消息的截获,用PeekMessage,GetMessage,  事件的等待来挂起线程WaitForSingleObject(...).线程消息的传递PostThreadMessage,这些都是常用的线程之间控制和同步和相互通知的方法