JNA - 更改 Windows 光标

JNA - Changing the Windows Cursor

我正在尝试将 Windows 游标设置为来自名为 cursorOptions 的数组中的随机游标,该数组保存每种游标类型的值。

int[] cursorOptions = new int[]{32650, 32515, 32649, 32651, 32513, 32648, 32646, 32643, 32645, 32642, 32644, 32516, 32514, 32512};

我正在使用 SetCursor(WinDef.LONG hcur) JNA 方法(在第 1157 行找到:https://github.com/br45entei/SWT-Win32-Extension/blob/master/src/org/sf/feeling/swt/win32/extension/jna/win32/User32.java)但不知道我应该为 hcur 设置什么值。我尝试从数组发送新的游标值,但计算结果为 false。

WinDef.LONG u = new WinDef.LONG(cursorOptions[rand.nextInt(cursorOptions.length-1)]);
user32.SetCursor(u);
user32.ShowCursor(true);

接下来,我尝试分配不同游标值的 hashCode 值(IBar 游标为 65541),其计算结果为 true 但未更改游标值。

WinDef.LONG g = new WinDef.LONG(65541);
user32.SetCursor(g);
user32.ShowCursor(true);

希望更改光标的 hcur 值是多少?为什么在 SetCursor(WinDef.LONG hcur) 中发送时游标的 hashCode 值评估为真但不更改游标?

完整代码:

import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.W32APIOptions;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

class MouseManipulation {

private User32 user32;

MouseManipulation() {
    user32 = User32.INSTANCE;
}
/**
* @return cursorInfo.hCursor Returns the HCURSOR of the cursor on screen
 */
WinDef.HCURSOR getCurrentCursor(){
    CursorInfo cursorInfo = new CursorInfo();
    this.user32.GetCursorInfo(cursorInfo);
    return cursorInfo.hCursor;
}

/*
 * Set the cursor to be a random cursor within the defined scope of cursorOptions
 */
void ChangeMouseCursor() {
    try {
        int[] cursorOptions = new int[]{32650, 32515, 32649, 32651, 32513, 32648, 32646, 32643, 32645, 32642, 32644, 32516, 32514, 32512};
        Random rand = new Random();

        WinDef.HCURSOR hc = getCurrentCursor();
        System.out.println("The HCURSOR: "+hc.toString());
        System.out.println("The HCURSOR hashCode: "+hc.hashCode());

        //I want this to randomly pick from the Array of cursor values and set that as the newest cursor icon 
        //but I have no clue what value for WinDef.LONG should be
        WinDef.LONG u = new WinDef.LONG(cursorOptions[rand.nextInt(cursorOptions.length-1)]);
        user32.SetCursor(u);
        user32.ShowCursor(true);
        System.out.println("When using the array: "+user32.SetCursor(u));

       //This evaluates to true yet doesn't change the cursor icon on screen; 
       //for instance 65541 is the hashCode for IBar and when cursor is NormalPointer it doesn't change.
        WinDef.LONG g = new WinDef.LONG(65541);
        user32.SetCursor(g);
        user32.ShowCursor(true);
        System.out.println("When using the hashCode: "+user32.SetCursor(g));

    }
    //Sometimes the cursor won't be found so we catch the NullPointerException
    catch (NullPointerException e){
        e.printStackTrace();
    }
}

/*
* Take advantage of the JNA 4.5.2 and the JNA 4.5.2 platform to interact with the Win32 API
*/
public interface User32 extends com.sun.jna.Library {
    MouseManipulation.User32 INSTANCE = (MouseManipulation.User32) Native.loadLibrary("user32", MouseManipulation.User32.class, W32APIOptions.DEFAULT_OPTIONS);
    boolean SetCursor(WinDef.LONG hcur);
    int GetCursorInfo(CursorInfo cursorInfo);
    int ShowCursor(boolean bShow);
}

/*
* This class was made to get the cursor's information such as its pointer and then later gets its hashCode value
Credits: deFreitas at: 
*/
public static class CursorInfo extends Structure {

    public int cbSize;//Access must be public
    public int flags;
    public WinDef.HCURSOR hCursor;//Access must be public
    public WinDef.POINT ptScreenPos;

    CursorInfo() {
        this.cbSize = Native.getNativeSize(CursorInfo.class, null);
    }
    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("cbSize", "flags", "hCursor", "ptScreenPos");
    }
}
}

使用的库:

compile group: 'net.java.dev.jna', name: 'jna', version: '4.5.2'
compile group: 'net.java.dev.jna', name: 'jna-platform', version: '4.5.2'

通话中:

final MouseManipulation mouse = new MouseManipulation();
mouse.ChangeMouseCursor();

注意:即使不在 java 应用程序上,我也希望 windows 光标发生变化,因此 JFrame 解决方案和其他类似的东西是没有根据的。

先谢谢你了!

SetCursor 的效果只持续到下一次 SetCursor 调用。 SetCursor 从 windows 程序中调用了很多,以响应 Windows 管理器发送的消息,以便在您将鼠标移到 windows 和更新版本上时通过更改光标形状来向用户提供反馈Windows 个版本,即使鼠标是静止的。

要永久更改光标,您可以使用 SetClassLongPtr( hwnd, GCLP_HCURSOR, cursor_handle ); 或子类 window 过程并处理 WM_SETCURSOR 消息(不幸的是在 C 中):

case WM_SETCURSOR:
    // If you omit test below, you will change cursor also for scrollbars, frames, etc.
    if ( LOWORD( lparam ) == HTCLIENT )
        SetCursor( cursor_handle );
    else
        // This will also handle cursor for scrollbars and frames.
        return DefWindowProc( hwnd, msg, wparam, lparam );
    return TRUE;

cursor_handle 必须是 创建的 window 进程的有效句柄。