winapiとkernel32のクレートを使って、RustでWindowsコンソールの前景色を変更しようとしています。出力ハンドルを取得Windowsコンソールのテキストの色が期待どおりに動作しない
#[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")
}
}
機能私は前景色値を格納
[dependencies]
winapi = "0.2.8"
kernel32-sys = "0.2.1"
コード
列挙 を使用rnel32;私main.rs
で
// 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);
}
}
私はRED
色の内側の境界線にCYAN
の色を与えるとしたいY.に20 X上のブロックと20でボックスを作成しています。何らかの理由で
// 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にコンソールラインの色を保存するバッファがありますか? 1行に複数の色を使用するには、どこかに指定する必要がありますか?
Windowsコンソールは、非ASCII値の悪名高いトリッキーです。 ■より簡単なものを試してみませんか? – Shepmaster
@Shepmaster '■'は、 ' + 254'を押すとASCIIテーブルに置かれます。そして、この問題は通常の数字(試しただけ)でも発生します。 –
私はあなたが戻って、ASCIIが何であるか再読することを強くお勧めします。 128未満の数値のみがASCIIです。 – Shepmaster