设置Windows控制台的文本颜色无法正常工作

Tim*_*ost 0 console winapi colors kernel32 rust

我正在尝试使用winapi和kernel32条板箱使用Rust更改Windows控制台的前景色。

[dependencies]
winapi = "0.2.8"
kernel32-sys = "0.2.1" 
Run Code Online (Sandbox Code Playgroud)

码

我存储前景色值的枚举:

#[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,
    // ...
}
Run Code Online (Sandbox Code Playgroud)

获取输出句柄的函数:

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")
    }
}
Run Code Online (Sandbox Code Playgroud)

设置前景色的函数使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的main.rs 我创建一个盒子是X 20块和20 Y.我想给边框的颜色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!();
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,所有人?都会有CYAN颜色,而不会有任何红色。

当我有相同的代码,并更换print!()有println!(),将打印既RED与CYAN预期彩色块。所有的?颜色都具有预期的正确颜色,但是现在的问题是?它们位于自己的行上。

为什么使用时文字的颜色会发生预期的变化println!()?为什么不能在同一行上使用不同的颜色 print!()?winapi中是否有一些缓冲区可以存储控制台行的颜色?在一行中可以使用多种颜色之前,是否需要在某个地方指定它?

int*_*jay 5

Rust的标准输出是行缓冲的。因此,您的文本一次只能发送到控制台一行,这意味着整行将具有相同的颜色。

您可以在每次print!使用之后刷新输出:

use std::io::Write;

std::io::stdout().flush().expect("Flush stdout failed");
Run Code Online (Sandbox Code Playgroud)