我原来的实现方法:
MainFrame:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_TEST, OnTest)
ON_COMMAND(ID_TEST_STOP, OnTestStop)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MyNotify,OnMyNotify) //WM_MyNotify由动态DLL文件发送
END_MESSAGE_MAP()
void CMainFrame::OnMyNotify() 
{
gGetData.SetEventNowGetData();
}
GetData:
void SetEventNowGetData(void){SetEvent(evtNowGetData);};
void GetData::Thread_GetData()
{
long i=0;
// AfxMessageBox("In Thread GetData");
while(this->GetThreadSuspend())
{
if(WaitForSingleObject(evtNowGetData,this->WaitNotifyTime)!=WAIT_TIMEOUT)
{
//获取数据
this->AdCard.ADResult((ADCard_Result*)this->ADBuf);
// 翻译数据并写入画图缓冲区
this->TranslateData(); }
else 
{
AfxMessageBox("GetData WAIT_TIMEOUT");
if (++i>=2)
{
AfxMessageBox("Break exiting....");
break;
}
}
}
}
这时,运行正常,但是我将鼠标一放到最小化按钮上或是菜单栏或是改变窗体大小时,就会执行:AfxMessageBox("GetData WAIT_TIMEOUT");
我怀疑是将鼠标一放到最小化按钮上或是菜单栏或是改变窗体大小时,mainFrame 就不会处理WM_MyNotify事件,也就不会执行:gGetData.SetEventNowGetData();函数,造成超时错误!
我想,有什么办法能防止这种错误发生,(不要改等待时间),最能能告诉我如何从工作线程中响应处理WM_MyNotify事件,那该多好呀!
各位高手,大哥大姐,帮我呀!

解决方案 »

  1.   

    我不是这样玩的也许设置几个全局的FLAG,在主线程
    中设定true/false,在工作线程中读取flag的状态。
    每一个耗时比较长的功能前面加一个if(b_Cancel)
    {
     ...
    }
      

  2.   

    详细一点:当主线程完成响应notify 
    use switch
    caseblocks.
    then to set flag = true or flase(每一个时间间隔)推荐您看win32多绪程式设计
      

  3.   

    我是设置的事件,通过事件来进行判断的,但是我发现当鼠标指向最小化等时,主线程就不处理 notify 事件了。
      

  4.   

    线程中可以接收WM_MyNotify消息:
    void worker_thead()
    {
         //do initilization here
         MSG msg;
         while(GetMessage(&msg,NULL,0,0))
         {
               assert(msg.message==WM_MyNotify);
               //处理WM_MyNotify消息
         }
         // 收到WM_QUIT,退出线程。
    }
      

  5.   

    Card.RegisterNotify(0,::AfxGetMainWnd()->m_hWnd,WM_MyNotify,48,0);
    这个是用来注册消息的,这时,::AfxGetMainWnd()->m_hWnd应当怎么写呀,
    我还是收不到,我的例子是这样的:
    void CMainFrame::OnTest() 
    {
    //TODO: Add your command handler code here
    pThreadtest=AfxBeginThread(this->TestThread,(LPVOID)NULL);
    }UINT CMainFrame::TestThread(LPVOID p)
    {
    MSG msg;
    // if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
    AfxMessageBox("线程启动成功");
    for(int i=0;i<=300;i++)
    {
    // assert(msg.message==WM_MyNotify);
    if(!::GetMessage(&msg,NULL,0,0))
    {
    //处理WM_MyNotify消息
    AfxMessageBox("收到消息");
    }
    else 
    {
    AfxMessageBox("收到,但不是我的消息");
    Sleep(10);
    }
    }
    return 0;
    }
    为什么我什么也收不到呀,只能收到启动线程成功!
      

  6.   

    RegisterNotify是个什么东西啊?如果你把消息发到mainwnd,工作线程当然收不到消息了。 要把消息发到线程中才行。 
      或者你在线程中创建一个隐藏的窗口,RegisterNotify的时候的把这个隐藏窗口的句柄传过去,这样消息就能传到你的工作线程了。
      

  7.   

    RegisterNotify
    是注册一个消息,让一个DLL程序把WM_MyNotify消息发过来,(在满足了一定的条件之后)
      

  8.   

    create一个窗口,ShowWindow的时候用SW_HIDE就是了。把你处理WM_MyNotify消息的代码全放到窗口的窗口过程里去。
      

  9.   

    void CMainFrame::OnTestStart() 
    {
    // TODO: Add your command handler code here
    if(this->recvMsgDlg==NULL)
    {
    recvMsgDlg=new CRecvMsg;
    recvMsgDlg->Create(IDD_RECVMSG,this);
    recvMsgDlg->ShowWindow(SW_HIDE);
    }
    this->SuspendThread(true);

    }
    处理WM_MyNotify消息的代码全放到窗口的窗口过程
    void CRecvMsg::OnMyNotify() 
    {
    // TODO: Add your command handler code here
    gGetData.SetEventNowGetData();
    }
    可是为什么还是当我还原窗口后,当用鼠标在标题栏上按下左键时,画图还是停止了!
    我是怎么回事呀,不会是它们属于同一个进程,就是这样吧?
    大哥,还有什么办法没有呀?
      

  10.   

    this->SuspendThread(true)???? 能编译吗?
      

  11.   

    void CMainFrame::SuspendThread(BOOL lSuspend)
    {
    switch(lSuspend)
    {
    case true:
    //设置线程状态为运行
    gGetData.SetMsgDlg(this->recvMsgDlg);
    gGetData.SetThreadSuspend(true);
    pThread=AfxBeginThread(gGetData.ThreadFunc,(LPVOID)(&gGetData));
    break;
    case false:
    //设置线程状态为停止
    gGetData.SetThreadSuspend(false);
    ::WaitForSingleObject(pThread,INFINITE);
    gGetData.SetMsgDlg(NULL);
    break;
    }

    }
    可以呀?