【问题标题】:How to SetWindowPos Z-order of a window to just under the activated window?如何将窗口的 Z 顺序设置到激活窗口的正下方?
【发布时间】:2014-09-01 14:38:05
【问题描述】:

我有一个侧边栏应用程序(对话框 Win 表单应用程序),它使用 Watin 自动化控制关联的 IE 浏览器。

当侧边栏被激活时,我还想将关联的浏览器向前移动,但我不希望 win 表单应用失去焦点

我已经尝试了以下代码的许多设置/变体,但是 winforms 应用程序一旦激活就会失去对浏览器的关注,因此无法按下表单上的任何按钮!

    private void BrowserControlForm_Activated(object sender, EventArgs e)
    {
        if (this.Browser != null)
        {
            SetWindowPos(this.Browser.hWnd, -1, this.Width, 0, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - this.Width, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height, 0);
        }
    }

问。将另一个窗口放在(Z 顺序)当前激活的(Winforms)窗口下方的正确方法是什么?

示例代码还调整了浏览器占据屏幕其余部分的大小,但这与问题无关。更多现有代码无助于解决问题。

更新:

SWP_NOACTIVATE 根本无法使浏览器窗口向前移动:

SetWindowPos(this.CareCheckBrowser.hWnd, -1, this.Width, 0, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - this.Width, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height, 0x0010 /*SWP_NOACTIVATE*/);

在当前窗口的句柄仍然失去焦点之后插入:

SetWindowPos(this.Browser.hWnd, (int)this.Handle, this.Width, 0, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - this.Width, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height, 0);

在浏览器不起作用后将当前窗口设置为顶部,因为焦点已经丢失(因此仍然忽略按钮单击)。焦点/激活只是在任何点击时来回滑动,例如:

SetWindowPos(this.Browser.hWnd, 0, this.Width, 0, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - this.Width, System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height, 0x0004);
SetForegroundWindow(this.Browser.hWnd);
SetForegroundWindow(this.Handle);

【问题讨论】:

  • @Hans Passant:这是一种Form 方法。我需要提出单独的 IE 浏览器实例。可以将其应用于单独的 IE 实例(我只有一个 hWnd)吗?
  • 那么您将需要 SetWindowPos() 的 SWP_NOACTIVATE 选项。
  • @Hans Passant:我在更新时的 cmets 错误(剪切和粘贴错误)。我已经尝试过 SWP_NOACTIVATE。你能发现这个例子有什么问题吗?
  • 你为什么不调用 SetForegroundWindow() 两次。一个用于浏览器,一个用于您的窗口。

标签: c# winforms winapi


【解决方案1】:

获取所有打开的窗口句柄并查看未最小化的窗口句柄。遍历除浏览器句柄外的列表:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsIconic(IntPtr hWnd); //returns true if window is minimized

private List<IntPtr> windowsHandles = new List<IntPtr>();
//fill list with window handles

for (i = 0; i < windowsHandles.Count; i++)
{
    if (windowsHandles[i] != browserHandle && windowsHandles[i] != this.Handle && !IsIconic(windowsHandles[i]))
    { 
        SetWindowPos(windowsHandles[i], HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
    }
}

瓦尔特

【讨论】:

  • 我对此进行了扩展以排除当前应用程序 hWnd 以及浏览器 hWnd 并且它可以工作。 “不升桥,降河”。做得好。谢谢:)
  • @TrueBlueAussie 只是为了好奇。如何使用 GetWindow() 或 EnumWindows() 获得句柄?
  • 我将EnumWindowsIsWindowVisible()!IsIconic() 一起使用以过滤掉打开的应用程序窗口句柄。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多