在Windows上停靠java应用程序jna [英] Docking a java application jna on windows
问题描述
我正在尝试构建一个Windows可停靠应用程序,该应用程序会保留屏幕的一部分以防止其他应用程序在该空间中显示。
I'm trying to build a Windows dockable application that reserves a section of the screen to prevent other applications from show in that space.
我尝试使用JNI和JNA。上面的代码显示了我有多远。
I have try using JNI and JNA. The code above shows how far I have got.
package jnadock;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.ShellAPI;
import com.sun.jna.platform.win32.ShellAPI.APPBARDATA;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
public class JNADock {
private HWND hWndGlobal;
private final String frameTitle = "Dockable frame";
public interface Shell32 extends StdCallLibrary {
final static Map<String, Object> WIN32API_OPTIONS = new HashMap<String, Object>() {
private static final long serialVersionUID = 1L;
{
put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
}
};
public Shell32 INSTANCE = (Shell32) Native.loadLibrary("Shell32", Shell32.class, WIN32API_OPTIONS);
UINT_PTR SHAppBarMessage(DWORD dwMessage, APPBARDATA pData);
}
public interface User32 extends StdCallLibrary {
final static Map<String, Object> WIN32API_OPTIONS = new HashMap<String, Object>() {
private static final long serialVersionUID = 1L;
{
put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
}
};
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, WIN32API_OPTIONS);
boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc, Pointer arg);
int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);
HWND FindWindowA(String winClass, String title);
}
public static void main(String[] args) {
JNADock jna = new JNADock();
}
public JNADock() {
JFrame frame = new JFrame(frameTitle);
frame.setSize(600, 100);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
appbarRemove();
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
appbarSetPos();
final User32 user32 = User32.INSTANCE;
hWndGlobal = user32.FindWindowA(null, frameTitle);
appbarNew() ;
appbarSetPos();
frame.setLocation(0,0);
}
private void appbarNew() {
APPBARDATA data = new APPBARDATA.ByReference();
data.cbSize.setValue(data.size());
int WM_USER = 0x0400;
data.hWnd = hWndGlobal;
data.uCallbackMessage.setValue(WM_USER + 1);
UINT_PTR result = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_NEW), data);
System.out.println("result: " + result);
}
private void appbarSetPos() {
APPBARDATA data = new APPBARDATA.ByReference();
data.cbSize.setValue(data.size());
data.uEdge.setValue(ShellAPI.ABE_TOP);
data.rc.top = 0;
data.rc.left = 0;
data.rc.bottom = 100;
data.rc.top = 600;
UINT_PTR result = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_SETPOS), data);
System.out.println("result: " + result);
}
private void appbarRemove(){
APPBARDATA data = new APPBARDATA.ByReference();
data.cbSize.setValue(data.size());
int WM_USER = 0x0400;
data.hWnd = hWndGlobal;
data.uCallbackMessage.setValue(WM_USER + 1);
UINT_PTR result = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_REMOVE), data);
System.out.println("result: " + result);
}
}
执行时,框架显示但没有错误或印刷了我正在做错的提示。
When executed, the frame is shown but no error or hint of what I'm doing wrong is printed.
请注意,我刚刚开始使用JNA,我可能会犯下新手错误。随意将它们抽出来。
Note that I just started using JNA and I could be committing rookie mistakes. Feel free to smoke them out.
推荐答案
致电之前 SHAppBarMessage(ABM_SETPOS)
你必须初始化一个新的AppBar,调用 SHAppBarMessage(ABM_NEW)
,如下所示。
Before you call SHAppBarMessage(ABM_SETPOS)
you have to initialize a new AppBar calling SHAppBarMessage(ABM_NEW)
as show below.
private void appbarNew() {
APPBARDATA data = new APPBARDATA.ByReference();
data.cbSize.setValue(data.size());
int WM_USER = 0x0400;
data.hWnd = hWndGlobal;
data.uCallbackMessage.setValue(WM_USER + 1);
UINT_PTR result = Shell32.INSTANCE.SHAppBarMessage(new DWORD(ShellAPI.ABM_NEW), data);
System.out.println("result: " + result);
}
最后不要忘记删除新的AppBar调用 SHAppBarMessage(ABM_REMOVE)
At the end don't forget to remove the new AppBar calling SHAppBarMessage(ABM_REMOVE)
这篇关于在Windows上停靠java应用程序jna的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!