.NET/C# 使窗口永不激活(No Activate 永不获得焦点)

本文介绍如何使用C#和Win32 API让窗口在运行时不抢夺其他窗口的焦点,通过添加WS_EX_NOACTIVATE样式实现。适用于辅助程序如输入法窗口,确保外部程序的用户体验不受干扰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文 .NET/C# 使窗口永不激活(No Activate 永不获得焦点)

有些窗口天生就是为了辅助其它程序而使用的,典型的如“输入法窗口”。这些窗口不希望抢夺其它窗口的焦点。

有 Win32 方法来解决这样的问题,WS_EX_NOACTIVATE 便是关键。


具体来说,是给窗口样式中额外添加一个 WS_EX_NOACTIVATE 位。

var handle = GetTheWindowHandle(); int exstyle = GetWindowLong(handle, GWL_EXSTYLE); SetWindowLong(handle, GWL_EXSTYLE, exstyle | WS_EX_NOACTIVATE); 

当然,这里需要用到 P/Invoke 平台调用,可以阅读 使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名 了解快速生成平台调用方法签名的方法。

于是,我们将完整的窗口代码写完,是下面这样。

注意 64 位系统中需调用 GetWindowLongPtr 和 SetWindowLongPtr,而 32 位系统中是没有这两个方法的;在任何版本的 Windows 中都是这样。当然,64 位系统会为其上运行的 32 位进程模拟 32 位系统的环境。

using System;
using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; namespace Walterlv.Demo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); SourceInitialized += OnSourceInitialized; } private void OnSourceInitialized(object sender, EventArgs e) { var handle = new WindowInteropHelper(this).Handle; var exstyle = GetWindowLong(handle, GWL_EXSTYLE); SetWindowLong(handle, GWL_EXSTYLE, new IntPtr(exstyle.ToInt32() | WS_EX_NOACTIVATE)); } #region Native Methods private const int WS_EX_NOACTIVATE = 0x08000000; private const int GWL_EXSTYLE = -20; public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex) { return Environment.Is64BitProcess ? GetWindowLong64(hWnd, nIndex) : GetWindowLong32(hWnd, nIndex); } public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { return Environment.Is64BitProcess ? SetWindowLong64(hWnd, nIndex, dwNewLong) : SetWindowLong32(hWnd, nIndex, dwNewLong); } [DllImport("user32.dll", EntryPoint = "GetWindowLong")] private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")] private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLong")] private static extern IntPtr SetWindowLong32(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] private static extern IntPtr SetWindowLong64(IntPtr hWnd, int nIndex, IntPtr dwNewLong); #endregion } } 

运行这段代码,可以发现,即时我们的窗口中文本框获得了焦点,焦点其实依然在外面的程序中。(我们的文本框依然不会响应键盘输入的。)

No Activate


参考资料

本文会经常更新,请阅读原文: https://walterlv.com/post/no-activate-window.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值