V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
GuoJikun
V2EX  ›  程序员

在 rust 中如何获取文件选择弹窗中鼠标选中的文件路径

  •  
  •   GuoJikun · 1 天前 · 744 次点击

    环境: tauri:v2 windows:0.57.0

    获取上图中选中的文件路径“1.png”;

    这个弹窗是其它程序开启的,但是我可以拿到窗口的 HWND ;

    尝试的方法:

    • IShellWindow 中是找不到这个弹窗的(遍历 IShellWindow 获得其 HWND 和弹窗的 HWND 进行对比);
    • 通过 Window 的 WindowsAndMessaging::GetWindowTextW(hwnd, &mut buffer) 分别哪目录和文件名时,文件名获取不到,但是通过 Spy++可以看到
    12 条回复    2025-01-06 15:36:06 +08:00
    PTLin
        1
    PTLin  
       1 天前
    你是要在打开这个文件选择窗口,鼠标点上这个文件的时候,获取到这个的路径吗?这么硬核的需求吗?
    tinytoadd
        2
    tinytoadd  
       1 天前
    自己实现一个 file picker 可能可以
    geelaw
        3
    geelaw  
       1 天前   ❤️ 1
    答案是不要尝试做这件事情。

    IShellWindows 枚举的是 shell (Explorer) 里面打开的窗口,其他程序打开的文件选择对话框和 shell 没什么必然关系。

    使用 GetWindowTextW 得到的是 hwnd 里面的文字,首先在那个文件对话框里面,对话框本身和对话框里面的文件名组合框(可以输入文本、可以下拉选择,也可以通过选定项目改变的,左边写着“文件名(&N):”的框),是两个窗口(甚至有可能那个组合框是无窗口控件),它们的 hwnd 都不一样,在对话框的 hwnd 上调用 GetWindowTextW 得到的是对话框的标题,和文件名没有关系。

    那个组合框里的文本可以是用户乱写的,不一定对应任何一个文件。

    即使用户通过选择一个文件导致组合框显示了文件名,它显示的名字也不一定是你期待的那一个——你可以在 notepad.exe 里面打开“打开”对话框,然后导航到 C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Accessibility ,选定放大镜的快捷方式,你会发现:

    1. 显示的名字没有 .lnk
    2. 显示的名字不是 Magnify.lnk 而是(中文)“放大镜”或者(英文)“Magnifier”

    但是那个文件的名字是 Magnifier.lnk ,显示的名字是通过 desktop.ini 控制的。

    ————

    最好直接问你想要做什么最终用户受益的事情,而不是怎么做你想到的一种可能的做法,避免 X-Y 问题。
    geelaw
        4
    geelaw  
       1 天前
    @geelaw #3 那个文件的名字是 Magnify.lnk 。另外要让 notepad.exe 显示所有文件,只要在文件名里面输入 * 再按一下回车。
    vvhy
        5
    vvhy  
       1 天前
    换个思路,拦截 GetOpenFileName 调用
    GuoJikun
        6
    GuoJikun  
    OP
       1 天前
    @PTLin
    不是,是鼠标选中后,按空格键预览,类似于[QuickLook]( https://github.com/QL-Win/QuickLook)
    为了实现类似的功能,在选择文件前预览文件内容
    GuoJikun
        7
    GuoJikun  
    OP
       1 天前
    @geelaw
    > GetWindowTextW 看来这种方式时不可取的;
    我想要完成的功能是,选择文件后按空格对文件进行预览,类似于 macos 的按空格预览功能
    seansong
        8
    seansong  
       1 天前
    自己实现一个文件选择功能比较靠谱,根据自己的需要自定义功能,这样还可以做出跟 app 更适配的 ui 风格
    GuoJikun
        9
    GuoJikun  
    OP
       1 天前
    @tinytoadd
    ```rust
    let file_dialog: IFileOpenDialog = CoCreateInstance(
    &FileOpenDialog,
    None,
    CLSCTX_INPROC_SERVER
    )?;
    ```
    这种吗?
    geelaw
        10
    geelaw  
       1 天前 via iPhone
    @GuoJikun #7 Alt+P 是官方的预览方式(但很可惜在 pickerhost 里不行)
    cppc
        11
    cppc  
       1 天前
    我觉得思路应该是跟文件管理器(Explorer.exe)进行交互,比如做成它的插件,捕获它的事件,甚至是 API HOOK 之类来得到你关注的信息。
    GuoJikun
        12
    GuoJikun  
    OP
       1 天前
    已解决! 通过 ui 自动化获取选中文件名,然后通过获取地址栏的 text ( GetWindowTextW )获取目录结构,最后合并两者即可得到完整的地址
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1036 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:27 · PVG 06:27 · LAX 14:27 · JFK 17:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.