通过Google快速搜索Windows中的Focus Stealing解决方案,可以看到两个主要结果类别:
在两种常见情况下尤其令人讨厌:
有些东西触发程序在全屏应用程序聚焦时在后台弹出对话框窗口,从而使全屏应用程序最小化.
在您打字时,窗口会窃取焦点,窃取您的所有击键.如果您碰巧按空格键,输入键或触发键盘快捷键(如Y表示是),则可能会导致完全不良后果.
可以应用哪些创意解决方案来解决这些问题中的一个或两个问题?
如何获取打开的文件夹列表,通过它进行枚举并以编程方式最小化每个文件夹?
有时,一些打开的文件夹在从应用程序中的一个表单跳转到另一个表单时会从该工具中窃取焦点.防止这种情况对我们的客户来说是高度优先的.客户是视障人士,因此他们只能通过屏幕阅读器访问机器.最小化其他窗口(文件夹)根本不是问题,实际上是一个要求.
我试过这个:
foreach (Process p in Process.GetProcessesByName("explorer"))
{
p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样没有好处.
更新:
从这里的答案,我试过这个:
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processID)
{
List<IntPtr> handles = new List<IntPtr>();
EnumThreadDelegate addWindowHandle = delegate(IntPtr hWnd, IntPtr param)
{
handles.Add(hWnd);
return true;
};
foreach (ProcessThread thread in Process.GetProcessById(processID).Threads)
EnumThreadWindows(thread.Id, addWindowHandle, IntPtr.Zero);
return handles;
}
const int SW_MINIMIZED = 6;
[DllImport("user32.dll")]
static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
private …
Run Code Online (Sandbox Code Playgroud) 在(嵌入式)Ubuntu 12.04系统上,我们有一个简单的Java程序,它在窗口上显示一些图形模式,每秒钟更新一次.我们用它来监控系统上运行的一些进程.问题在于,虽然它是活动的而不是最小化的,但只要窗口更新,它就会窃取焦点.这使得无法使用开放式终端窗口.
运行应用程序表单命令行或从Eclipse IDE时,行为是相同的.
在NetBeans IDE下运行时,Windows 7上不会出现同样的问题.
我们如何防止Java应用程序将重点放在Ubuntu机器上?
更新1:发现这个问题似乎很难解决同样的问题: 如何停止/解决Java应用程序窃取Linux窗口管理器的焦点.阅读它,我了解到问题是使用JFrame作为容器,这是我们使用的.他们的解决方案是使用JWindow容器而不是JFrame容器.然而,寻找差异,JWindow是"赤裸裸",并没有表现得像一个"真正的"窗口,因为没有装饰.有没有办法在 JFrame中使用JWindow ,从而消除焦点窃取?
更新2:尝试在PC上的Ubuntu虚拟机上运行此程序会产生同样的错误行为.这表明Windows 7和Linux的Java运行时存在差异,并且该问题并非特定于嵌入式Linux.
更新3:这是一个SSCCE:
//package SSCCE;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class MonitorSSCCE extends JFrame{
public static void main(String[] args)
{
// Set the frame
JFrame ecoreFrame = new JFrame("SSCCE");
ecoreFrame.setSize(120, 120);
ecoreFrame.setVisible(true);
// Refresh frame every 200 msec
while (true) {
GRFX grfx = new GRFX();
ecoreFrame.add(grfx);
ecoreFrame.setVisible(true);
grfx = null;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
} …
Run Code Online (Sandbox Code Playgroud) 我想打开一个隐藏的Internet Explorer窗口而不会窃取焦点.我有一个Timer对象,每5分钟打开一次Internet Explorer,检查网站是否有更新.问题是每次检查更新时,都会从前台的当前应用程序中窃取焦点.以下是我开始这个过程的方法:
Process m_Proc = new Process();
m_Proc.StartInfo.Arguments = String.Format("{0}{1}", "-nomerge ", browserURL);
m_Proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
m_Proc.StartInfo.UseShellExecute = true;
m_Proc.StartInfo.CreateNoWindow = true;
m_Proc.StartInfo.FileName = String.Format("iexplore.exe");
m_Proc.Start();
Run Code Online (Sandbox Code Playgroud)
它总是窃取焦点,即使它被隐藏.我希望它从没有发生任何事情开始,因此用户可以继续处理他们正在做的事情.谢谢.
重现我的案例 (.net 4.0)
你的项目准备好了,
你会看到你不能在 Window1 中将焦点设置在文本框上,因为 MainWindow Texbox(在 winformshost 中会窃取你对你的应用程序激活的关注)
任何的想法?
主窗口.xaml
<Window x:Class="WinFormsHostFocusProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WinFormsHostFocusProblem"
xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
Title="MainWindow" Height="350" Width="525">
<Grid>
<my:WindowsFormsHost Focusable="False" >
<local:UserControl1>
</local:UserControl1>
</my:WindowsFormsHost>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
主窗口.xaml.cs
namespace WinFormsHostFocusProblem
{
public partial class MainWindow : Window
{ …
Run Code Online (Sandbox Code Playgroud)