WM_HELP 在启动 vtk 或 spy++ 时停止发送 运行

WM_HELP stops being send when vtk is started or spy++ is running

在我们的软件中,我们偶尔使用通过 SendMessage api 向控件发送 WM_HELP。通常 "HelpRequested" 事件随后会被触发(或在父层次结构中向上,直到事件处理程序被注册)。

我们包含了一个名为 "VTK" 的外部复杂 3d 可视化库,此后,此消息传递不再有效。在试图追查问题时,我使用 Spy++ 查看消息是否显示在那里,并意识到 运行 spy++ 正在生成相同的问题! (也没有任何 vtk 的东西)。可以用这个小程序显示:

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestHelp
{
    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        struct HelpInfo
        {
            public uint cbSize;
            public int iContextType;
            public int iCtrlID;
            public int hItemHandle;
            public int dwContextID;
            public int MouseX;
            public int MouseY;
        }

        [DllImport("user32.DLL", EntryPoint = "SendMessage", SetLastError = true)]
        private static extern int SendHelpMessage(int hWnd, uint Msg, uint wparam, ref HelpInfo helpinfo);

        public static void RaiseHelp(Control ctrl)
        {
            HelpInfo helpInfo = new HelpInfo
            {
                cbSize = 48,
                iContextType = 1,
                iCtrlID = 0,
                hItemHandle = ctrl.Handle.ToInt32(),
                dwContextID = 0,
                MouseX = 10,
                MouseY = 10,
            };

            var res = SendHelpMessage(ctrl.Handle.ToInt32(), 0x053, 0, ref helpInfo);
            Debug.WriteLine($"SendMessage returns:{res}");
        }

        public Form1()
        {
            InitializeComponent();

            button1.HelpRequested += (sender, hlpevent) => { Trace.WriteLine("HelpRequested called"); };

            timer = new Timer() {Interval = 1000, Enabled = true};
            timer.Tick += (sender, args) => RaiseHelp(button1);
        }
        private Timer timer;
    }
}

表单仅包含一个名为 "button1" 的按钮。

当您在调试器中启动时,您每秒都会在输出 window 中看到 "HelpRequested called"。当您启动 Spy++ 时,仅此而已,只要启动,它就会停止!当关闭 spy++ 时,它会继续工作。每个人都对这种行为有解释吗? Spy++ 对我的应用程序做了什么?我希望相同的机制对 vtk 的相同问题负责(尽管只有进程内)。 当然,使用 win32 api SendMessage 似乎不适合 WinForms 应用程序,但我们现在没有时间重构所有这些东西,但我还是想了解这里发生了什么! 顺便说一句:用户 window 消息不受影响(WM_USER 到 0x7FFF),通过覆盖 WndProc 检查。 WM_HELP 也不会显示在 WndProc 中,而 spy++ 是 运行,顺便说一句。

问题是 HelpInfo.cbSize 的尺码错误。在 64 位模式下它是 40,在 32 位模式下它是 28。是的我应该使用 sizeof(),但这只允许在 "unsafe" 模式下。 但是 spy++ 或 VTK 到底是怎么干扰这个的?