除了这个窗口看不见之外,它和程序中创建的另外的子窗口有什么区别?好象没有吧? 实际上根本就不要创建这个窗口,直接将这段代码放到g_hWndMain窗口的窗口过程中然后给g_hWndMain发消息不也可以起到同样的效果吗?

解决方案 »

  1.   

    所谓Winsock消息通知,也是搞了一个隐藏窗口的
      

  2.   

    xxxbird(*说你行,你就行,不行也行*) 对,但这样生成的线程占用了单独的cpu时间片,也许有好处,只是可能要考虑同步,线程结束等其他问题,这就成了自寻烦恼了
      

  3.   


    vcbear(一只平凡无知的熊)说的可能是指CSocket/CAsyncSocket的实现吧,实际上通常的Winsock 消息通知倒不一定要求窗口是不可见的。
      

  4.   

    这个不能实现多线程的优点,因为只有一个线程。1 如果用PostMessage。
    如果窗口g_hwnd[0]的一个消息处理函数做一个长时间的操作,那么在这个操作完成之前,procedure2是得不到运行机会的。反过来也一样,在procedure2完成之前,窗口g_hwnd[0]也是得不到运行消息处理机制机会的。2 如果用SendMessage
    就是在当前线程做,SendMessage将等待Procedure2完成。
      

  5.   

    TO xxxbird(*说你行,你就行,不行也行*),如果我这个g_hWndMain消息处理很繁忙,而MyThread()又是一个很耗时的程序段,你不觉得我单独开一个宪成会更好吗?还有,我所说的用窗口过程实现多线程也就是利用了该窗口看不见.虽然对于程序员这个窗口的确是与普通的窗口没区别,但是她的确实现了多线程的功能.至于leky2000说的同步,用SendMessage和PostMessage实际上就是实现了两种情况.SendMessage是要在线程执行完才返回,而PostMessage是表示不需要同步了
      

  6.   

    ShowWindow(g_hwnd[0],SW_HIDE);应该是ShowWindow(g_hwnd,SW_HIDE);了
    to platoprocedure是g_hwnd的窗口过程,由于这个窗口的目的的单一性,它会是专门用来发wm_com消息的,一般不会收到别的消息,除了wm_create和wm_close外.相对于主线程他的确是相当于又开了一个线程
      

  7.   

    其实跟Create一个Thread,然后PostThreadMessage比较,没有任何的优势和精妙之处
      

  8.   

    略微更正一下,g_hwnd[0]用的就是procedure2如果另外一个窗口,和m_hwnd[0]同属于一个线程,该窗口的一个消息处理函数做一个长时间的操作,那么在这个操作完成之前,procedure2是得不到运行机会的。反过来也一样,在procedure2完成之前,其它窗口也是得不到运行消息处理机制机会的。多线程的优点体现在哪里了?
      

  9.   


    这种实现方法和将其放在g_hWndMain中的效果完全一样。因为Windows的调度是以线程为单位的。如果MyThread()是一个很耗时的程序段,那么在执行MyThread()函数的时候,你的这个软件的其它部分也不会执行。除非在MyThread中有将控制权释放的函数如Yield等,如果这样的话,这段函数与放在g_hWndMain的窗口函数中还是没有任何区别。这样实现的唯一一个好处是可能使程序结构清楚一些, 在模拟多线程的功能上没有什么创意。
      

  10.   

    也许你会说,这个m_hwnd[0]所在的线程没有任何其他窗口。那岂不是多此一举?我先建立一个线程,在那个线程里面建立m_hwnd[0],我不能直接建立一个线程来做吗?如果这个m_hwnd[0]和其他窗口一样,在主线程里面建立的,那么:如果另外一个窗口,和m_hwnd[0]同属于主线程,该窗口的一个消息处理函数做一个长时间的操作,那么在这个操作完成之前,procedure2是得不到运行机会的。反过来也一样,在procedure2完成之前,其它窗口也是得不到运行消息处理机制机会的。多线程的优点体现在哪里了?  
      

  11.   

    to xxxbird(*说你行,你就行,不行也行*);实际上任何多线程都是这样,当单个cpu时,系统只有一个线程工作,因为系统只有一个cpu,也就是系统只能有一个cpu时间片,但是多线程不是在一个进程中抢占时间,所以多一个线程应该多一份抢占cpu的机会。当然线程太多不是好事 
      

  12.   

    ok,请教admire0兄,你在那里创建了线程?
      

  13.   

    真是低效率的办法,我觉得像WINDOWS 3.X的协作式多任务,始终只有一个线程,收到消息调用MyThread()时,发消息的地方还不是停止运行了,与其用这种方法还不如在你发消息的地方直接调用MyThread(),简单的任务还可以勉强,稍重点的运算界面就不听使唤了。节省一个线程的资源多出来这么多麻烦,不划算
      

  14.   

    to threads,假如在要执行MyThread()程序段的主线程里,调用
    PostMessage( g_hWnd,WM_COM,0,0 ).主程序返回,但程序在MyThread()里执行.实现多线程功能.
    所以在任何只要能得到g_hWnd句柄的地方,都可以调用到MyThread()函数.但不阻塞本线程的工作,因为你把消息寄出去后就不用管了.
    我看到的这段程序调用是在用户自定义的控件里,通过像g_hWnd送消息,来达到执行MyThread()程序段的效果.(而且很频繁)
      

  15.   

    to plato(天天) 在那个线程里的确是只有一个窗口.
    还有,你说的如果另外一个窗口,和m_hwnd[0]同属于一个线程,该窗口的一个消息处理函数做一个长时间的操作,那么在这个操作完成之前,procedure2是得不到运行机会的。反过来也一样,在procedure2完成之前,其它窗口也是得不到运行消息处理机制机会的。那是不是意味着DispatchMessage()要等消息执行完了之后才有返回?
      

  16.   

    我同意to plato(天天) 的观点。
      

  17.   


    DispatchMessage() 仅仅把消息放到相应的消息队列里,它并不等待消息执行完成。
      

  18.   

    呵呵,那看来是DispatchMessage后,线程的消息队列顺序执行,所以也就成了plato所说的了.
      

  19.   

    to admire0
    一个线程里的消息肯定是处理了一条,函数返回了再处理另一条的。说来说去,顶上那段代码只是通过消息循环来实现的,不是多线程。
    如果你坚持认为是多线程,比较大的可能是上面的代码原先就是运行在另一个线程里的。看不出这种做法有多少可取之处。
      

  20.   

    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
    哈哈,都被admireO(初学者)耍了,这根本不是多线程!
      

  21.   

    2 admire:
    實在看不出來是多線程,若你的看不見窗口和主窗口在一個線程中,那當你在主窗口的過程中發出WM_COM(假定用PostMessage),然后主窗口過程返回,又進入消息循環,再取出WM_COM,調用看不見窗口的窗口過程,到目前為止,始終都是在一個線程打轉,若MyThread是個死循環,難道該線程不會被挂住嗎? 才怪。2 xxxbird(*说你行,你就行,不行也行*):
    >>>DispatchMessage() 仅仅把消息放到相应的消息队列里,它并不等待消息执行完成。<<<
     如果DispatchMessage只是把消息放到相應消息隊列中,那到底由誰來調用窗口過程呢?
      

  22.   


    操作系统会调用窗口过程(Window procedure)来处理这些消息。
      

  23.   

    2 xxxbird(*说你行,你就行,不行也行*):
      我覺得你的說法不對,若照你這樣說,DispatchMessage在將消息放入消息隊列后就返回,那麼則消息循環在任何情況下都不會受阻,那又何來因窗口過程占用時間太長而導致窗口無法及時響應鍵盤、mouse事件之說呢?
      

  24.   

    上面这位老兄,你搞搞清楚,你说的无法响应键盘,鼠标事件,是对你自己那个窗口而言。别的进程的窗口不会受影响。每个进程(确切说是每个线程)都有它自己的消息循环。如果窗口进程(线程)忙于处理前一个消息,那么后面的那些WM_PAINT,键盘和鼠标消息都没有办法响应了。但是这只是影响你自己的窗口,而且跟你想反驳的“DispatchMessage在將消息放入消息隊列后就返回,那麼則消息循環在任何情況下都不會受阻”论点一点关系都没有。也就是说,你搞混淆了那个不同的概念。
      

  25.   

    请注意,线程是线程,窗口是窗口,这是两个完全不同的概念。最上面的那个人给出的那个代码根本就不是多线程的。所有这些隐含窗口全部运行在同一个线程下。也就是说,不管你开了多少窗口,线程只有一个,除非你用CreateThread()或者C Run Time Libary里的_beginThread/_beginThreadEx来产生新的线程。
      

  26.   

    to skeeter:
       你沒搞懂我的意思,我說的就是在一個線程的情況下。為簡單化,我們假設該線程只有一個窗口,那麼當收到一個消息后,GetMessage()->DispatchMessage()->窗口過程(中間的其它處理我們暫且略過),若窗口過程處理此消息耗時很久,那麼緊接輸入的key,mouse消息都將得不到處理(注意,是指發生在當前窗口上的各消息)。這個情況我想你也認同。
       但如果照xxxbird所說,DispatchMessage只是將消息放入消息隊列后就返回,那麼它將馬上又運行GetMessage()來取得下一消息,那麼你說在這樣的情況下,key,mouse消息會因為上一耗時消息的處理而受阻嗎?
       同時還有一點,DispathMessage是有返回值的,而其返回值正是窗口過程的返回值,如果DispatchMessage()只將消息放入消息隊列就走人,那麼請問,該返回值從哪里來?
       
       最后,我從來就沒有認為此帖子所說的是多線程,"最上面的那个人给出的那个代码根本就不是多线程的" 這句話我不知為何要對我說。
      

  27.   

    to admireO
    我觉得你还没有理解多线程和消息处理的机理
      

  28.   

    to all是因为我的代码没有贴完全
    while(::GetMessage( &message,NULL,0,0) )
    {
        .......
    }
    和主线程是不在同一线程里.所以不会造成MATE()所说的问题.
    今天我又找了些资料,这个应该是线程池的特例吧,和vcbear说的PostThreadMessage()差不多
    的确是没什么新意,不过大家的热烈讨论的确长了不少见识,再次谢过了
      

  29.   

    我的看法,下面的是出自msdn.
    The GetMessage function retrieves a message from the calling thread's message queue
    The return value(of DispatchMessage Function) specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored. 
    上面那句话的意思应该是DispatchMessage函数的返回值指定了窗口过程的返回值.所以,mate所说的,DispathMessage是有返回值的,而其返回值正是窗口過程的返回值.关系是否搞反了?但是Dispatch应该是消息处理完后才返回吧,这点同意mate所说的
    按照,GetMessage函数的说明,GetMessage是从消息队列中取出消息,所以,消息从GetMessage函数开始就已经被取出来了.
      

  30.   

    用CWinApp::OnIdle()加几个CEvent,不更简单方便吗?
      

  31.   

    TO mate, admire0,上面我说得不对,DispatchMessage 确实是等待消息处理完成后才返回的。
      

  32.   


    实际上,DispatchMessage函数调用了窗口过程函数。
      

  33.   


    有几个特殊情况,在WM_TIMER消息中,它调用的是TimerProc而不是窗口过程, 而且不是每次WM_PAINT消息时都调用窗口过程。
      

  34.   

    2 admireO(初学者):
      不好意思,我沒說清楚,我的意思就是DispatchMessage返回的就是窗口過程的返回值。
      

  35.   

    to admire0
    原来你上面的代码本来就是运行在另一个线程中的。被我猜中了吧。
    你这样建一个窗口,只是把该线程从工作者线程变成了界面线程。
      

  36.   

    看到csdn上一次心平气和的讨论真好.我看,最重要的的还是大家都把问题搞清楚了.
    再次谢过,xxxbird,mate,threads,plato,vcbear以及所有讨论的老兄们.