I want to write a &str
to the console using WriteConsoleOutputAttribute
from the winapi crate. I only have an u8 array which will be passed from the std::io::Write
implementation of a struct to my winapi code.
The following does not work correctly as I see colored cells instead of text.
use std::ffi::CString;
use std::str;
use winapi::um::wincon::{
GetConsoleScreenBufferInfo, WriteConsoleOutputAttribute, CONSOLE_SCREEN_BUFFER_INFO, COORD,
};
use winapi::um::winnt::HANDLE;
pub fn write_char_buffer(handle: HANDLE, buf: &[u8]) {
// get buffer info
let csbi = get_console_screen_buffer_info();
// get string from u8[] and parse it to an c_str
let data = str::from_utf8(buf).unwrap();
let c_str = CString::new(data).unwrap();
let ptr: *const u16 = (c_str.as_ptr() as *const u16);
// get current position
let current_pos = COORD {
X: csbi.dwCursorPosition.X,
Y: csbi.dwCursorPosition.Y,
};
let mut cells_written: u32 = 0;
// write to console
unsafe {
WriteConsoleOutputAttribute(
handle,
ptr,
data.len() as u32,
current_pos,
&mut cells_written,
);
}
}
pub fn get_console_screen_buffer_info() -> CONSOLE_SCREEN_BUFFER_INFO {
let output_handle = get_output_handle();
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
let success;
unsafe { success = GetConsoleScreenBufferInfo(output_handle, &mut csbi) }
if success == 0 {
panic!("Cannot get console screen buffer info");
}
csbi
}
I think that it is going wrong with the CString
and the pointer. See this link for the code.
Rust strings are utf8 while winapi strings are utf16. So I convert the utf8 array to utf16 String but the same output is shown, just collored cells in the console without text:
let utf8 = str::from_utf8(buf).unwrap();
let utf16: Vec<u16> = utf8.encode_utf16().collect();
let utf_string = String::from_utf16(&utf16).unwrap();
let c_str = CString::new(utf_string).unwrap();
I want to write a
&str
to the console usingWriteConsoleOutputAttribute
That's not what that function does. WriteConsoleOutputAttribute
sets character attributes: things like background color, foreground color, underline. This page has a (more) complete list.
To write text to the console, use WriteConsoleOutputCharacter
after converting it to UTF-16.