我希望程序进程可控,因此添加了如下处理函数:CMainFrame::OnRun()
{
     thread = AfxBeginThread(run, this);
}其中的线程函数我是如下处理的:UINT CMainFrame::run(LPVOID p)
{
CMainFrame * me = (CMainFrame *)p;
me->run();
return 0;
}
 
void CMainFrame::run()
{
        //......
        m_wndSplitter.SetActivePane(0,0);  //这里出了问题!!!
        //......}我的问题是:
1. 为什么原先运行很好的函数,当放到线程里会出问题?
   我已经确认是SetActivePane()函数的问题!
2. 即便没有上述问题,我的窗口内的其他控件(如状态栏里的进度条)为什么不能刷新了?
3. 我只会一种方法来获得指向各View的指针,
CMainFrame * pFrame  = (CMainFrame *)AfxGetMainWnd();
pFrame->m_wndSplitter.SetActivePane(0, 0,NULL);
CListView* view = (CListView*) pFrame->GetActiveView();
   如果不能用SetActivePane()函数,那怎么办呀?这可是我一个多月的心血呀!希望各位一定帮忙解决这个问题!!!

解决方案 »

  1.   

    http://www.csdn.net/develop/Read_Article.asp?id=26152
      

  2.   

    me->run()
    该函数在工作线程中运行,在处理与主线程窗口相关的操作时请使用发送消息方法例如添加#define WM_UPDATEDISPLAY WM_USER + 101消息映射
    ON_MESSAGE_VOID(WM_UPDATEDISPLAY, UpdateDisplay) afx_msg void UpdateDisplay(); //类消息函数
    void CMainFrame::UpdateDisplay()
    {
    //为线程使用
    //......
            m_wndSplitter.SetActivePane(0,0);  //这里出了问题!!!
            //......}void CMainFrame::run()
    {
            SendMessage(WM_UPDATEDISPLAY);
    }
      

  3.   

    试试看在线程调用me->run();之前加上这句:
    AfxSetModuleState(AfxGetThreadState()->m_pPrevModuleState);
      

  4.   

    非常感谢 ukyoking老师的指导,但是还是有一个残留问题:
    我的目的是通过UI对程序进行控制,可是按照上面的方法,虽然程序可以运行,但是发现无法对界面控件(如菜单、按钮)进行控制。
    而我原先在一个CMyView的一个简单程序里,确是可以这样做的。望指教!
      

  5.   

    codewarrior兄台的方法我试过了,可惜不行。
    觉得 ukyoking的方法很奏效,就差一步就可以实现我的功能了。
    希望各位多帮忙,谢谢!!!
      

  6.   

    无法对界面控件(如菜单、按钮)进行控制???void CMainFrame::run()
    {
            //把你的代码贴出来
    }
      

  7.   

    我的run()函数里是我以前的编的console函数的main()函数,很大。我在没有加入这个线程函数时,是可以运行的,只是在运行时不能暂停。因此我希望通过线程函数来解决这个问题,没想到是这样:(能不能请楼上的各位高手帮助分析一下?
      

  8.   

    void CMainFrame::run()
    这个函数变成静态!这个函数里面所有的东西都是变为全局的,这样做定义全局变量CXXXDlg *app;   CXXXDlg是你的对话框类。然后在onInitDlg()里面加上
    app=this;void CMainFrame::run()
    {
            //......
            app->m_wndSplitter.SetActivePane(0,0);//看到那里改变了吗?          
           //......}小问题啊,别担心,各种办法都试试看。肯定可以解决的。
      

  9.   

    你这个问题我遇到过,当时我在线程里想得到状态栏的高度,结果虽然GetMessageBar正确返回了一个CStatusBar的指针,但是GetWindowRect总是返回0。而同样的代码不在线程里做,就是ok的。
      

  10.   

    To  codewarrior(会思考的草) (★)
    "同样的代码不在线程里做"的意思是不是:将同样的代码写到某个函数里,然后在线程里只是调用那个函数?
      

  11.   

    看不到你的代码,实在是不好判断,你尝试如下代码看有没有问题void CMainFrame::Run()
    {
    MSG msg;
    while (1)
    {
    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    if (msg.message == WM_QUIT)
    {
    break;
    }
    }
    else
    {
    Sleep(10000);
    }
    }
    AfxMessageBox("exit thread");
    m_pThread->ExitInstance();
    }void CMainFrame::OnRun() 
    {
    // TODO: Add your command handler code here
    m_pThread = AfxBeginThread((AFX_THREADPROC)Run, this,
    0, 0,
    CREATE_SUSPENDED, NULL);
    m_pThread->ResumeThread();
    }void CMainFrame::OnStop() 
    {
    // TODO: Add your command handler code here
    m_pThread->PostThreadMessage(WM_QUIT, 0, 0);
    }
      

  12.   

    如下这篇文章描述的正是我的问题:试图在worker thread当中修改UI。希望各位看看。谢谢http://www.codeproject.com/threads/usingworkerthreads.asp
    【Worker threads and the GUI II: Don't touch the GUI】
      

  13.   

    不是不能修改GUI,而是不要在线程之间传递C++对象。C++对象有其生命期和作用域,最好传递句柄。
      

  14.   

    能解释的具体些吗?
    我快绝望了,幸亏codewarrior(会思考的草) 还在一步步指引着我。
      

  15.   

    请看错误停下的位置,MFC的一段注释:
    // Note: if either of the above asserts fire and you are
    // writing a multithreaded application, it is likely that
    // you have passed a C++ object from one thread to another
    // and have used that object in a way that was not intended.
    // (only simple inline wrapper functions should be used)
    //
    // In general, CWnd objects should be passed by HWND from
    // one thread to another.  The receiving thread can wrap
    // the HWND with a CWnd object by using CWnd::FromHandle.
    //
    // It is dangerous to pass C++ objects from one thread to
    // another, unless the objects are designed to be used in
    // such a manner.
      

  16.   

    to wangyang2000() :我刚刚试过,上面的方法导致程序界面僵化,而且没有对话框弹出。
    必须通过“任务管理器”才可以结束程序。你真的试过了吗???当然了为了安全起见你应该传递句柄
    UINT CMainFrame::Run(LPVOID p)
    {
    HWND hWnd = (HWND)p;
    ASSERT(hWnd != NULL); CMainFrame *pMain = (CMainFrame*)CMainFrame::FromHandle(hWnd);
    pMain->Run(); return 0;
    }void CMainFrame::Run()
    {
    MSG msg;
    while (1)
    {
    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    if (msg.message == WM_QUIT)
    {
    break;
    }
    }
    else
    {
    Sleep(10000);
    }
    }
    AfxMessageBox("exit thread");
    }void CMainFrame::OnRun() 
    {
    // TODO: Add your command handler code here
    m_pThread = AfxBeginThread((AFX_THREADPROC)Run, GetSafeHwnd(),
    0, 0,
    CREATE_SUSPENDED, NULL);
    m_pThread->ResumeThread();
    }
      

  17.   

    To: ukyoking(累) (★★)
        你的方法我试过了,不行。
        能否留下email,把我的project发给你看看???
      

  18.   

    为什么这么多人帮我却始终解决不了问题?是我没叙述清楚吗???我的主函数CProg::Run()是通过界面触发开始运行的。
    它的结构是这样的。for(int i=0;i<1000000;i++)
    {
      // 进行复杂的运算
      // 存于各个object当中
      // ......
      // 对UI界面进行刷新
    }整个程序的运作方式如下:1. 点击“开始”按钮
    2. 进入“Run()”的循环当中
    3. 循环结束,程序结束。
      

  19.   

    热泪盈眶:我解决问题了!!!!!!!!!!!
    谢谢大家的耐心解答,尤其是 ukyoking(累) (★★★★★)
    我是按照您的方法解决问题的。致礼!  ukyoking(累) (★★★★★)
    致礼!  CSDN的良好氛围!!!!!!
      

  20.   

    ukyoking(累) (★★★★★) ???????????????????????????楼主你你太抬举我了吧,虽然我也很想:)
      

  21.   

    wangyang2000() 提醒你一下,以后难题得解了以后最好申请加入FAQ,让更多的人受益,而你自己也可以得到1分信誉分的奖励,何乐而不为呢?