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

有 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 位系统中需调用 GetWindowLongPtrSetWindowLongPtr,而 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
}
}

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


参考资料

最新文章

  1. 转载一些Android性能优化建议
  2. SpringSecurity操作指南-基于Spring、SpringMVC和MyBatis自定义SpringSecurity权限认证规则
  3. 【BZOJ】3757: 苹果树
  4. MYSQL中创建存储过程实现向表中循环插入数据
  5. unsigned 整型实现无溢出运算
  6. Ubuntu 14.04 AM335x TI-RTOS 编译
  7. js函数:setInterval()/clearInterval()——js网页计时器
  8. 使用django+mysql+scrapy制作的一个小说网站
  9. 10min系列之二日志可视化进阶
  10. 互联网金融P2P主业务场景自动化测试
  11. Python爬虫入门:爬虫基础了解
  12. 基于keras的BiLstm与CRF实现命名实体标注
  13. saltstack syndic
  14. 拜托!面试请不要再问我Spring Cloud底层原理[z]
  15. java 对象锁学习
  16. __getattr__和__setattt__使用
  17. Shell脚本编程基础笔记二
  18. 背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar
  19. hadoop家族成员
  20. LOJ2522:[FJOI2018]邮递员问题(乱搞)

热门文章

  1. .net 获取浏览器Cookie(包括HttpOnly)
  2. 聚类算法——MCL
  3. Swoft 快速上手小贴士
  4. angular 当使用ng-repeat 时出现 $$hashKey的键值对
  5. buctoj——合法的出栈顺序
  6. H3C WA2610i-GN FitAP telnet打开
  7. UITextView文字上方一段空白的解决方法
  8. 【LeetCode 104_二叉树_遍历】Maximum Depth of Binary Tree
  9. APUE学习笔记——5缓冲Buffering、流、文件对象
  10. dilworth定理+属性排序(木棍加工)