说明
通过jna获取鼠标类型
依赖
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.7.0</version>
</dependency>
java
鼠标状态的枚举类
package top.malaoshi.cursor;
public enum Cursor {
APPSTARTING(32650),
NORMAL(32512),
CROSS(32515),
HAND(32649),
HELP(32651),
IBEAM(32513),
NO(32648),
SIZEALL(32646),
SIZENESW(32643),
SIZENS(32645),
SIZENWSE(32642),
SIZEWE(32644),
UP(32516),
WAIT(32514),
PEN(32631)
;
private final int code;
Cursor(final int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
鼠标状态,原windows定义的内容:
#define IDC_ARROW MAKEINTRESOURCE(32512)
#define IDC_IBEAM MAKEINTRESOURCE(32513)
#define IDC_WAIT MAKEINTRESOURCE(32514)
#define IDC_CROSS MAKEINTRESOURCE(32515)
#define IDC_UPARROW MAKEINTRESOURCE(32516)
#define IDC_SIZE MAKEINTRESOURCE(32640) /* OBSOLETE: use IDC_SIZEALL */
#define IDC_ICON MAKEINTRESOURCE(32641) /* OBSOLETE: use IDC_ARROW */
#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
#define IDC_SIZENESW MAKEINTRESOURCE(32643)
#define IDC_SIZEWE MAKEINTRESOURCE(32644)
#define IDC_SIZENS MAKEINTRESOURCE(32645)
#define IDC_SIZEALL MAKEINTRESOURCE(32646)
#define IDC_NO MAKEINTRESOURCE(32648) /*not in win3.1 */
#if(WINVER >= 0x0500)
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif /* WINVER >= 0x0500 */
#define IDC_APPSTARTING MAKEINTRESOURCE(32650) /*not in win3.1 */
#if(WINVER >= 0x0400)
#define IDC_HELP MAKEINTRESOURCE(32651)
#endif /* WINVER >= 0x0400 */
相应的解释:
#define IDC_ARROW MAKEINTRESOURCE(32512)
#define IDC_IBEAM MAKEINTRESOURCE(32513)
#define IDC_WAIT MAKEINTRESOURCE(32514)
#define IDC_CROSS MAKEINTRESOURCE(32515)
#define IDC_UPARROW MAKEINTRESOURCE(32516)
#define IDC_SIZE MAKEINTRESOURCE(32640) /* OBSOLETE: use IDC_SIZEALL */
#define IDC_ICON MAKEINTRESOURCE(32641) /* OBSOLETE: use IDC_ARROW */
#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
#define IDC_SIZENESW MAKEINTRESOURCE(32643)
#define IDC_SIZEWE MAKEINTRESOURCE(32644)
#define IDC_SIZENS MAKEINTRESOURCE(32645)
#define IDC_SIZEALL MAKEINTRESOURCE(32646)
#define IDC_NO MAKEINTRESOURCE(32648) /*not in win3.1 */
#if(WINVER >= 0x0500)
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif /* WINVER >= 0x0500 */
#define IDC_APPSTARTING MAKEINTRESOURCE(32650) /*not in win3.1 */
#if(WINVER >= 0x0400)
#define IDC_HELP MAKEINTRESOURCE(32651)
#endif /* WINVER >= 0x0400 */
鼠标结构体
package top.malaoshi.cursor;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import java.util.Arrays;
import java.util.List;
// typedef struct {
// DWORD cbSize;
// DWORD flags;
// HCURSOR hCursor;
// POINT ptScreenPos;
// } top.malaoshi.cursor.CURSORINFO, *PCURSORINFO, *LPCURSORINFO;
public class CURSORINFO extends Structure {
public int cbSize;
public int flags;
public WinDef.HCURSOR hCursor;
public WinDef.POINT ptScreenPos;
public CURSORINFO() {
this.cbSize = Native.getNativeSize(CURSORINFO.class, null);
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("cbSize", "flags", "hCursor", "ptScreenPos");
}
}
引用的windows api
package top.malaoshi.cursor;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinGDI;
import com.sun.jna.platform.win32.WinNT;
public interface User32 extends com.sun.jna.Library {
User32 INSTANCE = Native.load("User32.dll", User32.class);
// BOOL WINAPI GetCursorInfo(
// _Inout_ PCURSORINFO pci
// );
int GetCursorInfo(CURSORINFO cursorinfo);
// HANDLE WINAPI LoadImage(
// _In_opt_ HINSTANCE hinst,
// _In_ LPCTSTR lpszName,
// _In_ UINT uType,
// _In_ int cxDesired,
// _In_ int cyDesired,
// _In_ UINT fuLoad
// );
WinNT.HANDLE LoadImageA(
WinDef.HINSTANCE hinst,
Pointer lpszName,
int uType,
int cxDesired,
int cyDesired,
int fuLoad
);
boolean GetIconInfo(WinDef.HICON hicon, WinGDI.ICONINFO iconinfo);
WinDef.HDC GetDC(WinDef.HWND hwdn);
void DestroyIcon(WinDef.HICON hicon);
}
主启动类
package top.malaoshi.cursor;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* https://msdn.microsoft.com/pt-br/library/windows/desktop/ms648029(v=vs.85).aspx
* Test cursors - https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
* Chromium cursor map - https://github.com/mageddo/chromium/blob/master/webkit/glue/webcursor_win.cc
* Load icon example - https://github.com/java-native-access/jna/blob/master/contrib/platform/test/com/sun/jna/platform/win32/GDI32Test.java#L54
* understanding makeintresource - https://stackoverflow.com/questions/3610565/why-does-makeintresource-work
* all possible windows error codes - https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386(v=vs.85).aspx
* Cursor ids - https://msdn.microsoft.com/en-us/library/windows/desktop/ms648391(v=vs.85).aspx
*
*/
/**
* 获取鼠标状态
*/
public class Main {
public static void main(String[] args) throws Exception {
Main main = new Main();
while(true){
System.out.println(main.getCurrentCursor());
Thread.sleep(500);
}
}
private final Map<WinNT.HANDLE, Cursor> cursors;
private final User32 user32 = User32.INSTANCE;
public Main(){
cursors = loadCursors();
}
/**
* Load all possible cursors to a map
*/
private Map<WinNT.HANDLE, Cursor> loadCursors() {
final Map<WinNT.HANDLE, Cursor> cursors = new HashMap<>();
for (final Cursor cursor : Cursor.values()) {
final Memory memory = new Memory(Native.getNativeSize(Long.class, null));
memory.setLong(0, cursor.getCode());
final Pointer resource = memory.getPointer(0);
final WinNT.HANDLE hcursor = this.user32.LoadImageA(
null, resource, WinUser.IMAGE_CURSOR, 0, 0, WinUser.LR_SHARED
);
if(hcursor == null || Native.getLastError() != 0){
throw new Error("Cursor could not be loaded: " + String.valueOf(Native.getLastError()));
}
cursors.put(hcursor, cursor);
}
return Collections.unmodifiableMap(cursors);
}
public Cursor getCurrentCursor(){
final CURSORINFO cursorinfo = new CURSORINFO();
final int success = user32.GetCursorInfo(cursorinfo);
if(success != 1){
throw new Error("Could not retrieve cursor info: " + String.valueOf(Native.getLastError()));
}
System.out.printf("currentPointer=%s%n", cursorinfo.hCursor);
return cursors.get(cursorinfo.hCursor);
}
}
参考
https://www.coder.work/article/4732041
https://blog.csdn.net/moiit/article/details/50700265
https://blog.csdn.net/qq_22642239/article/details/99633129