C++ windows 10中的控制台图像闪烁

C++ windows 10中的控制台图像闪烁,c++,console-application,windows-10,doublebuffered,C++,Console Application,Windows 10,Doublebuffered,以下代码在windows xp中正常工作,但在windows 10中,图像开始闪烁。如何使其在windows 10中工作 #include <windows.h> #include <ctime> #include <vector> #define xMax 180 #define yMax 45 #define Fps 250 class dbconsole { private: int width, height, FPS, delay;

以下代码在windows xp中正常工作,但在windows 10中,图像开始闪烁。如何使其在windows 10中工作

#include <windows.h>
#include <ctime>
#include <vector>

#define xMax 180
#define yMax 45
#define Fps 250

class dbconsole
{
private:
    int width, height, FPS, delay;
    HANDLE h0, h1;
    std::vector<CHAR_INFO> chiBuffer;
    bool curBuffer;
    int drawingTimer;

    void preparebuffer(HANDLE &h)
    {
        CONSOLE_CURSOR_INFO cursor = {false, 1};
        SMALL_RECT windowRectangle = {0,0,width-1,height-1};
        h = CreateConsoleScreenBuffer(
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                CONSOLE_TEXTMODE_BUFFER,
                NULL);
        SetConsoleCursorInfo(h, &cursor);
        SetConsoleScreenBufferSize (h, {width,height});
        SetConsoleWindowInfo(h,true,&windowRectangle);
    }

public:

    dbconsole(int Width, int Height, int fps)
    {
        chiBuffer.reserve(Width*Height);
        width = Width;
        height = Height;
        FPS = fps;
        preparebuffer(h0);
        preparebuffer(h1);
        curBuffer = 0;
        drawingTimer = clock();
        for (int i = 0; i < xMax; i++) for (int j = 0; j < yMax; j++) chiBuffer[i+width*j] = {'t',16};
    }

    void depict()
    {
        SMALL_RECT srctWriteRect;
        srctWriteRect.Top = 0;
        srctWriteRect.Left = 0;
        srctWriteRect.Bottom = height-1;
        srctWriteRect.Right = width-1;
        if ((clock()-drawingTimer)*FPS>CLOCKS_PER_SEC)
        {
            if (curBuffer)
            {
                WriteConsoleOutput(h0, &chiBuffer[0], {width,height}, {0,0}, &srctWriteRect);
                SetConsoleActiveScreenBuffer(h0);
            }
            else
            {
                WriteConsoleOutput(h1, &chiBuffer[0], {width,height}, {0,0}, &srctWriteRect);
                SetConsoleActiveScreenBuffer(h1);
            }
            curBuffer=!curBuffer;
            drawingTimer = clock();
        }
    }

};

int main(void)
{
    dbconsole myConsole = dbconsole(xMax,yMax,Fps);
    while (true) myConsole.depict();
}
#包括
#包括
#包括
#定义xmax180
#定义yMax 45
#定义Fps 250
类dbconsole
{
私人:
整数宽度、高度、FPS、延迟;
手柄h0、h1;
std::载体缓冲区;
布尔·库布弗;
内画计时器;
真空准备缓冲(手柄和h)
{
CONSOLE_CURSOR_INFO CURSOR={false,1};
小矩形窗口={0,0,宽度-1,高度-1};
h=CreateConsolesScreenbuffer(
一般的读,一般的写,
文件共享读取文件共享写入,
无效的
控制台\文本模式\缓冲区,
无效);
SetConsoleCursorInfo(h和光标);
SetConsoleScreenBufferSize(h,{宽度,高度});
SetConsoleWindowInfo(h、true和windowRectangle);
}
公众:
dbconsole(整数宽度、整数高度、整数fps)
{
缓冲区预留(宽*高);
宽度=宽度;
高度=高度;
FPS=FPS;
制备缓冲液(h0);
制备缓冲液(h1);
柯布费=0;
drawingTimer=时钟();
对于(inti=0;i时钟每秒)
{
if(courbuffer)
{
WriteConsoleOutput(h0,&chiBuffer[0],{width,height},{0,0},&srctWrite);
设置控制台活动屏幕缓冲区(h0);
}
其他的
{
WriteConsoleOutput(h1,&chiBuffer[0],{width,height},{0,0},&srctWrite);
设置控制台活动屏幕缓冲区(h1);
}
柯布费=!柯布费;
drawingTimer=时钟();
}
}
};
内部主(空)
{
dbconsole myConsole=dbconsole(xMax、yMax、Fps);
而(true)myConsole.descript();
}

我希望程序在蓝色背景上显示黑色字母“t”,但不闪烁且具有双缓冲

好的,在研究了问题之后,这里有一个答案

CONSOLE\u CURSOR\u INFO
定义为第一个
DWORD dwSize
和第二个
BOOL bVisible
,但您使用它时,就像使用第一个和第二个成员一样,反之亦然。因此,
setConsoleUrsorInfo
失败,返回值
0
GetLastError
返回87,这是
ERROR\u无效的参数()


正确地禁用光标应该可以解决问题,尽管我没有windows 10可供测试。

我记得在windows 10之前很久就有过类似的问题。。。我不确定,但我认为那是XP时代。对我来说,解决方案是为当前屏幕缓冲区编写一个更新例程,而不是频繁切换缓冲区,但是我没有选择250 fps…切换到60 fps没有帮助。此外,该绘图适用于windows 8。我想用这些控制台来显示一些信息,我可能需要在瞬间重画每一次,所以双缓冲似乎是必要的。当然。。。无论如何,60fps可能是您的显示器刷新率。您应该降低到1fps,以便评估一次刷新的效果。只要你能看到任何效果,它就会随着更快的更新而闪烁。1fps不会闪烁,但光标会出现在左上角,而我确信行控制台\u cursor\u INFO cursor={false,1};我不知道如何在windows 10中隐藏光标,但我想现在你知道该查找什么了,你就可以找到它了;)谢谢,光标已经消失,它以1fps的速度工作,但图像仍以40fps的速度闪烁