WPF 让窗口激活作为前台最上层窗口的方法
在 WPF 中,如果想要使用代码控制,让某个窗口作为当前用户的输入的逻辑焦点的窗口,也就是在当前用户活动的窗口的最上层窗口,默认使用 Activate 方法,通过这个方法在大部分设备都可以做到激活窗口
但是在一些特殊的设备上,使用下面代码调起窗口只是在任务栏闪烁图标,而没有让窗口放在最上层
window.Show();
window.Activate();
在大部分设备上,通过 Show 和 Activate 组合可以让窗口作为当前用户活动的,即使窗口之前是最小化或隐藏,都可以通过 Show 的方法显示
但是某些设备窗口被盖在其他的窗口的下面,此时的窗口的 window.IsActive 还是 true 但是调用 Activate 不会让窗口放在上层
我在网上看到好多小伙伴调用了 SetForegroundWindow 方法,其实现在 WPF 是开源的,可以看到 Window 的 Activate 方法是这样写
public bool Activate()
{
// this call ends up throwing an exception if Activate
// is not allowed
VerifyApiSupported();
VerifyContextAndObjectState();
VerifyHwndCreateShowState();
// Adding check for IsCompositionTargetInvalid
if (IsSourceWindowNull || IsCompositionTargetInvalid)
{
return false;
}
return UnsafeNativeMethods.SetForegroundWindow(new HandleRef(null, CriticalHandle));
}
源代码请看 github
也就是调用 SetForegroundWindow 和调用 Activate 方法是差不多的,如果调用 Activate 应该调用 SetForegroundWindow 也差不多
通过大佬的 SetForegroundWindow的正确用法 - 子坞 - 博客园 可以了解到,需要按照以下步骤
1.得到窗口句柄FindWindow
2.切换键盘输入焦点AttachThreadInput
3.显示窗口ShowWindow(有些窗口被最小化/隐藏了)
4.更改窗口的Zorder,SetWindowPos使之最上,为了不影响后续窗口的Zorder,改完之后,再还原
5.最后SetForegroundWindow
在 WPF 中对应的更改窗口的顺序使用的是 Topmost 属性,同时设置顺序需要做一定小的更改
在 WPF 中通过 c# - Bring a window to the front in WPF - Stack Overflow 可以了解到如何用 AttachThreadInput 方法
整个代码请看下面,具体的 win32 方法我就没有写出来了,请小伙伴自己添加
private static void SetWindowToForegroundWithAttachThreadInput(Window window)
{
var interopHelper = new WindowInteropHelper(window);
var thisWindowThreadId = Win32.User32.GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);
var currentForegroundWindow = Win32.User32.GetForegroundWindow();
var currentForegroundWindowThreadId = Win32.User32.GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);
// [c# - Bring a window to the front in WPF - Stack Overflow](https://stackoverflow.com/questions/257587/bring-a-window-to-the-front-in-wpf )
// [SetForegroundWindow的正确用法 - 子坞 - 博客园](https://www.cnblogs.com/ziwuge/archive/2012/01/06/2315342.html )
/*
1.得到窗口句柄FindWindow
2.切换键盘输入焦点AttachThreadInput
3.显示窗口ShowWindow(有些窗口被最小化/隐藏了)
4.更改窗口的Zorder,SetWindowPos使之最上,为了不影响后续窗口的Zorder,改完之后,再还原
5.最后SetForegroundWindow
*/
Win32.User32.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);
window.Show();
window.Activate();
// 去掉和其他线程的输入链接
Win32.User32.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);
// 用于踢掉其他的在上层的窗口
window.Topmost = true;
window.Topmost = false;
我测试了几个原本没有让窗口放在上层的设备,使用上面的代码可以设置,但是我不了解设置上面代码可能的坑是什么
附带 walterlv 的测试工具,可以用来拿到当前的 GetForegroundWindow 是哪个
另外少君小伙伴写了一个有趣的库,里面封装了很多 win32 的方法,请看 kkwpsv lsjutil
WPF 让窗口激活作为前台最上层窗口的方法的更多相关文章
- 将后台窗口激活到前台的方法(使用AttachThreadInput和SetForegroundWindow两个API)
下面这种方法是我见到的最理想的,还有一些其他的方法,像通过SetWindowsPos这个API设置窗口的Z-oder到最顶层,再设置回去.还有通过把当前窗口设置到底层,然后激活目标窗口等等方法. HW ...
- js设置当前窗口为最上层窗口
实际使用iframe框架时会遇到当前窗口页面不能位于最上层窗口的情况,或者是防止自己的网站被别人放在他们的iframe中,这时就需要设置: <script language="java ...
- WPF的消息机制(三)- WPF内部的5个窗口之处理激活和关闭的消息窗口以及系统资源通知窗口
原文:WPF的消息机制(三)- WPF内部的5个窗口之处理激活和关闭的消息窗口以及系统资源通知窗口 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/p ...
- WPF中禁止WebBrowser控件打开新窗口
一.针对纯WPF的WebBrowser控件: <summary> Suppress Script Errors In WPF WebBrowser </summary> pub ...
- Win32 程序在启动时激活前一个启动程序的窗口
UWP 程序天生单实例.当然,新 API (10.0.17134)开始也提供了多实例功能.不过,传统 Win32 程序可就要自己来控制单实例了. 本文介绍简单的几个 Win32 方法调用,使 Win3 ...
- WPF DispatcherTimer(定时器应用) 无人触摸60s自动关闭窗口
原文:WPF DispatcherTimer(定时器应用) 无人触摸60s自动关闭窗口 如果无人触摸:60s自动关闭窗口 xmal:部分 <s:SurfaceWindow x:Class=&qu ...
- WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口
原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...
- C# 禁用窗口激活
如果界面点击时,不想让窗口激活,可以按如下操作: 1 public MainWindow() 2 { 3 InitializeComponent(); 4 SourceInitialized += O ...
- C# 获取指定窗口的上层窗口
如何获取当前窗口层级上方的所有窗口信息 User32有函数GetWindow function (winuser.h) - Win32 apps | Microsoft Docs,可以根据已知窗口句柄 ...
- WPF编程,C#中对话框自动关闭的一种方法。
原文:WPF编程,C#中对话框自动关闭的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8 ...
随机推荐
- 记录--你不知道的forEach函数
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 老实说我不喜欢用forEach,因为它导致的一些bug总是这么不经意,盘点我不喜欢的原因 原因一:不支持处理异步函数 先看一个例子: as ...
- Java freemarker 模板生成word动态表格
1.新建一个word文档 2.把调整完的word另存为xml格式: 3.使用文本编辑器打开 4.xml格式化XML 在线格式化 | 菜鸟工具菜鸟工具-XML 在线格式化..https://c.runo ...
- List和ObservableCollection的转换
1.我们后台查询全部List数据的时候,前台需要ObservableCollection展示 这个时候List需要转换成ObservableCollection public static Obser ...
- MyBatis 简介、优缺点
40)谈谈 MyBatis Mybatis 是一个半自动化的 ORM 框架,它对 jdbc 的操作数据库的过程进行封装,使得开发者只需要专注于 SQL 语句本身,而不用去关心注册驱动,创建 conne ...
- 开源LaTex可视化编辑器推荐,支持LaTex代码补全,一键套用模板!
https://latexlive.com/ 这还是个开源项目,不过是C#的,搭建的成本比较大,没PHP好搞. 下面是这个网站
- 7. The Singular Value Decomposition(SVD)
7.1 Singular values and Singular vectors The SVD separates any matrix into simple pieces. A is any m ...
- js调用摄像头,实现简单的视频展台软件
参考文档: web api:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices codeantenna:https://code ...
- 机器学习常见的sampling策略 附PyTorch实现
简单的采样策略 首先介绍三种简单采样策略: Instance-balanced sampling, 实例平衡采样. Class-balanced sampling, 类平衡采样. Square-roo ...
- AI数字人互动大屏:如何改变我们的生活?
随着科技的飞速进步和人工智能技术的日益成熟,智能制造正在成为推动制造业转型升级的核心力量. 互动数字人具有强大的情感分析能力,可以根据观众的表情.语气等实时反馈,作出恰当而富有情感的回应.这不仅让每一 ...
- sql 语句系列(字符串之裂开)[八百章之第十三章]
创建分割列表 一张表: 先查询出来的效果是这样的: mysql: select emp_copy.deptno,GROUP_CONCAT(emp_copy.emps SEPARATOR ',') fr ...