现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

MFC 界面假死问题解决方法

2014-03-11 05:48 工业·编程 ⁄ 共 2805字 ⁄ 字号 暂无评论
文章目录

在界面处理函数中,可以会长时间处理数据,导致界面假死,这时可以在代码块中加入下面代码:

方法一

1. 单线程解决: 
OnBtn1() 

        while(m_bLoop) 
       { 
                your code.... 
 
              // 派发消息 
               MSG  msg; 
               if (PeekMessage(&msg,(HWND)NULL, 0, 0, PM_REMOVE)) 
               { 
                        ::SendMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);   
                } 
       } 

 
OnBtn2() 

       m_bLoop = FALSE; 

方法二

2. 多线程 (参考:http://www.vckbase.com/document/viewdoc/?id=1704) 
a. 在xxxDlg.h中类的外面(即大括号外面)定义一个函数 void ThreadFunc();(外部函数) 
b. 在xxxDlg类中定义在类CMultiThread1Dlg内部添加protected型变量: 
HANDLE hThread;  DWORD ThreadID; 
     分别代表线程的句柄和ID。  
c. 在xxxDlg.cpp中定义全局变量volatileBOOL m_Flag; 
d.在xxxDlg.cpp中写ThreadFunc函数 
    void ThreadFunc() 
    { 
           while(m_Flag) 
           { 
                    //your code here 
            } 
           return; //线程自杀 
    } 
e. 按钮A代表开始循环 
void CxxxDlg::OnStart() 

         hThread=CreateThread( 
               NULL, 
0,   (LPTHREAD_START_ROUTINE)ThreadFunc,     NULL,   0, 
&ThreadID 
); 

f. 按钮B代表结束循环 
void CxxxDlg::OnStop() {    m_bRun=FALSE;} 

void CConsoleTestDlg::OnButtonClose()  

    // TODO: Add your control notification handler code here 
    CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_CLOSE); 
 
    if (g_isOpen) 
    { 
        //ConWin.Close(); 
 
        HANDLE hProcessHandle; 
        ULONG nProcessID; 
        HWND TheWindow; 
         
        TheWindow = ::FindWindow(NULL,"console"); 
        ::GetWindowThreadProcessId(TheWindow,&nProcessID); 
        hProcessHandle = ::OpenProcess(THREAD_TERMINATE,FALSE,nProcessID); 
        ::TerminateProcess(hProcessHandle,4); 
         
        if(pBtn != NULL) 
        { 
            pBtn->SetWindowText("close"); 
        } 
 
        g_isOpen = FALSE; 
    } 
    else 
    { 
        ConWin.Open(); 
        int i; 
 
        while(1) 
        { 
            g_isOpen = TRUE; 
 
            ConWin.printf("========test======%d\n",i++); 
             
            // 派发消息 
            MSG msg; 
            if (PeekMessage(&msg,(HWND)NULL, 0, 0, PM_REMOVE)) 
            { 
                ::SendMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);   
            } 
 
            Sleep(100); 
        } 
 
        if(pBtn != NULL) 
        { 
            pBtn->SetWindowText("close"); 
        } 
    } 

方法三

从别人博客中看到还可以用下方法:
/* -------------------------------------------------------------------------      
Ok, call this to pump messages... 
------------------------------------------------------------------------- */ 
void CDoeventsDlg::DoEvents() 

    MSG msg; 
    if (::PeekMessage(&msg,NULL,0,0,PM_REMOVE))  
    { 
    //从Windows消息队列中取出消息  
        if (msg.message== WM_QUIT)//如果消息为退出,发送退出消息 
        { 
            ::PostQuitMessage(-1); 
        } 
         
        if(!AfxGetApp()->PreTranslateMessage(&msg))//如果无法预处理消息 
        { 
            ::TranslateMessage(&msg);//转换消息 
            ::DispatchMessage(&msg);//发送消息 
        } 
    } 
     
    AfxGetApp()->OnIdle(0); 
    AfxGetApp()->OnIdle(1);//消息队列为空时闲置一段时间 

给我留言

留言无头像?