WndProc覆盖不一致地捕获消息C#

use*_*868 0 c# wndproc

所以我遇到了一个非常奇怪的bug /计时问题,所以我简化了下面的代码来准确显示正在发生的事情.它在调试步进过程中非常有效,但是在没有断点的情况下运行奇怪的东西.

在我的MainForm中,我正在捕捉任务栏点击

    const int WM_ACTIVATEAPP = 0x1C; 
    int count = 0;
    protected override void WndProc(ref Message m)
    {
     if (m.Msg == WM_ACTIVATEAPP)
        {
         if (m.LParam.ToInt32() == 2504)
            {
               using (StreamWriter writer = new StreamWriter("C:\\log.txt", true))
                {
                    count++;
                    writer.WriteLine(count);
                }
            }
        }
     }
Run Code Online (Sandbox Code Playgroud)

m.LParam.ToInt32()== 2504表示在任务栏中单击了该程序.

如果我在"使用(StreamWriter ...",断开运行调试并单击10次(每次在编译器中必须为f5)之后设置断点,我将在日志中出现1-10.

如果我取下断点并且每隔几秒钟单击一次,总共10次(与上面相同),我最终得到的是1-2,1-4,但现在再也没有了.

没有断点和10次快速双击,每次都会记录1-20.

Ben*_*igt 6

m.LParam.ToInt32() == 2504 表示在任务栏中单击了该程序.

我不知道你为什么这么想,或者你得到了神奇的数字2504.

MSDN实际上说的什么

如果wParam参数是TRUE,lParam则拥有该窗口的线程的标识符被停用.如果wParamFALSE,lParam是否拥有正在激活的窗口的线程的标识符.

线程标识符可以在每次运行程序时更改,因此您根本看不到此数字也就不足为奇了.


如果你问的是如何能有更多的消息而不是点击,那是因为WM_ACTIVATEAPP它既有来又出.你无视wParam哪个让你分辨出来.

如果您想知道为什么断点会改变行为,那是因为lParam取决于"另一个窗口".断点会导致调试器窗口被激活,因此接收焦点的窗口序列会发生变化.