Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制java swt程序;将自身移动到前景“中?”;?_Java_Shell_User Interface_Swt_Foreground - Fatal编程技术网

如何强制java swt程序;将自身移动到前景“中?”;?

如何强制java swt程序;将自身移动到前景“中?”;?,java,shell,user-interface,swt,foreground,Java,Shell,User Interface,Swt,Foreground,目前使用swt时,我有时希望一个程序能够任意出现在前台(就像闹钟可能出现的那样) 通常包括以下工作(jruby): 如果壳被最小化,这会将壳带到前面 在任何时候创建一个新的shell也会将(新shell)带到最前面 不过,到目前为止还不错,如果shell没有最小化,上面的代码只会在任务栏中闪烁应用程序的图标。实际上,你第一次运行它时,它就把它带到了最前面。之后,它只会在任务栏上闪烁。那是窗户。在Linux上,它似乎只在任务栏中闪烁(ubuntu默认) 有没有人知道一种跨平台的方法可以让应用程序在

目前使用swt时,我有时希望一个程序能够任意出现在前台(就像闹钟可能出现的那样)

通常包括以下工作(jruby):

如果壳被最小化,这会将壳带到前面

在任何时候创建一个新的shell也会将(新shell)带到最前面

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

有没有人知道一种跨平台的方法可以让应用程序在swt中占据领先地位

似乎没有一句咒语能做到这一点:forceActive setActive setMinimized(false)setFocus forceFocus和setVisible

我很确定这是可能的(至少在windows中),就像E文本编辑器所做的那样。这不是swt,但至少是其他一些应用

我在想也许这是

非常感谢

相关的:

  • 这个swing示例也可能是某种类型的线索

显示了我是如何在windows中完成的(使用ffi)

一些有用的技巧“可能”是

在BringToFront.SetForegroundWindow(需要)之后添加“sleep 0.1” 打电话(希望这一个不是必须的)

将窗口置于前台后,添加一个shell.set_活动。出于某些原因,forceActive不调用setActive

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

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

(包含一些关于如何正确操作的好提示)

在Linux上,forceActive确实可以工作——但只有在移动到其他几个窗口之后,它才会在任务栏中闪烁(仅限)。猜swt错误。[1]

还涉及:

“set_前台”似乎同时适用于xp和windows 7


[1] 这实际上是Windows的一项功能,可以通过Tweak UI power toy启用(至少对于Windows XP是如此)。启用时,O/S故意阻止窗口强制自己成为聚焦窗口,以阻止其“窃取焦点”。因此,抓取焦点的操作被更改为仅闪烁任务栏图标-因为O/S是根据用户的请求故意转换操作的,所以您对此无能为力(这是一件好事)

之所以这样做(可能是因为)是因为太多应用程序滥用了“带到前台”API,而这种行为既惹恼了用户,又导致他们输入错误的应用程序。

private static void onTop(Shell){
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();
            }
        }
    }
int s=-1; Shell[]Shell=display.getshell(); 对于(int i=0;i
这对我在Windows 7和Ubuntu上很有效:

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

我们的回答是:做我们需要的事情

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);
  }
public void forceActive(外壳){
int hFrom=OS.GetForegroundWindow();
如果(hFrom 0){
如果(!OS.AttachThreadInput(_threadid,pid,true)){
返回;
}
OS.SetForegroundWindow(shell.handle);
AttachThreadInput(_threadid,pid,false);
}
OS.BringWindowToTop(shell.handle);
OS.UpdateWindow(shell.handle);
SetActiveWindow(shell.handle);
}

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

shell.getDisplay().syncExec(new Runnable() {

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

看起来你链接到的SWT bug准确地描述了你的问题,而且听起来他们似乎无法修复它。我认为这确实是windows的问题——很好。目前的解决方法是首先最小化一个shell,然后取消它的小型化(或者使用一些本机代码[通过ffi或jni]来强制它)。在Linux中,我不太确定问题出在哪里(只是在任务托盘中闪烁)。它可能在更新版本的swt.jar>=3.5中得到修复,如果您在forceForeGround上搜索,您将看到一个解决方法,无论是好是坏(我假设这是awt用于toFront方法的方法,而swt似乎没有)。我同意forceActive应该谨慎使用:)啊,是的,仍然有太多的应用程序从后台弹出,在你忙于输入其他内容时窃取输入。我以前经历过这样的数据丢失。背景应用程序弹出“你想删除废话吗?”而我正在键入其他恰好包含“是”选择器的内容。啊。不幸的是,这个变通方法在我的Windows 10副本上不起作用。
shell.getDisplay().syncExec(new Runnable() {

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