I am writing an OSX Quick-look alternative for Windows using Java and was having trouble on how to get the active selections of file in a n active Explorer window, below is my attempt:
@Override
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("key up:"
+ NativeKeyEvent.getKeyText(e.getKeyCode()));
if (e.getKeyCode() == NativeKeyEvent.VK_SPACE) {
System.out.println("Space detected! intercept active window");
char[] buffer = new char[MSWindowConstants.MAX_TITLE_LENGTH * 2];
User32DLL.GetWindowTextW(User32DLL.GetForegroundWindow(),
buffer, MSWindowConstants.MAX_TITLE_LENGTH);
System.out.println("Active window title: "
+ Native.toString(buffer));
PointerByReference pointer = new PointerByReference();
User32DLL.GetWindowThreadProcessId(
User32DLL.GetForegroundWindow(), pointer);
Pointer process = Kernel32.OpenProcess(
Kernel32.PROCESS_QUERY_INFORMATION
| Kernel32.PROCESS_VM_READ, false,
pointer.getValue());
Psapi.GetModuleBaseNameW(process, null, buffer,
MSWindowConstants.MAX_TITLE_LENGTH);
System.out.println("Active window process: "
+ Native.toString(buffer));
if(MSWindowConstants.SHELL_PROCESS_NAME.equals(Native.toString(buffer))){
System.out.println("shell focused! intercept selection");
// retrieve selected FileItems and get the path ...
//Ole32.INSTANCE
}
}
The MSEnumeration class:
public class MSEnumeration {
public static class Psapi {
static {
Native.register("psapi");
}
public static native int GetModuleBaseNameW(Pointer hProcess,
Pointer hmodule, char[] lpBaseName, int size);
}
public static class Kernel32 {
static {
Native.register("kernel32");
}
public static int PROCESS_QUERY_INFORMATION = 0x0400;
public static int PROCESS_VM_READ = 0x0010;
public static native int GetLastError();
public static native Pointer OpenProcess(int dwDesiredAccess,
boolean bInheritHandle, Pointer pointer);
}
public static class User32DLL {
static {
Native.register("user32");
}
public static native int GetWindowThreadProcessId(HWND hWnd,
PointerByReference pref);
public static native HWND GetForegroundWindow();
public static native int GetWindowTextW(HWND hWnd, char[] lpString,
int nMaxCount);
}
// public static class Shell32DLL{
// static {
// Native.register("shell32");
// }
//
// public static native Shell32 Windows();
// }
//
// public static class SHDocVwDLL{
// static {
// Native.register("shdocvw");
// }
//
// public static native ShellWindows ShellWindows();
//
// }
}
I was confused by how to implement the following in JNA:
Get current selection in WindowsExplorer from a C# application?
IntPtr handle = GetForegroundWindow();
List<string> selected = new List<string>();
var shell = new Shell32.Shell();
foreach(SHDocVw.InternetExplorer window in shell.Windows())
{
if (window.HWND == (int)handle)
{
Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
foreach(Shell32.FolderItem item in items)
{
selected.Add(item.Path);
}
}
}
How can I translate this into JNA calls?
I looked into JNA'S Shell32 class and COM(Ole32 classes) but that still didn't get me anywhere.
The only workaround I can think of now is to compile the given C# into a separate executable that takes arguments and return the paths of the files, but I don't really like the idea of embedding another executable in java.
EDIT:
Some progress:
public static final String CLSID_ShellWindows = "9BA05972-F6A8-11CF-A442-00A0C90A8F39";
public static final String IID_IShellWindows = "85CB6900-4D95-11CF-960C-0080C7F4EE85";
HRESULT hr = Ole32.INSTANCE
.CoCreateInstance(
GUID.fromString(CLSID_ShellWindows),
null,
WTypes.CLSCTX_ALL,
GUID.fromString(IID_IShellWindows),
p);
System.out.println("result:" + W32Errors.SUCCEEDED(hr)
+ "raw:" + hr.toString());
but the result is never true for some reason...