windows-api-utils 0.1.0

Windows API utilities for coordinate conversion, bit operations, and message parameter handling with feature gating
Documentation

Windows API Utils

Crates.io Documentation License Build Status

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)

[dependencies]
windows-api-utils = "0.1"
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

[dependencies]
windows-api-utils = { version = "0.1", default-features = false, features = ["coordinates"] }
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

[dependencies]
windows-api-utils = { version = "0.1", default-features = false, features = ["bit-ops"] }
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)

[dependencies]
windows-api-utils = { version = "0.1", default-features = false }
use windows_api_utils::WindowsUtilsError;

// Only error types available in minimal mode

API Overview

Coordinate Conversion

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

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

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:

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.

#![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:

cargo run --example coordinates_demo --features coordinates
cargo run --example full_demo --features full

License

Licensed under either of:

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 for version history and changes.

Documentation

Full API documentation is available at docs.rs.