你如何强制java swt程序“将自己移到前台”?

目前有了swt,我有时想让一个程序随意地走到前台(就像闹钟一样)。

通常以下作品(jruby):

@shell.setMinimized(false) @shell.forceActive 

如果它被最小化,它会将壳体带到前面。

随时创建一个新shell也会将(新shell)带到前面。

到目前为止,如果shell 没有最小化,上面的代码只是闪烁(闪烁)任务栏中的应用程序图标。 实际上,当你第一次运行它时,它会把它带到前面。 之后,它只是在任务栏中闪烁。 那是窗户。 在Linux上,它似乎只在任务栏中闪烁(默认为ubuntu)。

有人知道跨平台的方式让应用程序走到前面,在swt?

看来没有任何forceActive的setActive setMinimized(false)setFocus forceFocus和setVisible都可以完成这件事。

我很确定它是可能的(至少在Windows中),就像E文本编辑器那样。 嗯,这不是swt,但至少其他一些应用程序已经知道这样做 。

我想也许这是swt bug 192036 ?

非常感谢。

有关:

  • 如何将窗户拉到前面?
  • 打开壳牌
  • 将窗口保持在前景中(即使它失去焦点)
  • 错误244597 – 无法在gtk上以编程方式激活shell
  • 需要在Windows上将应用程序带到前台
  • 如何将窗户拉到前面? 这个摆动的例子可能也是某种类型的线索……

http://github.com/rdp/redcar/commit/d7dfeb8e77f13e5596b11df3027da236f23c83f0

显示我是如何在Windows中完成的(无论如何)(使用ffi)。

一些有用的技巧“可能”

在BringToFront.SetForegroundWindow(想要)调用之后添加’sleep 0.1’(希望实际上不需要这个)。

将窗口置于前台添加shell.set_active。 由于某种原因,forceActive不会调用setActive。

请注意,setActive会执行user32.dll BringWindowToTop调用,并且需要在分离线程输入之前完成。

另请注意,如果您可以按正确的顺序进行调用,则可能根本不需要使用线程输入hack(?)

http://betterlogic.com/roger/?p=2950

(包含几个关于如何正确执行此操作的好提示)

在Linux上,forceActive 确实有效 – 但只有在你移动到另外几个窗口之后,它才会在那之后(仅)在任务栏中闪烁。 猜swt bug。 [1]

还有关系:

如何将窗户拉到前面?

http://github.com/jarmo/win32screenshot/blob/master/lib/win32/screenshot/bitmap_maker.rb#L110“set_foreground ”似乎适用于xp和windows 7

[1] 需要在Windows上将应用程序带到前台并且https://bugs.eclipse.org/bugs/show_bug.cgi?id=303710

这在Windows 7和Ubuntu上对我有用:

 private void bringToFront(final Shell shell) { shell.getDisplay().asyncExec(new Runnable() { public void run() { shell.forceActive(); } }); } 

这实际上是Windows的一项function,可以通过Tweak UI电动玩具启用(至少对于Windows XP)。 当启用时,操作系统会故意阻止窗口强制自己成为聚焦窗口以阻止它“窃取焦点”。 因此,抓取焦点的动作改为仅闪烁任务栏图标 – 因为操作系统是故意根据用户的请求转换动作,所以你无能为力(这是一件好事)。

这可能(可能)已经完成,因为许多应用程序滥用了从前到底的API,并且这些行为都使用户烦恼并导致他们输入错误的应用程序。

 private static void onTop(Shell shell) { int s = -1; Shell[] shells = display.getShells(); for (int i = 0; i < shells.length; ++i) { if (!shells[i].equals(shell)) { shells[i].setEnabled(false); shells[i].update(); } else { s = i; } } while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } for (int i = 0; i < shells.length; ++i) { if (i != s) { shells[i].setEnabled(true); shells[i].update(); } } } 

错误192036 – Shell.forceActive不会在所有其他窗口上方引发窗口

@ rogerdpack对Eclipse bug跟踪器的查询得到了以下肮脏的解决方法 ,以满足我们的需求。

 public void forceActive(Shell shell) { int hFrom = OS.GetForegroundWindow(); if (hFrom <= 0) { OS.SetForegroundWindow(shell.handle); return; } if (shell.handle == hFrom) { return; } int pid = OS.GetWindowThreadProcessId(hFrom, null); int _threadid = OS.GetWindowThreadProcessId(shell.handle, null); if (_threadid == pid) { OS.SetForegroundWindow(shell.handle); return; } if (pid > 0) { if ( !OS.AttachThreadInput(_threadid, pid, true)) { return; } OS.SetForegroundWindow(shell.handle); OS.AttachThreadInput(_threadid, pid, false); } OS.BringWindowToTop(shell.handle); OS.UpdateWindow(shell.handle); OS.SetActiveWindow(shell.handle); } 

有一种方法可以使它与您最初尝试的方法一起使用。 实际上你需要调用shell.setMinimized(false)并在那个shell.setActive()之后恢复shell的先前状态。 但是 ,只有在shell真正处于最小化状态时才有效。 所以这是我的最终解决方案,如果它没有最小化,人工最小化shell 。 如果必须进行最小化,则成本是快速动画。

 shell.getDisplay().syncExec(new Runnable() { @Override public void run() { if (!shell.getMinimized()) { shell.setMinimized(true); } shell.setMinimized(false); shell.setActive(); } });