use crate::msgbox::{MsgBoxType, MsgBtnType, raw_msgbox};
use std::slice;
fn wide_ptr_to_string(ptr: *const u16) -> String {
if ptr.is_null() {
return String::new();
}
unsafe {
let mut len = 0;
while *ptr.add(len) != 0 {
len += 1;
}
String::from_utf16_lossy(slice::from_raw_parts(ptr, len))
}
}
#[unsafe(no_mangle)]
pub extern "system" fn custom_msgbox_w(
msg: *const u16,
title: *const u16,
msgbox_type: u32,
msgboxbtn_type: u32,
timeout_ms: u64,
) -> i32 {
let msgbox_type = match msgbox_type {
0x0010 => MsgBoxType::Error,
0x0020 => MsgBoxType::Quest,
0x0030 => MsgBoxType::Warn,
0x0040 => MsgBoxType::Info,
_ => return 0, };
let msgboxbtn_type = match msgboxbtn_type {
0x0000 => MsgBtnType::Ok,
0x0001 => MsgBtnType::OkCancel,
0x0004 => MsgBtnType::YesNo,
_ => return 0, };
let msg = wide_ptr_to_string(msg);
let title = wide_ptr_to_string(title);
raw_msgbox(msg, title, msgbox_type, msgboxbtn_type, timeout_ms)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wide_ptr_to_string_null() {
assert_eq!(wide_ptr_to_string(std::ptr::null()), "");
}
#[test]
fn wide_ptr_to_string_valid() {
let input: Vec<u16> = "Hello\0".encode_utf16().collect();
assert_eq!(wide_ptr_to_string(input.as_ptr()), "Hello");
}
#[test]
fn wide_ptr_to_string_empty() {
let input: Vec<u16> = "\0".encode_utf16().collect();
assert_eq!(wide_ptr_to_string(input.as_ptr()), "");
}
#[test]
fn wide_ptr_to_string_non_bmp() {
let input: Vec<u16> = vec![0xD83D, 0xDE00, 0x0000];
assert_eq!(wide_ptr_to_string(input.as_ptr()), "\u{1F600}");
}
#[test]
fn custom_msgbox_w_null_pointers() {
let result = custom_msgbox_w(
std::ptr::null(),
std::ptr::null(),
MsgBoxType::Info as u32,
MsgBtnType::Ok as u32,
0,
);
assert!(result == 1 || result == -1);
}
}