Skip to content

Commit d6f19d2

Browse files
committed
fix msgbox
1 parent ebc951a commit d6f19d2

2 files changed

Lines changed: 59 additions & 3 deletions

File tree

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn main() {
1616
#[cfg(windows)]
1717
{
1818
let mut res = winres::WindowsResource::new();
19-
res.set("FileDescription", "Starter for ScreenCapture");
19+
res.set("FileDescription", "Starter of ScreenCapture");
2020
res.set(
2121
"LegalCopyright",
2222
"Copyright (C) Mikachu2333 2025-2026. MIT License.",

src/msgbox.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,16 @@ extern "system" {
4747
) -> i32;
4848
fn FindWindowW(lpClassName: LPCWSTR, lpWindowName: LPCWSTR) -> HWND;
4949
fn PostMessageW(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> BOOL;
50+
fn CreateWindowExW(
51+
dwExStyle: u32, lpClassName: *const u16, lpWindowName: *const u16,
52+
dwStyle: u32, x: i32, y: i32, nWidth: i32, nHeight: i32,
53+
hWndParent: HWND, hMenu: isize, hInstance: isize, lpParam: *mut std::ffi::c_void,
54+
) -> HWND;
55+
fn DestroyWindow(hWnd: HWND) -> i32;
5056
}
5157

58+
const HWND_MESSAGE: HWND = -3; // Message-only window parent
59+
5260
/// Button combinations for message boxes
5361
#[allow(dead_code)]
5462
enum MsgBtnType {
@@ -424,6 +432,51 @@ pub fn show_notification(
424432
NotifyIconType::Error => NIIF_ERROR,
425433
};
426434

435+
let title_w = to_wide(title.to_string());
436+
let msg_w = to_wide(msg.to_string());
437+
let tip_w = to_wide(PROCESS_NAME);
438+
439+
// Set tooltip (shown on hover)
440+
for (i, &c) in tip_w.iter().take(127).enumerate() {
441+
nid.szTip[i] = c;
442+
}
443+
// Set balloon title
444+
for (i, &c) in title_w.iter().take(63).enumerate() {
445+
nid.szInfoTitle[i] = c;
446+
}
447+
// Set balloon message
448+
for (i, &c) in msg_w.iter().take(255).enumerate() {
449+
nid.szInfo[i] = c;
450+
}
451+
452+
// First, try to delete any existing icon with the same ID (cleanup from previous calls)
453+
unsafe { Shell_NotifyIconW(NIM_DELETE, &nid) };
454+
455+
// 创建一个仅用于接收消息的隐藏系统窗口 (Message-only window)
456+
let class_name = to_wide("STATIC"); // 使用系统自带静态类
457+
let hwnd = unsafe {
458+
CreateWindowExW(
459+
0,
460+
class_name.as_ptr(),
461+
ptr::null(), // 无名
462+
0, 0, 0, 0, 0,
463+
HWND_MESSAGE,
464+
0, 0, ptr::null_mut()
465+
)
466+
};
467+
468+
let mut nid: NOTIFYICONDATAW = unsafe { std::mem::zeroed() };
469+
nid.cbSize = std::mem::size_of::<NOTIFYICONDATAW>() as u32;
470+
nid.hWnd = hwnd;
471+
nid.uID = STANDALONE_NOTIFY_ICON_ID;
472+
nid.uFlags = NIF_ICON | NIF_TIP | NIF_INFO;
473+
nid.hIcon = unsafe { LoadIconW(0, IDI_APPLICATION) };
474+
nid.dwInfoFlags = match icon_type {
475+
NotifyIconType::Info => NIIF_INFO,
476+
NotifyIconType::Warning => NIIF_WARNING,
477+
NotifyIconType::Error => NIIF_ERROR,
478+
};
479+
427480
let title_w = to_wide(title);
428481
let msg_w = to_wide(msg);
429482
let tip_w = to_wide(PROCESS_NAME);
@@ -455,9 +508,12 @@ pub fn show_notification(
455508
thread::sleep(std::time::Duration::from_millis(timeout_ms));
456509
let mut cleanup_nid: NOTIFYICONDATAW = unsafe { std::mem::zeroed() };
457510
cleanup_nid.cbSize = std::mem::size_of::<NOTIFYICONDATAW>() as u32;
458-
cleanup_nid.hWnd = 0;
511+
cleanup_nid.hWnd = hwnd; // 对应当初的hwnd
459512
cleanup_nid.uID = STANDALONE_NOTIFY_ICON_ID;
460-
unsafe { Shell_NotifyIconW(NIM_DELETE, &cleanup_nid) };
513+
unsafe {
514+
Shell_NotifyIconW(NIM_DELETE, &cleanup_nid);
515+
DestroyWindow(hwnd); // 释放伪窗口
516+
};
461517
});
462518

463519
true

0 commit comments

Comments
 (0)