Dual Buffer Solution Console Application Output "splash screen" (c/c++,windows)

Source: Internet
Author: User
Tags call back win32

In the C language to write the game of the small partners must initially encounter such a problem, in the process of continuously clear the output data, the console output will be constantly flashing screen. This problem occurs because the time the program spends on data processing affects the display, and perhaps you can use the local overlay Update method (which reduces the amount of updated data) to mitigate the splash screen, but this approach does not apply to all occasions, especially if the update data itself is very large.

This article will address the end-level resolution of the console application output splash screen-double buffering.

Problem Presentation

The following code demonstrates the splash screen problem in the process of continuously clearing the screen output data at high speed, and invited you to try:

12345678910111213141516 #include <stdio.h>int main(){    while (1)    {        for (char c=‘a‘; c<‘z‘; c++)        {            system("cls");            for (int i=0; i<800; i++)            {                printf("%c",c);            }        }    }}
Incomplete Solution: Partial overwrite update

This example code will use two Win32 API functions, GetStdHandle, SetConsoleCursorPosition,

Legend Name Description
HANDLE GetStdHandle (
_in_ DWORD Nstdhandle
);
Get Standard device handle
Nstdhandle standard equipment, desirable values:
Std_input_handle (DWORD)-10, input device
Std_output_handle (DWORD)-11, output device
Std_error_handle (DWORD)-12, error device
Call Back:
Successful, returns the device handle (HANDLE);
Failure, return invalid_handle_value;
If there is no standard device, returns NULL.
BOOL SetConsoleCursorPosition (
_in_ HANDLE Hconsoleoutput,
_in_ COORD dwcursorposition
);
Setting the console cursor position
Hconsoleoutput Console output device handle
dwcursorposition cursor Position

The COORD structure is used in the function arguments:

Legend Name Description
X
Short X;
Horizontal coordinate or column value, starting with 0
Y
Short X;
Vertical coordinate or row value, starting with 0

Example code:

123456789101112131415161718192021 #include <stdio.h>#include <Windows.h> int main(){    HANDLE hOutput;    COORD coord={0,0};    hOutput=GetStdHandle(STD_OUTPUT_HANDLE);    while (1)    {        for (char c=‘a‘; c<‘z‘; c++)        {            SetConsoleCursorPosition(hOutput, coord);            for (int i=0; i<800; i++)            {                printf("%c",c);            }        }    }}
Flash screen causes and solutions

First of all, it is stated that only the data in the "Display buffer" will be displayed. The display structure of the default console application is this:

When the output of a large amount of data, because the data processing takes time, resulting in data arrival in the display buffer sequence. That is, when the monitor displays data, it is possible that only some of the displayed data has reached the display buffer, and the other data has not arrived, so that the image is displayed as a partial rendering complete. This is the root cause of the splash screen that updates a large number of display data.

Complete Solution: Using dual buffering technology

In the process of graphics processing, double buffering is one of the basic techniques, it is an effective solution to solve the flash screen. Especially in the field of game programming, double buffering technology has been widely used.

So it seems that the problem of seeming to be worried, in fact, we only need one more buffer to completely solve this problem. If you apply a dual-buffering technique, the structure of the console program will change slightly:

Because the default buffer has support for standard input and output streams, for ease of input and output, we use the default display buffer as the back buffer and the newly created display buffer as the active screen. The basic procedure is to first display the data to the default buffer, and then fill in the newly created display buffer once it is all written.

To implement this process, we also need to invoke several Win32 APIs (Createconsolescreenbuffer, Setconsoleactivescreenbuffer, Setconsolecursorinfo, Readconsoleoutputcharactera, Writeconsoleoutputcharactera),

Legend Name Description
HANDLE winapicreateconsolescreenbuffer (
  _In_         dword dwdesiredaccess,
  _In_        DWORD  dwShareMode,
  _In_opt_    const security_attributes *lpsecurityattributes,
   _in_        dword dwflags,
  _Reserved_   Lpvoidlpscreenbufferdata
);
Create console display buffer
dwdesiredaccess, console buffering security and access, desirable value:
generic _read (0x80000000l), Read permissions
Generic_write (0x40000000l), write permissions
dwsharemode, shared mode, desirable value:
Span style= "Font-size:xx-small;" >file_share_read, read share
File_share_write, write share
lpsecurityattributes, security properties, NULL
dwflags, buffer type, Optional: console_textmode_buffer, console text-mode buffering
lpscreenbufferdata, reserved, NULL
BOOL Winapisetconsoleactivescreenbuffer (
_in_ HANDLE Hconsoleoutput
);
Setting Console activity display buffering
Hconsoleoutput, console output device handle
BOOL Winapisetconsolecursorinfo (
_in_ HANDLE Hconsoleoutput,
_in_ Const Console_cursor_info *lpconsolecursorinfo
);
Setting Console cursor Information
Hconsoleoutput, console output device handle
Lpconsolecursorinfo, cursor information (size, visibility)
BOOL winapireadconsoleoutputcharactera (
  _In_  HANDLE  Hconsoleoutput,
  _out_ lptstr lpcharacter,
  _in_  dword nlength ,
  _in_  coord dwreadcoord,
  _out_ lpdwordlpnumbersofcharsread
);
read console output to character array
hconsoleoutput, console output device handle
Lpcharacter, saved character array pointer
Nlength, read length Dwreadcoord , read start coordinate lpnumbersofcharsread, actual read length
BOOL Winapiwriteconsoleoutputcharactera (
_in_ HANDLE Hconsoleoutput,
_in_ LPTSTR Lpcharacter,
_in_ DWORD Nlength,
_in_ COORD Dwwritecoord,
_out_ Lpdwordlpnumberofcharswritten
);
Writes a character array to the console output
Hconsoleoutput, console output device handle
Lpcharacter, writing a character array pointer
Nlength, write length Dwwritecoord, write start coordinate lpnumberofcharswritten, actual write length

The CONSOLE_CURSOR_INFO structure is used in the function arguments:

Legend Name Description
dwsize
DWORD dwsize;
The cursor size, in the range 1 to 100 to take the value.
Bvisible
BOOL bvisible;
Visibility, desirable value:
false,0, not visible; true,1, visible.

Example code:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546 #include <stdio.h>#include <Windows.h>int main(){    //获取默认标准显示缓冲区句柄    HANDLE hOutput;    COORD coord={0,0};    hOutput=GetStdHandle(STD_OUTPUT_HANDLE);     //创建新的缓冲区    HANDLE hOutBuf = CreateConsoleScreenBuffer(        GENERIC_READ | GENERIC_WRITE,         FILE_SHARE_READ | FILE_SHARE_WRITE,         NULL,         CONSOLE_TEXTMODE_BUFFER,         NULL    );    //设置新的缓冲区为活动显示缓冲    SetConsoleActiveScreenBuffer(hOutBuf);    //隐藏两个缓冲区的光标    CONSOLE_CURSOR_INFO cci;    cci.bVisible=0;    cci.dwSize=1;    SetConsoleCursorInfo(hOutput, &cci);    SetConsoleCursorInfo(hOutBuf, &cci);    //双缓冲处理显示    DWORD bytes=0;    char data[800];    while (1)    {        for (char c=‘a‘; c<‘z‘; c++)        {            system("cls");            for (int i=0; i<800; i++)            {                printf("%c",c);            }            ReadConsoleOutputCharacterA(hOutput, data, 800, coord, &bytes);            WriteConsoleOutputCharacterA(hOutBuf, data, 800, coord, &bytes);        }    }    return 0;}

Dual Buffer Solution Console Application Output "splash screen" (c/c++,windows)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.