【问题标题】:In c# winforms, how to get the event that activated a window and forward itc#winforms中,如何获取激活窗口的事件并转发
【发布时间】:2017-02-03 16:36:38
【问题描述】:

首先让我解释一下我目前的情况以及为什么我认为我需要这个。很可能是我处理这件事的方式完全错误,因此愿意接受建议。

我们有一个使用 winforms 的 c# 程序,并且只有一个嵌入式 System.Windows.Forms.WebBrowser,它显示了一个带有嵌入式 Java 小程序的网站。 我们的用户一次打开了几个这样的程序。 java小程序有时需要一些时间来计算数据,而用户同时只使用他的其他窗口之一。当 java 小程序完成时,它会将焦点设置为自身,并且整个窗口弹出在顶部,这会中断用户正在执行的其他任务。我们无权访问 java applet 源代码,也无法以任何方式对其进行修改。调用通过 COM 连接到 WebBrowser 的 java 脚本函数具有相同的效果。

为了解决这个问题,我们在整个表单上创建了“停用”事件。调用时,它会设置嵌入式 WebBrowser.Enabled = false。在相应的“已激活”事件中,WebBrowser 再次启用。 这真的很好用:不再仅仅因为 java 小程序想要在后台将焦点设置为自身而弹出窗口。

我们现在遇到的问题是,当用户单击已停用的窗口时,窗口会被激活,但鼠标单击不会转发到 WebBrowser。例如,用户必须单击两次才能按下按钮。

所以我认为我的问题是如何将激活窗口的鼠标单击转发到 WebBrowser。

提前致谢 马库斯

【问题讨论】:

  • 当我说得对时,您可以在Form_Activated 事件中致电WebBrowser.Select()msdn.microsoft.com/en-us/library/…
  • 听起来很棘手。通过托管 Webbrowser 的表单中的 WndProc 覆盖,可能更容易抑制来自 java 的导致窗口聚焦的窗口消息。 (@RomCoo 他们试图转发实际的点击事件,而不仅仅是激活。就像当你打开两个相邻的浏览器时,你可以在后台打开一个链接,只需单击一下)
  • @dlatikay 谢谢你的建议。我刚刚试了一下,为整个窗口覆盖了 WndProc,并查看了它得到的消息,这些消息总是按 WM_WINDOWPOSCHANGING 和 WM_WINDOWPOSCHANGED 的顺序排列。之后,我收到几条不同的消息,它们总是以不同的顺序出现:WM_ACTIVATEAPP WM_GETICON、WM_NCACTIVE、WM_ACTIVATE。我认为这还没有定论,因为我需要知道这些消息的来源:-/

标签: c# winforms


【解决方案1】:

我想我找到了解决办法。它有效,但我不喜欢它:

    [DllImport( "user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall )]
    public static extern void mouse_event( uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo );

    private const int MOUSEEVENTF_LEFTDOWN = 0x02;
    private const int MOUSEEVENTF_RIGHTDOWN = 0x08;

    protected override void WndProc( ref Message m )
    {
        // If the panel which contains the WebBrowser was diabled, the messages WM_LBUTTONDOWN and WM_RBUTTONDOWN will not reach the panel
        // but will reach the window instead. We then resend them.
        if( m.Msg == 0x0201 ) // WM_LBUTTONDOWN
        {
            short x, y;
            MouseCoordsFromMessage( m, out x, out y );

            mouse_event( MOUSEEVENTF_LEFTDOWN, (uint)x, (uint)y, 0, 0 );
        }
        else if( m.Msg == 0x0204 ) // WM_RBUTTONDOWN
        {
            short x, y;
            MouseCoordsFromMessage( m, out x, out y );

            mouse_event( MOUSEEVENTF_RIGHTDOWN, (uint)x, (uint)y, 0, 0 );
        }
        else
        {
            base.WndProc( ref m );
        }
    }

    private static void MouseCoordsFromMessage( Message m, out short x, out short y )
    {
        x = unchecked( (short)(long)m.LParam );
        y = unchecked( (short)( (long)m.LParam >> 16 ) );
    }

我不确定这有多脆弱,想听听其他意见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多