Skip to content

Instantly share code, notes, and snippets.

@fgimian
Last active November 20, 2022 09:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fgimian/32245272b26409681c2cdb6a2d970881 to your computer and use it in GitHub Desktop.
Save fgimian/32245272b26409681c2cdb6a2d970881 to your computer and use it in GitHub Desktop.
Example Window for Volume Widget using winit
use anyhow::Result;
use thiserror::Error;
use windows::Win32::UI::{
Input::KeyboardAndMouse::{
RegisterHotKey, MOD_SHIFT, VK_VOLUME_DOWN, VK_VOLUME_MUTE, VK_VOLUME_UP,
},
WindowsAndMessaging::{MSG, WM_HOTKEY},
};
use winit::{
dpi::{PhysicalPosition, PhysicalSize},
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoopBuilder},
platform::windows::{EventLoopBuilderExtWindows, WindowBuilderExtWindows, WindowExtWindows},
window::WindowBuilder,
};
#[derive(Error, Debug)]
#[error("unable to bind the required hotkey")]
pub struct HotKeyBindError;
#[derive(Debug)]
pub enum HotKey {
VolumeUp = 1,
VolumeDown = 2,
VolumeUpFine = 3,
VolumeDownfine = 4,
Mute = 5,
}
pub fn register_hotkeys() -> Result<()> {
for (id, modifiers, key) in [
(HotKey::VolumeUp, None, VK_VOLUME_UP),
(HotKey::VolumeDown, None, VK_VOLUME_DOWN),
(HotKey::VolumeUpFine, Some(MOD_SHIFT), VK_VOLUME_UP),
(HotKey::VolumeDownfine, Some(MOD_SHIFT), VK_VOLUME_DOWN),
(HotKey::Mute, None, VK_VOLUME_MUTE),
] {
let result = unsafe {
RegisterHotKey(
None,
id as i32,
modifiers.unwrap_or_default(),
u32::from(key.0),
)
};
if !result.as_bool() {
return Err(HotKeyBindError.into());
}
}
Ok(())
}
fn main() {
register_hotkeys().unwrap();
let event_loop = EventLoopBuilder::new()
.with_msg_hook(|msg| {
let msg = unsafe { &*(msg as *const MSG) };
if msg.message != WM_HOTKEY {
return false;
}
let hotkey = match msg.wParam.0 {
1 => HotKey::VolumeUp,
2 => HotKey::VolumeDown,
3 => HotKey::VolumeUpFine,
4 => HotKey::VolumeDownfine,
5 => HotKey::Mute,
_ => return false,
};
println!("Got a registered hotkey: {:?}", hotkey);
true
})
.build();
let owner = WindowBuilder::new()
.with_visible(false)
.build(&event_loop)
.unwrap();
let window = WindowBuilder::new()
.with_owner_window(owner.hwnd())
.with_position(PhysicalPosition { x: 40, y: 40 })
.with_decorations(false)
.with_always_on_top(true)
.with_resizable(false)
.with_transparent(true)
.with_inner_size(PhysicalSize {
width: 165,
height: 165,
})
.with_visible(false)
.build(&event_loop)
.unwrap();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => *control_flow = ControlFlow::Exit,
_ => {
println!("Got another event: {:?}", event);
}
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment