设置 Windows 控制台的文本颜色未按预期工作
Setting text color of the Windows console is not working as expected
我正在尝试使用 winapi 和 kernel32 crates 用 Rust 更改 Windows 控制台前景文本颜色。
[dependencies]
winapi = "0.2.8"
kernel32-sys = "0.2.1"
代码
存储前景颜色值的枚举:
#[repr(u16)]
pub enum ForegroundColor {
RED = (winapi::FOREGROUND_INTENSITY | winapi::FOREGROUND_RED) as u16,
CYAN = (winapi::FOREGROUND_INTENSITY | winapi::FOREGROUND_GREEN | winapi::FOREGROUND_BLUE) as u16,
// ...
}
获取输出句柄的函数:
use winapi;
use winapi::{CONSOLE_SCREEN_BUFFER_INFO, COORD, HANDLE, SMALL_RECT, WORD};
use kernel32;
static mut CONSOLE_OUTPUT_HANDLE: Option<HANDLE> = None;
pub fn get_output_handle() -> HANDLE {
unsafe {
if let Some(handle) = CONSOLE_OUTPUT_HANDLE {
handle_check(handle);
handle
} else {
let handle = kernel32::GetStdHandle(winapi::STD_OUTPUT_HANDLE);
handle_check(handle);
CONSOLE_OUTPUT_HANDLE = Some(handle);
handle
}
}
}
fn handle_check(handle: HANDLE) {
if handle == winapi::INVALID_HANDLE_VALUE {
panic!("NoConsole")
}
}
设置前景色的函数
使用 kernel32;
// ForegroundColor is a struct containing win32 colors
pub fn set_foreground_color(for_color: ForegroundColor) {
// function shown above
let output_handle = kernel::get_output_handle();
// cast the enum value to a u16: fn to_u16(&self) -> u16 { *self as u16 }
let forground_color = for_color.to_u16();
unsafe {
kernel32::SetConsoleTextAttribute(output_handle, forground_color);
}
}
在我的 main.rs
中,我正在创建一个盒子,它在 X 上有 20 个方块,在 Y 上有 20 个方块。我想给边框颜色 CYAN
和内部颜色 RED
颜色。
// for example 1 has to be cyan and 2 red but than on larger scale
// 1111
// 1221
// 1111
for y in 0..21 {
for x in 0..21 {
if (x == 0 || y == 0) || (x == 20 || y == 20) {
// function shown above
set_foreground_color(ForegroundColor::CYAN);
// Print a cyan colored ■
print!("■")
} else {
// function shown above
set_foreground_color(ForegroundColor::RED);
// Print a red colored ■
print!("■")
}
}
// reset cursor to start of new line
println!();
}
出于某种原因,所有 ■
都将具有 CYAN
颜色,并且不会有任何红色。
当我使用相同的代码并将 print!()
替换为 println!()
时,它将按预期打印 RED
和 CYAN
彩色块。所有 ■
都具有预期的正确颜色,但现在的问题是 ■
在它们自己的行上。
为什么使用 println!()
时文本的颜色会按预期变化?为什么我不能在 print!()
的同一行上有不同的颜色? winapi 中是否有一些缓冲区存储控制台行的颜色?我需要在某处指定它才能在一行中使用多种颜色吗?
Rust 的标准输出是行缓冲的。因此,您的文本一次一行地发送到控制台,这意味着整行将具有相同的颜色。
您可以在每次 print!
之后刷新输出,使用:
use std::io::Write;
std::io::stdout().flush().expect("Flush stdout failed");
我正在尝试使用 winapi 和 kernel32 crates 用 Rust 更改 Windows 控制台前景文本颜色。
[dependencies]
winapi = "0.2.8"
kernel32-sys = "0.2.1"
代码
存储前景颜色值的枚举:
#[repr(u16)]
pub enum ForegroundColor {
RED = (winapi::FOREGROUND_INTENSITY | winapi::FOREGROUND_RED) as u16,
CYAN = (winapi::FOREGROUND_INTENSITY | winapi::FOREGROUND_GREEN | winapi::FOREGROUND_BLUE) as u16,
// ...
}
获取输出句柄的函数:
use winapi;
use winapi::{CONSOLE_SCREEN_BUFFER_INFO, COORD, HANDLE, SMALL_RECT, WORD};
use kernel32;
static mut CONSOLE_OUTPUT_HANDLE: Option<HANDLE> = None;
pub fn get_output_handle() -> HANDLE {
unsafe {
if let Some(handle) = CONSOLE_OUTPUT_HANDLE {
handle_check(handle);
handle
} else {
let handle = kernel32::GetStdHandle(winapi::STD_OUTPUT_HANDLE);
handle_check(handle);
CONSOLE_OUTPUT_HANDLE = Some(handle);
handle
}
}
}
fn handle_check(handle: HANDLE) {
if handle == winapi::INVALID_HANDLE_VALUE {
panic!("NoConsole")
}
}
设置前景色的函数 使用 kernel32;
// ForegroundColor is a struct containing win32 colors
pub fn set_foreground_color(for_color: ForegroundColor) {
// function shown above
let output_handle = kernel::get_output_handle();
// cast the enum value to a u16: fn to_u16(&self) -> u16 { *self as u16 }
let forground_color = for_color.to_u16();
unsafe {
kernel32::SetConsoleTextAttribute(output_handle, forground_color);
}
}
在我的 main.rs
中,我正在创建一个盒子,它在 X 上有 20 个方块,在 Y 上有 20 个方块。我想给边框颜色 CYAN
和内部颜色 RED
颜色。
// for example 1 has to be cyan and 2 red but than on larger scale
// 1111
// 1221
// 1111
for y in 0..21 {
for x in 0..21 {
if (x == 0 || y == 0) || (x == 20 || y == 20) {
// function shown above
set_foreground_color(ForegroundColor::CYAN);
// Print a cyan colored ■
print!("■")
} else {
// function shown above
set_foreground_color(ForegroundColor::RED);
// Print a red colored ■
print!("■")
}
}
// reset cursor to start of new line
println!();
}
出于某种原因,所有 ■
都将具有 CYAN
颜色,并且不会有任何红色。
当我使用相同的代码并将 print!()
替换为 println!()
时,它将按预期打印 RED
和 CYAN
彩色块。所有 ■
都具有预期的正确颜色,但现在的问题是 ■
在它们自己的行上。
为什么使用 println!()
时文本的颜色会按预期变化?为什么我不能在 print!()
的同一行上有不同的颜色? winapi 中是否有一些缓冲区存储控制台行的颜色?我需要在某处指定它才能在一行中使用多种颜色吗?
Rust 的标准输出是行缓冲的。因此,您的文本一次一行地发送到控制台,这意味着整行将具有相同的颜色。
您可以在每次 print!
之后刷新输出,使用:
use std::io::Write;
std::io::stdout().flush().expect("Flush stdout failed");