Vorweg : der Grundgedanke ist diesem Thema gleich : http://forum.byte-welt.net/threads/11914-Kommunikation-Java-Programm-nicht-Java-Programm
Um es noch einmal genau auf den Punkt zu bringen : ich möchte von Java aus mit Hilfe der Win-API und JNA ein Key-Command an einen fremden Prozess schicken. Google hat sich dabei schon soweit als nützlich erwiesen das ich auch einen lauffähigen Code zusammen bekommen habe. Hier mal die aktuelle Version :
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
public class JNATest
{
public static void main(String[] args) throws Exception
{
User32 user32=User32.INSTANCE;
WinDef.HWND hwnd=user32.FindWindow(null, "Audacity");
List<WinDef.HWND> list=new ArrayList<WinDef.HWND>();
user32.EnumChildWindows(hwnd, new WinUser.WNDENUMPROC()
{
public boolean callback(WinDef.HWND h, Pointer data)
{
list.add(h);
return true;
}
}, null);
WinDef.HWND aufnahme=null;
for(WinDef.HWND h : list)
{
int l=user32.GetWindowTextLength(h)+1;
char[] c=new char[l];
int i=user32.GetWindowText(h, c, l);
String name=new String(c, 0, i);
if(name.equals("Aufnahme"))
aufnahme=h;
}
int remote=user32.GetWindowThreadProcessId(aufnahme, null);
int local=Kernel32.INSTANCE.GetCurrentThreadId();
System.out.println(user32.AttachThreadInput(new WinDef.DWORD(remote), new WinDef.DWORD(local), true)); // Event-Queue attachen
System.out.println(user32.SetFocus(aufnahme));
user32.PostMessage(aufnahme, 0x0100, new WinDef.WPARAM(0x52), new WinDef.LPARAM(0)); // KeyDown
user32.PostMessage(aufnahme, 0x0101, new WinDef.WPARAM(0x52), new WinDef.LPARAM(0)); // KeyUp
System.out.println(user32.AttachThreadInput(new WinDef.DWORD(remote), new WinDef.DWORD(local), false)); // Event-Queue detachen (laut MSDN vorgeschrieben)
}
}```
Das Problem :
Man kann es mit der Frage vergleichen : wie unter Java ein "global Hotkey" implementieren ohne Focus ? Denn auch mit Hilfe der Win-API hat man immer noch das Problem : man kann zwar Key-Events an einen Prozess schicken, dieser reagiert aber, genau wie Java, nur darauf wenn das entsprechende Fenster den Focus hat.
Es ist mir also gelungen mit Hilfe SetFocus den Focus auf den gewünschten Bereich zu setzen, nur wird dabei das entsprechende Fenster in den Vordergrund geholt.
Mein Frage also ein jemanden der sich mit der Win-API auskennt : wie das ganze umsetzen ohne SetFocus ?
Unter Java würde ich dafür diese Lib nutzen : http://kra.lc/blog/2011/07/java-global-system-hook/
Hier macht sich der Autor einen Hook zu nutze um entsprechende die EventQueue abzufangen.
Im Netz findet man dazu leider den Punkt : Audacity unterstützt diese Art der Nutzung nicht da es nicht für Background-Nutzung gedacht ist, weshalb sich auch in den Settings in der aktuellen Version keine globalen Hotkeys definieren lassen.
Die Antwort habe ich eigentlich schon im anderen Thread gegeben : ich müsste mich nicht nur an die normale EventQueue des entsprechenden Threads hängen sondern diese eigentlich hooken um a-sync Events auszulösen ohne einen Focus zu benötigen. Nur das wiederum erfordert low-level-Programmierung in C wozu ich leider nicht in der Lage bin.
Wenn jemand sowas umsetzen kann oder eine Lib kennt mit der dies möglich ist würde ich mich über Rückmeldung freuen.
ps : ja, mir ist bewusst das die Frage eigentlich ins C-Forum gehört, aber da leider in den anderen Fach-Bereichen so gut wie keine Aktivität ist hau ich es einfach mal hier rein.
// EDIT
Doch noch eine Java-spezifische Frage : ich greife ja von der anonymen inneren Klasse auf die äußere List zu. Mir war eigentlich so das bei sowas der Compiler immer mit der Meldung "must be final" ausgestiegen ist. Wurde dies jetzt in Java8 geändert das final nicht mehr nötig ist bzw. das es vom Compiler automatisch gesetzt wird oder liegt es an dem speziellen Call auf das Objekt ?