windows向けswt.jarのバージョンをあげると使えるWin32APIが増えている 2007/04/21
2007/07/10

javaからWindowsのwin32APIをお手軽に使うのは、swtを使うのがともて簡単です。

win32API
のAttachThreadInput関数は、少なくともswt.jarのversion 3.139にはなかったです。

version 3.333にはありました。

何故、AttachThreadInput関数をもとめているかといいますと、javaの画面を、バックグランドから、手前にもってきたいという方法を解決するためです。

winodwsアプリケーションのお作法として、いきなり他のアプリより前にもってこないのがいいのかもしれません。
参考:
http://www.microsoft.com/japan/technet/prodtechnol/winxppro/deploy/exappmigratoxp.mspx
http://techtips.belution.com/ja/vc/0012/


シナリオ:
ターゲットos:windows
java:1.4
バックグランドプロセスとして動作しているjavaアプリケーションがメッセージを受信して、他のアプリケーションより前にダイアログを表示したい。



コードの説明
eclipseから提供されているswtを使用しています。バージョンは古いのだとだめです。AttachThreadInputが使えるものを使用します。
java1.4のためのものなので、それよりあとのjavaですとwindows上の動作で、手前にもってくるという処理が他にあるかもしれません。が未調査です。


単純にフレームを表示させて3秒後にフレームを手前にだします。
実験の方法は、3秒のあいがに他のアプリケーションを手前に表示します。
すると3秒後Javaのフレームが手前に表示されます。


package swt;

import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;

import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.internal.win32.TCHAR;

public class TestFindWindow {

public static void main(String[] args) {
JFrame frame = new JFrame("日本語タイトル");
frame.setBounds(500, 500, 300, 300);
frame.setVisible(true);

TimerTask task = new TimerTask() {

public void run() {

SetAbsoluteForegroundWindow("日本語タイトル");
}
};

Timer timer = new Timer();
timer.schedule(task, 3000);
}

static void SetAbsoluteForegroundWindow(String windowTitle) {
final int hWnd = OS.FindWindow(null, new TCHAR(OS.CP_INSTALLED,
windowTitle, true));
if (hWnd == 0) {
System.out.println("failed find window:[" + hWnd + "]");
return;
}

final int nForegroundID = OS.GetWindowThreadProcessId(OS
.GetForegroundWindow(), null);
final int nTargetID = OS.GetWindowThreadProcessId(hWnd, null);

System.out.println("nForegroundID:>>>" + nForegroundID);
System.out.println("nTargetID:>>>" + nTargetID);

boolean b = OS.AttachThreadInput(nTargetID, nForegroundID, true);// Threadの結びつけ
System.out.println("AttachThreadInput:" + b);
/* OS.SetActiveWindow(hWnd) */
OS.ShowWindow(hWnd, OS.SW_RESTORE);
System.out.println(OS.SetForegroundWindow(hWnd));

/* 以下のコードが本当に必要かどうかは不明 */
/*
* 1秒後に切り離し。
*/
TimerTask task = new TimerTask() {

public void run() {

System.out
.println("切り離し>>>"
+ OS.AttachThreadInput(nTargetID,
nForegroundID, false)); /* Threadの切り離し */
}
};

Timer timer = new Timer();
timer.schedule(task, 1000);

}
}

: