热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:WPF让窗口激活作为前台最上层窗口的方法

篇首语:本文由编程笔记#小编为大家整理,主要介绍了WPF让窗口激活作为前台最上层窗口的方法相关的知识,希望对你有一定的参考价值。在WPF中,如果想要使用代码控制,让

篇首语:本文由编程笔记#小编为大家整理,主要介绍了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 是哪个

walterlv 的工具

另外少君小伙伴写了一个有趣的库,里面封装了很多 win32 的方法,请看 kkwpsv lsjutil


推荐阅读
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 如何在C#中配置组合框的背景颜色? ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 提升视觉效果:Unity3D中的HDR与Bloom技术(高动态范围成像与光线散射)
    提升视觉效果:Unity3D中的HDR与Bloom技术(高动态范围成像与光线散射) ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 基于试题数据的智能化管理平台采用Java语言进行面向对象编程,旨在构建一个高效的试题信息管理系统。该系统在JDK 6.0和MyEclipse 10.6环境下开发,通过优化试题数据管理和处理流程,提升系统的稳定性和用户体验。平台支持多用户操作,具备强大的数据处理能力和灵活的扩展性,适用于各类教育机构和考试组织。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 本文探讨了如何在C#应用程序中通过选择ComboBox项从MySQL数据库中检索数据值。具体介绍了在事件处理方法 `comboBox2_SelectedIndexChanged` 中可能出现的常见错误,并提供了详细的解决方案和优化建议,以确保数据能够正确且高效地从数据库中读取并显示在界面上。此外,还讨论了连接字符串的配置、SQL查询语句的编写以及异常处理的最佳实践,帮助开发者避免常见的陷阱并提高代码的健壮性。 ... [详细]
  • 本文深入探讨了C#中的反射与特性功能。首先,介绍了反射的基本概念,即通过元数据(包括类的方法、属性和字段等)在运行时动态获取和操作程序信息的能力。此外,还详细解析了特性的使用方法及其在代码注解和元数据扩展中的重要作用,为开发者提供了丰富的编程技巧和实践指导。 ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
author-avatar
手机用户2502871761
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有