Unicode MesssageBox example in Rust

In this post, I’ll show you how to use the Unicode version of the MessageBox api we used in the previous post. The end result should look something like this:

Screenshot of messagebox

To get started, we’ll use the previous version of the code which you can find here. The first thing we need to do is find the correct version of the MessageBox() function to call. As I mentioned previously, there are two versions of the function: MessageBoxA() for ASCII and MessageBoxW() for Unicode. The first thing we need to do is change the call from MessageBoxA() to MessageBoxW().

Now that we’ve done that, we need to change the lpText and lpCaption arguments to point to utf-16 encoded strings instead of ASCII encoded strings. The Rust standard library includes a method on str to do this called encode_utf16(). So we’ll change these lines:

let lp_text = CString::new("Hello, world!").unwrap();
let lp_caption = CString::new("MessageBox Example").unwrap();

to:

let lp_text: Vec<u16> = "Hello, world! \u{1F60E}\0".encode_utf16().collect();
let lp_caption: Vec<u16> = "MessageBox Example\0".encode_utf16().collect();

I’ve added a Unicode character (a smiley face) to the output so we can see that it is working correctly. Remember that C strings are NULL terminated; CString::new() took care of appending it for us, so now we need to add the NULL character ('\0') to the end of the string. Since we still need to pass a pointer to MessageBoxW(), we’ll collect() the results of encode_utf16() into a Vec<u16> which gives us the same as_ptr() method we used previously.

After removing some unused imports, this gives us:

extern crate user32;
extern crate winapi;

use user32::MessageBoxW;
use winapi::winuser::{MB_OK, MB_ICONINFORMATION};

fn main() {
    let lp_text: Vec<u16> = "Hello, world! \u{1F60E}\0".encode_utf16().collect();
    let lp_caption: Vec<u16> = "MessageBox Example\0".encode_utf16().collect();

    unsafe {
        MessageBoxW(
            std::ptr::null_mut(),
            lp_text.as_ptr(),
            lp_caption.as_ptr(),
            MB_OK | MB_ICONINFORMATION
        );
    }
}

You can find all of the code from this post in this repository. Thanks for reading!