如何在WPF(或者Interop)中恢复一个窗口,而不让它获得焦点?

9
我需要恢复(“取消最小化”)一个已创建的WPF窗口,但当前在顶部的窗口(不一定是WPF)不能失去焦点或激活。我已经尝试了所有我能找到的WIN32函数,但都没有成功。现在变得非常沮丧,真的很感谢任何提示和建议。
显然,仅在WPF中更改为WindowState.Normal并不够,因为这会使窗口获得焦点和激活。在恢复时,我还尝试了各种组合,包括设置Hidden和IsEnabled。
我尝试使用HWND_TOP、HWND_TOPMOST等WIN32 SetWindowPos,但该函数不旨在恢复窗口,而且只会更改已“显示”的窗口的位置。
尝试过WIN32 ShowWindow和SetWindowPlacement,但也没有帮助。我试图添加HwndHook来尝试侦听WM_SETFOCUS并将焦点恢复到原始窗口,但我只得到了上一个聚焦窗口句柄的零。
编辑 - 从Joel Lucsy得到的窗口扩展解决方案:
public static class RestoreWindowNoActivateExtension
{        
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool ShowWindow(IntPtr hWnd, UInt32 nCmdShow);

    private const int SW_SHOWNOACTIVATE = 4;

    public static void RestoreNoActivate(this Window win)
    {
        WindowInteropHelper winHelper = new WindowInteropHelper(win);
        ShowWindow(winHelper.Handle, SW_SHOWNOACTIVATE); 
    }
}

请问您能否提供您当前的代码? - Mare Infinitus
如果你真的觉得需要,我可以发布代码,但由于它只是一堆尝试使用不同调用的混乱,所以并没有什么可看的。但如果我成功了,我会发布一些东西的。 - Niclas
1个回答

8

调用 ShowWindow 函数并传递 SW_SHOWNOACTIVATE 标志。


我已经尝试了所有我能想到的参数组合来完成这个任务。现在我很有信心,SetWindowPos不能用于恢复窗口,但我很愿意被证明是错误的 :) - Niclas
1
ShowWindow和SW_SHOWNOACTIVATE怎么样? - Joel Lucsy
+1 我编辑了你的答案,包含了正确答案。留下一个不起作用的原始答案没有意义。 - David Heffernan
尝试了你的建议,但无法使其工作。奇怪的事情是,WindowState从最小化更改为普通状态,但窗口未能显示在屏幕上。有人可以确认ShowWindow应该恢复和显示窗口吗?今晚会尝试创建一个最小的示例来测试它。 - Niclas
我可以确认,使用SW_SHOWNOACTIVATE参数的ShowWindow函数应该能够恢复并显示窗口,而不会激活它或改变焦点。在一个最小化的示例中,它可以完美地工作。我需要找出在其他地方出了什么问题。感谢您的提示。 - Niclas
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接