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
122
123
124
//! Active Instruction Example
//!
//! Demonstrates how to use the `active` instruction to ensure a window is in the foreground
//! before executing input operations.
//!
//! # Feature Requirements
//! This example requires:
//! - `scripts_window` feature (provides the active instruction)
//! - `script_process_context` feature (provides HWND support)
//! - `hwnd` feature (for window enumeration)
//!
//! # Build and Run
//! ```bash
//! cargo run --example active_instruction --features "scripts_window,hwnd"
//! ```
use win_auto_utils::hwnd::get_hwnd_by_title;
use win_auto_utils::script_engine::{ScriptEngine, InterruptController};
fn main() {
println!("=== Active Instruction Demo ===\n");
// ========================================================================
// Step 1: Create script engine with built-in instructions
// ========================================================================
println!("1. Setting up script engine with window activation support...");
let engine = ScriptEngine::with_builtin();
println!(" ✓ Engine ready with all built-in instructions (including 'active')");
// ========================================================================
// Step 2: Find target window
// ========================================================================
println!("\n2. Finding target window...");
let window_title = "Notepad";
if let Some(hwnd) = get_hwnd_by_title(window_title) {
println!(" ✓ Found {}: {:?}", window_title, hwnd);
// Note: The 'active' instruction will automatically retrieve HWND from VM context
// No need to manually set it - the engine handles this internally
} else {
println!(" ✗ {} not found. Please open Notepad and try again.", window_title);
return;
}
// ========================================================================
// Step 3: Execute script with 'active' instruction
// ========================================================================
println!("\n3. Executing script with 'active' instruction...");
let script = r#"
# Ensure window is in foreground before sending input
active
# Now safe to send keyboard input
key H
key E
key L
key L
key O
"#;
println!(" Script content:");
for line in script.lines() {
println!(" {}", line);
}
println!("\n Executing...");
// Compile once for better performance
match engine.compile(script) {
Ok(compiled_script) => {
// Execute with interrupt control for safety
let interrupt = InterruptController::new();
match engine.execute_with_interrupt(&compiled_script, &interrupt) {
Ok(_) => println!(" ✓ Script executed successfully!"),
Err(e) => {
println!(" ✗ Execution failed: {}", e);
println!("\n Note: If you see 'activation timed out', it means");
println!(" Windows blocked the activation (foreground lock).");
println!(" Try clicking on the Notepad window manually first.");
}
}
}
Err(e) => {
println!(" ✗ Compilation failed: {}", e);
}
}
// ========================================================================
// Step 4: Demonstrate error handling
// ========================================================================
println!("\n4. Error Handling Demo");
println!(" Testing what happens when 'active' fails...");
// Create a simple test without proper window setup
let test_script = "active";
match engine.compile_and_execute(test_script) {
Ok(_) => println!(" Unexpected success (window was already active)"),
Err(e) => {
println!(" ✓ Expected behavior: {}", e);
println!(" This protects against sending input to wrong window!");
}
}
// ========================================================================
// Summary
// ========================================================================
println!("\n=== Key Takeaways ===");
println!("✓ The 'active' instruction ensures window is in foreground");
println!("✓ Automatically retrieves HWND from VM context");
println!("✓ Uses adaptive polling (not fixed delay) for verification");
println!("✓ Fails safely if activation is blocked by Windows");
println!("✓ Essential for reliable keyboard/mouse automation");
println!("\n=== Best Practices ===");
println!("1. Always call 'active' before input operations");
println!("2. Check execution errors for activation failures");
println!("3. Consider user interaction if activation is blocked");
println!("4. Use reasonable timeouts (default 300ms works well)");
}