다른 응용 프로그램이 화면에 표시되지 않도록 화면의 일부분을 예약하는 Windows 도킹 가능한 응용 프로그램을 빌드하려고합니다.Windows에서 Java 응용 프로그램 jna 도킹
나는 JNI와 JNA를 사용해 보았습니다. 위의 코드는 제가 가지고있는 정도를 보여줍니다.
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);
}
}
실행하면 프레임이 표시되지만 내가 잘못하고있는 것의 오류나 힌트는 인쇄되지 않습니다.
방금 JNA를 사용하기 시작 했으므로 루키 오류를 범할 수 있습니다. 담배를 피우십시오.
귀하의'User32' 라이브러리를 호출하는 새로운 AppBar를 제거하는 것을 잊지 마세요. JNA의'platform.jar'에서 제공되는 라이브러리의 버전에서 쉽게 파생되는 것을 알 수 있습니다. – technomage
@technomage 끝났지 만 "제공되는 라이브러리의 버전에서 간단히 파생된다"고 말할 때 나는 당신을 쫓지 않을 것입니다. 다시이 분야에 대한 저의 경험 부족을 용서하십시오. – Neikon
JNA는 Shell32, User32 등의 버전을 제공합니다. 그 platform.jar 패키지에. 라이브러리 인터페이스를 파생시킨 경우 정의 할 인터페이스 메소드가 적습니다. – technomage