我有这么一个问题:主程序中有一棵树,点击树的某结点会执行一段读取数据库的操作,数据量很大时系统繁忙,如果鼠标在此时再点击其他节点,会死机。为了屏蔽鼠标动作,我想通过新开线程的方法弹出对话框,在数据读取完成以后再自动干掉此对话框。
用domodal()会报错,而messagebox()可以,但是怎样在程序中控制messagebox自己消失呢?另外,不能用creat对话框,因为不能锁定点击树的操作。不要给我讲用主线程弹出对话框,子线程读数据的方法,不想修改别人做好的东东。

解决方案 »

  1.   

    模式对话框就是把主窗体Disable掉,然后自己弄个个消息循环,把子窗体Show出来,所以我在想,为什么把菜单灰掉没有用?
      

  2.   

    回lake-cx,灰掉树后,鼠标在树的各个结点的点击仍然会被依次响应,造成死机,我问过师父能不能修改鼠标消息队列长度让它只接受一次响应.师父说不要修改win本身的东西...我郁....
      

  3.   

    注意起始和结束的位置分别在不同的函数中.
    Selecting()
    {
     ...
    开始  (在这里弹出模式对话框)
     ...
    }
    Selected()
    {
     ...
    结束  (这里让模式对话框消失)
     ...
    }
    但这两个函数属同一个类CLeftTree;逻辑不复杂,谢谢各位了..
      

  4.   

    我建议你这样做,把数据库读取显示做到线程里面,而不是把对话框做到线程里面。
    然后用一个变量bReadOver来表示这次数据库读取是否完成,树里面就根据这个变量来决定是否开的读数据库线程!
    这样来的好处就是界面肯定不会出现不响应的情况!
      

  5.   

    在进行子线程读写之前,禁用掉不可以点击的按钮、菜单、窗口,
    子线程读写完毕后,恢复按钮、菜单、窗口
    非模态对话框是很好的对策,模态对话框会阻塞线程,
    禁用控件的点击可以在父窗口的 PreTranslateMessage 中处理BOOL CD6Dlg::PreTranslateMessage(MSG* pMsg) 
    {
    if(pMsg->hwnd == GetDlgItem(IDC_TREE1)->m_hWnd 
    && pMsg->message == WM_LBUTTONDOWN)
    {
    if(b_Disable)
    {
    return(true);
    }
    }
    return CDialog::PreTranslateMessage(pMsg);
    }
      

  6.   

    EnableWindow函数功能:该函数允许/禁止指定的窗口或控制接受鼠标和键盘的输入,当输入被禁止时,窗口不响应鼠标和按键的输入,输入允许时,窗口接受所有的输入。
      

  7.   

    非要由主线程work,子线程显示对话框的话可以这么做:创建界面线程,由新创建的界面线程显示对话框。主线程读数据库,在读之前让MainFrame  EnableWindow(FALSE),数据库操作结束后,PostThreadMessage(dwChildThreadId, WM_QUIT, 0,0)给子线程
    并MainFrame  EnableWindow(TRUE)。这样可以达到目的,但是界面响应上还是不完美。
    这种做法并不好。较好的做法应该是让子线程(工作线程)去做耗时的事情,主线程响应界面。
      

  8.   

    回7楼:请将逻辑说的更清楚些,我的工程初始的逻辑结构在5楼写出来了.最好用类似方法表示;
    回8楼:谢谢;
    回9楼:非模式对话框和enablewindow对我来讲效果差不多,不能彻底解决问题;
    回10楼:请看2楼补充说明.回所有人:请将前5层楼都看完再提出解决方法,我现在想了一下,在子线程读取数据也可,只是怎样做呢?因为读取和读取结束不在同一函数中...郁闷!!
    注意了:解决了要多少给多少分
      

  9.   

    唉~~咋办呀,目前只能用create对付客户了,但愿客户别乱点鼠标。