一个程序,赶了半个月,明天前搞不定就全完了。在这个论坛上也发了很多帖子一点一点问,一点一点学,有很多阻碍但是都一个一个搞定了。现在到了最后,推翻了之前的思路,但是遇到了一个整了半天也没搞定的问题,不知道这个问题背后还有什么更大的问题,但这个搞不定一切都白费,就留下最后的分给各位大侠了。小弟没学过mfc 面向对象也没学好,现在只是边学api边用c面向过程编,所以解答时用的太高深我搞不定。
问题:建立了一个线程在线程里建立了线程的窗口绑定了窗口消息处理函数,在线程里建立了一个socket 然后用::WSAAsyncSelect绑定在线程的窗口上。//主线程int CreateOnlineThread(HWND hWnd)
{

::CreateThread(NULL,0,SocketThread,(LPVOID)hWnd,0,NULL); return 0;

}//子线程DWORD WINAPI SocketThread(LPVOID lpParam)
{
//建立线程窗口
::CreateWnd2(hWnd);
//主消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
//下面这个if判断,如果不要,那么从主线程中post或是send过来的TM_START消息用DispatchMessage(&msg);送不到线程窗口处理函数winproc2中了。
         //而且网络消息在这个主消息循环中一个也接收不到
if(msg.message==TM_START)
{

::SendMessage(g_ThreadhWnd,TM_START,NULL,NULL); //g_ThreadhWnd 是线程窗口句柄,见下
}

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

}
return 0;
}//消息处理函数LRESULT CALLBACK WndProc2(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam) 

HWND p_hWnd;
p_hWnd=::FindWindow(NULL,"text");

switch (wMsg) 
{


case TM_START:
if(g_SocketChoice==1)
{
                 //在这里开了另一个函数
                    //响应主线程发送过来的 TM_START消息
StartServer(hWnd);
}
else
{
StartClient(hWnd);
}

break;
//接收网络消息处理
case WID_SOCKET:
{

SOCKET s=wParam;

switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:

g_ServerSocket=::accept(g_Socket,NULL,NULL);
::WSAAsyncSelect(g_ServerSocket,hWnd,WID_SOCKET,FD_READ|FD_WRITE|FD_CLOSE);

break;
case FD_CLOSE:
::closesocket(g_Socket);
break;
case FD_WRITE:
break;
case FD_READ:


SocketRead(p_hWnd);
break;
default:
break;
}
}
break;

case WM_DESTROY:
::ExitThread(0);
::CloseHandle(::GetCurrentThread());
break;




default:
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}

return 0;

//建立窗口,绑定消息处理函数
void CreateWnd2(HWND hWnd) 
{         WNDCLASS wc = {0}; 
    wc.style         = 0; 
    wc.lpfnWndProc   = (WNDPROC)WndProc2; //绑定消息处理函数
    wc.cbClsExtra    = 0; 
    wc.cbWndExtra    = 0; 
    wc.hInstance     = g_hInst; 
    wc.hIcon         = NULL;  
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); 
    wc.lpszMenuName  = NULL; 
    wc.lpszClassName = TEXT("SimpleWindow");     RegisterClass(&wc);     g_ThreadhWnd = CreateWindowEx(0, 
                                TEXT("SimpleWindow"), 
TEXT("SimpleWindow"), 
WS_ICONIC, 
0, 
0, 
0, 
0, 
hWnd,  
NULL,  
g_hInst,  
0); 
} //响应主线程发送过来的 TM_START消息
StartServer(hWnd)
{.......
//我怀疑主消息循环中接收不到消息 是因为这里有个循环,但是这里的循环只接收到FD_ACCEPT 一个网络消息就退出了
while (GetMessage(&msg, NULL, 0, 0)&&WSAGETSELECTEVENT(msg.lParam)!=FD_ACCEPT)
{
if(!IsDialogMessage(hdlg,&msg))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

}

if(msg.message==WID_SOCKET&&WSAGETSELECTEVENT(msg.lParam)==FD_ACCEPT)
{
phWnd=::FindWindow(NULL,"text");
::PostMessage(phWnd,IDM_START,NULL,NULL);


DestroyWindow(hdlg);
break;
}
....
}
小弟水平不高,可能代码很乱,很多,望达人耐心指点,小弟在这多谢了。这个问题可能很简单,或是很复杂,但这个对我很重要,谢谢!
怎么另加170分 请留言

解决方案 »

  1.   

    题就是 明明建立了 子线程窗口,网络消息在StartServer(hWnd)
    中可以接收,在主消息循环中不行,为什么?
    还有DispatchMessage(&msg);无法把主线程post过来的消息发送给 线程窗口处理函数,也不能把网络消息给窗口消息处理函数
      

  2.   

    把这段注释掉.    case TM_START:
                    if(g_SocketChoice==1)
            {
                     //在这里开了另一个函数
                        //响应主线程发送过来的 TM_START消息
                StartServer(hWnd);
            }
            else
            {
                StartClient(hWnd);
            }
                    
            break;
    DispatchMessage()本来就不跨线程. 
    如果要跨线程,用:
    SendMessage(),SendThreadMessage() 等
      

  3.   

    把这段注释掉.    case TM_START:
                    if(g_SocketChoice==1)
            {
                     //在这里开了另一个函数
                        //响应主线程发送过来的 TM_START消息
                StartServer(hWnd);
            }
            else
            {
                StartClient(hWnd);
            }
                    
            break;
    DispatchMessage()本来就不跨线程. 
    如果要跨线程,用:
    SendMessage(),SendThreadMessage() 等
      

  4.   

    1. 开启线程,建立网络连接,把网络事件映射到Event上面
    2. 接收到数据post到窗口主线程
      

  5.   

    在 ::CreateWnd2(hWnd); 后面插入一句
    ::CreateWnd2(hWnd);WSAAsyncSelect(g_ServerSocket,
        g_ThreadhWnd,
        WID_SOCKET_server,  //---每个socket用1个消息
        FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE);  //--- 对server_socket, 要FD_ACCEPT