首页 新闻 会员 周边 捐助

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

0
悬赏园豆:200 [已解决问题] 解决于 2025-01-21 16:05

环境:
tauri: v2
windows:0.57.0

获取上图中选中的文件路径“1.png”
补充说明:这个弹窗是其它程序开启的,但是我可以拿到窗口的HWND

_zhiqiu的主页 _zhiqiu | 初学一级 | 园豆:31
提问于:2025-01-02 13:41

rust 调用这个窗口的时候,有没有这个窗口的返回值?

echo_lovely 3周前

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

_zhiqiu 3周前
< >
分享
最佳答案
0
收获园豆:200
dudu | 高人七级 |园豆:28576 | 2025-01-03 09:54

这可能行不通,因为在IShellWindows中找不到这个弹窗

_zhiqiu | 园豆:31 (初学一级) | 2025-01-03 10:00
dudu | 园豆:28576 (高人七级) | 2025-01-03 10:24

@dudu: 非常感谢您的回答,但是这个帖子中步骤还是要先获取IShellWindows。
我已经完在 explorer和桌面中完成了同样的功能(都是通过IShellWindows -> IDispath -> IShellBrowser -> IShellView)。
但是上面的流程在文件选择框中没有效果。

_zhiqiu | 园豆:31 (初学一级) | 2025-01-03 10:35

@dudu: 我现在准备换一种方式去实现,思路是分别找到搜索栏的窗口和文件名的窗口,然后获取起title,具体可以看下面的代码;但是我碰到一个问题,在spy++能看到文件名窗口的窗口标题但是在代码中获取不到

// 获取选中文件窗口的 Text
        let seleced_file_hwnd = unsafe {
            WindowsAndMessaging::FindWindowExW(fw_hwnd, None, w!("ComboBoxEx32"), None)
        };
        println!("seleced_file_hwnd: {:?}", seleced_file_hwnd);
        if seleced_file_hwnd.is_err() {
            return Ok(target_path);
        }
        let seleced_file_hwnd = seleced_file_hwnd.unwrap();
        let mut real_selected_file_hwnd: Option<HWND> = None;
        let _ = unsafe {
            WindowsAndMessaging::EnumChildWindows(seleced_file_hwnd, Some(Self::get_select_file_from_dialog_proc), LPARAM(&mut real_selected_file_hwnd as *const _ as _))
        };
        println!("real_selected_file_hwnd: {:?}", real_selected_file_hwnd);
        if real_selected_file_hwnd.is_none() {
            return Ok(target_path);
        }
        let real_selected_file_hwnd = real_selected_file_hwnd.unwrap();
        let seleced_file_title = win::get_window_text(real_selected_file_hwnd);
        println!("seleced_file_title: {:?}", seleced_file_title);

        // 获取搜索框的 Text
        let mut breadcrumb_parent_hwnd: Option<HWND> = None;
        let _ = unsafe {
            WindowsAndMessaging::EnumChildWindows(fw_hwnd, Some(Self::get_select_file_from_dialog_proc), LPARAM(&mut breadcrumb_parent_hwnd as *const _ as _))
        };
        if breadcrumb_parent_hwnd.is_none() {
            return Ok(target_path);
        }
        let breadcrumb_parent_hwnd = breadcrumb_parent_hwnd.unwrap();
        let breadcrumb_hwnd = unsafe {
            WindowsAndMessaging::FindWindowExW(breadcrumb_parent_hwnd, None, w!("ToolbarWindow32"), None)
        };
        if breadcrumb_hwnd.is_err() {
            return Ok(target_path);
        }
        let breadcrumb_hwnd = breadcrumb_hwnd.unwrap();
        let breadcrumb_title = win::get_window_text(breadcrumb_hwnd);
        println!("breadcrumb_title: {:?}", breadcrumb_title);

        target_path = format!("{}\\{}", breadcrumb_title, seleced_file_title);
_zhiqiu | 园豆:31 (初学一级) | 2025-01-03 10:39

@_zhiqiu: win::get_window_text 是怎么实现的?其他窗口可以获取到标题吗?

dudu | 园豆:28576 (高人七级) | 2025-01-03 10:59

@dudu: 是的,其它窗口是正常的,比如上面代码中的 breadcrumb_title 可以正常获取。
下面是 win::get_window_text 的实现:

pub fn get_window_text(hwnd: HWND) -> String {
    let len = unsafe { WindowsAndMessaging::GetWindowTextLengthW(hwnd) + 1 };
    let mut buffer = vec![0u16; len as usize];
    let len = unsafe { WindowsAndMessaging::GetWindowTextW(hwnd, &mut buffer) };
    String::from_utf16_lossy(&buffer[0..len as usize])
}
_zhiqiu | 园豆:31 (初学一级) | 2025-01-03 11:01

@_zhiqiu: 建议确认一下是否是权限问题,参考 https://stackoverflow.com/a/54280690

dudu | 园豆:28576 (高人七级) | 2025-01-03 11:06

@dudu: 感谢,我试试

_zhiqiu | 园豆:31 (初学一级) | 2025-01-03 13:16

@dudu:
这是窗口的层级结构,现在有 SHELLDLL_DefView, 可以通过 SHELLDLL_DefView 拿到 IUnknown/IDisaptch/IShellBrowser 吗?由于我对于 windows 相关的接口不是很了解。

我尝试了通过 WindowsAndMessaging::SendMessageW(defview, WindowsAndMessaging::RegisterWindowMessageW(w!("SHELL_IUnknown")), WPARAM(0), LPARAM(&mut unknown as *const _ as _)) 方式去获取却无法获取到。
麻烦您了。

_zhiqiu | 园豆:31 (初学一级) | 2025-01-03 13:40
dudu | 园豆:28576 (高人七级) | 2025-01-03 18:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册