mirror of
https://github.com/italicsjenga/muda.git
synced 2024-12-23 20:11:29 +11:00
use native apis for getters on windows
This commit is contained in:
parent
832e4964e7
commit
2ccd400497
|
@ -13,7 +13,8 @@ features = [
|
||||||
"Win32_UI_WindowsAndMessaging",
|
"Win32_UI_WindowsAndMessaging",
|
||||||
"Win32_Foundation",
|
"Win32_Foundation",
|
||||||
"Win32_Graphics_Gdi",
|
"Win32_Graphics_Gdi",
|
||||||
"Win32_UI_Shell"
|
"Win32_UI_Shell",
|
||||||
|
"Win32_Globalization"
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#![cfg(target_os = "windows")]
|
#![cfg(target_os = "windows")]
|
||||||
|
|
||||||
use crate::util::{encode_wide, Counter, LOWORD};
|
use crate::util::{encode_wide, wchar_ptr_to_string, Counter, LOWORD};
|
||||||
use windows_sys::Win32::{
|
use windows_sys::Win32::{
|
||||||
Foundation::{HWND, LPARAM, LRESULT, WPARAM},
|
Foundation::{HWND, LPARAM, LRESULT, WPARAM},
|
||||||
UI::{
|
UI::{
|
||||||
Shell::{DefSubclassProc, SetWindowSubclass},
|
Shell::{DefSubclassProc, SetWindowSubclass},
|
||||||
WindowsAndMessaging::{
|
WindowsAndMessaging::{
|
||||||
AppendMenuW, CreateMenu, EnableMenuItem, SetMenu, SetMenuItemInfoW, MENUITEMINFOW,
|
AppendMenuW, CreateMenu, EnableMenuItem, GetMenuItemInfoW, SetMenu, SetMenuItemInfoW,
|
||||||
MF_DISABLED, MF_ENABLED, MF_GRAYED, MF_POPUP, MIIM_STRING, WM_COMMAND,
|
MENUITEMINFOW, MFS_DISABLED, MF_DISABLED, MF_ENABLED, MF_GRAYED, MF_POPUP, MIIM_STATE,
|
||||||
|
MIIM_STRING, WM_COMMAND,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -36,8 +37,6 @@ impl Menu {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
Submenu {
|
Submenu {
|
||||||
label: label.as_ref().to_string(),
|
|
||||||
enabled,
|
|
||||||
hmenu,
|
hmenu,
|
||||||
parent_hmenu: self.0,
|
parent_hmenu: self.0,
|
||||||
}
|
}
|
||||||
|
@ -53,34 +52,49 @@ impl Menu {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Submenu {
|
pub struct Submenu {
|
||||||
label: String,
|
|
||||||
enabled: bool,
|
|
||||||
hmenu: isize,
|
hmenu: isize,
|
||||||
parent_hmenu: isize,
|
parent_hmenu: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Submenu {
|
impl Submenu {
|
||||||
pub fn label(&self) -> String {
|
pub fn label(&self) -> String {
|
||||||
self.label.clone()
|
let mut label = Vec::<u16>::new();
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
|
||||||
self.label = label.as_ref().to_string();
|
|
||||||
|
|
||||||
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
info.fMask = MIIM_STRING;
|
info.fMask = MIIM_STRING;
|
||||||
info.dwTypeData = encode_wide(&self.label).as_mut_ptr();
|
info.dwTypeData = label.as_mut_ptr();
|
||||||
|
|
||||||
|
unsafe { GetMenuItemInfoW(self.parent_hmenu, self.hmenu as _, false.into(), &mut info) };
|
||||||
|
|
||||||
|
info.cch += 1;
|
||||||
|
info.dwTypeData = Vec::with_capacity(info.cch as usize).as_mut_ptr();
|
||||||
|
|
||||||
|
unsafe { GetMenuItemInfoW(self.parent_hmenu, self.hmenu as _, false.into(), &mut info) };
|
||||||
|
|
||||||
|
wchar_ptr_to_string(info.dwTypeData)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
||||||
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
|
info.fMask = MIIM_STRING;
|
||||||
|
info.dwTypeData = encode_wide(label.as_ref()).as_mut_ptr();
|
||||||
|
|
||||||
unsafe { SetMenuItemInfoW(self.parent_hmenu, self.hmenu as u32, false.into(), &info) };
|
unsafe { SetMenuItemInfoW(self.parent_hmenu, self.hmenu as u32, false.into(), &info) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enabled(&self) -> bool {
|
pub fn enabled(&self) -> bool {
|
||||||
self.enabled
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
|
info.fMask = MIIM_STATE;
|
||||||
|
|
||||||
|
unsafe { GetMenuItemInfoW(self.parent_hmenu, self.hmenu as _, false.into(), &mut info) };
|
||||||
|
|
||||||
|
(info.fState & MFS_DISABLED) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
self.enabled = enabled;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
EnableMenuItem(
|
EnableMenuItem(
|
||||||
self.parent_hmenu,
|
self.parent_hmenu,
|
||||||
|
@ -105,8 +119,6 @@ impl Submenu {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
Submenu {
|
Submenu {
|
||||||
label: label.as_ref().to_string(),
|
|
||||||
enabled,
|
|
||||||
hmenu,
|
hmenu,
|
||||||
parent_hmenu: self.hmenu,
|
parent_hmenu: self.hmenu,
|
||||||
}
|
}
|
||||||
|
@ -127,8 +139,6 @@ impl Submenu {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
TextMenuItem {
|
TextMenuItem {
|
||||||
label: label.as_ref().to_string(),
|
|
||||||
enabled,
|
|
||||||
id,
|
id,
|
||||||
parent_hmenu: self.hmenu,
|
parent_hmenu: self.hmenu,
|
||||||
}
|
}
|
||||||
|
@ -137,34 +147,53 @@ impl Submenu {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TextMenuItem {
|
pub struct TextMenuItem {
|
||||||
label: String,
|
|
||||||
enabled: bool,
|
|
||||||
id: u64,
|
id: u64,
|
||||||
parent_hmenu: isize,
|
parent_hmenu: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextMenuItem {
|
impl TextMenuItem {
|
||||||
pub fn label(&self) -> String {
|
pub fn label(&self) -> String {
|
||||||
self.label.clone()
|
let mut label = Vec::<u16>::new();
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
|
||||||
self.label = label.as_ref().to_string();
|
|
||||||
|
|
||||||
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
info.fMask = MIIM_STRING;
|
info.fMask = MIIM_STRING;
|
||||||
info.dwTypeData = encode_wide(&self.label).as_mut_ptr();
|
info.dwTypeData = label.as_mut_ptr();
|
||||||
|
|
||||||
|
unsafe { GetMenuItemInfoW(self.parent_hmenu, self.id as _, false.into(), &mut info) };
|
||||||
|
|
||||||
|
info.cch += 1;
|
||||||
|
info.dwTypeData = Vec::with_capacity(info.cch as usize).as_mut_ptr();
|
||||||
|
|
||||||
|
unsafe { GetMenuItemInfoW(self.parent_hmenu, self.id as _, false.into(), &mut info) };
|
||||||
|
|
||||||
|
wchar_ptr_to_string(info.dwTypeData)
|
||||||
|
.split("\t")
|
||||||
|
.next()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
||||||
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
|
info.fMask = MIIM_STRING;
|
||||||
|
info.dwTypeData = encode_wide(label.as_ref()).as_mut_ptr();
|
||||||
|
|
||||||
unsafe { SetMenuItemInfoW(self.parent_hmenu, self.id as u32, false.into(), &info) };
|
unsafe { SetMenuItemInfoW(self.parent_hmenu, self.id as u32, false.into(), &info) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enabled(&self) -> bool {
|
pub fn enabled(&self) -> bool {
|
||||||
self.enabled
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
|
info.fMask = MIIM_STATE;
|
||||||
|
|
||||||
|
unsafe { GetMenuItemInfoW(self.parent_hmenu, self.id as _, false.into(), &mut info) };
|
||||||
|
|
||||||
|
(info.fState & MFS_DISABLED) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
self.enabled = enabled;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
EnableMenuItem(
|
EnableMenuItem(
|
||||||
self.parent_hmenu,
|
self.parent_hmenu,
|
||||||
|
|
|
@ -29,3 +29,10 @@ pub fn encode_wide(string: impl AsRef<std::ffi::OsStr>) -> Vec<u16> {
|
||||||
pub fn LOWORD(dword: u32) -> u16 {
|
pub fn LOWORD(dword: u32) -> u16 {
|
||||||
(dword & 0xFFFF) as u16
|
(dword & 0xFFFF) as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn wchar_ptr_to_string(wchar: windows_sys::core::PWSTR) -> String {
|
||||||
|
let len = unsafe { windows_sys::Win32::Globalization::lstrlenW(wchar) } as usize;
|
||||||
|
let wchar_slice = unsafe { std::slice::from_raw_parts(wchar, len) };
|
||||||
|
String::from_utf16_lossy(wchar_slice)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue