# Windows API Utils
[](https://crates.io/crates/windows-api-utils)
[](https://docs.rs/windows-api-utils)
[](https://github.com/ymc-github/windows-api-utils/blob/main/LICENSE)
[](https://github.com/ymc-github/windows-api-utils/actions)
A comprehensive Rust library providing utilities for Windows API programming, including coordinate conversion, bit manipulation, and Windows message handling with feature gating support.
## Features
- **Coordinate Conversion**: Client-to-screen and screen-to-client coordinate transformation
- **Bit Manipulation**: Extract high/low words and bytes from integers (LOWORD, HIWORD, LOBYTE, HIBYTE)
- **Message Handling**: Type-safe WPARAM and LPARAM handling for Windows messages
- **Cross-platform**: Works on Windows, Linux, and macOS
- **No-std Support**: Core functionality available without standard library
- **Feature Gating**: Enable only the functionality you need
- **Serialization**: Optional serde support for message types
## Feature Flags
- `coordinates`: Enables coordinate conversion types and traits
- `bit-ops`: Enables bit manipulation utilities
- `messages`: Enables Windows message handling
- `serde`: Enables serialization support for types
- `std`: Enables std support with thiserror (enabled by default)
- `full`: Enables all features
- `minimal`: Disables all optional features
## Quick Start
### Using Default Features (coordinates + messages)
```toml
[dependencies]
windows-api-utils = "0.1"
```
```rust
use windows_api_utils::prelude::*;
// Coordinate conversion
let window = Window::new(12345, Rect::new(100, 100, 500, 400), Default::default());
let client_point = Point::new(50, 30);
let screen_point = window.client_to_screen(client_point).unwrap();
// Message handling
let message = WindowMessage::mouse_move(100, 200, KeyModifiers::default());
if let Some(mouse_event) = MessageParser::parse_mouse_message(message) {
println!("Mouse at ({}, {})", mouse_event.x, mouse_event.y);
}
```
### Using Only Coordinate Features
```toml
[dependencies]
windows-api-utils = { version = "0.1", default-features = false, features = ["coordinates"] }
```
```rust
use windows_api_utils::{Point, Rect, Window, CoordinateTransformer};
let window = Window::new(12345, Rect::new(100, 100, 500, 400), Default::default());
let client_point = Point::new(50, 30);
let screen_point = window.client_to_screen(client_point).unwrap();
```
### Using Only Bit Operations
```toml
[dependencies]
windows-api-utils = { version = "0.1", default-features = false, features = ["bit-ops"] }
```
```rust
use windows_api_utils::{loword, hiword, make_long, BitUtils};
let value = 0x12345678;
let low = loword(value); // 0x5678
let high = hiword(value); // 0x1234
let reconstructed = make_long(high, low);
```
### Minimal Usage (no-std compatible)
```toml
[dependencies]
windows-api-utils = { version = "0.1", default-features = false }
```
```rust
use windows_api_utils::WindowsUtilsError;
// Only error types available in minimal mode
```
## API Overview
### Coordinate Conversion
```rust
use windows_api_utils::{Point, Rect, Window, WindowStyle, CoordinateTransformer};
// Create a window with specific style
let style = WindowStyle {
has_border: true,
has_title_bar: true,
border_width: 8,
title_bar_height: 30,
};
let window = Window::new(12345, Rect::new(100, 100, 500, 400), style);
// Convert coordinates
let client_point = Point::new(50, 30);
let screen_point = window.client_to_screen(client_point)?;
let back_to_client = window.screen_to_client(screen_point)?;
assert_eq!(client_point, back_to_client);
```
### Bit Manipulation
```rust
use windows_api_utils::{loword, hiword, make_long, lobyte, hibyte, make_word, BitUtils, LowHighWord};
// Basic bit operations
let value = 0x12345678;
assert_eq!(loword(value), 0x5678);
assert_eq!(hiword(value), 0x1234);
assert_eq!(make_long(0x1234, 0x5678), 0x12345678);
// Byte operations
assert_eq!(lobyte(0x1234), 0x34);
assert_eq!(hibyte(0x1234), 0x12);
assert_eq!(make_word(0x12, 0x34), 0x1234);
// Advanced bit manipulation
let bits = BitUtils::get_bits(0b1010, 1, 2); // Extract bits 1-2: 0b01
let modified = BitUtils::set_bits(0, 0b11, 2, 2); // Set bits 2-3: 0b1100
// LowHighWord utility
let lhw = LowHighWord::new(0x12345678);
assert_eq!(lhw.loword(), 0x5678);
assert_eq!(lhw.hiword(), 0x1234);
```
### Message Handling
```rust
use windows_api_utils::{
WindowMessage, MessageParser, MouseButton, KeyModifiers,
windows_messages, MouseEvent, KeyEvent
};
// Create mouse messages
let mouse_move = WindowMessage::mouse_move(100, 200, KeyModifiers::default());
let mouse_click = WindowMessage::mouse_button(
MouseButton::Left,
true,
150,
250,
KeyModifiers { shift: true, ..Default::default() }
);
// Parse messages
if let Some(mouse_event) = MessageParser::parse_mouse_message(mouse_move) {
println!("Mouse moved to ({}, {})", mouse_event.x, mouse_event.y);
}
if let Some(mouse_event) = MessageParser::parse_mouse_message(mouse_click) {
println!("Mouse button {:?} clicked at ({}, {})",
mouse_event.button, mouse_event.x, mouse_event.y);
}
// Create and parse keyboard messages
let key_down = WindowMessage::key_event(
windows_messages::WM_KEYDOWN,
0x41, // 'A' key
0x1E, // scan code
1 // repeat count
);
if let Some(key_event) = MessageParser::parse_key_message(key_down) {
println!("Key pressed: {}", key_event.virtual_key);
}
```
## Error Handling
The crate provides comprehensive error handling through the `WindowsUtilsError` enum:
```rust
use windows_api_utils::{WindowsUtilsError, WindowsUtilsResult};
fn coordinate_operation() -> WindowsUtilsResult<Point> {
let window = Window::new(12345, Rect::new(100, 100, 500, 400), Default::default());
let point = Point::new(-10, -20); // Invalid coordinates
// This will return Err(WindowsUtilsError::InvalidCoordinates { x: -10, y: -20 })
window.client_to_screen(point)
}
match coordinate_operation() {
Ok(point) => println!("Success: {}", point),
Err(WindowsUtilsError::InvalidCoordinates { x, y }) => {
println!("Invalid coordinates: ({}, {})", x, y);
}
Err(WindowsUtilsError::OutOfBounds { x, y }) => {
println!("Point ({}, {}) is out of bounds", x, y);
}
Err(e) => println!("Other error: {}", e),
}
```
## No-std Support
The crate supports `no_std` environments. When used without the `std` feature, error types use `&'static str` instead of `String` and don't depend on `thiserror`.
```rust
#![no_std]
use windows_api_utils::WindowsUtilsError;
// Error types work in no_std environments
let error = WindowsUtilsError::InvalidCoordinates { x: -1, y: -1 };
```
## Examples
Check out the examples in the `examples` directory:
- `coordinates_demo`: Demonstrates coordinate conversion
- `bit_ops_demo`: Shows bit manipulation utilities
- `messages_demo`: Illustrates Windows message handling
- `full_demo`: Comprehensive example using all features
Run examples with:
```bash
cargo run --example coordinates_demo --features coordinates
cargo run --example full_demo --features full
```
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
## Documentation
Full API documentation is available at [docs.rs](https://docs.rs/windows-api-utils).