- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在寻找使外部应用程序(不是像记事本或 calc.exe 这样的 Windows 应用程序)在 Java GUI 中按下按钮后始终保持在最前面的解决方案。我在 C++ 中使用此代码获取桌面上所有打开的窗口并将它们的进程 ID (PID) 与发送的 PID(来 self 的 Java 应用程序)相匹配:
#include "cjni.h"
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
BOOL CALLBACK EnumWindowsProc(HWND windowHandle, LPARAM lParam){
DWORD searchedProcessId = (DWORD)lParam;
DWORD windowProcessId = 0;
GetWindowThreadProcessId(windowHandle, &windowProcessId);
printf("process id=%d\n", windowProcessId);
if(searchedProcessId == windowProcessId) {
HWND hwnd = windowHandle;
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
printf("Process ID found !");
return FALSE;
}
return TRUE;
}
JNIEXPORT void JNICALL Java_gui_CJNI_AlwaysOnTop
(JNIEnv *env, jclass jobj, jint processId) {
//(*env)->EnumWindows(&EnumWindowsProc, (LPARAM)processId);
EnumWindows(&EnumWindowsProc, (LPARAM)processId);
}
Java JNI 中的实现:
package gui;
public class CJNI {
static {
System.loadLibrary("cjni");
}
static native void AlwaysOnTop(int processId);
public void metoda(final int processId) {
//AlwaysOnTop(processId);
}
在 Java 中,我使用这段代码获取所选进程的 PID:
public int getPID(Process p) {
try {
Field f = p.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl = f.getLong(p);
Kernel32 kernel = Kernel32.INSTANCE;
WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handl));
return kernel.GetProcessId(handle);
} catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException e) {
return -1;
}
}
我的程序与 MS Windows 应用程序配合良好,使它们始终位于最前面。不幸的是,外部应用程序并不总是最重要的。我正在使用 SetWindowPos();来自 C++ 的方法。当我通过 GetForegroundWindow() 选择外部程序窗口并将此窗口句柄 (HWND) 作为 SetWindowPos() 的参数时,它会起作用;这是与始终位于顶部的外部应用程序一起工作的代码(但我必须自己选择应用程序窗口 - 通过鼠标选择):
#include <windows.h>
#include <iostream>
using namespace std;
int main(){
cout << "Select window within 2 seconds\n";
Sleep(2000);
HWND hWnd = GetForegroundWindow();
//HWND hWnd = (HWND)0x8036c;
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
cout <<"Number hwnd: " << hWnd << endl;
cout << "Always on top set on window.\n";
return 0;
}
是否可以从 JNI 获取 C++ 方法的实现,并使用 JNA 打开外部并使用 Java GUI 将应用程序设置为始终在最前面?
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package gui;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
//import com.sun.jna.platform.win32.User32;
//import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
//import com.sun.jna.platform.win32.WinUser;
//import com.sun.jna.win32.StdCallLibrary;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;
//import com.sun.jna.platform.win32.WinDef.DWORD;
//import com.sun.jna.platform.win32.WinNT.HANDLE;
/**
*
* @author adrians
*/
public class Test extends javax.swing.JFrame /*implements WndEnumProc*/ {
long startTime;
long stopTime;
/**
* Creates new form Test
*/
public Test() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
jButton4 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Kalkulator");
jButton1.setMaximumSize(new java.awt.Dimension(87, 23));
jButton1.setMinimumSize(new java.awt.Dimension(87, 23));
jButton1.setPreferredSize(new java.awt.Dimension(83, 23));
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("Notatnik");
jButton2.setMaximumSize(new java.awt.Dimension(87, 23));
jButton2.setMinimumSize(new java.awt.Dimension(87, 23));
jButton2.setPreferredSize(new java.awt.Dimension(83, 23));
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
jButton3.setText("SeaNet Pro");
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
jButton4.setText("Paint");
jButton4.setMaximumSize(new java.awt.Dimension(87, 23));
jButton4.setMinimumSize(new java.awt.Dimension(87, 23));
jButton4.setPreferredSize(new java.awt.Dimension(87, 23));
jButton4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton4ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(50, 50, 50)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jButton4, javax.swing.GroupLayout.DEFAULT_SIZE, 127, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jButton3, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)
.addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)
.addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)))
.addContainerGap(53, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(30, 30, 30)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(25, 25, 25)
.addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(25, 25, 25)
.addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(25, 25, 25)
.addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(30, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
run("calc.exe");
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
run("notepad.exe");
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
run("\"C:\\Program Files\\vlc-2.1.1\\vlc.exe\"");
}
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
run("mspaint.exe");
}
public void run(String name) {
try {
Process process = Runtime.getRuntime().exec(name);
final int pid = getPID(process);
System.out.println("Program name: " + name + ", PID=" + pid);
new Thread(new Runnable() {
public void run() {
try {
startTime = System.currentTimeMillis();
Thread.sleep(150);
CJNI.AlwaysOnTop(pid);
stopTime = System.currentTimeMillis() - startTime;
System.out.println("Time: "+stopTime);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
} catch (IOException ex) {
Logger.getLogger(Okno.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int getPID(Process p) {
try {
Field f = p.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl = f.getLong(p);
Kernel32 kernel = Kernel32.INSTANCE;
WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handl));
//final User32 user32 = User32.INSTANCE;
return kernel.GetProcessId(handle);
} catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException e) {
return -1;
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Test().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
// End of variables declaration
}
请帮忙。对于外部应用程序(非 MS Windows 软件),我无法始终设置在最前面。我使用的是 JNA 3.0.0 版本。
我正在尝试将 C++ Win Api 方法(来 self 上面的第一个问题)- EnumWindowsProc、EnumWindows GetWindowThreadProcessId 和 SetWindowPos - 用于 Java 代码实现,以简化我的应用程序代码。我试图将 C++/JNI 代码的功能转移到 JNA。不幸的是,我只能打印所有带有窗口标题的桌面窗口的句柄 (HWND),而没有 PID。
我想将 Java 中打开的程序(exe 文件)的进程 ID 发送到 Java JNA 中的 EnumWindows 实现,并通过 Java JNA 中桌面上每个打开的窗口(在 EnumWindowsProc 方法中)搜索此进程 ID。然后我想将发送进程 ID 的 windowHandle 与桌面上打开的窗口的 windowHandle 进行比较。找到发送进程 ID 的 windowHandle 后,我想调用 SetWindowPos 方法,它允许我将打开的窗口设置为始终在顶部(最顶部)。换句话说,我想通过 JNA 将函数从 C++/JNI 复制到 Java 代码。
这是我的代码:
import com.sun.jna.Pointer;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.win32.StdCallLibrary;
public class n {
// Equivalent JNA mappings
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
interface WNDENUMPROC extends StdCallCallback {
boolean callback(Pointer hWnd, Pointer arg);
}
boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);
int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);
//int GetWindowThread(Pointer hWnd, int windowProcessId);
}
public static void main(String[] args) {
final User32 user32 = User32.INSTANCE;
user32.EnumWindows(new User32.WNDENUMPROC() {
int count;
public boolean callback(Pointer hWnd, Pointer userData) {
/*
Pointer searchedProcessId = userData;
int windowProcessId = 0;
user32.GetWindowThread(searchedProcessId, windowProcessId);
System.out.println("Process id = "+user32.GetWindowThread(searchedProcessId, windowProcessId));
*/
byte[] windowText = new byte[512];
user32.GetWindowTextA(hWnd, windowText, 512);
String wText = Native.toString(windowText);
wText = (wText.isEmpty()) ? "" : "; text: " + wText;
System.out.println("Found window " + hWnd + ", total " + ++count + wText);
return true;
}
}, null);
}
}
我的第二个问题是当我尝试为外部应用程序设置 Aways On Top 时,哪个 exe 文件生成了一个以上的 PID(进程 ID),因为它不起作用。有什么问题吗?对于只生成一个进程 ID 的软件,它正在运行,对于生成多个 PID 的另一种软件(exe 文件)(例如,当我打开 Adobe Reader,它为一个 exe 文件生成两个 pid 时)它不工作。
如果能帮助我将 C++/JNI 代码的功能转移到 JNA,我将不胜感激。我想通过 JNA 解决 Java 代码中的这些问题。
最佳答案
如果找到进程,您的 JNI/C++ 实现将在第一个窗口之后停止枚举窗口。如果该窗口是虚拟的不可见窗口,则您无法为该进程处理其他窗口:您应该始终在 EnumWindowsProc
中返回 TRUE
。
另外,不要为不可见的窗口使用 SetWindowPos
。
关于java - 无法在 Java/C++ 中为外部应用程序设置永远在线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21183994/
有人可以解释预定义谓词forall如何在列表中找到最小值吗? 最佳答案 对于列表L,您可以使用: member(Min,L), forall(member(N,L), N>=Min). 但是,尽管这是
编辑:澄清一下,我正在搜索的对象数组确实已按搜索变量的字母数字顺序进行了预排序。 我做了一个二分搜索函数并将它嵌套在另一个函数中。出于某种原因,每次我使用二进制搜索都无法找到相关的字符数组。 基本上,
是否可以阻止用户(甚至是管理员)终止我的程序? 或者万一被杀死,它会迅速恢复自身? 更新:澄清一下:我正在编写一个监控程序,类似于家长控制,它记录用户对 PC 的操作。你可以通过查看我最近的其他问题来
我有一个 for 循环,我希望它永远递增。 我的代码: for a in (0...Float::INFINITY).step(2) puts a end 输出: 0.0 2.0 4.0 Et
我很困惑。我有一个运行Ubuntu 14.04的VM。我在这里遵循了以下程序:http://clang.llvm.org/docs/LibASTMatchersTutorial.html,现在正在运行
这是我的代码 #include #include #include #include #include #include #include #include #include usi
我有一个程序会或多或少地通过标准输入使用 COPY FROM 将大量数据复制到 Postgres 9 中。 这目前工作正常,但我正在缓冲数据 block ,然后分批运行 COPY FROM 操作。 我
我想我不小心在某个地方安装了 Foreverjs 并启动了它。每次我杀死这个进程时,另一个进程就会取代它的位置 ] 1 我不知道永远在哪里(或者这实际上是导致它的原因),因为我在本地安装了它。 最佳答
我得到了一个 forever: command not found 当我使用 forever 命令作为 cronjob 运行 nodejs 进程时出现错误(在亚马逊 ec2 机器中):我正在使用的 b
我创建了一些容器,它们还没有准备好使用,总是“重新启动”状态: docker ps CONTAINER ID IMAGE COMMAND
我试图永远重复一个 IO 操作,但是将一个执行的结果输入到下一个执行中。像这样的东西: -- poorly named iterateM :: Monad m => (a -> m a) -> a -
这里的代码样式问题。 我看着this问题,它询问.NET CLR是否真的总是初始化字段值。 (答案是肯定的。)但令我感到惊讶的是,我不确定执行此操作始终是个好主意。我的想法是,如果我看到这样的声明:
美好的一天,我对永久启动\停止脚本有一些问题。 中央操作系统 6.2 内核 2.6.32-220.el6.x86_64 node.js v0.6.19 npm v 1.1.24 永远@0.9.2 我创
我在让管道与 paramiko 一起工作时遇到问题。 这个有效: ssh = paramiko.SSHClient() [...] stdin, stdout, stderr = ssh.exec_c
我希望守护我的 Node.js 应用程序。 Upstart 和永远有什么区别?另外,还有其他我可能想要考虑的软件包吗? 最佳答案 正如评论中指出的,upstart将用于启动 forever脚本,因为
我有以下查询,其中包含在 5 秒内返回数据的选择查询。但是当我在前面添加创建物化 View 命令时,查询需要创建物化 View 。 最佳答案 当您创建物化 View 时,实际上是创建了 Oracle
当我今天访问我的项目的 Google Cloud 控制台并单击“计算引擎”或“云存储”时,它只会永远显示“正在加载”。几天前,我能够看到我的虚拟机和存储桶。有没有办法让控制台再次工作? 谢谢, 麦克风
我编写了一个函数,它当前显示 1000 以下的所有质数。 我可以继续增大 1000 以生成更多数字,但我不知道如何让它在运行后一直持续下去。 func generatePrimes() { l
这是由 another question 触发的. 具体来说,我有一个进程中的 COM 类,它在 CLSID registry 中定义。因为有 ThreadingModel of Both . 我们的
我正在试用新的 React Hooks的 useEffect API,它似乎永远在无限循环中运行!我只希望 useEffect 中的回调运行一次。这是我的引用代码: 单击“运行代码片段”以查看“运行
我是一名优秀的程序员,十分优秀!