#ifndef INCLUDED_C_CONSOLE_H #define INCLUDED_C_CONSOLE_H #ifndef INCLUDED_C_TYPES_H #include #endif /*INCLUDED_C_TYPES_H*/ #ifndef INCLUDED_STDIO_H #define INCLUDED_STDIO_H #include #endif /*INCLUDED_STDIO_H*/ #if defined(_WIN32) || defined(_WIN64) #include #include #else #include #include #include #endif /* ------------------------------------------------------------------------------------------------------------------ */ /* */ // ========================================== // 2. 终端控制 ANSI 转义宏 (全平台通用) // ========================================== #define CONSOLE_CLEAR() printf("\033[2J\033[H") // 清屏并将光标归位 #define CONSOLE_GOTOXY(x, y) printf("\033[%d;%dH", (y), (x)) // 移动光标 (1-based) #define CONSOLE_HIDE_CURSOR() printf("\033[?25l") // 隐藏光标 #define CONSOLE_SHOW_CURSOR() printf("\033[?25h") // 显示光标 #define CONSOLE_COLOR_RESET() printf("\033[0m") // 重置属性 #define CONSOLE_COLOR_RED() printf("\033[1;31m") // 高亮红 #define CONSOLE_COLOR_GREEN() printf("\033[1;32m") // 高亮绿 #define CONSOLE_COLOR_BLUE() printf("\033[1;34m") // 高亮蓝 /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /** * @brief 控制台 16 色标准颜色枚举(同时适用于前景色和背景色计算) */ typedef enum { C_COLOR_BLACK = 0, C_COLOR_RED = 1, C_COLOR_GREEN = 2, C_COLOR_YELLOW = 3, C_COLOR_BLUE = 4, C_COLOR_MAGENTA = 5, C_COLOR_CYAN = 6, C_COLOR_WHITE = 7, // 高亮色系列(加粗/明亮) C_COLOR_BRIGHT_BLACK = 8, C_COLOR_BRIGHT_RED = 9, C_COLOR_BRIGHT_GREEN = 10, C_COLOR_BRIGHT_YELLOW = 11, C_COLOR_BRIGHT_BLUE = 12, C_COLOR_BRIGHT_MAGENTA = 13, C_COLOR_BRIGHT_CYAN = 14, C_COLOR_BRIGHT_WHITE = 15, C_COLOR_NONE = -1 // 不改变原有颜色(保持默认) } c_ConsoleColor_t; // 鼠标事件类型 typedef enum { MOUSE_EVENT_NONE = 0, MOUSE_EVENT_PRESS_LEFT, // 左键按下 MOUSE_EVENT_PRESS_RIGHT, // 右键按下 MOUSE_EVENT_PRESS_MIDDLE, // 中键按下 MOUSE_EVENT_RELEASE, // 任意键释放 MOUSE_EVENT_WHEEL_UP, // 滚轮向上滚动 MOUSE_EVENT_WHEEL_DOWN, // 滚轮向下滚动 MOUSE_EVENT_MOVE // 鼠标移动 } c_ConsoleMouseEventType_t; // 统一的鼠标事件结构体 typedef struct { c_ConsoleMouseEventType_t type; // 事件类型 int x; // 触发时的列坐标 (从 1 开始) int y; // 触发时的行坐标 (从 1 开始) } c_ConsoleMouseEvent_t; typedef enum { // 基础控制键(单字节即可判定的按键) C_KEY_UNKNOWN = 0, C_KEY_ENTER = 13, // 统一回车键 C_KEY_ESC = 27, // 统一 ESC 键 C_KEY_SPACE = 32, // 空格键 C_KEY_BACKSPACE = 127,// 退格键 // 特殊扩展按键(方向键) C_KEY_UP = 1001, C_KEY_DOWN = 1002, C_KEY_LEFT = 1003, C_KEY_RIGHT = 1004 } c_ConsoleKeyCode_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /** * @brief 跨平台初始化控制台环境 * Windows: 激活全局 ANSI 转义序列支持 * Linux/macOS: 关闭行缓冲、关闭按键回显,并注册退出恢复钩子 */ void c_Console_Init(void); /** * @brief 跨平台非阻塞检查是否有键盘输入 * @return */ int c_Console_kbhit(void); /** * @brief 跨平台直接读取单个按键字符 * @return */ int c_Console_getch(void); /** * * @param milliseconds */ void c_Console_Sleep(int milliseconds); /** * @brief 跨平台清除控制台中的指定行 * @param y 目标行的纵坐标 (从 1 开始计) */ void c_Console_BlankLine(int y); /** * @brief 从指定坐标 (x, y) 开始清空到该行的末尾 */ void c_Console_BlankLineFrom(int x, int y); /** * @brief 跨平台移动控制台光标到指定坐标 * @param x 目标列坐标 (Column/Horizontal),从 1 开始计,自左向右递增 * @param y 目标行坐标 (Row/Vertical),从 1 开始计,自上向下递增 */ void c_Console_GotoXY(int x, int y); /** * @brief 跨平台获取当前控制台窗口的大小(宽高) * @param width 用于接收总列数(X方向字符数)的指针 * @param height 用于接收总行数(Y方向字符数)的指针 */ void c_Console_GetSize(int *width, int *height); /** * @brief 在控制台指定行的指定总宽度内,将 UTF-8 文本居中打印 * @param y 目标行坐标 (从 1 开始) * @param box_width 容器的总宽度(例如整个控制台的宽度,或一个 UI 矩形框的宽度) * @param str 要打印的 UTF-8 字符串 */ void c_Console_PrintCenter(int y, int box_width, const char *str); /** * @brief 精准计算一个 UTF-8 字符串在控制台上的实际“光标显示宽度” * @param str 输入的 UTF-8 字符串 * @return 屏幕实际占用的列数(英文字符算 1,中文/日文/韩文等全角字符算 2) */ int c_Console_GetVisualWidth(const char *str); /** * @brief 格式化等宽对齐打印(常用于表格、菜单选项对齐) * @param str 要打印的文本 * @param align_len 限定的视觉总宽度(若文本不足此宽度,自动在右侧补齐空格) */ void c_Console_PrintLeftAligned(const char *str, int align_len); /** * @brief 跨平台在指定坐标处格式化输出 UTF-8 文本 * @param x 目标列坐标 (从 1 开始计) * @param y 目标行坐标 (从 1 开始计) * @param format 格式化字符串 (与 printf 完全一致,如 "Score: %d") * @param ... 可变参数 * @return 成功打印的物理字节数(若失败返回负数) */ int c_Console_WriteXY(int x, int y, const char *format, ...); /** * @brief 跨平台在指定坐标处,以指定的颜色格式化输出文本 * @param x 目标列坐标 (从 1 开始) * @param y 目标行坐标 (从 1 开始) * @param fg 前景色 (文字颜色),传入 C_COLOR_NONE 表示不修改 * @param bg 背景色 (文字底色),传入 C_COLOR_NONE 表示不修改 * @param format 格式化字符串 * @param ... 可变参数 * @return 成功打印的物理字节数 */ int c_Console_WriteColorXY(int x, int y, c_ConsoleColor_t fg, c_ConsoleColor_t bg, const char *format, ...); /** * @brief 开启鼠标事件追踪 */ void c_Console_EnableMouse(void); /** * @brief 关闭鼠标事件追踪(程序退出时必须调用,避免污染用户终端) */ void c_Console_DisableMouse(void); /** * @brief 跨平台非阻塞读取鼠标事件 * @param mouse_evt 用于接收转换后的通用鼠标事件结构体 * @return int 如果成功捕获到鼠标事件返回 1,否则返回 0 */ int c_Console_ReadMouse(c_ConsoleMouseEvent_t *mouse_evt); /** * @brief 跨平台精准读取并转换键盘按键(包含方向键、Esc、Enter) * @note 必须确保终端已通过 c_Console_Init() 切换到非阻塞/Raw 模式 * @return int 返回转换后的统一 c_ConsoleKeyCode_t 键值,若为普通字符则原样返回其 ASCII 码 */ int c_Console_ReadKey(void); /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE void c_Console_HideCursor(void) { printf("\033[?25l"); } C_STATIC_FORCE_INLINE void c_Console_ShowCursor(void) { printf("\033[?25h"); } #endif /*INCLUDED_C_CONSOLE_H*/