1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::*;
use *;
/// \[[learn.microsoft.com](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-allowsetforegroundwindow)\]
/// ASFW_ANY
///
/// Used with [allow_set_foreground_window] to allow any process to set the foreground window.
pub use ASFW_ANY;
/// \[[learn.microsoft.com](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-allowsetforegroundwindow)\]
/// AllowSetForegroundWindow
///
/// **NOTE:** There are many restrictions on when a process can set (or grant the ability to set) the foreground window. See [set_foreground_window] for details.
///
/// Enables the specified process to set the foreground window using the [set_foreground_window] function.
/// The calling process must already be able to set the foreground window.
///
/// ### Arguments
/// * `process_id` The process ID to give access to [set_foreground_window], or [`ASFW_ANY`] to allow any process.
///
/// ### Errors
/// * [ERROR::ACCESS_DENIED] If the current process is itself restricted from setting the foreground window. See [set_foreground_window] for details.
/// * [ERROR::INVALID_PARAMETER] If `process_id` isn't a valid process ID
///
/// ### Examples
/// ```rust
/// # use hwnd::*;
/// # use winresult::*;
/// # let pid = ASFW_ANY;
/// let _ = allow_set_foreground_window(pid); // typical use
///
/// if let Err(e) = allow_set_foreground_window(ASFW_ANY) {
/// match e.code() {
/// None => {}, // typical
/// Some(ERROR::ACCESS_DENIED) => {}, // semi-common (focus another window and type while launching tests)
/// _ => panic!("allow_set_foreground_window(ASFW_ANY): unexpected error: {e:?}"),
/// }
/// }
///
/// if let Err(e) = allow_set_foreground_window(!42) {
/// match e.code() {
/// Some(ERROR::INVALID_PARAMETER) => {}, // typical
/// Some(ERROR::ACCESS_DENIED) => {}, // semi-common (focus another window and type while launching tests)
/// None => {}, // unlikely, but maybe pid !42 existed?
/// _ => panic!("allow_set_foreground_window(!42): unexpected error: {e:?}"),
/// }
/// }
/// ```
/// \[[learn.microsoft.com](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow)\]
/// SetForegroundWindow
///
/// **NOTE:** There are many restrictions on when a process can set the foreground window.
///
/// Brings the thread that created the specified window into the foreground and activates the window.
/// Keyboard input is directed to the window, and various visual cues are changed for the user.
/// The system assigns a slightly higher priority to the thread that created the foreground window than it does to other threads.
///
/// ### Errors
/// * [ERROR::ACCESS_DENIED] If restricted from setting the foreground window (see "Restrictions" bellow.)
/// * [ERROR::INVALID_WINDOW_HANDLE] If restricted from setting the foreground window, if given `desktop` (or other [HWnd]s belonging to other processes?)
/// * [ERROR::INVALID_WINDOW_HANDLE] If `hwnd`'s try_into fails, or results in a null or otherwise invalid window handle.
///
/// ### Examples
/// ```rust
/// # use hwnd::*;
/// # use winresult::*;
/// # use std::ptr::null_mut;
/// # let desktop = get_desktop_window();
/// # let hwnd = get_foreground_window();
/// # if !hwnd.is_null() {
/// let _ = set_foreground_window(hwnd); // typical use
/// # }
///
/// let e = set_foreground_window(null_mut()).err().unwrap();
/// match e.code() {
/// Some(ERROR::INVALID_WINDOW_HANDLE) => {}, // typical
/// Some(ERROR::ACCESS_DENIED) => {}, // semi-common (focus another window and type while launching tests)
/// _ => panic!("set_foreground_window(null_mut()): unexpected error: {e:?}"),
/// }
///
/// if let Err(e) = set_foreground_window(!42usize as HWND) {
/// match e.code() {
/// Some(ERROR::INVALID_WINDOW_HANDLE) => {}, // typical
/// _ => panic!("set_foreground_window(!42): unexpected error: {e:?}"),
/// }
/// }
///
/// if let Err(e) = set_foreground_window(desktop) {
/// match e.code() {
/// Some(ERROR::ACCESS_DENIED) => {}, // expected when tests unfocused, but instead we get:
/// Some(ERROR::INVALID_WINDOW_HANDLE) => {}, // ... on Windows 10.0.19041.1415
/// _ => panic!("set_foreground_window(desktop): unexpected error: {e:?}"),
/// }
/// }
// TODO: create a local window
/// ```
///
/// ### Restrictions
/// A process can set the foreground window only if one of the following conditions is true:
/// * The process is the foreground process.
/// * The process was started by the foreground process.
/// * The process received the last input event.
/// * There is no foreground process.
/// * The process is being debugged.
/// * The foreground process is not a Modern Application or the Start Screen.
/// * The foreground is not locked (see LockSetForegroundWindow).
/// * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
/// * No menus are active.