控制台双缓冲防闪烁--功能封装

使用时,将包括#define DATALEN 10000的语句以及整个类、全局变量scrbuf的定义都拷贝到你的代码文件中。
默认不开启双缓冲。

  • 调用scrbuf.on()开始双缓冲模式
  • 此模式下,输出文字不会立即显示在屏幕上。
    需要手动调用scrbuf.update()刚才输入的内容才会显示在屏幕上。
  • 清空屏幕操作不要用system("cls"),而是用成员函数scrbuf.clear()
  • 调用scrbuf.off()关闭双缓冲模式
#include
#include
using namespace std;
#define DATALEN 10000
class ScreenBuff{
public:
    HANDLE hOutput;
    HANDLE hOutBuf;
    COORD coord={0,0};
    DWORD bytes;
    bool isOn;
    char data[DATALEN];
    ScreenBuff(){
        bytes = 0;
        hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
        hOutBuf = CreateConsoleScreenBuffer(
            GENERIC_READ | GENERIC_WRITE, 
            FILE_SHARE_READ | FILE_SHARE_WRITE, 
            NULL, 
            CONSOLE_TEXTMODE_BUFFER, 
            NULL
        );
        CONSOLE_CURSOR_INFO cci;
        cci.bVisible=0;
        cci.dwSize=1;
        SetConsoleCursorInfo(hOutput, &cci);
        SetConsoleCursorInfo(hOutBuf, &cci);
    }
    void on()
    {//开启双缓冲后,在输出后必须调用update才能显示 
        isOn = true;
        SetConsoleActiveScreenBuffer(hOutBuf);
    }
    void off()
    {//关闭双缓冲 
        isOn = false;
        SetConsoleActiveScreenBuffer(hOutput);
    }
    void update()
    {//更新屏幕 
        if(isOn)
        {
            ReadConsoleOutputCharacterA(hOutput, data, DATALEN, coord, &bytes);
       	    WriteConsoleOutputCharacterA(hOutBuf, data, DATALEN, coord, &bytes);
        }
    }
    void clear()//清空屏幕 
    {
    	CONSOLE_SCREEN_BUFFER_INFO cinfo;//用于储存控制台缓冲区信息,在这里主要获取控制台缓冲区大小
		DWORD recnum;
		GetConsoleScreenBufferInfo(hOutput, &cinfo);//cinfo.dwSize储存的是缓冲区大小//cinfo.dwSize.X * cinfo.dwSize.Y 即需填充的字符数
		FillConsoleOutputCharacterW(hOutput,  L' ', cinfo.dwSize.X * cinfo.dwSize.Y, (COORD){0, 0}, &recnum);//从{0,0}处开始填充' '字符,成功填充个数为recnum
		FillConsoleOutputAttribute(hOutput, 0, cinfo.dwSize.X * cinfo.dwSize.Y, (COORD){0, 0}, &recnum);//设置输出颜色,如果不是单一颜色,可能会有清除字符而背景色没有清除的现象
		SetConsoleCursorPosition(hOutput, (COORD){0, 0});//将光标设为{0,0}
		update();	
	}
}scrbuf;
int main()
{
    scrbuf.on();
    while(1)
    {
	    for (char c='a'; c<='e'; c++)
	    {
	        scrbuf.clear();//清空屏幕 
	        for (int i=0; i<2000; i++)
	        {
	            printf("%c",c);
	        }
	        scrbuf.update();
	    }
	}
    scrbuf.off();
    return 0;
}

你可能感兴趣的:(控制台程序,c++,控制台)