zoukankan      html  css  js  c++  java
  • 关于在OnTimer中连续弹出对话框的讨论

     

    CxxxDlg::OnTimer(UINT nIDEvent)
    {
      static int i = 0,j;
      j = i++;
      if (i==2) KillTimer(nIDEvent);
      MessageBox("!");
      i++;
      CString str;
      str.Format("%d,%d ",j,i);
      ::OutputDebugString(str);
    }

       

          以上代码在执行的时候,会弹出2个messagebox。很多人都有1个疑问,那就是当第一个消息框弹出的时候,应该相当于是模态对话框,怎么还会第二次进入OnTimer,并且再次弹出messagebox?

        首先,让我们来了解一下计时器的原理。计时器可以响应事件,而用户界面也可以响应。但是程序却只有一个线程。CPU不得不分配一个时间片给应用程序专门处理定时器事件,应用程序不能在外面操作定时器。因为定时器处理是由CPU统一处理。

         让我们再来看看常见模态对话框的domodal到底干了些什么。MSDN解释如下:

    The   function   displays   the   dialog   box   ,   disables   the   owner   window,   and   starts   its   own   message   loop   to   retrieve   and   dispatch   messages   for   the   dialog   box.

    When   the   dialog   box   procedure   calls   the   EndDialog   function,   DialogBoxParam   destroys   the   dialog   box,   ends   the   message   loop,   enables   the   owner   window   。

         所以这里只是【Disables   the   owner   window】,所以主窗口中的定时器等都可以正常运行,只是无法响应用户的操作了。

        好,以上就解释了OnTimer还是定时响应的,问题的另一个关键是怎么第二个messagebox还能弹出来?

         原来,当你在主消息循环的消息处理函数中弹出一个模态对话框,他阻塞了主消息循环,理论上,这时可以把主窗口关闭了!但是因为这个弹出的模态对话框还在,它阻塞了winmain这个主消息循环,实际上你是关不掉的。注意,阻塞的实际意思是说:消息被模态对话框处理了,而没有传到后面的父窗口。而每次弹出对话框,都是由最上层的那个消息框掌握着消息循环,其他的消息循环被阻塞了。

          所以,上面代码运行的情况是:

    (1)弹出第一个messagebox,然后后续代码暂停执行。

    (2)第二次进入OnTimer

    (3)弹出第二个messagebox接替消息循环,第一个messagebox禁用。后续代码暂停执行。

    (4)用户点击第二个messagebox。此时显示结果,i = 3,j=1;再次,点击第一个messagebox,此时显示结果,i=4 ; j=0

  • 相关阅读:
    C# XML 文档注释
    大数据知识学习
    现在的人,买个钢铁做的车,每天擦,每周打蜡。可对自已的身体最应该保养的“车”,却从不养护
    Asp.net项目因Session阻塞导致页面打开速度变慢
    AvoidRepeatSubmit通过Javascript避免客户端重复提交请求
    Linux下Attansic L2 网卡驱动安装
    如果知道dll文件是面向32位系统还是面向64位系统的?
    整理C# 二进制,十进制,十六进制 互转
    连接Oracle时出现“System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”错误的问题
    [转]删除hbase表region块脚本
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/1994910.html
Copyright © 2011-2022 走看看