目前有了swt,我有时想让一个程序随意地走到前台(就像闹钟一样)。
通常以下作品(jruby):
@shell.setMinimized(false)
@shell.forceActive
如果它被最小化,它会将shell带到前面。
随时创建一个新shell也会将(新shell)带到前面。
到目前为止一切顺利,如果shell 不最小化,上面的代码只是闪烁(闪烁)任务栏中的应用程序图标。实际上,当你第一次运行它时,它会把它带到前面。之后,它只是在任务栏中闪烁。那是窗户。在Linux上,它似乎只在任务栏中闪烁(默认为ubuntu)。
有没有人知道让应用程序走到前面的跨平台方式,在swt?
似乎没有强制使用forceActive setActive setMinimized(false)setFocus forceFocus和setVisible可以完成这件事。
我很确定它是可能的(至少在Windows中),就像E文本编辑器那样。嗯,这不是swt,但至少还有其他一些应用程序have been known to do it。
我想也许这是swt bug 192036?
非常感谢。
相关:
答案 0 :(得分:6)
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]
也相关:
How to bring a window to the front?
http://github.com/jarmo/win32screenshot/blob/master/lib/win32/screenshot/bitmap_maker.rb#L110“set_foreground”似乎与 xp和Windows 7一起使用
[1] Need to bring application to foreground on Windows和https://bugs.eclipse.org/bugs/show_bug.cgi?id=303710
答案 1 :(得分:6)
这适用于Windows 7和Ubuntu:
private void bringToFront(final Shell shell) {
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
shell.forceActive();
}
});
}
答案 2 :(得分:4)
这实际上是Windows的一项功能,可以通过Tweak UI电源玩具启用(至少对于Windows XP)。当启用时,O / S故意阻止窗口强制自己成为聚焦窗口以阻止它“窃取焦点”。因此,抓取焦点的动作改为仅闪烁任务栏图标 - 因为操作系统是故意根据用户的请求转换动作,所以你无能为力(这是一件好事)。
这可能已经完成了,因为所以许多应用程序滥用了带到前面的API,这些行为都让用户烦恼并导致他们输入错误的应用程序。
答案 3 :(得分:2)
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();
}
}
}
答案 4 :(得分:2)
Bug 192036 - Shell.forceActive doesn't raise a window above all other windows
@rogerdpack's query on Eclipse bug tracker通过以下dirty workaround做了我们需要的回答。
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);
}