4 releases

0.0.4 Jul 1, 2021
0.0.3 Jun 1, 2021
0.0.2 Apr 1, 2021
0.0.1 Oct 28, 2019

#18 in Windows APIs

26 downloads per month

MIT license

30K SLoC


Crates.io Docs.rs Lines of code License: MIT

Win32 GUI and related APIs in safe, idiomatic Rust.

WinSafe has:

  • high-level structs to build native Win32 GUI applications;
  • low-level Win32 API constants, functions and structs related to GUI.

If you're looking for a comprehensive Win32 coverage, take a look at winapi or windows crates, which are unsafe, but have everything.

WinSafe documentation:

Current status

This crate is still in alpha stage. Below is an estimated progress of feature groups:

Feature group Estimated progress
User windows (main, modal and control) Progress
Native controls Progress
Window messages Progress
Overall Win32 APIs Progress


Add the dependency in your Cargo.toml:

winsafe = "0.0.4"

To enable the DirectShow COM module, use:

winsafe = { version = "0.0.4", features = ["dshow"] }

To enable the Shell COM module, use:

winsafe = { version = "0.0.4", features = ["shell"] }


Note: You can find several examples in the dedicated repo: github.com/rodrigocfd/winsafe-examples

WinSafe allows you to create windows in two ways:

  • programmatically defining parameters; or
  • loading dialogs from a .res file created with a WYSIWYG resource editor.

The example below creates a window with a button programmatically. Note how the click event is handled with a closure:

Example 01

#![windows_subsystem = "windows"]

use winsafe::{gui, POINT, SIZE, WinResult};

fn main() {
    let my = MyWindow::new();  // instantiate our main window
    if let Err(e) = my.wnd.run_main(None) { // ... and run it
        eprintln!("{}", e);

pub struct MyWindow {
    wnd:       gui::WindowMain, // responsible for managing the window
    btn_hello: gui::Button,     // a button

impl MyWindow {
    pub fn new() -> MyWindow {
        let wnd = gui::WindowMain::new( // instantiate the window manager
            gui::WindowMainOpts {
                title: "My window title".to_owned(),
                size: SIZE::new(300, 150),
                ..Default::default() // leave all other options as default

        let btn_hello = gui::Button::new(
            &wnd, // the window manager is the parent of our button
            gui::ButtonOpts {
                text: "&Click me".to_owned(),
                position: POINT::new(20, 20),

        let new_self = Self { wnd, btn_hello };
        new_self.events(); // attach our events

    fn events(&self) {
            let wnd = self.wnd.clone(); // clone so it can be passed into the closure
            move || {
                wnd.hwnd().SetWindowText("Hello, world!").unwrap();


Licensed under MIT license, see LICENSE.md for details.

No runtime deps


  • dshow
  • shell