我需要实现一个带进度条的界面,进度条根据数据进行变化。  如果点击了取消按钮,则关闭该窗口。现在的问题是, 我先用非模式的方式创建该窗口, 可以根据数据改变进度条, 但点击按钮没有响应。用模式窗口试了一下, 直接阻塞到了主线程里,没办法执行到获取数据的逻辑里。有点糊涂了,不知道该采用什么方式, 请高手指点一下,不胜感激。

解决方案 »

  1.   

    用非模态的。你说的点按钮没有响应,应该是因为你主线程里面一直在处理,导致界面没有响应了吧。
    如果处理数据的操作,可以放到另外的线程里面做,那么就可以用多线程,再开一个线程来做。要是不可以,那就再处理数据之后Sleep一下,让界面接收一下消息。
      

  2.   

    我的逻辑大概如下:while  ( true)
    {
        获取数据....
        if (ok)
        {
            break;
        }
        else
        {
            将数据传给非模式对话框
             显示非模式对话框
             Sleep(5000);   //主线程休眠 
         }
    }这样,非模式对话框就不能响应按钮事件 
      

  3.   

    你取消的响应函数是用的OnCancel()吧,那不管用,你用DestroyWindow()关闭对话框。
      

  4.   

    我用的是 OnOK()  ,因为只想关闭窗口,就没有区分。请问 zhuwuwei,  如果用DestroyWindow(), 是不是采用 dlg.DestroyWindow() 这样的方式 ?
      

  5.   

    将数据传给对话框不要用SendMessage.
      

  6.   

    to i_love_pc:能不能给个思路, 比如 多线程怎么分工?  我现在是点击主界面触发这个 进度条界面, 那么 处理线程该怎么分工呢 ?我初步想,似乎界面和数据处理都需要死循环(或做定时任务)。
      

  7.   

    用非模态会有以下问题:无法阻止用户对主对话框的操作,会引起问题
    <<<<<用模式窗口试了一下, 直接阻塞到了主线程里,没办法执行到获取数据的逻辑里。 >>>>>
    主窗口和进度条窗口需要用消息传递。得到的数据需要SENDMESSAGE到主窗口,主窗口SENDMESSAGE到进度条窗口来改变进度条的显示。
      

  8.   

    在WINDOWS下编程就要用事件和多线程的方法,不能再用DOS下单线程的老方法!这里只能给你个思路:1、分析你的数据处理过程,找出的规律,也就是确定何时该更新进度条;2、建立一个新的 Worker Thread (工作线程没有用户界面),用它来进行数据处理;3、在你的窗口中实现进度条界面,同时加入“取消”按钮;4、在 Worker Thread 中,当达到更新进度条的条件时,向你的窗口发送消息,指定要更新进度条;5、在窗口中响应这个消息,在响应函数中更新进度条;6、当用户点击“取消”按钮时,改变全局变量;7、在 Worker Thread 中,每做完一组计算操作时,都要判断这个全局变量,目的就是看是不是用户按了取消按钮;8、如果用户在计算过程中按了“取消”按钮,那 Worker Thread 停止计算,结束线程;
    说明:整个过程对于初学者是很复杂的!要实现以上方法,需要掌握以下几点:1、多线程
    2、在线程中发消息给主线程(需要传递窗口指针)
    3、主线程响应消息
    4、可能还要涉及到线程的同步问题
    5、软件的逻辑,什么条件下给主线程发消息,要求更新进度条
    不过,如果做过了,那就会明白一些WINDOWS编程的精髓了!
      

  9.   

    看了你的逻辑,建议你使用C++ Build中的函数处理方法,可以直接更新界面(有专门的函数),这样比较符合你的逻辑
      

  10.   

    谢谢各位的指点, 前天已经弄好了,不过急着完成其它功能,没有时间,昨天论坛有问题,所以今天来结贴。顺便总结一下我现在的实现:
    1。主界面(主线程) 启动 一个工作线程, 用于计算数据,并根据数据更新 进度条窗口。(为了能直接在线程函数中显示进度条窗口,我将该窗口声明为static,我想今后可能会改成传递消息的方式,就不用受这个限制了)2。工作线程中止,用postmessage 给主窗口发一个自定义消息,主界面响应该消息,用于刷新界面相应部分。 开始时的主要理解错误,就是windows的主界面(同时也是主线程),不能阻塞,否则,相应的窗口消息就没办法得到。
    再次感谢 zaodt的详细描述。