【问题标题】:C# - Windows Forms - Windows 7 - Overlay another application's windowC# - Windows 窗体 - Windows 7 - 覆盖另一个应用程序的窗口
【发布时间】:2013-05-24 23:55:37
【问题描述】:

我有一个应用程序需要覆盖另一个应用程序的窗口。随着重叠的移动,我需要我的应用程序随之移动。

我正在使用以下代码来获取窗口并将我的窗口定位在它上面。

public static void DockToWindow(IntPtr hwnd, IntPtr hwndParent)
    {
        RECT rectParent = new RECT();
        GetWindowRect(hwndParent, ref rectParent);

        RECT clientRect = new RECT();
        GetWindowRect(hwnd, ref clientRect);
        SetWindowPos(hwnd, hwndParent, rectParent.Left, 
                                     (rectParent.Bottom - (clientRect.Bottom - 
                                      clientRect.Top)),  // Left position
                                     (rectParent.Right - rectParent.Left),
                                     (clientRect.Bottom - clientRect.Top),
                                     SetWindowPosFlags.SWP_NOZORDER);

     }

我还将 form.TopMost 设置为 true。 我遇到的问题是覆盖将焦点从覆盖的窗口中移开。 我只希望我的叠加层位于此窗口的顶部,但不会窃取焦点。如果用户单击覆盖的窗口,我希望它像放置覆盖之前那样工作。 但是,如果用户单击叠加层,我需要在叠加层上捕获鼠标。

有什么想法吗? 谢谢

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    在 winforms 中,您可以通过覆盖 ShowWithoutActivation 来避免焦点设置

    protected override bool ShowWithoutActivation
    {
      get { return true; }
    }
    

    http://msdn.microsoft.com/en-us/library/system.windows.forms.form.showwithoutactivation.aspx

    【讨论】:

    • 我试过这个并且它确实有效,但是当我移动覆盖的窗口时它仍然在窃取焦点。我有一个解决方案。
    • @JimBucciferro 太棒了!您应该将您的修复作为自己的答案发布以供其他人稍后阅读,并编辑您的问题以包括在移动时也不要专注的要求。
    • 我的解决方案有效,但它将我的叠加层保留在所有窗口的顶部,而不仅仅是我想要叠加的窗口。
    【解决方案2】:

    来自Floating Controls, Tooltip-style,在您的叠加表单上试试这个:

    private const int WM_NCHITTEST             = 0x0084;
    private const int HTTRANSPARENT            = (-1);
    
    /// <summary>
    /// Overrides the standard Window Procedure to ensure the
    /// window is transparent to all mouse events.
    /// </summary>
    /// <param name="m">Windows message to process.</param>
    protected override void WndProc(ref Message m)
    {
      if (m.Msg == WM_NCHITTEST)
      {
        m.Result = (IntPtr) HTTRANSPARENT;
      }
      else
      {
        base.WndProc(ref m);
      }
    }
    

    【讨论】:

      【解决方案3】:

      我能够通过更新 SetWindowPos 代码以使用覆盖窗体的 Left、Top、Right 和 Bottom 属性而不是使用 GetWindowRect 来找到此问题的解决方案。

       RECT rect = new RECT();
       GetWindowRect(hostWindow, ref rect);
       SetWindowPos(this.Handle, NativeWindows.HWND_TOPMOST,
                                               rect.Left+10,
                                               rect.Bottom - (Bottom - Top),
                                              (rect.Right - rect.Left),
                                               Bottom - Top,
                                               0);
      

      此代码沿主机窗口的底部边缘对齐覆盖窗口。 我现在遇到的问题是我的覆盖在所有窗口之上,而不仅仅是我想要覆盖的窗口。我试过 HWND_TOP 做同样的事情,以及覆盖窗口句柄,它将我的覆盖层放在窗口下方。

      任何想法 - 我需要使用 SetParent() 吗?

      【讨论】:

      • 我认为问题是关于点击覆盖表单将焦点移开。
      • 是的。使用前面的代码,它会带走焦点。新代码修复了这个问题,但现在显示在所有窗口上方,我只希望它显示在选定窗口上方。
      猜你喜欢
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多