不抢占焦点,但允许交互?

10
Windows 7 中的屏幕键盘可让您在使用键盘输入时保持对文本框的关注。在 C# 和 .Net 中,如何强制另一个应用程序在接受输入时保持焦点,就像 Win7 屏幕键盘一样?或者更好的表述方式是,如何在与应用程序交互时不使我的应用程序获得焦点?
我尝试过 LockSetForegroundWindow,但没有看到任何结果。
1个回答

17

你需要在窗口上设置 WS_EX_NOACTIVATE 扩展样式。最简单的方法是使用 P/Invoke。

private const int WS_EX_NOACTIVATE = 0x08000000;
private const int GWL_EXSTYLE = -20;

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowLong(IntPtr hwnd, int index);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);

...

var window = new Window();
window.SourceInitialized += (s, e) => {
    var interopHelper = new WindowInteropHelper(window);
    int exStyle = GetWindowLong(interopHelper.Handle, GWL_EXSTYLE);
    SetWindowLong(interopHelper.Handle, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE);
};
window.Show();

您还可以使用WPF互操作类HwndSource来创建窗口。它的构造函数接受扩展窗口样式。


我现在正在工作,无法尝试这个,但是我对这样一个简单的解决方案感到非常兴奋。等我回家后,我会把它加进去并报告它的表现如何。 - Corey Ogburn
1
请注意,如果窗口与任何其他窗口具有父\所有者关系,则此标志WS_EX_NOACTIVATE将被忽略。 - Ievgen
我注意到如果尝试移动Windows 7在线键盘,那么当拖动时,您会得到一个边框,随着鼠标的移动而移动,就像移动任何其他窗口一样。但是,如果将其设置为永不激活,那么您是否发现失去了该行为?有没有办法保持该行为,但仍然在单击其上的按钮时不要获取焦点? - barlop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接