一、前言
对于操作系统来说,用户界面一般分为两个类型:命令行接口(CLI)、图形用户接口(GUI)。
对于初学者来说,控制台(即黑窗口)是最早接触,同时也是最利于学习知识点的,其更正规的叫法为“终端”。
虽然大多数情况,我们只需要使用其输入与显示功能即可。
但有时候我们可能也需要对控制台进行更加高级的操作,比如改变标题,改变颜色,改变大小等。
那么这个时候,你就需要对了解一些控制台的api了。
控制台的全部可使用API函数可以点击这里查看。
二、窗口标题
使用的函数有:
其定义分别如下,更详细的定义可点击链接跳转官网查看。
BOOL WINAPI SetConsoleTitleA(
_In_ LPCTSTR lpConsoleTitle //填标题
);
DWORD WINAPI GetConsoleTitle(
_Out_ LPTSTR lpConsoleTitle, //获取标题的缓存区
_In_ DWORD nSize //该缓存区的大小
);
使用方式:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
char buf[0xFF];
GetConsoleTitleA(buf,0xFF); //获取原标题
cout << buf << endl;
SetConsoleTitleA("test"); //设置一个新标题
GetConsoleTitleA(buf, 0xFF);//获取新标题
cout << buf << endl;
}
效果如下:
只不过由于我目前使用的是自行安装的PowerShell代替了原本的控制台,所以这里看不出来效果,但从其输出来看,该api是成功执行了的。
三、窗口大小
主要使用的函数有:
简单梳理一下三者之间的关系:
GetStdHandle
用于获取控制台的句柄,
句柄可以理解为控制台的标志,我们可以通过这个标志用其它函数来找到它、更改它。
SetConsoleScreenBufferSize
用于设置控制台缓存区的大小,就相当于一个二维数组,控制台显示内容的方式就是将该二维数组的内容映射到屏幕上。
SetConsoleWindowInfo
用于设置控制台大小,必须要小于控制台缓存区的大小(如果控制台比缓存区还大了,那就没东西显示了,很好理解)。
其函数原型为:
HANDLE WINAPI GetStdHandle(
_In_ DWORD nStdHandle //获取指定的句柄,输出:STD_OUTPUT_HANDLE,输入:STD_INPUT_HANDLE,错误:STD_ERROR_HANDLE,具体要哪种句柄,看实际需要
);
BOOL WINAPI SetConsoleWindowInfo(
HANDLE hConsoleOutput, //标准输出句柄
BOOL bAbsolute, //是否以全局窗口
SMALL_RECT *lpConsoleWindow //要设置的大小
);
BOOL WINAPI SetConsoleScreenBufferSize(
HANDLE hConsoleOutput, //标准输出句柄
COORD dwSize //要设置的大小
);
使用:
#include<Windows.h>
#include<iostream>
using namespace std;
bool SetSize(int width, int height)
{
HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE); //获取输出句柄
SMALL_RECT wrt = { 0, 0, width - 1, height - 1 }; //设置宽高
bool ret = SetConsoleWindowInfo(hOutput, TRUE, &wrt); // 设置窗体尺寸
if (!ret) return false;
COORD coord = { width, height };
ret = SetConsoleScreenBufferSize(hOutput, coord); // 设置缓冲尺寸
return ret;
}
int main() {
SetSize(50,40);
}
由于我目前使用的并不是电脑自带的控制台,所以看不出效果,这里就不演示了。
但如果将其编译为可执行文件后双击运行、让程序卡住,其实也是能够看到效果的,因为这种情况下它就会调用系统自带的控制台。
四、光标隐藏
用到的函数有:
函数原型:
BOOL WINAPI GetConsoleCursorInfo(
HANDLE hConsoleOutput, //标准输出句柄
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo //包含光标信息的结构体
);
BOOL WINAPI SetConsoleCursorInfo(
HANDLE hConsoleOutput, //标准输出句柄
CONSOLE_CURSOR_INFO *lpConsoleCursorInfo //包含光标信息的结构体
);
光标信息结构体:
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize; //光标大小 值可取1-100之间
BOOL bVisible; //光标是否可见
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
如果只想隐藏或显示光标,则先获取现有光标的属性,然后将是否显示光标的属性bVisible
更改,最后再设置回去。
当然如果都想更改,可不调用GetConsoleCursorInfo
函数,手动设置dwSize
和bVisible
然后传入SetConsoleCursorInfo
函数。
使用:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cInfo{};
GetConsoleCursorInfo(hOutput, &cInfo); //获取现有光标信息
cInfo.bVisible = false; //false为隐藏窗口,true为显示窗口
SetConsoleCursorInfo(hOutput, &cInfo); //重新设置光标信息
}
此时控制台上就不再有光标显示:
五、光标位置
用到的函数:SetConsoleCursorPosition
函数原型为:
BOOL WINAPI SetConsoleCursorPosition(
HANDLE hConsoleOutput, //标准输出句柄
COORD dwCursorPosition //要设置的位置信息
);
使用:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coo;
coo.X = 10;
coo.Y = 10;
SetConsoleCursorPosition(hOutput, coo);
}
六、固定窗口尺寸
这里用到了三个函数:
函数原型为:
HWND GetConsoleWindow();//返回控制台窗口的句柄
LONG_PTR GetWindowLongPtrA(
HWND hWnd, //窗口句柄
int nIndex //要获取的窗口属性类别,这里我们需要窗口样式GWL_STYLE
);
LONG_PTR SetWindowLongPtrA(
[in] HWND hWnd, //窗口句柄
[in] int nIndex,//要设置的窗口属性类别,这里我们需要设置窗口样式GWL_STYLE
[in] LONG_PTR dwNewLong //要设置的值
);
使用为逻辑:先获取控制台窗口样式,然后去除掉可更改,可最大,可最小化的属性,然后再设置回去
代码:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
HWND hWnd=GetConsoleWindow(); //获取窗口句柄
LONG_PTR sty=GetWindowLongPtrA(hWnd, GWL_STYLE); //获取窗口样式
sty = sty & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX; //去除可变化大小,最大,最小化按钮,~是取反,&是与,这是位运算相关的知识了
SetWindowLongPtrA(hWnd, GWL_STYLE, sty); //设置窗体不可更改大小,不可最大化
}
其效果为窗口右上角的最大最小按钮消失,且不可改变窗口的大小。
七、字体颜色
用到的函数:
函数原型:
BOOL WINAPI SetConsoleTextAttribute(
HANDLE hConsoleOutput, //标准输出句柄
WORD wAttributes //要设置的文本属性,包括字体颜色,字体背景颜色等属性
);
可选择属性,用|
符号组合:
使用:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输出句柄
SetConsoleTextAttribute(hOutput,FOREGROUND_BLUE|BACKGROUND_GREEN|COMMON_LVB_UNDERSCORE); //设置文本颜色蓝色,背景色绿色,有下划线
cout << "this is a test!";
}
此时效果为:
可以看到已经变成蓝色字,绿色背景,下划线样式未显示可能和我这个终端有关。
八、窗口背景
官方文档中,我没有找到可以改变整个窗口背景颜色的API,但是可以采用批处理命令实现。
该方法可同时改变背景色和文字颜色,官方文档为:
使用方法:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
system("color 0C"); //设置背景为黑色,字体为淡红色
cout << "this is a test!";
}
system
可以用来执行批处理命令:
九、控制台
我们可以使用
- FreeConsole:释放控制台,一旦调用了该函数,当前控制台就无法接收到结果了。
- AllocConsole:分配控制台,允许我们重新分配一个控制台。
首先是释放:
当使用了该函数,所有输出结果就接收不到了。
然后可以重新分配一个控制台:
#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
FreeConsole(); //分离原有的控制台
cout << "this is a test";
AllocConsole(); //分配一个新的控制台
cout << "this is a test llllllllllllllll";
}
其正常效果是会又出现了一个新的控制台,并将结果输出到了新控制台上。
但由于我使用了PowerShell的原因,新窗口一闪而逝,所以这里就不演示效果了。