Expand description
A minimal window context for Rust on Windows.
I read msdn so you don’t have to.
This crate provides a minimalistic method for setting up and running a window. A window on windows is more like a generic application framework and doesn’t actually need to have any visible elements, but is necessary to do many of the productive things you might want to do on Windows.
Some example of this are:
- Register and use a tray icon with a popup menu, or the “clickable icons” you see in the bottom right for running applications.
- Send desktop notifcations, or “balloons” as they are sometimes called.
- Interact with the clipboard and monitor it for changes.
- Copy data to a remote process, allowing for very simple unidirection IPC.
There are a few additional APIs provided by this crate because they are also useful:
- Basic safe registry access allowing for example of the registration of an application that should be started automatically when the user logs in.
This crate is an amalgamation and cleanup of code I’ve copied back and forth
between my projects, so it is fairly opinionated to things I personally find
useful. Not everything will be possible, but if there is something you’re
missing and hate being happy enjoy Windows programming feel free to open
an issue or a pull request.
§Example
The primary purpose of this crate is to:
- Define a window and its capabilities. I.e. if it should have a context menu or receive clipboard events.
- Handle incoming Events from the window.
The basic loop looks like this:
use std::pin::pin;
use tokio::signal::ctrl_c;
use winctx::{Event, CreateWindow};
const ICON: &[u8] = include_bytes!("tokio.ico");
let mut window = CreateWindow::new("se.tedro.Example")
.window_name("Example Application");
let icon = window.icons().insert_buffer(ICON, 22, 22);
let area = window.new_area().icon(icon);
let menu = area.popup_menu();
let first = menu.push_entry("Example Application").id();
menu.push_separator();
let quit = menu.push_entry("Quit").id();
menu.set_default(first);
let (sender, mut event_loop) = window
.build()
.await?;
let mut ctrl_c = pin!(ctrl_c());
let mut shutdown = false;
loop {
let event = tokio::select! {
_ = ctrl_c.as_mut(), if !shutdown => {
sender.shutdown();
shutdown = true;
continue;
}
event = event_loop.tick() => {
event?
}
};
match event {
Event::MenuItemClicked { item_id, .. } => {
println!("Menu entry clicked: {item_id:?}");
if item_id == quit {
sender.shutdown();
}
}
Event::Shutdown { .. } => {
println!("Window shut down");
break;
}
_ => {}
}
}
Modules§
- Types related to defining the notification area.
- Types related to events produced by this library.
- Types related to icons.
- Type used to interact with an icons collection.
- Types related to modifying the window context.
- Minor tools made available for convenience.
- Types related to finding and manipulating windows.
Macros§
- Helper macro to build a match pattern over an item id.
Structs§
- The identifier for an
Area
. - Helper to register and qeury for a binary to autostart.
- Construct a window.
- The error raised by this library.
- The event loop being run.
- A reference to an icon.
- An identifier for a menu item.
- A named exclusive mutex that can be used to ensure that only one instance of an application is running.
- An identifier for a notification.
- Helper to open a registry key with the ability to specify desired permissions.
- The structure of a popup menu.
- An open registry key.
- Handle used to interact with the system integration.
- Handle to a window on the system.
Enums§
- An event emitted by the event loop.
Type Aliases§
- Convenient result alias for this crate.