mirror of
https://github.com/italicsjenga/muda.git
synced 2025-01-10 03:41:30 +11:00
feat(windows): draw dark menubar if necessary (#98)
* feat(windows): draw dark menubar if necessary closes #97 * Update Cargo.toml
This commit is contained in:
parent
cfd4cb3fc5
commit
33168fa0a0
5
.changes/dark_menubar.md
Normal file
5
.changes/dark_menubar.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"muda": "patch"
|
||||||
|
---
|
||||||
|
|
||||||
|
On Windows, draw a dark menu bar if the Window supports and has dark-mode enabled.
|
|
@ -13,7 +13,7 @@ categories = [ "gui" ]
|
||||||
[features]
|
[features]
|
||||||
default = [ "libxdo" ]
|
default = [ "libxdo" ]
|
||||||
libxdo = [ "dep:libxdo" ]
|
libxdo = [ "dep:libxdo" ]
|
||||||
common-controls-v6 = [ "windows-sys/Win32_UI_Controls" ]
|
common-controls-v6 = [ ]
|
||||||
serde = [ "dep:serde" ]
|
serde = [ "dep:serde" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -33,8 +33,10 @@ features = [
|
||||||
"Win32_Globalization",
|
"Win32_Globalization",
|
||||||
"Win32_UI_Input_KeyboardAndMouse",
|
"Win32_UI_Input_KeyboardAndMouse",
|
||||||
"Win32_System_SystemServices",
|
"Win32_System_SystemServices",
|
||||||
|
"Win32_UI_Accessibility",
|
||||||
"Win32_UI_HiDpi",
|
"Win32_UI_HiDpi",
|
||||||
"Win32_System_LibraryLoader"
|
"Win32_System_LibraryLoader",
|
||||||
|
"Win32_UI_Controls"
|
||||||
]
|
]
|
||||||
|
|
||||||
[target."cfg(target_os = \"linux\")".dependencies]
|
[target."cfg(target_os = \"linux\")".dependencies]
|
||||||
|
|
|
@ -9,12 +9,12 @@ use muda::{
|
||||||
PredefinedMenuItem, Submenu,
|
PredefinedMenuItem, Submenu,
|
||||||
};
|
};
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use tao::platform::macos::WindowExtMacOS;
|
use wry::application::platform::macos::WindowExtMacOS;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use tao::platform::unix::WindowExtUnix;
|
use wry::application::platform::unix::WindowExtUnix;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use tao::platform::windows::{EventLoopBuilderExtWindows, WindowExtWindows};
|
use wry::application::platform::windows::{EventLoopBuilderExtWindows, WindowExtWindows};
|
||||||
use tao::{
|
use wry::application::{
|
||||||
event::{ElementState, Event, MouseButton, WindowEvent},
|
event::{ElementState, Event, MouseButton, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoopBuilder},
|
event_loop::{ControlFlow, EventLoopBuilder},
|
||||||
window::{Window, WindowBuilder},
|
window::{Window, WindowBuilder},
|
||||||
|
|
271
src/platform_impl/windows/dark_menu_bar.rs
Normal file
271
src/platform_impl/windows/dark_menu_bar.rs
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// this is a port of combination of https://github.com/hrydgard/ppsspp/blob/master/Windows/W32Util/UAHMenuBar.cpp and https://github.com/ysc3839/win32-darkmode/blob/master/win32-darkmode/DarkMode.h
|
||||||
|
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use windows_sys::{
|
||||||
|
s, w,
|
||||||
|
Win32::{
|
||||||
|
Foundation::{HMODULE, HWND, LPARAM, RECT, WPARAM},
|
||||||
|
Graphics::Gdi::{OffsetRect, DT_CENTER, DT_HIDEPREFIX, DT_SINGLELINE, DT_VCENTER, HDC},
|
||||||
|
System::LibraryLoader::{GetProcAddress, LoadLibraryA},
|
||||||
|
UI::{
|
||||||
|
Accessibility::HIGHCONTRASTA,
|
||||||
|
Controls::{
|
||||||
|
CloseThemeData, DrawThemeBackground, DrawThemeText, OpenThemeData, DRAWITEMSTRUCT,
|
||||||
|
MENU_POPUPITEM, MPI_DISABLED, MPI_HOT, MPI_NORMAL, ODS_DEFAULT, ODS_DISABLED,
|
||||||
|
ODS_GRAYED, ODS_HOTLIGHT, ODS_INACTIVE, ODS_NOACCEL, ODS_SELECTED,
|
||||||
|
},
|
||||||
|
WindowsAndMessaging::{
|
||||||
|
GetMenuBarInfo, GetMenuItemInfoW, GetWindowRect, SystemParametersInfoA, HMENU,
|
||||||
|
MENUBARINFO, MENUITEMINFOW, MIIM_STRING, OBJID_MENU, SPI_GETHIGHCONTRAST,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const WM_UAHDRAWMENU: u32 = 0x0091;
|
||||||
|
pub const WM_UAHDRAWMENUITEM: u32 = 0x0092;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct UAHMENUITEMMETRICS0 {
|
||||||
|
cx: u32,
|
||||||
|
cy: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct UAHMENUITEMMETRICS {
|
||||||
|
rgsizeBar: [UAHMENUITEMMETRICS0; 2],
|
||||||
|
rgsizePopup: [UAHMENUITEMMETRICS0; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct UAHMENUPOPUPMETRICS {
|
||||||
|
rgcx: [u32; 4],
|
||||||
|
fUpdateMaxWidths: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct UAHMENU {
|
||||||
|
hmenu: HMENU,
|
||||||
|
hdc: HDC,
|
||||||
|
dwFlags: u32,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
struct UAHMENUITEM {
|
||||||
|
iPosition: u32,
|
||||||
|
umim: UAHMENUITEMMETRICS,
|
||||||
|
umpm: UAHMENUPOPUPMETRICS,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
struct UAHDRAWMENUITEM {
|
||||||
|
dis: DRAWITEMSTRUCT,
|
||||||
|
um: UAHMENU,
|
||||||
|
umi: UAHMENUITEM,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draws a dark menu bar if needed and returns whether it draws it or not
|
||||||
|
pub fn draw(hwnd: HWND, msg: u32, _wparam: WPARAM, lparam: LPARAM) -> bool {
|
||||||
|
if !should_use_dark_mode(hwnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match msg {
|
||||||
|
WM_UAHDRAWMENU => {
|
||||||
|
let pudm = lparam as *const UAHMENU;
|
||||||
|
|
||||||
|
// get the menubar rect
|
||||||
|
let rc = {
|
||||||
|
let mut mbi = MENUBARINFO {
|
||||||
|
cbSize: std::mem::size_of::<MENUBARINFO>() as _,
|
||||||
|
..unsafe { std::mem::zeroed() }
|
||||||
|
};
|
||||||
|
unsafe { GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mut mbi) };
|
||||||
|
|
||||||
|
let mut window_rc = RECT {
|
||||||
|
..unsafe { std::mem::zeroed() }
|
||||||
|
};
|
||||||
|
unsafe { GetWindowRect(hwnd, &mut window_rc) };
|
||||||
|
|
||||||
|
let mut rc = mbi.rcBar;
|
||||||
|
// the rcBar is offset by the window rect
|
||||||
|
unsafe { OffsetRect(&mut rc, -window_rc.left, -window_rc.top) };
|
||||||
|
rc.top -= 1;
|
||||||
|
rc
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let theme = OpenThemeData(hwnd, w!("Menu"));
|
||||||
|
|
||||||
|
DrawThemeBackground(
|
||||||
|
theme,
|
||||||
|
(*pudm).hdc,
|
||||||
|
MENU_POPUPITEM,
|
||||||
|
MPI_NORMAL,
|
||||||
|
&rc,
|
||||||
|
std::ptr::null(),
|
||||||
|
);
|
||||||
|
CloseThemeData(theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WM_UAHDRAWMENUITEM => {
|
||||||
|
let pudmi = lparam as *const UAHDRAWMENUITEM;
|
||||||
|
|
||||||
|
// get the menu item string
|
||||||
|
let (label, cch) = {
|
||||||
|
let mut label = Vec::<u16>::with_capacity(256);
|
||||||
|
let mut info: MENUITEMINFOW = unsafe { std::mem::zeroed() };
|
||||||
|
info.cbSize = std::mem::size_of::<MENUITEMINFOW>() as _;
|
||||||
|
info.fMask = MIIM_STRING;
|
||||||
|
info.dwTypeData = label.as_mut_ptr();
|
||||||
|
info.cch = (std::mem::size_of_val(&label) / 2 - 1) as _;
|
||||||
|
unsafe {
|
||||||
|
GetMenuItemInfoW(
|
||||||
|
(*pudmi).um.hmenu,
|
||||||
|
(*pudmi).umi.iPosition,
|
||||||
|
true.into(),
|
||||||
|
&mut info,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
(label, info.cch)
|
||||||
|
};
|
||||||
|
|
||||||
|
// get the item state for drawing
|
||||||
|
let mut dw_flags = DT_CENTER | DT_SINGLELINE | DT_VCENTER;
|
||||||
|
let mut i_text_state_id = 0;
|
||||||
|
let mut i_background_state_id = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
if (((*pudmi).dis.itemState & ODS_INACTIVE)
|
||||||
|
| ((*pudmi).dis.itemState & ODS_DEFAULT))
|
||||||
|
!= 0
|
||||||
|
{
|
||||||
|
// normal display
|
||||||
|
i_text_state_id = MPI_NORMAL;
|
||||||
|
i_background_state_id = MPI_NORMAL;
|
||||||
|
}
|
||||||
|
if (*pudmi).dis.itemState & ODS_HOTLIGHT != 0 {
|
||||||
|
// hot tracking
|
||||||
|
i_text_state_id = MPI_HOT;
|
||||||
|
i_background_state_id = MPI_HOT;
|
||||||
|
}
|
||||||
|
if (*pudmi).dis.itemState & ODS_SELECTED != 0 {
|
||||||
|
// clicked -- MENU_POPUPITEM has no state for this, though MENU_BARITEM does
|
||||||
|
i_text_state_id = MPI_HOT;
|
||||||
|
i_background_state_id = MPI_HOT;
|
||||||
|
}
|
||||||
|
if ((*pudmi).dis.itemState & ODS_GRAYED) != 0
|
||||||
|
|| ((*pudmi).dis.itemState & ODS_DISABLED) != 0
|
||||||
|
{
|
||||||
|
// disabled / grey text
|
||||||
|
i_text_state_id = MPI_DISABLED;
|
||||||
|
i_background_state_id = MPI_DISABLED;
|
||||||
|
}
|
||||||
|
if ((*pudmi).dis.itemState & ODS_NOACCEL) != 0 {
|
||||||
|
dw_flags |= DT_HIDEPREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
let theme = OpenThemeData(hwnd, w!("Menu"));
|
||||||
|
DrawThemeBackground(
|
||||||
|
theme,
|
||||||
|
(*pudmi).um.hdc,
|
||||||
|
MENU_POPUPITEM,
|
||||||
|
i_background_state_id,
|
||||||
|
&(*pudmi).dis.rcItem,
|
||||||
|
std::ptr::null(),
|
||||||
|
);
|
||||||
|
DrawThemeText(
|
||||||
|
theme,
|
||||||
|
(*pudmi).um.hdc,
|
||||||
|
MENU_POPUPITEM,
|
||||||
|
i_text_state_id,
|
||||||
|
label.as_ptr(),
|
||||||
|
cch as _,
|
||||||
|
dw_flags,
|
||||||
|
0,
|
||||||
|
&(*pudmi).dis.rcItem,
|
||||||
|
);
|
||||||
|
CloseThemeData(theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_use_dark_mode(hwnd: HWND) -> bool {
|
||||||
|
should_apps_use_dark_mode() && !is_high_contrast() && is_dark_mode_allowed_for_window(hwnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
static HUXTHEME: Lazy<HMODULE> = Lazy::new(|| unsafe { LoadLibraryA(s!("uxtheme.dll")) });
|
||||||
|
|
||||||
|
fn should_apps_use_dark_mode() -> bool {
|
||||||
|
const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: u16 = 132;
|
||||||
|
type ShouldAppsUseDarkMode = unsafe extern "system" fn() -> bool;
|
||||||
|
static SHOULD_APPS_USE_DARK_MODE: Lazy<Option<ShouldAppsUseDarkMode>> = Lazy::new(|| unsafe {
|
||||||
|
if *HUXTHEME == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetProcAddress(
|
||||||
|
*HUXTHEME,
|
||||||
|
UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL as usize as *mut _,
|
||||||
|
)
|
||||||
|
.map(|handle| std::mem::transmute(handle))
|
||||||
|
});
|
||||||
|
|
||||||
|
SHOULD_APPS_USE_DARK_MODE
|
||||||
|
.map(|should_apps_use_dark_mode| unsafe { (should_apps_use_dark_mode)() })
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_dark_mode_allowed_for_window(hwnd: HWND) -> bool {
|
||||||
|
const UXTHEME_ISDARKMODEALLOWEDFORWINDOW_ORDINAL: u16 = 137;
|
||||||
|
type IsDarkModeAllowedForWindow = unsafe extern "system" fn(HWND) -> bool;
|
||||||
|
static IS_DARK_MODE_ALLOWED_FOR_WINDOW: Lazy<Option<IsDarkModeAllowedForWindow>> =
|
||||||
|
Lazy::new(|| unsafe {
|
||||||
|
if *HUXTHEME == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetProcAddress(
|
||||||
|
*HUXTHEME,
|
||||||
|
UXTHEME_ISDARKMODEALLOWEDFORWINDOW_ORDINAL as usize as *mut _,
|
||||||
|
)
|
||||||
|
.map(|handle| std::mem::transmute(handle))
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(_is_dark_mode_allowed_for_window) = *IS_DARK_MODE_ALLOWED_FOR_WINDOW {
|
||||||
|
unsafe { _is_dark_mode_allowed_for_window(hwnd) }
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_high_contrast() -> bool {
|
||||||
|
const HCF_HIGHCONTRASTON: u32 = 1;
|
||||||
|
|
||||||
|
let mut hc = HIGHCONTRASTA {
|
||||||
|
cbSize: 0,
|
||||||
|
dwFlags: Default::default(),
|
||||||
|
lpszDefaultScheme: std::ptr::null_mut(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ok = unsafe {
|
||||||
|
SystemParametersInfoA(
|
||||||
|
SPI_GETHIGHCONTRAST,
|
||||||
|
std::mem::size_of_val(&hc) as _,
|
||||||
|
&mut hc as *mut _ as _,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
ok != 0 && (HCF_HIGHCONTRASTON & hc.dwFlags) != 0
|
||||||
|
}
|
|
@ -3,9 +3,11 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
mod accelerator;
|
mod accelerator;
|
||||||
|
mod dark_menu_bar;
|
||||||
mod icon;
|
mod icon;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
use self::dark_menu_bar::{WM_UAHDRAWMENU, WM_UAHDRAWMENUITEM};
|
||||||
pub(crate) use self::icon::WinIcon as PlatformIcon;
|
pub(crate) use self::icon::WinIcon as PlatformIcon;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -1002,91 +1004,101 @@ unsafe extern "system" fn menu_subclass_proc(
|
||||||
uidsubclass: usize,
|
uidsubclass: usize,
|
||||||
dwrefdata: usize,
|
dwrefdata: usize,
|
||||||
) -> LRESULT {
|
) -> LRESULT {
|
||||||
let mut ret = -1;
|
let mut ret = None;
|
||||||
if msg == WM_COMMAND {
|
match msg {
|
||||||
let id = util::LOWORD(wparam as _) as u32;
|
WM_COMMAND => {
|
||||||
let item = if uidsubclass == MENU_SUBCLASS_ID {
|
let id = util::LOWORD(wparam as _) as u32;
|
||||||
let menu = dwrefdata as *mut Box<Menu>;
|
let item = if uidsubclass == MENU_SUBCLASS_ID {
|
||||||
(*menu).find_by_id(id)
|
let menu = dwrefdata as *mut Box<Menu>;
|
||||||
} else {
|
(*menu).find_by_id(id)
|
||||||
let menu = dwrefdata as *mut Box<MenuChild>;
|
} else {
|
||||||
(*menu).find_by_id(id)
|
let menu = dwrefdata as *mut Box<MenuChild>;
|
||||||
};
|
(*menu).find_by_id(id)
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(item) = item {
|
if let Some(item) = item {
|
||||||
ret = 0;
|
ret = Some(0);
|
||||||
|
|
||||||
let (mut dispatch, mut menu_id) = (true, None);
|
let (mut dispatch, mut menu_id) = (true, None);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut item = item.borrow_mut();
|
let mut item = item.borrow_mut();
|
||||||
|
|
||||||
if item.item_type() == MenuItemType::Predefined {
|
if item.item_type() == MenuItemType::Predefined {
|
||||||
dispatch = false;
|
dispatch = false;
|
||||||
} else {
|
} else {
|
||||||
menu_id.replace(item.id.clone());
|
menu_id.replace(item.id.clone());
|
||||||
}
|
|
||||||
|
|
||||||
match item.item_type() {
|
|
||||||
MenuItemType::Check => {
|
|
||||||
let checked = !item.checked;
|
|
||||||
item.set_checked(checked);
|
|
||||||
}
|
}
|
||||||
MenuItemType::Predefined => {
|
|
||||||
if let Some(predefined_item_type) = &item.predefined_item_type {
|
|
||||||
match predefined_item_type {
|
|
||||||
PredefinedMenuItemType::Copy => {
|
|
||||||
execute_edit_command(EditCommand::Copy)
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::Cut => {
|
|
||||||
execute_edit_command(EditCommand::Cut)
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::Paste => {
|
|
||||||
execute_edit_command(EditCommand::Paste)
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::SelectAll => {
|
|
||||||
execute_edit_command(EditCommand::SelectAll)
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::Separator => {}
|
|
||||||
PredefinedMenuItemType::Minimize => {
|
|
||||||
ShowWindow(hwnd, SW_MINIMIZE);
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::Maximize => {
|
|
||||||
ShowWindow(hwnd, SW_MAXIMIZE);
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::Hide => {
|
|
||||||
ShowWindow(hwnd, SW_HIDE);
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::CloseWindow => {
|
|
||||||
SendMessageW(hwnd, WM_CLOSE, 0, 0);
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::Quit => {
|
|
||||||
PostQuitMessage(0);
|
|
||||||
}
|
|
||||||
PredefinedMenuItemType::About(Some(ref metadata)) => {
|
|
||||||
show_about_dialog(hwnd, metadata)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
match item.item_type() {
|
||||||
|
MenuItemType::Check => {
|
||||||
|
let checked = !item.checked;
|
||||||
|
item.set_checked(checked);
|
||||||
|
}
|
||||||
|
MenuItemType::Predefined => {
|
||||||
|
if let Some(predefined_item_type) = &item.predefined_item_type {
|
||||||
|
match predefined_item_type {
|
||||||
|
PredefinedMenuItemType::Copy => {
|
||||||
|
execute_edit_command(EditCommand::Copy)
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::Cut => {
|
||||||
|
execute_edit_command(EditCommand::Cut)
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::Paste => {
|
||||||
|
execute_edit_command(EditCommand::Paste)
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::SelectAll => {
|
||||||
|
execute_edit_command(EditCommand::SelectAll)
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::Separator => {}
|
||||||
|
PredefinedMenuItemType::Minimize => {
|
||||||
|
ShowWindow(hwnd, SW_MINIMIZE);
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::Maximize => {
|
||||||
|
ShowWindow(hwnd, SW_MAXIMIZE);
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::Hide => {
|
||||||
|
ShowWindow(hwnd, SW_HIDE);
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::CloseWindow => {
|
||||||
|
SendMessageW(hwnd, WM_CLOSE, 0, 0);
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::Quit => {
|
||||||
|
PostQuitMessage(0);
|
||||||
|
}
|
||||||
|
PredefinedMenuItemType::About(Some(ref metadata)) => {
|
||||||
|
show_about_dialog(hwnd, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
|
|
||||||
|
if dispatch {
|
||||||
|
MenuEvent::send(MenuEvent {
|
||||||
|
id: menu_id.unwrap(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if dispatch {
|
WM_UAHDRAWMENUITEM | WM_UAHDRAWMENU => {
|
||||||
MenuEvent::send(MenuEvent {
|
if dark_menu_bar::draw(hwnd, msg, wparam, lparam) {
|
||||||
id: menu_id.unwrap(),
|
ret = Some(0);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ret == -1 {
|
_ => {}
|
||||||
DefSubclassProc(hwnd, msg, wparam, lparam)
|
};
|
||||||
} else {
|
|
||||||
|
if let Some(ret) = ret {
|
||||||
ret
|
ret
|
||||||
|
} else {
|
||||||
|
DefSubclassProc(hwnd, msg, wparam, lparam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue