mirror of
https://github.com/italicsjenga/muda.git
synced 2024-12-23 12:01:31 +11:00
feat: add common-controls-v6
(#69)
This commit is contained in:
parent
7af4477896
commit
ac14222934
5
.changes/common-controls-v6.md
Normal file
5
.changes/common-controls-v6.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"muda": "minor"
|
||||
---
|
||||
|
||||
Add `common-controls-v6` feature flag, disabled by default, which could be used to enable usage of `TaskDialogIndirect` API from `ComCtl32.dll` v6 on Windows for The predefined `About` menu item.
|
13
.github/workflows/test.yml
vendored
13
.github/workflows/test.yml
vendored
|
@ -14,15 +14,15 @@ env:
|
|||
RUST_BACKTRACE: 1
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ['windows-latest', 'macos-latest', 'ubuntu-latest']
|
||||
os: ["windows-latest", "macos-latest", "ubuntu-latest"]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
@ -44,4 +44,9 @@ jobs:
|
|||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
command: test
|
||||
|
||||
- name: test common-controls-v6
|
||||
if: matrix.os == "windows-latest"
|
||||
working-directory: examples/windows-common-controls-v6
|
||||
run: cargo run
|
||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -3,16 +3,17 @@ name = "muda"
|
|||
version = "0.5.0"
|
||||
description = "Menu Utilities for Desktop Applications"
|
||||
edition = "2021"
|
||||
keywords = [ "windowing", "menu" ]
|
||||
keywords = ["windowing", "menu"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/amrbashir/muda"
|
||||
documentation = "https://docs.rs/muda"
|
||||
categories = [ "gui" ]
|
||||
categories = ["gui"]
|
||||
|
||||
[features]
|
||||
default = [ "libxdo" ]
|
||||
libxdo = [ "dep:libxdo" ]
|
||||
default = ["libxdo"]
|
||||
libxdo = ["dep:libxdo"]
|
||||
common-controls-v6 = ["windows-sys/Win32_UI_Controls"]
|
||||
|
||||
[dependencies]
|
||||
crossbeam-channel = "0.5"
|
||||
|
@ -29,7 +30,7 @@ features = [
|
|||
"Win32_UI_Shell",
|
||||
"Win32_Globalization",
|
||||
"Win32_UI_Input_KeyboardAndMouse",
|
||||
"Win32_System_SystemServices"
|
||||
"Win32_System_SystemServices",
|
||||
]
|
||||
|
||||
[target."cfg(target_os = \"linux\")".dependencies]
|
||||
|
|
|
@ -14,7 +14,8 @@ muda is a Menu Utilities library for Desktop Applications.
|
|||
|
||||
### Cargo Features
|
||||
|
||||
- `libxdo` (enabled by default): Enables linking to `libxdo` which is used for the predfined `Copy`, `Cut`, `Paste` and `SelectAll` menu item.
|
||||
- `common-controls-v6`: Use `TaskDialogIndirect` API from `ComCtl32.dll` v6 on Windows for showing the predefined `About` menu item dialog.
|
||||
- `libxdo`: Enables linking to `libxdo` on Linux which is used for the predfined `Copy`, `Cut`, `Paste` and `SelectAll` menu item.
|
||||
|
||||
## Dependencies (Linux Only)
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ fn main() {
|
|||
None,
|
||||
Some(AboutMetadata {
|
||||
name: Some("tao".to_string()),
|
||||
version: Some("1.2.3".to_string()),
|
||||
copyright: Some("Copyright tao".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
|
|
2
examples/windows-common-controls-v6/.gitignore
vendored
Normal file
2
examples/windows-common-controls-v6/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
18
examples/windows-common-controls-v6/Cargo.toml
Normal file
18
examples/windows-common-controls-v6/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "windows-common-controls-v6"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
muda = { path = "../../", features = ["common-controls-v6"] }
|
||||
winit = "0.28"
|
||||
image = "0.24"
|
||||
|
||||
[target."cfg(target_os = \"windows\")".dependencies.windows-sys]
|
||||
version = "0.48"
|
||||
features = ["Win32_UI_WindowsAndMessaging", "Win32_Foundation"]
|
||||
|
||||
[build-dependencies]
|
||||
embed-resource = "1.6"
|
15
examples/windows-common-controls-v6/app.exe.manifest
Normal file
15
examples/windows-common-controls-v6/app.exe.manifest
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
4
examples/windows-common-controls-v6/build.rs
Normal file
4
examples/windows-common-controls-v6/build.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
fn main() {
|
||||
#[cfg(target_os = "windows")]
|
||||
embed_resource::compile("manifest.rc");
|
||||
}
|
2
examples/windows-common-controls-v6/manifest.rc
Normal file
2
examples/windows-common-controls-v6/manifest.rc
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define RT_MANIFEST 24
|
||||
1 RT_MANIFEST "app.exe.manifest"
|
207
examples/windows-common-controls-v6/src/main.rs
Normal file
207
examples/windows-common-controls-v6/src/main.rs
Normal file
|
@ -0,0 +1,207 @@
|
|||
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#![allow(unused)]
|
||||
use muda::{
|
||||
accelerator::{Accelerator, Code, Modifiers},
|
||||
AboutMetadata, CheckMenuItem, ContextMenu, IconMenuItem, Menu, MenuEvent, MenuItem,
|
||||
PredefinedMenuItem, Submenu,
|
||||
};
|
||||
#[cfg(target_os = "macos")]
|
||||
use winit::platform::macos::{EventLoopBuilderExtMacOS, WindowExtMacOS};
|
||||
#[cfg(target_os = "windows")]
|
||||
use winit::platform::windows::{EventLoopBuilderExtWindows, WindowExtWindows};
|
||||
use winit::{
|
||||
event::{ElementState, Event, MouseButton, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoopBuilder},
|
||||
window::{Window, WindowBuilder},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut event_loop_builder = EventLoopBuilder::new();
|
||||
|
||||
let menu_bar = Menu::new();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let menu_bar_c = menu_bar.clone();
|
||||
event_loop_builder.with_msg_hook(move |msg| {
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::{TranslateAcceleratorW, MSG};
|
||||
unsafe {
|
||||
let msg = msg as *const MSG;
|
||||
let translated = TranslateAcceleratorW((*msg).hwnd, menu_bar_c.haccel(), msg);
|
||||
translated == 1
|
||||
}
|
||||
});
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
event_loop_builder.with_default_menu(false);
|
||||
|
||||
let event_loop = event_loop_builder.build();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("Window 1")
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
let window2 = WindowBuilder::new()
|
||||
.with_title("Window 2")
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let app_m = Submenu::new("App", true);
|
||||
menu_bar.append(&app_m);
|
||||
app_m.append_items(&[
|
||||
&PredefinedMenuItem::about(None, None),
|
||||
&PredefinedMenuItem::separator(),
|
||||
&PredefinedMenuItem::services(None),
|
||||
&PredefinedMenuItem::separator(),
|
||||
&PredefinedMenuItem::hide(None),
|
||||
&PredefinedMenuItem::hide_others(None),
|
||||
&PredefinedMenuItem::show_all(None),
|
||||
&PredefinedMenuItem::separator(),
|
||||
&PredefinedMenuItem::quit(None),
|
||||
]);
|
||||
}
|
||||
|
||||
let file_m = Submenu::new("&File", true);
|
||||
let edit_m = Submenu::new("&Edit", true);
|
||||
let window_m = Submenu::new("&Window", true);
|
||||
|
||||
menu_bar.append_items(&[&file_m, &edit_m, &window_m]);
|
||||
|
||||
let custom_i_1 = MenuItem::new(
|
||||
"C&ustom 1",
|
||||
true,
|
||||
Some(Accelerator::new(Some(Modifiers::ALT), Code::KeyC)),
|
||||
);
|
||||
|
||||
let path = concat!(env!("CARGO_MANIFEST_DIR"), "../../icon.png");
|
||||
let icon = load_icon(std::path::Path::new(path));
|
||||
let image_item = IconMenuItem::new("Image Custom 1", true, Some(icon), None);
|
||||
|
||||
let check_custom_i_1 = CheckMenuItem::new("Check Custom 1", true, true, None);
|
||||
let check_custom_i_2 = CheckMenuItem::new("Check Custom 2", false, true, None);
|
||||
let check_custom_i_3 = CheckMenuItem::new(
|
||||
"Check Custom 3",
|
||||
true,
|
||||
true,
|
||||
Some(Accelerator::new(Some(Modifiers::SHIFT), Code::KeyD)),
|
||||
);
|
||||
|
||||
let copy_i = PredefinedMenuItem::copy(None);
|
||||
let cut_i = PredefinedMenuItem::cut(None);
|
||||
let paste_i = PredefinedMenuItem::paste(None);
|
||||
|
||||
file_m.append_items(&[
|
||||
&custom_i_1,
|
||||
&image_item,
|
||||
&window_m,
|
||||
&PredefinedMenuItem::separator(),
|
||||
&check_custom_i_1,
|
||||
&check_custom_i_2,
|
||||
]);
|
||||
|
||||
window_m.append_items(&[
|
||||
&PredefinedMenuItem::minimize(None),
|
||||
&PredefinedMenuItem::maximize(None),
|
||||
&PredefinedMenuItem::close_window(Some("Close")),
|
||||
&PredefinedMenuItem::fullscreen(None),
|
||||
&PredefinedMenuItem::about(
|
||||
None,
|
||||
Some(AboutMetadata {
|
||||
name: Some("winit".to_string()),
|
||||
version: Some("1.2.3".to_string()),
|
||||
copyright: Some("Copyright winit".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
),
|
||||
&check_custom_i_3,
|
||||
&image_item,
|
||||
&custom_i_1,
|
||||
]);
|
||||
|
||||
edit_m.append_items(&[©_i, &PredefinedMenuItem::separator(), &paste_i]);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
menu_bar.init_for_hwnd(window.hwnd() as _);
|
||||
menu_bar.init_for_hwnd(window2.hwnd() as _);
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
menu_bar.init_for_nsapp();
|
||||
window_m.set_windows_menu_for_nsapp();
|
||||
}
|
||||
|
||||
let menu_channel = MenuEvent::receiver();
|
||||
|
||||
let mut x = 0_f64;
|
||||
let mut y = 0_f64;
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CursorMoved { position, .. },
|
||||
window_id,
|
||||
..
|
||||
} => {
|
||||
if window_id == window2.id() {
|
||||
x = position.x;
|
||||
y = position.y;
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::MouseInput {
|
||||
state: ElementState::Pressed,
|
||||
button: MouseButton::Right,
|
||||
..
|
||||
},
|
||||
window_id,
|
||||
..
|
||||
} => {
|
||||
if window_id == window2.id() {
|
||||
show_context_menu(&window2, &file_m, x, y);
|
||||
}
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
window.request_redraw();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if let Ok(event) = menu_channel.try_recv() {
|
||||
if event.id == custom_i_1.id() {
|
||||
file_m.insert(&MenuItem::new("New Menu Item", true, None), 2);
|
||||
}
|
||||
println!("{event:?}");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn show_context_menu(window: &Window, menu: &dyn ContextMenu, x: f64, y: f64) {
|
||||
#[cfg(target_os = "windows")]
|
||||
menu.show_context_menu_for_hwnd(window.hwnd() as _, x, y);
|
||||
#[cfg(target_os = "macos")]
|
||||
menu.show_context_menu_for_nsview(window.ns_view() as _, x, y);
|
||||
}
|
||||
|
||||
fn load_icon(path: &std::path::Path) -> muda::icon::Icon {
|
||||
let (icon_rgba, icon_width, icon_height) = {
|
||||
let image = image::open(path)
|
||||
.expect("Failed to open icon path")
|
||||
.into_rgba8();
|
||||
let (width, height) = image.dimensions();
|
||||
let rgba = image.into_raw();
|
||||
(rgba, width, height)
|
||||
};
|
||||
muda::icon::Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon")
|
||||
}
|
|
@ -113,6 +113,7 @@ fn main() {
|
|||
None,
|
||||
Some(AboutMetadata {
|
||||
name: Some("winit".to_string()),
|
||||
version: Some("1.2.3".to_string()),
|
||||
copyright: Some("Copyright winit".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
icon::Icon,
|
||||
predefined::PredfinedMenuItemType,
|
||||
util::{AddOp, Counter},
|
||||
MenuEvent, MenuItemType,
|
||||
AboutMetadata, MenuEvent, MenuItemType,
|
||||
};
|
||||
use std::{
|
||||
cell::{RefCell, RefMut},
|
||||
|
@ -31,12 +31,11 @@ use windows_sys::Win32::{
|
|||
WindowsAndMessaging::{
|
||||
AppendMenuW, CreateAcceleratorTableW, CreateMenu, CreatePopupMenu,
|
||||
DestroyAcceleratorTable, DrawMenuBar, EnableMenuItem, GetMenuItemInfoW, InsertMenuW,
|
||||
MessageBoxW, PostQuitMessage, RemoveMenu, SendMessageW, SetMenu, SetMenuItemInfoW,
|
||||
ShowWindow, TrackPopupMenu, HACCEL, HMENU, MB_ICONINFORMATION, MENUITEMINFOW,
|
||||
MFS_CHECKED, MFS_DISABLED, MF_BYCOMMAND, MF_BYPOSITION, MF_CHECKED, MF_DISABLED,
|
||||
MF_ENABLED, MF_GRAYED, MF_POPUP, MF_SEPARATOR, MF_STRING, MF_UNCHECKED, MIIM_BITMAP,
|
||||
MIIM_STATE, MIIM_STRING, SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, TPM_LEFTALIGN, WM_CLOSE,
|
||||
WM_COMMAND, WM_DESTROY,
|
||||
PostQuitMessage, RemoveMenu, SendMessageW, SetMenu, SetMenuItemInfoW, ShowWindow,
|
||||
TrackPopupMenu, HACCEL, HMENU, MENUITEMINFOW, MFS_CHECKED, MFS_DISABLED, MF_BYCOMMAND,
|
||||
MF_BYPOSITION, MF_CHECKED, MF_DISABLED, MF_ENABLED, MF_GRAYED, MF_POPUP, MF_SEPARATOR,
|
||||
MF_STRING, MF_UNCHECKED, MIIM_BITMAP, MIIM_STATE, MIIM_STRING, SW_HIDE, SW_MAXIMIZE,
|
||||
SW_MINIMIZE, TPM_LEFTALIGN, WM_CLOSE, WM_COMMAND, WM_DESTROY,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1160,53 +1159,7 @@ unsafe extern "system" fn menu_subclass_proc(
|
|||
PostQuitMessage(0);
|
||||
}
|
||||
PredfinedMenuItemType::About(Some(metadata)) => {
|
||||
use std::fmt::Write;
|
||||
|
||||
let mut message = String::new();
|
||||
if let Some(name) = &metadata.name {
|
||||
let _ = writeln!(&mut message, "Name: {}", name);
|
||||
}
|
||||
if let Some(version) = &metadata.version {
|
||||
let _ = writeln!(&mut message, "Version: {}", version);
|
||||
}
|
||||
if let Some(authors) = &metadata.authors {
|
||||
let _ = writeln!(&mut message, "Authors: {}", authors.join(", "));
|
||||
}
|
||||
if let Some(license) = &metadata.license {
|
||||
let _ = writeln!(&mut message, "License: {}", license);
|
||||
}
|
||||
match (&metadata.website_label, &metadata.website) {
|
||||
(Some(label), None) => {
|
||||
let _ = writeln!(&mut message, "Website: {}", label);
|
||||
}
|
||||
(None, Some(url)) => {
|
||||
let _ = writeln!(&mut message, "Website: {}", url);
|
||||
}
|
||||
(Some(label), Some(url)) => {
|
||||
let _ = writeln!(&mut message, "Website: {} {}", label, url);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(comments) = &metadata.comments {
|
||||
let _ = writeln!(&mut message, "\n{}", comments);
|
||||
}
|
||||
if let Some(copyright) = &metadata.copyright {
|
||||
let _ = writeln!(&mut message, "\n{}", copyright);
|
||||
}
|
||||
|
||||
let message = encode_wide(message);
|
||||
let title = encode_wide(format!(
|
||||
"About {}",
|
||||
metadata.name.as_deref().unwrap_or_default()
|
||||
));
|
||||
std::thread::spawn(move || {
|
||||
MessageBoxW(
|
||||
hwnd,
|
||||
message.as_ptr(),
|
||||
title.as_ptr(),
|
||||
MB_ICONINFORMATION,
|
||||
);
|
||||
});
|
||||
show_about_dialog(hwnd, metadata)
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
@ -1322,3 +1275,103 @@ fn create_icon_item_info(hbitmap: HBITMAP) -> MENUITEMINFOW {
|
|||
info.hbmpItem = hbitmap;
|
||||
info
|
||||
}
|
||||
|
||||
fn show_about_dialog(hwnd: HWND, metadata: &AboutMetadata) {
|
||||
use std::fmt::Write;
|
||||
|
||||
let mut message = String::new();
|
||||
if let Some(name) = &metadata.name {
|
||||
let _ = writeln!(&mut message, "Name: {}", name);
|
||||
}
|
||||
if let Some(version) = &metadata.version {
|
||||
let _ = writeln!(&mut message, "Version: {}", version);
|
||||
}
|
||||
if let Some(authors) = &metadata.authors {
|
||||
let _ = writeln!(&mut message, "Authors: {}", authors.join(", "));
|
||||
}
|
||||
if let Some(license) = &metadata.license {
|
||||
let _ = writeln!(&mut message, "License: {}", license);
|
||||
}
|
||||
match (&metadata.website_label, &metadata.website) {
|
||||
(Some(label), None) => {
|
||||
let _ = writeln!(&mut message, "Website: {}", label);
|
||||
}
|
||||
(None, Some(url)) => {
|
||||
let _ = writeln!(&mut message, "Website: {}", url);
|
||||
}
|
||||
(Some(label), Some(url)) => {
|
||||
let _ = writeln!(&mut message, "Website: {} {}", label, url);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(comments) = &metadata.comments {
|
||||
let _ = writeln!(&mut message, "\n{}", comments);
|
||||
}
|
||||
if let Some(copyright) = &metadata.copyright {
|
||||
let _ = writeln!(&mut message, "\n{}", copyright);
|
||||
}
|
||||
|
||||
let message = encode_wide(message);
|
||||
let title = encode_wide(format!(
|
||||
"About {}",
|
||||
metadata.name.as_deref().unwrap_or_default()
|
||||
));
|
||||
|
||||
#[cfg(not(feature = "common-controls-v6"))]
|
||||
std::thread::spawn(move || unsafe {
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::{MessageBoxW, MB_ICONINFORMATION};
|
||||
MessageBoxW(hwnd, message.as_ptr(), title.as_ptr(), MB_ICONINFORMATION);
|
||||
});
|
||||
|
||||
#[cfg(feature = "common-controls-v6")]
|
||||
{
|
||||
use windows_sys::Win32::UI::Controls::{
|
||||
TaskDialogIndirect, TASKDIALOGCONFIG, TASKDIALOGCONFIG_0, TASKDIALOGCONFIG_1,
|
||||
TDCBF_OK_BUTTON, TDF_ALLOW_DIALOG_CANCELLATION, TD_INFORMATION_ICON,
|
||||
};
|
||||
|
||||
std::thread::spawn(move || unsafe {
|
||||
let task_dialog_config = TASKDIALOGCONFIG {
|
||||
cbSize: core::mem::size_of::<TASKDIALOGCONFIG>() as u32,
|
||||
hwndParent: hwnd,
|
||||
dwFlags: TDF_ALLOW_DIALOG_CANCELLATION,
|
||||
pszWindowTitle: title.as_ptr(),
|
||||
pszContent: message.as_ptr(),
|
||||
Anonymous1: TASKDIALOGCONFIG_0 {
|
||||
pszMainIcon: TD_INFORMATION_ICON,
|
||||
},
|
||||
Anonymous2: TASKDIALOGCONFIG_1 {
|
||||
pszFooterIcon: std::ptr::null(),
|
||||
},
|
||||
dwCommonButtons: TDCBF_OK_BUTTON,
|
||||
pButtons: std::ptr::null(),
|
||||
cButtons: 0,
|
||||
pRadioButtons: std::ptr::null(),
|
||||
cRadioButtons: 0,
|
||||
cxWidth: 0,
|
||||
hInstance: 0,
|
||||
pfCallback: None,
|
||||
lpCallbackData: 0,
|
||||
nDefaultButton: 0,
|
||||
nDefaultRadioButton: 0,
|
||||
pszCollapsedControlText: std::ptr::null(),
|
||||
pszExpandedControlText: std::ptr::null(),
|
||||
pszExpandedInformation: std::ptr::null(),
|
||||
pszMainInstruction: std::ptr::null(),
|
||||
pszVerificationText: std::ptr::null(),
|
||||
pszFooter: std::ptr::null(),
|
||||
};
|
||||
|
||||
let mut pf_verification_flag_checked = 0;
|
||||
let mut pn_button = 0;
|
||||
let mut pn_radio_button = 0;
|
||||
|
||||
TaskDialogIndirect(
|
||||
&task_dialog_config,
|
||||
&mut pn_button,
|
||||
&mut pn_radio_button,
|
||||
&mut pf_verification_flag_checked,
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue