.NET/C# 使窗口永不获得焦点
2024-08-22 09:53:57
有些窗口天生就是为了辅助其它程序而使用的,典型的如“输入法窗口”。这些窗口不希望抢夺其它窗口的焦点。
有 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
}
}
运行这段代码,可以发现,即时我们的窗口中文本框获得了焦点,焦点其实依然在外面的程序中。(我们的文本框依然不会响应键盘输入的。)
参考资料
- c# - Not take focus, but allow interaction? - Stack Overflow
- Extended Window Styles - Microsoft Docs
- GetWindowLongPtr function (Windows)
- SetWindowLongPtr function (Windows)
最新文章
- 转载一些Android性能优化建议
- SpringSecurity操作指南-基于Spring、SpringMVC和MyBatis自定义SpringSecurity权限认证规则
- 【BZOJ】3757: 苹果树
- MYSQL中创建存储过程实现向表中循环插入数据
- unsigned 整型实现无溢出运算
- Ubuntu 14.04 AM335x TI-RTOS 编译
- js函数:setInterval()/clearInterval()——js网页计时器
- 使用django+mysql+scrapy制作的一个小说网站
- 10min系列之二日志可视化进阶
- 互联网金融P2P主业务场景自动化测试
- Python爬虫入门:爬虫基础了解
- 基于keras的BiLstm与CRF实现命名实体标注
- saltstack syndic
- 拜托!面试请不要再问我Spring Cloud底层原理[z]
- java 对象锁学习
- __getattr__和__setattt__使用
- Shell脚本编程基础笔记二
- 背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar
- hadoop家族成员
- LOJ2522:[FJOI2018]邮递员问题(乱搞)
热门文章
- .net 获取浏览器Cookie(包括HttpOnly)
- 聚类算法——MCL
- Swoft 快速上手小贴士
- angular 当使用ng-repeat 时出现 $$hashKey的键值对
- buctoj——合法的出栈顺序
- H3C WA2610i-GN FitAP telnet打开
- UITextView文字上方一段空白的解决方法
- 【LeetCode 104_二叉树_遍历】Maximum Depth of Binary Tree
- APUE学习笔记——5缓冲Buffering、流、文件对象
- dilworth定理+属性排序(木棍加工)