自己创建了一个线程,然后在该线程中使用了while循环,结果发现主窗体(用的是非模态对话框)没有反应了(无法移动,最大最小化,按钮也没法按),调试后才发现,程序一直卡在线程中的while循环,进不了GetMessage循环,有什么解决方法吗?

解决方案 »

  1.   

    如果象你说的新开了一个线程, 在里面运行的while循环, 就算是while(1), 主窗口也应该有反应.
    两个线程序根本是两回事.
      

  2.   

    给一下部分源代码,在这里创建线程:
    case WM_INITDIALOG:
    hThread=CreateThread(NULL,0,ThreadProc,hDlg,CREATE_SUSPENDED,&dwThreadID);
    return FALSE;
    然后在对话框的按钮处理中恢复线程,ThreadProc部分如下
    DWORD WINAPI ThreadProc(LPVOID param)
    { short ctlState;//ctrl键的状态
    short altState;//alt键的状态
    HDC hdc;//画布窗体设备上下文
    short ctlState;//ctrl键的状态
    short altState;//alt键的状态
    HWND hDlgCanvas;//画布窗体句柄
    HPEN hpn;//画笔 hDlgCanvas=CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DLGCANVAS),hWnd,DlgCanvasProc);
    hdc=GetDC(hDlgCanvas);
    hpn=CreatePen(PS_SOLID,5,RGB(67,131,248));
    SelectObject(hdc,hpn); while(TRUE)
    {
    ctlState=GetAsyncKeyState(VK_CONTROL);
    altState=GetAsyncKeyState(VK_MENU); ShowWindow(hDlgCanvas,TRUE);
    ....其他处理
    ShowWindow(hDlgCanvas,FALSE);
    sleep(10);
    }
    return 0;
    }
      

  3.   

    我觉得跟我在线程里面创建的对话框有关系,但是我有找不到到底哪里出问题了,我把    hDlgCanvas=CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DLGCANVAS),hWnd,DlgCanvasProc);
        hdc=GetDC(hDlgCanvas);
        hpn=CreatePen(PS_SOLID,5,RGB(67,131,248));
        SelectObject(hdc,hpn)
    注释掉就OK了,我的主窗体是非模态对话框。
      

  4.   

    我觉得在_wWinMain函数中的
    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    需要修改,但不知道怎样改
      

  5.   

    while (GetMessage(&msg, NULL, 0, 0))
    {
    switch(msg.hwnd){
    case hwnd:
    IsDialogMessage(hwnd, &msg);
    break;
    case DlgCanvas:
    IsDialogMessage(DlgCanvas, &msg);
    break;
    }改成上面的试试.
      

  6.   

    额。。首先,switch(msg.hwnd)无法执行,我把它改成while (GetMessage(&msg, NULL, 0, 0))
    {
    if(msg.hwnd==hDlgMain)
    IsDialogMessage(hDlgMain, &msg);
    else if(msg.hwnd==hDlgCanvas)
    IsDialogMessage(hDlgCanvas, &msg);
    }
    发现按钮无法点击了,于是改成了
    while (GetMessage(&msg, NULL, 0, 0))
    {
    if(msg.hwnd==hDlgMain)
    IsDialogMessage(hDlgMain, &msg);
    else if(msg.hwnd==hDlgCanvas)
    IsDialogMessage(hDlgCanvas, &msg);
    else
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    } }
    结果跟没改一样。主窗口还是没有响应
      

  7.   

    用modalless做主窗口的还真少见.......
    程序大么, 不大整个发出来.
      

  8.   

    我觉得如果你把,对话框建立在线程中,对话框的消息最好也由线程来处理,如下形式
       while(TRUE)
        {
          while(PeekMessage(&Message,NULL,(UINT) 0,(UINT) 0,PM_REMOVE))
            {
                // Check for the WM_QUIT message            if(Message.message == WM_QUIT)
                {
                    return NOERROR;
                }            // Send the message to the window procedure            TranslateMessage(&Message);
                DispatchMessage(&Message);
            }
            ctlState=GetAsyncKeyState(VK_CONTROL);
            altState=GetAsyncKeyState(VK_MENU);        ShowWindow(hDlgCanvas,TRUE);
            ....其他处理
            ShowWindow(hDlgCanvas,FALSE);
            sleep(10);
        }
      

  9.   

    while(TRUE)
    {
    if(PeekMessage(&msg,0,0,0,PM_REMOVE))
    {
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
    if(msg.message==IDCANCEL) // <---这里退出 
    break; 
    }
    }
    这样就可以相应退出的消息
      

  10.   

    程序总共有918行,是我看完Programming Windows写的一个练习的实用程序,我也是个新手,所以在很多方面还有不足对于楼上的加入while(PeekMessage(&Message,NULL,(UINT) 0,(UINT) 0,PM_REMOVE))
    {
    if(Message.message == WM_QUIT)
    {
    return NOERROR;
    }
    TranslateMessage(&Message);
    DispatchMessage(&Message);
    }
    我有个疑问,加入这段代码之后程序不就在PeekMessage中循环了吗,不会执行下面的语句了呀。
      

  11.   

    好了,问题解决了,我参考了CSDN上面的这个帖子:http://topic.csdn.net/t/20060423/12/4707073.html
    原因在于在线程中创建的窗体需要有自己的消息循环。最后在线程中的while循环最后添加了如下代码,
      MSG msg;
    PeekMessage(&msg,hDlgCanvas,NULL,NULL,PM_NOREMOVE);
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    不过总觉得不太妥当。
    初学SDK,很多方面的知识还需要完善,我会继续努力的。感谢大家的热心回复!
      

  12.   

    CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DLGCANVAS),hWnd,DlgCanvasProc);
    第3个参数指定了父窗口HWND, 我以为消息都跑父窗口所属的线程了.
    这个问题以前还真没注意过.
      

  13.   

    PeekMessage只在消息对列中有消息时它才返回真,消息队列中的消息处理完后,它就会跳出循环,这和GetMessage是不同的。