Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created June 30, 2018 08:31
Show Gist options
  • Save rust-play/abb336dc0542ee63924f53445fc30407 to your computer and use it in GitHub Desktop.
Save rust-play/abb336dc0542ee63924f53445fc30407 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
/// CARGO.toml
/// [target.'cfg(windows)'.dependencies]
/// winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] }
extern crate winapi;
use winapi::um::winnt::HANDLE;
use winapi::um::winbase::{STD_OUTPUT_HANDLE };
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
use winapi::um::processenv::{GetStdHandle};
use winapi::um::wincon::
{
WriteConsoleOutputCharacterW,
GetConsoleScreenBufferInfo,
CONSOLE_SCREEN_BUFFER_INFO,
SMALL_RECT,
COORD,
};
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::iter::once;
use std::io::Write;
fn main()
{
let mut a = Wrapper {};
write!(a, "Some text \nSome text on new line");
}
struct Wrapper
{}
impl Write for Wrapper
{
fn write(&mut self, buf: &[u8]) -> Result<usize, ::std::io::Error> {
write_char_buffer(buf);
Ok(0)
}
fn flush(&mut self) -> Result<(), ::std::io::Error> {
unimplemented!()
}
}
/* Code to write for writing to console with WinApi */
/// Write utf8 buffer to console.
pub fn write_char_buffer(buf: &[u8])
{
// get string from u8[] and parse it to an c_str
let utf8 = match ::std::str::from_utf8(buf)
{
Ok(string) => string,
Err(_) => "",
};
let os_str = win32_string(utf8);
// get buffer info
let csbi = get_console_screen_buffer_info();
// get current position
let current_pos = COORD {X: csbi.dwCursorPosition.X, Y: csbi.dwCursorPosition.Y};
let mut cells_written: u32 = 0;
let handle = get_output_handle();
// write to console
unsafe
{
WriteConsoleOutputCharacterW(handle, os_str.as_ptr(), os_str.len() as u32, current_pos, &mut cells_written);
}
}
fn win32_string( value : &str ) -> Vec<u16> {
OsStr::new( value ).encode_wide().chain( once( 0 ) ).collect()
}
/// Get the std_output_handle of the console
pub fn get_output_handle() -> HANDLE {
unsafe {
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
if !is_valid_handle(&handle)
{
panic!("Cannot get output handle")
}
handle
}
}
/// Create a new console screen buffer info struct.
pub fn get_console_screen_buffer_info() -> CONSOLE_SCREEN_BUFFER_INFO {
let output_handle = get_output_handle();
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO {
dwSize: COORD { X: 0, Y: 0 },
dwCursorPosition: COORD { X: 0, Y: 0 },
wAttributes: 0,
srWindow:SMALL_RECT {
Top: 0,
Right: 0,
Bottom: 0,
Left: 0,
},
dwMaximumWindowSize: COORD { X: 0, Y: 0 },
};
let success;
unsafe { success = GetConsoleScreenBufferInfo(output_handle, &mut csbi) }
if success == 0 {
panic!("Cannot get console screen buffer info");
}
csbi
}
/// Checks if the console handle is an invalid handle value.
fn is_valid_handle(handle: &HANDLE) -> bool {
if *handle == INVALID_HANDLE_VALUE {
false
} else {
true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment