彻底解决了现有组件刷新时画面闪烁的问题

This commit is contained in:
梦凌汐 2024-12-11 21:18:25 +08:00
parent b952c340d3
commit c95bb4eb3d
7 changed files with 54 additions and 38 deletions

View File

@ -4,6 +4,7 @@
class BaseComponent { class BaseComponent {
protected: protected:
int top, left, width, height; int top, left, width, height;
bool focused;
public: public:
BaseComponent(int top, int left, int width, int height) : top(top), left(left), width(width), height(height) {}; BaseComponent(int top, int left, int width, int height) : top(top), left(left), width(width), height(height) {};
@ -35,6 +36,10 @@ public:
return height; return height;
} }
void setFocused(bool focused) {
this->focused = focused;
}
void setPosition(int top, int left) { void setPosition(int top, int left) {
this->top = top; this->top = top;
this->left = left; this->left = left;

View File

@ -9,6 +9,7 @@
class Rect : public BaseComponent { class Rect : public BaseComponent {
private: private:
RichText title_;
MColor color_ = COLOR_WHITE; MColor color_ = COLOR_WHITE;
public: public:
@ -38,20 +39,34 @@ public:
putchar('|'); putchar('|');
} }
} }
for(int i = 0; i < width && left + i < csbi.dwSize.X; i++) { if(top >= 0) {
if(top >= 0) { for(int i = 0; i < width && left + i < csbi.dwSize.X; i++) {
if(i > 1 && i < strlen(title_.plainText().c_str()) + 2) continue;
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top - 1)}); SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top - 1)});
putchar('-'); putchar('-');
} }
if(top + height - 1 < csbi.dwSize.Y) { }
if(top + height - 1 < csbi.dwSize.Y) {
for(int i = 0; i < width && left + i < csbi.dwSize.X; i++) {
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top + height - 2)}); SetConsoleCursorPosition(hConsole, {static_cast<short>(left + i - 1), static_cast<short>(top + height - 2)});
putchar('-'); putchar('-');
} }
} }
//绘制标题
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + 1), static_cast<short>(top - 1)});
for(auto part : title_.getParts()) {
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(getBackColor(part.color)) | FrontColorToWinColor(getFrontColor(part.color)));
printf("%s", part.text.c_str());
}
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(COLOR_BLACK) | FrontColorToWinColor(COLOR_WHITE)); SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(COLOR_BLACK) | FrontColorToWinColor(COLOR_WHITE));
} }
void setTitle(const RichText title) {
title_ = title;
}
void onKeyPress(int key) override { void onKeyPress(int key) override {
//不处理按键 //不处理按键
} }

View File

@ -3,7 +3,7 @@
#include "BaseComponent.h" #include "BaseComponent.h"
#include <windows.h> #include <windows.h>
#include <vector> #include "../mystl/my_vector.h"
#include <conio.h> #include <conio.h>
#include "../utils/RichText.h" #include "../utils/RichText.h"
@ -11,7 +11,7 @@ class Text : public BaseComponent {
private: private:
RichText text_; RichText text_;
int viewLeft_ = 0, viewTop_ = 0; int viewLeft_ = 0, viewTop_ = 0;
std::vector<RichText> lines_; MyVector<RichText> lines_;
int maxLineWidth_ = 0; int maxLineWidth_ = 0;
public: public:

Binary file not shown.

View File

@ -3,7 +3,6 @@
#include "BaseComponent.h" #include "BaseComponent.h"
#include <windows.h> #include <windows.h>
#include <vector>
#include <conio.h> #include <conio.h>
#include "../utils/RichText.h" #include "../utils/RichText.h"
#include "Rect.h" #include "Rect.h"
@ -12,7 +11,6 @@
class TextArea : public BaseComponent { class TextArea : public BaseComponent {
private: private:
Text text_ = Text(0, 0, 0, 0); Text text_ = Text(0, 0, 0, 0);
RichText title_;
Rect border_ = Rect(0, 0, 0, 0); Rect border_ = Rect(0, 0, 0, 0);
public: public:
@ -36,13 +34,6 @@ public:
CONSOLE_SCREEN_BUFFER_INFO csbi; CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi); GetConsoleScreenBufferInfo(hConsole, &csbi);
//绘制标题
SetConsoleCursorPosition(hConsole, {static_cast<short>(left + 1), static_cast<short>(top - 1)});
for(auto part : title_.getParts()) {
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(getBackColor(part.color)) | FrontColorToWinColor(getFrontColor(part.color)));
printf("%s", part.text.c_str());
}
text_.draw(); text_.draw();
SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(COLOR_BLACK) | FrontColorToWinColor(COLOR_WHITE)); SetConsoleTextAttribute(hConsole, BackgroundColorToWinColor(COLOR_BLACK) | FrontColorToWinColor(COLOR_WHITE));
@ -81,7 +72,7 @@ public:
} }
void setTitle(const RichText& newTitle) { void setTitle(const RichText& newTitle) {
this->title_ = newTitle; border_.setTitle(newTitle);
} }
}; };

View File

@ -18,27 +18,28 @@ int main() {
TextArea textArea(3, 3, 64, 7, richText); TextArea textArea(3, 3, 64, 7, richText);
// 创建后台缓冲区 // // 创建后台缓冲区
HANDLE hBackBuffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); // HANDLE hBackBuffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// 清空后台缓冲区 // // 清空后台缓冲区
CONSOLE_SCREEN_BUFFER_INFO csbi; // CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hConsole, &csbi); // GetConsoleScreenBufferInfo(hConsole, &csbi);
DWORD dwBytesWritten; // DWORD dwBytesWritten;
FillConsoleOutputCharacter(hBackBuffer, ' ', csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten); // FillConsoleOutputCharacter(hBackBuffer, ' ', csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten);
FillConsoleOutputAttribute(hBackBuffer, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten); // FillConsoleOutputAttribute(hBackBuffer, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten);
CONSOLE_CURSOR_INFO cci; // CONSOLE_CURSOR_INFO cci;
cci.bVisible = false; // cci.bVisible = false;
cci.dwSize = 1; // cci.dwSize = 1;
SetConsoleCursorInfo(hBackBuffer, &cci); // SetConsoleCursorInfo(hBackBuffer, &cci);
SetConsoleCursorInfo(hConsole, &cci); // SetConsoleCursorInfo(hConsole, &cci);
textArea.setTitle(RichText("TextArea Demo", COLOR_RED)); textArea.setTitle(RichText("TextArea Demo", COLOR_RED));
textArea.draw(); textArea.draw();
while(true) { while(true) {
if (_kbhit()) {SetConsoleActiveScreenBuffer(hBackBuffer); if (_kbhit()) {
// SetConsoleActiveScreenBuffer(hBackBuffer);
char opt = _getch(); char opt = _getch();
textArea.setText(richText + StringPart("Last Key: " + std::to_string(opt), COLOR_CYAN)); textArea.setText(richText + StringPart("Last Key: " + std::to_string(opt), COLOR_CYAN));
switch(opt) { switch(opt) {
@ -55,22 +56,22 @@ int main() {
textArea.moveRight(); textArea.moveRight();
break; break;
case 'q': case 'q':
SetConsoleActiveScreenBuffer(hConsole); // SetConsoleActiveScreenBuffer(hConsole);
CloseHandle(hBackBuffer); // CloseHandle(hBackBuffer);
return 0; return 0;
} }
// 清空后台缓冲区 // // 清空后台缓冲区
FillConsoleOutputCharacter(hBackBuffer, ' ', csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten); // FillConsoleOutputCharacter(hBackBuffer, ' ', csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten);
FillConsoleOutputAttribute(hBackBuffer, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten); // FillConsoleOutputAttribute(hBackBuffer, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, {0, 0}, &dwBytesWritten);
// 在后台缓冲区中绘制 // // 在后台缓冲区中绘制
textArea.draw(); textArea.draw();
// 切换到后台缓冲区,显示绘制的内容 // // 切换到后台缓冲区,显示绘制的内容
SetConsoleActiveScreenBuffer(hConsole); // SetConsoleActiveScreenBuffer(hConsole);
} }
Sleep(1); Sleep(1);
} }

4
utils/InputManager.h Normal file
View File

@ -0,0 +1,4 @@
#ifndef INPUTMANAGER_H
#define INPUTMANAGER_H
#endif