私はJNAライブラリーを使用して、Windowsですべての可視ウィンドウハンドルを取得しています。JNAを使用してmacOSで同様のことを行う必要があります。
Windowsのすべてのウィンドウハンドルを取得するコードは次のとおりです。
public static List<HWND> findAll() {
final List<HWND> windows = new LinkedList<>();
User32.INSTANCE.EnumWindows(new User32.WNDENUMPROC() {
@Override
public boolean callback(HWND hWnd, Pointer arg) {
if (User32.INSTANCE.IsWindowVisible(hWnd)) {
windows.add(hWnd);
}
return true;
}
}, null);
return windows;
}
macOSの同等のコードは何ですか?
Core Graphics Frameworkの一部をマップする必要があります。CGWindowListCopyWindowInfo()関数を使用してウィンドウをリストできます。
フレームワークをロードするには、CoreGraphics
JNAのLibrary
クラスを拡張するインターフェースをマップし、必要な関数をマップする必要があります。
public interface CoreGraphics extends Library {
CoreGraphics INSTANCE = Native.load("CoreGraphics", CoreGraphics.class);
CFArrayRef CGWindowListCopyWindowInfo(int option, int relativeToWindow);
}
CFArrayRef
タイプはすでにJNAにマッピングされているCoreFoundation
クラス。適切なウィンドウリストオプションを選択します(おそらくkCGWindowListOptionAll
= 0)。すでにウィンドウ番号がある場合は、相対参照を使用できます。それ以外の場合はkCGNullWindowID
、2番目のパラメーターに(0)を使用します。コードから呼び出すのは簡単です:
CFArrayRef windowInfo = CoreGraphics.INSTANCE.CGWindowListCopyWindowInfo(0, 0);
これによりCFDictionaryRef
、ウィンドウを表すオブジェクトの配列が得られます。配列を反復処理してCFDictionaryRef
から、クラスのその他のメソッドを使用して、これらのディクショナリオブジェクトを探索CFString
できます。キーのを作成します。必要なキーのリストはここに記載されており、オプションのキーはここにあります。定数文字列は変数名と一致します。
これによりCFNumberRef
、ウィンドウ番号ごとに(同等の「ハンドル」)が得られます。
// Set up keys for dictionary lookup
CFStringRef kCGWindowNumber = CFStringRef.createCFString("kCGWindowNumber");
CFStringRef kCGWindowOwnerPID = CFStringRef.createCFString("kCGWindowOwnerPID");
// Note: the Quartz name is rarely used
CFStringRef kCGWindowName = CFStringRef.createCFString("kCGWindowName");
CFStringRef kCGWindowOwnerName = CFStringRef.createCFString("kCGWindowOwnerName");
// Iterate the array
int numWindows = windowInfo.getCount();
for (int i = 0; i < numWindows; i++) {
// For each array element, get the dictionary
Pointer result = windowInfo.getValueAtIndex(i);
CFDictionaryRef windowRef = new CFDictionaryRef(result);
// Now get information from the dictionary.
// Get a pointer to the result, in this case a CFNumber
result = windowRef.getValue(kCGWindowNumber);
// "Cast" the pointer to the appropriate type
CFNumberRef windowNumber = new CFNumberRef(result);
// CoreFoundation.INSTANCE.CFNumberGetType(windowNumber)
// --> 4 = kCFNumberSInt64Type, signed 64 bit so use getLong()
// Get a pointer to the result, in this case a CFNumber
result = windowRef.getValue(kCGWindowOwnerPID);
// "Cast" the pointer to the appropriate type
CFNumberRef windowOwnerPID = new CFNumberRef(result);
// CoreFoundation.INSTANCE.CFNumberGetType(windowOwnerPID)
// --> 4 = kCFNumberSInt64Type, signed 64 bit so use getLong()
// Get a pointer to the result, in this case a CFString
result = windowRef.getValue(kCGWindowName);
// "Cast" the pointer to the appropriate type
// Optional key, check for null
String windowName = result == null ? "" : new CFStringRef(result).stringValue();
// Get a pointer to the result, in this case a CFString
result = windowRef.getValue(kCGWindowOwnerName);
// "Cast" the pointer to the appropriate type
// Optional key, check for null
String windowOwnerName = result == null ? "" : new CFStringRef(result).stringValue();
// ... look up other keys if needed ...
// use ProcessHandle with the PID to get start time
// Output or add to List, etc.
System.out.println(windowNumber.longValue()
+ " (" + windowOwnerName + ", pid="
+ windowOwnerPID.longValue()
+ "): " + windowName);
}
// CF references from "Copy" or "Create" must be released
// release the created key references
kCGWindowNumber.release();
kCGWindowOwnerPID.release();
kCGWindowName.release();
kCGWindowOwnerName.release();
// release the array
windowInfo.release();
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加