kihlh / hmc-win32

HMC Easier Access to System APIs 简化连接winapi的过程的node c++模块

Home Page:https://kihlh.gitbook.io/hmc/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

这是一个很好的项目,这里有一个小需求

BitmapLong opened this issue · comments

能否在api里面加入一个调用系统 TrackPopupMenuEx 弹出右键菜单的接口

例如,传递给接口一个或多个文件路径(其中可能会有文件夹路径), 然后接口接收到这些路径后,获取系统默认的菜单句柄,交给 TrackPopupMenuEx ,然后在当前鼠标位置弹出右键菜单

我使用 net8 winform 完成了这个小需求,但是它的文件体积太大了,如果选择“可移植”,还需要安装 net8 运行时
所以,能否出一个这样的接口,方便调用

我目前在做一个文件资源管理器

commented

这个接口是存在的,但是我没暴露

这个接口是存在的,但是我没暴露

啊,太好了,预期多久可以暴露这个接口?或者我应该怎么做,让它暴露给electron

commented

近期添加,不过我记得他只能选择单文件,不知道是不是通过\0切割为数组的,我需要确认下再添加导出

需要传给你一份 net 代码么,里面是指定位置弹出菜单的具体操作

commented

如果可以的话您可以提供下原始net代码

我看了下此api定义,改成多文件的应该问题也不大Screenshot_2024-02-01-14-49-02-391_com.github.android.jpg

ShellContextMenu.zip

此处感谢 https://www.codeproject.com/Articles/22012/Explorer-Shell-Context-Menu

它的调用很简单

ShellContextMenu scm = new ShellContextMenu();
FileInfo[] files = new FileInfo[1];
files[0] = new FileInfo(@"c:\windows\notepad.exe");
scm.ShowContextMenu(this.Handle, files, Cursor.Position);

ShellContextMenu.zip

此处感谢 https://www.codeproject.com/Articles/22012/Explorer-Shell-Context-Menu

它的调用很简单

ShellContextMenu scm = new ShellContextMenu(); FileInfo[] files = new FileInfo[1]; files[0] = new FileInfo(@"c:\windows\notepad.exe"); scm.ShowContextMenu(this.Handle, files, Cursor.Position);

需要注意的是,它只能在 winform 中运行,在控制台中,调用 ShowContextMenu 方法不起作用

微软的api 说明也证明了这一点

最低受支持的客户端 | Windows 2000 Professional [仅限桌面应用] -- | -- 最低受支持的服务器 | Windows 2000 Server [仅限桌面应用]
commented

您好十分感谢您的建议 但是由于我的个人时间不足 本次代码改动又过大所以无法添加到hmc模块中,我单独写了个独立的模块,您可以了解下如下情况

ShowContextMenu.zip

  • showContextMenu
    输入类型定义: showContextMenu(hwnd:number, filePath:string|string[], x?:number|null, y?:number|null);
    返回值 布尔

他必须在Electron主进程中调用 参数1是窗口句柄 你可以在 BrowserWindow..getNativeWindowHandle() 获取到缓冲区 然后使用以下代码转换为数字 再传递给api

// 将 electron 句柄内存缓冲区转换为标准 窗口数字句柄
function readHandle(handleBuffer)
{
    let num = 0;

    // Node.js 10.5.0 以上版本
    if (typeof BigInt != = 'undefined')
    {
        let handleBigInt = handleBuffer.readBigUInt64LE();
        return (Number(handleBigInt));
    }
    else
    {
        if (process.platform == = 'win32')
        {
            num = handleBuffer.readUInt32LE();
        }
        else if (process.platform == = 'darwin')
        {
            num = handleBuffer.readUInt32LE(0) + 2 * *32 * handleBuffer.readUInt32LE(4);
        }
        else
        {
            num = handleBuffer.readUInt32LE(0) + 2 * *32 * handleBuffer.readUInt32LE(4);
        }

        return num;
    }
    return num;
}

// 当x+y==0 的时候将会从鼠标所在的地方显示
let x = 0;
let y = 0;

// 当窗口句柄为0或者为null时候将在聚焦中的窗口显示
let hwnd = Electron.BrowserWindow.getFocusedWindow().getNativeWindowHandle()

hmc_debug.showContextMenu(readHandle(hwnd), [ "f:\\1.exe", "f:/2.exe" ], x, y);
hmc_debug.showContextMenu(readHandle(hwnd), "f:\\1.exe", x, y);

// 一个shell空白 驱动器菜单
hmc_debug.showContextMenu(readHandle(hwnd), "", x, y);

太感谢了,它是一个很好的礼物

commented

值得注意的是文件不能添加不存在,不然会导致严重的错误,虽然我已经屏蔽了,但是会出现显示失败

commented

需求被合并到 #68