即使窗口位于顶部也无法获得焦点

问题描述 投票:0回答:1

我正在开发一个程序,该程序使用低级键盘挂钩(LowLevelKeyboardProc)来检测组合键并在特定进程窗口之间切换焦点目标是让程序在检测到 Shift + E 或 Shift + Q 时将焦点移动到一组程序的下一个上一个窗口。

但是,当当前窗口不是我自己程序的窗口时,SetForegroundWindow函数不起作用,所以我必须使用AttachThreadInput将窗口带到顶部。问题是窗口没有接收焦点,所以当我发送键盘命令时,它们仍然会转到上一个窗口。

如何为顶部的窗口启用焦点?

这是我正在使用的函数的片段:

    let target_window =
        self.get_window_by_name(process_id, "Window Name".to_string());

    if let Some(target_window) = target_window {
        unsafe {
            if current_process_id.is_none() {
                ShowWindow(target_window.0, SW_NORMAL);
                SetForegroundWindow(target_window.0);
                SetActiveWindow(target_window.0);
            } else {
                let foreground_window = GetForegroundWindow();
                let foreground_thread_id =
                    GetWindowThreadProcessId(foreground_window, std::ptr::null_mut());
                let target_thread_id =
                    GetWindowThreadProcessId(target_window.0, std::ptr::null_mut());

                AttachThreadInput(foreground_thread_id, target_thread_id, TRUE);

                BringWindowToTop(target_window.0);
                ShowWindow(target_window.0, SW_NORMAL);
                // SetForegroundWindow(target_window.0);
                // SetFocus(target_window.0);
                SetActiveWindow(target_window.0);

                AttachThreadInput(foreground_thread_id, target_thread_id, FALSE);
            }
        }
    }

观察:

当current_process_id为None时,表示当前进程是我的程序,所以我只执行SetForegroundWindow,一切正常。当它是 Some 时,这意味着我位于我想要在其之间转换的窗口之一,并且它无法正常工作。

windows winapi rust
1个回答
0
投票

正如评论中@IInspectable所建议的,从LowLevelKeyboardProc切换到RegisterHotKey允许调用SetForegroundWindow将窗口带到前台并聚焦它们接收键盘输入

通过此更改,也不需要使用AttachThreadInput

以下是更新代码的简短片段:

热键.rs

//call in main trehad 
pub struct HotkeyEvent {}

impl HotkeyEvent {
    pub fn register() -> Result<(), ()> {
        unsafe {
            if RegisterHotKey(null_mut(), HOTKEY_ID_Q, MOD_SHIFT as u32, 0x51 as u32) == 0 {
                eprintln!("Failed to register hotkey SHIFT + Q");
                return Err(());
            }
            if RegisterHotKey(null_mut(), HOTKEY_ID_E, MOD_SHIFT as u32, 0x45 as u32) == 0 {
                eprintln!("Failed to register hotkey SHIFT + E");
                return Err(());
            }

            Ok(())
        }
    }

    pub fn start_loop_message() {
        unsafe {
            let mut msg: MSG = std::mem::zeroed();

            while GetMessageW(&mut msg, null_mut(), 0, 0) > 0 {
                if msg.message == WM_HOTKEY {
                // Here, I perform the logic to obtain the ID of the next window 
                //  and call the set_window_foreground function.
                    process_message_hotkey(msg.wParam as u32) 
                }
                TranslateMessage(&msg);
                DispatchMessageW(&msg);
            }
        }
    }
}

pub fn set_window_foreground(
    &self,
    process_id: u32,
    current_process_id: Option<u32>,
) -> Option<bool> {
    let target_window =
        self.get_window_by_name(process_id, "Window Name".to_string());

    if let Some(target_window) = target_window {
        unsafe {
            ShowWindow(target_window.0, SW_NORMAL);
            SetForegroundWindow(target_window.0);
            SetActiveWindow(target_window.0);
        }
    }
    None
}
© www.soinside.com 2019 - 2024. All rights reserved.