C/C++中有时候需要在屏幕任意位置输出,这样可以在控制台输出定义好的形状,使用\b可以删除上一个字符,但是如果对于模拟LED这种情况就无能为力了,如果实在windows下,可以使用win32 API来设置光标位置解决.
模拟LED:
可以使用win32api来设置光标位置,核心代码:
#include <windows.h> void gotoxy(int x, int y) // x,y坐标 { COORD coord = {x, y}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }
类似的,有一个获得光标位置的函数
void getxy(int *x, int *y) { CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); *x = (int)(csbi.dwCursorPosition.X); *y = (int)(csbi.dwCursorPosition.Y); }
一个完整的例子:控制台LED显示数字
#include <iostream> #include <string> #include <sstream> #include <windows.h> using namespace std; void gotoxy(int x, int y) { COORD coord = {x, y}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } string codes[10][7] = { { " --- ", // 0 "| |", "| |", "| |", "| |", "| |", " --- "}, { " ", // 1 " |", " |", " |", " |", " |", " "}, { " --- ", " |", " |", " --- ", "| ", "| ", " --- "}, { " --- ", " |", " |", " --- ", " |", " |", " --- "}, { " ", "| |", "| |", " --- ", " |", " |", " "}, { " --- ", "| ", "| ", " --- ", " |", " |", " --- "}, { " --- ", "| ", "| ", " --- ", "| |", "| |", " --- "}, { " --- ", " |", " |", " |", " |", " |", " "}, { " --- ", "| |", "| |", " --- ", "| |", "| |", " --- "}, { " --- ", "| |", "| |", " --- ", " |", " |", " --- "}}; void printNum(int prev, int start_y, const char &c) { int x, y = start_y; x = prev*6; // prev_num+gap for (int i=0;i<7;i++) { gotoxy(x,y++); cout << codes[(int)(c-'0')][i]; } } void LEDprint(int num, int start_y = 0) { stringstream is; string nums; is << num; is >> nums; for (size_t i=0;i<nums.size();i++) printNum(i,start_y,nums[i]); } void LEDprint(string nums, int start_y = 0) { for (size_t i=0;i<nums.size();i++) printNum(i,start_y,nums[i]); } int main() { LEDprint(1234567890); LEDprint("0123456",7); return 0; }
一个更复杂,更完整的例子
#include <windows.h> #include <stdio.h> void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void); int main(int argc, char* argv[]) { HideTheCursor(); ClearConsoleToColors(15, 1); ClearConsole(); gotoXY(1, 1); SetColor(14); printf("This is a test...\n"); Sleep(500); ShowTheCursor(); SetColorAndBackground(15, 12); ConPrint("This is also a test...\n", 23); SetColorAndBackground(1, 7); ConPrintAt(22, 15, "This is also a test...\n", 23); gotoXY(0, 24); SetColorAndBackground(7, 1); return 0; } //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) { WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F); //Get the handle to the current output buffer... HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //This is used to reset the carat/cursor to the top left. COORD coord = {0, 0}; //A return value... indicating how many chars were written //not used but we need to capture this since it will be //written anyway (passing NULL causes an access violation). DWORD count; //This is a structure containing all of the console info // it is used here to find the size of the console. CONSOLE_SCREEN_BUFFER_INFO csbi; //Here we will set the current color SetConsoleTextAttribute(hStdOut, wColor); if(GetConsoleScreenBufferInfo(hStdOut, &csbi)) { //This fills the buffer with a given character (in this case 32=space). FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count); FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count); //This will set our cursor position for the next print statement. SetConsoleCursorPosition(hStdOut, coord); } } //This will clear the console. void ClearConsole() { //Get the handle to the current output buffer... HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //This is used to reset the carat/cursor to the top left. COORD coord = {0, 0}; //A return value... indicating how many chars were written // not used but we need to capture this since it will be // written anyway (passing NULL causes an access violation). DWORD count; //This is a structure containing all of the console info // it is used here to find the size of the console. CONSOLE_SCREEN_BUFFER_INFO csbi; //Here we will set the current color if(GetConsoleScreenBufferInfo(hStdOut, &csbi)) { //This fills the buffer with a given character (in this case 32=space). FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count); FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count); //This will set our cursor position for the next print statement. SetConsoleCursorPosition(hStdOut, coord); } } //This will set the position of the cursor void gotoXY(int x, int y) { //Initialize the coordinates COORD coord = {x, y}; //Set the position SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } //This will set the forground color for printing in a console window. void SetColor(int ForgC) { WORD wColor; //We will need this handle to get the current background attribute HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csbi; //We use csbi for the wAttributes word. if(GetConsoleScreenBufferInfo(hStdOut, &csbi)) { //Mask out all but the background attribute, and add in the forgournd color wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F); SetConsoleTextAttribute(hStdOut, wColor); } } //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) { WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); } //Direct console output void ConPrint(char *CharBuffer, int len) { DWORD count; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); } //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) { DWORD count; COORD coord = {x, y}; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hStdOut, coord); WriteConsole(hStdOut, CharBuffer, len, &count, NULL); } //Hides the console cursor void HideTheCursor() { CONSOLE_CURSOR_INFO cciCursor; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if(GetConsoleCursorInfo(hStdOut, &cciCursor)) { cciCursor.bVisible = FALSE; } } //Shows the console cursor void ShowTheCursor() { CONSOLE_CURSOR_INFO cciCursor; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if(GetConsoleCursorInfo(hStdOut, &cciCursor)) { cciCursor.bVisible = TRUE; } }
No comments :
Post a Comment