在Windows上停靠java应用程序jna

时间:2014-10-10 14:39:49

标签: java jna dock shell32

我正在尝试构建一个Windows可停靠应用程序,该应用程序会保留屏幕的一部分,以防止其他应用程序显示在该空间中。

我尝试使用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,我可能会犯下新手的错误。随意抽烟。

1 个答案:

答案 0 :(得分:2)

在致电SHAppBarMessage(ABM_SETPOS)之前,您必须初始化一个名为SHAppBarMessage(ABM_NEW)的新AppBar,如下所示。

 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);

}

最后,请不要忘记删除调用SHAppBarMessage(ABM_REMOVE)

的新AppBar

Related docs from Microsoft Dev Center