[英]Invalid parameter implementing GetMenuItemInfoW with JNA
我正在調用 win32 API 函數GetMenuItemInfoW
。 當我調用該函數時,它返回false
,而Native.getLastError()
返回 87:
ERROR_INVALID_PARAMETER 87 (0x57) The parameter is incorrect.
我認為我的錯誤在於我對結構 MenuItemInfoW 的實現:
@Structure.FieldOrder({"cbSize", "fMask", "fType", "fState", "wId", "hSubMenu", "hBmpChecked", "hBmpUnchecked", "dwItemData", "dwTypeData", "cch", "hbmpItem"})
public class MENUITEMINFOW extends Structure {
public int cbSize;
public int fMask;
public int fType;
public int fState;
public int wId;
public Pointer hSubMenu;
public Pointer hBmpChecked;
public Pointer hBmpUnchecked;
public WinDef.ULONGByReference dwItemData;
public WString dwTypeData;
public int cch;
public Pointer hbmpItem;
public MENUITEMINFOW() {
super();
}
public MENUITEMINFOW(Pointer pointer) {
super(pointer);
}
}
這是我調用函數的代碼:
MENUITEMINFOW menuiteminfow = new MENUITEMINFOW();
menuiteminfow.fMask = 0x00000040 | 0x00000080 | 0x00000004 | 0x00000002;
menuiteminfow.fType = 0x00000000;
menuiteminfow.cch = 256;
menuiteminfow.dwTypeData = new WString(String.join("", Collections.nCopies(256, " ")));
menuiteminfow.cbSize = Native.getNativeSize(menuiteminfow.getClass());
WinDef.BOOL result = User32Ex.INSTANCE.GetMenuItemInfoW(hMenu.getPointer(), 0, true, menuiteminfow.getPointer());
if (!result.booleanValue()) {
int errorCode = Native.getLastError();
System.out.println("Error Code: " + errorCode);
}
我已經為你的提示編輯了我的代碼,但我得到了同樣的錯誤 87。這是我的新代碼:
MENUITEMINFOW menuiteminfow = new MENUITEMINFOW();
menuiteminfow.fMask = 0x00000040 | 0x00000080 | 0x00000004 | 0x00000002;
menuiteminfow.fType = 0x00000000;
menuiteminfow.cch = 0;
menuiteminfow.dwTypeData = Pointer.NULL;
menuiteminfow.cbSize = Native.getNativeSize(menuiteminfow.getClass());
WinDef.BOOL result = User32Ex.INSTANCE.GetMenuItemInfoW(hMenu.getPointer(),
new WinDef.UINT(0), new WinDef.BOOL(true), menuiteminfow.getPointer());
if (!result.booleanValue()) {
int errorCode = Native.getLastError();
System.out.println("Error Code: " + errorCode);
}
這是我的結構的新版本:
@Structure.FieldOrder({"cbSize", "fMask", "fType", "fState", "wId", "hSubMenu", "hBmpChecked", "hBmpUnchecked", "dwItemData", "dwTypeData", "cch", "hbmpItem"})
public class MENUITEMINFOW extends Structure {
public int cbSize;
public int fMask;
public int fType;
public int fState;
public int wId;
public Pointer hSubMenu;
public Pointer hBmpChecked;
public Pointer hBmpUnchecked;
public BaseTSD.LONG_PTR dwItemData;
public Pointer dwTypeData;
public int cch;
public WinDef.HBITMAP hbmpItem;
public MENUITEMINFOW() {
super();
}
public MENUITEMINFOW(Pointer pointer) {
super(pointer);
this.read();
}
}
謝謝您的答復。
您可以改進結構映射。
首先, ULONG_PTR
與WinDef.ULONGByReference
。 ULONG_PTR
是一個指針大小的值,但它實際上並不指向任何東西。
JNA 有一個內置的BaseTSD.LONG_PTR
類型,你可以在這里使用它。
雖然Pointer
技術上適用於hbmpItem
和其他位圖字段,但類型WinDef.HBITMAP
已在 JNA 中定義,因此您應該使用該映射。
最后,也是您錯誤的可能原因, dwTypeData
接收一個字符串,但它是您需要分配和填充的緩沖區。 來自MENUITEMINFO文檔:
要檢索
MFT_STRING
類型的菜單項,首先通過將MENUITEMINFO
的dwTypeData
成員設置為NULL
然后調用GetMenuItemInfo
來查找字符串的大小。cch+1
的值是需要的大小。 然后分配此大小的緩沖區,指針放置在緩沖dwTypeData
,增量cch
,並調用GetMenuItemInfo
再次以填補該字符串的緩沖區。
因此,在這種情況下,你要映射Pointer
到dwTypeData
,調用函數在第一時間與指針設置為Pointer.NULL
,然后根據遞增它alloating內存cch
:
menuiteminfow.cch++;
// allocate 2 bytes per widechar
menuiteminfow.dwTypeData = new Memory(cch * 2);
您可以在使用menuiteminfow.dwTypeData.getWideString()
函數調用后從那里獲取字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.