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

简介: 原文 .NET/C# 使窗口永不激活(No Activate 永不获得焦点) 有些窗口天生就是为了辅助其它程序而使用的,典型的如“输入法窗口”。这些窗口不希望抢夺其它窗口的焦点。 有 Win32 方法来解决这样的问题,WS_EX_NOACTIVATE 便是关键。

原文 .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 ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

目录
相关文章
|
C# Windows 容器
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示气球状提示框(Win10只有为本地Toast通知),ToolTip\oolTipText可以...
1477 0
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
|
消息中间件 安全 API
C#实现操作Windows窗口句柄:SendMessage/PostMessage发送系统消息、事件和数据【窗口句柄总结之二】
SendMessage/PostMessage API 可以实现发送系统消息,这些消息可以定义为常见的鼠标或键盘事件、数据的发送等各种系统操作......
3731 1
C#实现操作Windows窗口句柄:SendMessage/PostMessage发送系统消息、事件和数据【窗口句柄总结之二】
|
1月前
|
设计模式 C#
36.c#:如何设置MDL窗口
36.c#:如何设置MDL窗口
15 1
|
1月前
|
C# 开发者
35.c#:winform窗口
35.c#:winform窗口
12 1
|
2月前
|
安全 C# 开发者
.NET开源的一键自动化下载、安装、激活Microsoft Office利器
.NET开源的一键自动化下载、安装、激活Microsoft Office利器
|
5月前
|
Windows
基于.Net Core实现自定义皮肤WidForm窗口
基于.Net Core实现自定义皮肤WidForm窗口
49 0
|
5月前
|
开发框架 自然语言处理 文字识别
一款C#开发的窗口文本提取开源软件
一款C#开发的窗口文本提取开源软件
45 2
|
关系型数据库 API C#
C#调用执行命令行窗口cmd,及需要交互执行的处理
C#执行外部程序用到的是Process进程类,打开一个进程,可以指定进程的启动信息StartInfo(启动的程序名、输入输出是否重定向、是否显示UI界面、一些必要参数等)...
2334 0
C#调用执行命令行窗口cmd,及需要交互执行的处理
|
SQL 数据库连接 C#
C#项目 学生选课系统 C#窗口 Winform 项目 项目源码及使用说明
C#项目 学生选课系统 C#窗口 Winform 项目 项目源码及使用说明
432 0
C#项目 学生选课系统 C#窗口 Winform 项目 项目源码及使用说明
|
C# Windows
推荐一个C#开发的窗口扩展菜单,支持系统所有窗口
一个C#开发的窗口扩展项目,采用.NET Framework 4.0开发,支持Windows Xp以及更高版本的系统,同时支持命令模式,可供代码调用。
98 0
推荐一个C#开发的窗口扩展菜单,支持系统所有窗口