Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JNA实现IContextMenu COM接口_Java_Winapi_Com_Jna_Vtable - Fatal编程技术网

Java 使用JNA实现IContextMenu COM接口

Java 使用JNA实现IContextMenu COM接口,java,winapi,com,jna,vtable,Java,Winapi,Com,Jna,Vtable,我需要Windows资源管理器外壳菜单中的所有项目。我正在用jna实现IShellFolder COM对象接口。但是现在我在实现用于查询上下文菜单的接口IContextMenu时遇到了问题。当我调用QueryContextMenu函数时,HResult的结果与true一样为0,但当我调用函数GetMenuItemCount时,HMenu为空,结果为0 你能告诉我哪里有虫子吗。多谢各位 这是我的IContextMenu代码: public interface IContextMenu { Guid

我需要Windows资源管理器外壳菜单中的所有项目。我正在用jna实现IShellFolder COM对象接口。但是现在我在实现用于查询上下文菜单的接口IContextMenu时遇到了问题。当我调用QueryContextMenu函数时,HResult的结果与true一样为0,但当我调用函数GetMenuItemCount时,HMenu为空,结果为0

你能告诉我哪里有虫子吗。多谢各位

这是我的IContextMenu代码:

public interface IContextMenu {
Guid.IID IID_IContextMenu = new Guid.IID("{000214E4-0000-0000-C000-000000000046}");

WinNT.HRESULT QueryContextMenu(WinDef.HMENU hMenu, int indexMenu, int idCmdFirst, int idCmdLast, int uFlags);
WinNT.HRESULT InvokeCommand(Pointer pici);
WinNT.HRESULT GetCommandString(IntByReference idCmd, int uType, IntByReference pReserved, WTypes.LPSTR pszName, int cchMax);

public static class Converter {
    public Converter() {
    }

    public static IContextMenu PointerToIContextMenu(PointerByReference ptr) {
        final Pointer interfacePointer = ptr.getValue();
        final Pointer vTablePointer = interfacePointer.getPointer(0);
        final Pointer[] vTable = new Pointer[3];
        vTablePointer.read(0, vTable, 0, 3);

        return new IContextMenu() {
            @Override
            public WinNT.HRESULT QueryContextMenu(WinDef.HMENU hMenu, int indexMenu, int idCmdFirst, int idCmdLast, int uFlags) {
                Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION);
                return new WinNT.HRESULT(f.invokeInt(new Object[] { interfacePointer, hMenu.getPointer(), indexMenu, idCmdFirst, idCmdLast, uFlags }));
            }

            @Override
            public WinNT.HRESULT InvokeCommand(Pointer pici) {
                Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION);
                return new WinNT.HRESULT(f.invokeInt(new Object[]{ interfacePointer, pici }));
            }

            @Override
            public WinNT.HRESULT GetCommandString(IntByReference idCmd, int uType, IntByReference pReserved, WTypes.LPSTR pszName, int cchMax) {
                Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION);
                return new WinNT.HRESULT(f.invokeInt(new Object[] { interfacePointer, idCmd, uType, pReserved, pszName, cchMax }));
            }
        };
    }
}
IContextMenu contextMenu = null;
PointerByReference contextMenuPtr = new PointerByReference();
Pointer ppidlsPointer = new Memory(Native.POINTER_SIZE * ppidls.length);
ppidlsPointer.setPointer(0, ppidls[0].getValue());
hResult = psfParentFolder.GetUIObjectOf(null, 1, ppidls[0].getPointer(), new Guid.REFIID(IContextMenu.IID_IContextMenu), new IntByReference(0), contextMenuPtr);
if (!COMUtils.SUCCEEDED(hResult))
   return false;

/* End Section */

/* Begin Get Context Menu Section */

contextMenu = IContextMenu.Converter.PointerToIContextMenu(contextMenuPtr);
WinDef.HMENU hMenu = User32Ex.INSTANCE.CreatePopupMenu();
hResult = contextMenu.QueryContextMenu(hMenu, 0, 1, 30, 0x00000004);
if (!COMUtils.SUCCEEDED(hResult)) {
   int error = Native.getLastError();
   return false;
}

int count = User32Ex.INSTANCE.GetMenuItemCount(hMenu.getPointer());
if (count > 0) {
}

/* End Section */
}

这是我调用QueryContextMenu的代码:

public interface IContextMenu {
Guid.IID IID_IContextMenu = new Guid.IID("{000214E4-0000-0000-C000-000000000046}");

WinNT.HRESULT QueryContextMenu(WinDef.HMENU hMenu, int indexMenu, int idCmdFirst, int idCmdLast, int uFlags);
WinNT.HRESULT InvokeCommand(Pointer pici);
WinNT.HRESULT GetCommandString(IntByReference idCmd, int uType, IntByReference pReserved, WTypes.LPSTR pszName, int cchMax);

public static class Converter {
    public Converter() {
    }

    public static IContextMenu PointerToIContextMenu(PointerByReference ptr) {
        final Pointer interfacePointer = ptr.getValue();
        final Pointer vTablePointer = interfacePointer.getPointer(0);
        final Pointer[] vTable = new Pointer[3];
        vTablePointer.read(0, vTable, 0, 3);

        return new IContextMenu() {
            @Override
            public WinNT.HRESULT QueryContextMenu(WinDef.HMENU hMenu, int indexMenu, int idCmdFirst, int idCmdLast, int uFlags) {
                Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION);
                return new WinNT.HRESULT(f.invokeInt(new Object[] { interfacePointer, hMenu.getPointer(), indexMenu, idCmdFirst, idCmdLast, uFlags }));
            }

            @Override
            public WinNT.HRESULT InvokeCommand(Pointer pici) {
                Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION);
                return new WinNT.HRESULT(f.invokeInt(new Object[]{ interfacePointer, pici }));
            }

            @Override
            public WinNT.HRESULT GetCommandString(IntByReference idCmd, int uType, IntByReference pReserved, WTypes.LPSTR pszName, int cchMax) {
                Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION);
                return new WinNT.HRESULT(f.invokeInt(new Object[] { interfacePointer, idCmd, uType, pReserved, pszName, cchMax }));
            }
        };
    }
}
IContextMenu contextMenu = null;
PointerByReference contextMenuPtr = new PointerByReference();
Pointer ppidlsPointer = new Memory(Native.POINTER_SIZE * ppidls.length);
ppidlsPointer.setPointer(0, ppidls[0].getValue());
hResult = psfParentFolder.GetUIObjectOf(null, 1, ppidls[0].getPointer(), new Guid.REFIID(IContextMenu.IID_IContextMenu), new IntByReference(0), contextMenuPtr);
if (!COMUtils.SUCCEEDED(hResult))
   return false;

/* End Section */

/* Begin Get Context Menu Section */

contextMenu = IContextMenu.Converter.PointerToIContextMenu(contextMenuPtr);
WinDef.HMENU hMenu = User32Ex.INSTANCE.CreatePopupMenu();
hResult = contextMenu.QueryContextMenu(hMenu, 0, 1, 30, 0x00000004);
if (!COMUtils.SUCCEEDED(hResult)) {
   int error = Native.getLastError();
   return false;
}

int count = User32Ex.INSTANCE.GetMenuItemCount(hMenu.getPointer());
if (count > 0) {
}

/* End Section */

您可能没有从
IContextMenuVtbl
中阅读您的想法。此代码表示您只收集了3个函数指针:

final Pointer[] vTable = new Pointer[3];
vTablePointer.read(0, vTable, 0, 3);
但是,此接口(与大多数COM接口一样)扩展了
IUnknown
,因此在索引0处自动获取方法
QueryInterface
、在索引1处获取方法
AddRef
、在索引2处获取方法
Release
。因此,这三个方法似乎是您正在调用的,尽管参数错误

从中,指针索引继续:

  • 3:
    QueryContextMenu
  • 4:
    InvokeCommand
  • 5:
    GetCommandString
您可以读入所有6个函数指针并引用最后3个,也可以尝试使用现有编号以3个指针的偏移量读取(但顺序相反!)


我认为您还应该在接口定义中添加
扩展IUnknown

您可能没有从
IContextMenuVtbl
中阅读您的想法。此代码表示您只收集了3个函数指针:

final Pointer[] vTable = new Pointer[3];
vTablePointer.read(0, vTable, 0, 3);
但是,此接口(与大多数COM接口一样)扩展了
IUnknown
,因此在索引0处自动获取方法
QueryInterface
、在索引1处获取方法
AddRef
、在索引2处获取方法
Release
。因此,这三个方法似乎是您正在调用的,尽管参数错误

从中,指针索引继续:

  • 3:
    QueryContextMenu
  • 4:
    InvokeCommand
  • 5:
    GetCommandString
您可以读入所有6个函数指针并引用最后3个,也可以尝试使用现有编号以3个指针的偏移量读取(但顺序相反!)

我认为您还应该在接口定义中添加一个
扩展IUnknown