我需要一種方法,可以像系統顏色一樣不使用系統調用。我知道這裏有setConsoleTextAttribute(),但是它並沒有用全新的字符填充整個前景和背景。我使用的windows7雖然我很想做所有的Windows替換爲系統(「顏色」)
回答
根據您的評論此兼容,這裏是你正在試圖解決的問題更完整的解決方案。它基於我的原始答案(可以在答案的最後找到答案)。
我在Windows API發現了一個限制,即它不能由300行讀取80列的默認控制檯模式窗口,整個屏幕緩衝區。由於Windows進程堆不足,導致ERROR_NOT_ENOUGH_MEMORY錯誤(我從某些Google搜索中可以看出最好)。我最終實現了XxxConsoleOutput函數的包裝,以支持根據需要自動細分屏幕緩衝區,直到函數成功或未能讀取1 X 1(單字符)區域。
同樣,這段代碼很可能不是完美的,它的目的是解釋概念,而不是(必然)爲您提供一個完整的解決方案。但是,它現在填充了整個控制檯(以前我只填充了窗口的可見部分)並設置了控制檯的文本屬性以供將來輸出。
跳過該代碼閱讀原答覆。
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <iostream>
#include <vector>
using namespace std;
// Split a rectangular region into two smaller rectangles
// based on the largest dimension.
void SplitRegion(
SHORT width, SHORT height,
COORD dwBufferCoord, const SMALL_RECT& readRegion,
COORD& dwBufferCoordA, SMALL_RECT& readRegionA,
COORD& dwBufferCoordB, SMALL_RECT& readRegionB)
{
dwBufferCoordA = dwBufferCoordB = dwBufferCoord;
readRegionA = readRegionB = readRegion;
if (height >= width)
{
SHORT half = height/2;
dwBufferCoordB.Y += half;
readRegionB.Top += half;
readRegionA.Bottom = readRegionB.Top - 1;
}
else
{
SHORT half = width/2;
dwBufferCoordB.X += half;
readRegionB.Left += half;
readRegionA.Right = readRegionB.Left - 1;
}
}
// Utility function to figure out the distance
// between two points.
template <typename type>
inline type DiffHelper(type first, type second)
{
return (second >= first) ? (second - first + 1) : 0;
}
// A template that wraps up the shared code common between
// reading and writing the screen buffer. If it is ever
// given a region of zero width or height, it will
// "succeed". If it ever tries to subdivide a 1 by 1
// region, it will fail.
template <typename lpBufferType>
BOOL XferConsoleOutputWrapper(
HANDLE hConsoleOutput,
lpBufferType lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
SMALL_RECT& xferRegion,
BOOL (WINAPI * xferConsoleOutput)(
HANDLE, lpBufferType, COORD, COORD, PSMALL_RECT))
{
SHORT width = DiffHelper(xferRegion.Left, xferRegion.Right);
SHORT height = DiffHelper(xferRegion.Top, xferRegion.Bottom);
if ((width == 0) || (height == 0))
{
return TRUE;
}
BOOL success = xferConsoleOutput(hConsoleOutput,
lpBuffer, dwBufferSize, dwBufferCoord, &xferRegion);
if (!success)
{
if ((GetLastError() == ERROR_NOT_ENOUGH_MEMORY) &&
((width * height) > 1))
{
COORD dwBufferCoordA, dwBufferCoordB;
SMALL_RECT xferRegionA, xferRegionB;
SplitRegion(
width, height,
dwBufferCoord, xferRegion,
dwBufferCoordA, xferRegionA,
dwBufferCoordB, xferRegionB);
success =
XferConsoleOutputWrapper(hConsoleOutput, lpBuffer, dwBufferSize,
dwBufferCoordA, xferRegionA, xferConsoleOutput) &&
XferConsoleOutputWrapper(hConsoleOutput, lpBuffer, dwBufferSize,
dwBufferCoordB, xferRegionB, xferConsoleOutput);
}
}
return success;
}
// ReadConsoleOutput failed to read an 80 by 300 character screen
// buffer in a single call, resulting in ERROR_NOT_ENOUGH_MEMORY.
// ReadConsoleOutputWrapper will subdivide the operation into
// smaller and smaller chunks as needed until it succeeds in reading
// the entire screen buffer.
inline BOOL ReadConsoleOutputWrapper(
HANDLE hConsoleOutput,
PCHAR_INFO lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
SMALL_RECT& readRegion)
{
return XferConsoleOutputWrapper(hConsoleOutput, lpBuffer, dwBufferSize,
dwBufferCoord, readRegion, ReadConsoleOutput);
}
// WriteConsoleOutputWrapper will subdivide the operation into
// smaller and smaller chunks as needed until it succeeds in writing
// the entire screen buffer. This may not be necessary as
// WriteConsoleOutput never failed, but it was simple to implement
// so it was done just to be safe.
inline BOOL WriteConsoleOutputWrapper(
HANDLE hConsoleOutput,
const CHAR_INFO* lpBuffer,
COORD dwBufferSize,
COORD dwBufferCoord,
SMALL_RECT& writeRegion)
{
return XferConsoleOutputWrapper(hConsoleOutput, lpBuffer, dwBufferSize,
dwBufferCoord, writeRegion, WriteConsoleOutput);
}
void ConsoleFillWithAttribute(WORD fillAttribute)
{
// Get the handle to the output
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Get the information for the current screen buffer
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(hStdout, &info);
// Allocate a vector to hold the visible screen buffer data
vector<CHAR_INFO> buffer(info.dwSize.X * info.dwSize.Y);
// Initialize a couple of pointers to the begin and end of the buffer
CHAR_INFO* begin = buffer.data();
CHAR_INFO* end = begin + buffer.size();
// Start at the upper left corner of the screen buffer.
COORD coord;
coord.X = coord.Y = 0;
// Initialize the region to encompass the entire screen buffer.
SMALL_RECT region;
region.Left = region.Top = 0;
region.Right = info.dwSize.X - 1;
region.Bottom = info.dwSize.Y - 1;
// Read the buffer from the console into the CHAR_INFO vector.
ReadConsoleOutputWrapper(hStdout, buffer.data(), info.dwSize, coord, region);
// Change all the attributes to the specified fill attribute.
while (begin != end)
{
begin->Attributes = fillAttribute;
++begin;
}
// Write the buffer from the CHAR_INFO vector back to the console.
WriteConsoleOutputWrapper(hStdout, buffer.data(), info.dwSize, coord, region);
// Finally, set the console text attribute to the fill attribute
// so that all new text will be printed in the same manner as
// the attributes we just changed.
SetConsoleTextAttribute(hStdout, fillAttribute);
}
int main()
{
cout << "I would like to fill up the console with some text." << endl;
cout << "The quick brown fox jumped over the lazy dogs." << endl;
for (int i = 0; i < 100; ++i)
{
cout << ' ' << i;
}
cout << endl;
ConsoleFillWithAttribute(
BACKGROUND_BLUE | FOREGROUND_INTENSITY |
FOREGROUND_RED | FOREGROUND_GREEN);
cout << endl;
cout << "This should also be printed in the new attribute" << endl;
return 0;
}
原來答案是如下:
如果我明白你問什麼,你希望能夠改變的屬性整個控制檯模式窗口。您可能需要查看ReadConsoleOutput
和WriteConsoleOutput
函數。您可以使用ReadConsoleOutput
將部分或全部控制檯緩衝區讀入內存,然後根據需要爲應用程序操作屬性數據,然後使用WriteConsoleOutput
將內存寫回控制檯輸出緩衝區。
下面是一些代碼,這將改變屬性爲控制檯的當前顯示部分(假設輸出沒有被重定向到一個非控制檯手柄):
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <iostream>
#include <vector>
using namespace std;
void ConsoleFillDisplayWithAttribute(WORD fillAttribute)
{
// Get the handle to the output
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Get the information for the current screen buffer
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(hStdout, &info);
// Calculate the size of the displayed portion of the screen buffer
COORD size;
size.X = (info.srWindow.Right - info.srWindow.Left + 1);
size.Y = (info.srWindow.Bottom - info.srWindow.Top + 1);
// Allocate a vector to hold the visible screen buffer data
vector<CHAR_INFO> buffer(size.X * size.Y);
COORD coord;
coord.X = coord.Y = 0;
// Read the buffer from the console into the CHAR_INFO vector
ReadConsoleOutput(hStdout, buffer.data(), size, coord, &info.srWindow);
// Initialize a couple of pointers to the begin and end of the buffer
CHAR_INFO* begin = buffer.data();
CHAR_INFO* end = begin + buffer.size();
// Change all the attributes to the specified fill attribute
while (begin != end)
{
begin->Attributes = fillAttribute;
++begin;
}
// Write the buffer from the CHAR_INFO vector back to the console
WriteConsoleOutput(hStdout, buffer.data(), size, coord, &info.srWindow);
}
int main()
{
cout << "I would like to fill up the console with some text." << endl;
cout << "The quick brown fox jumped over the lazy dogs." << endl;
for (int i = 0; i < 100; ++i)
{
cout << ' ' << i;
}
cout << endl;
ConsoleFillDisplayWithAttribute(
BACKGROUND_BLUE | FOREGROUND_INTENSITY |
FOREGROUND_RED | FOREGROUND_GREEN);
return 0;
}
does not work以及系統不是所有的文字都轉換,並不是所有的未來的文字都是在正確的顏色 –
嗯,這並不意味着作爲替代品的下降。這是爲了說明你如何完成你的任務。添加一行代碼和修改兩行代碼可能會爲您提供確切的解決方案,但我並未嘗試爲您編寫代碼。 – CasaDeRobison
哦生病嘗試來調整其輸出從系統(暫停)的文本和其他來源的犯規出現右 –
- 1. 系統顏色 - WPF
- 2. 顏色android系統
- 3. 替換windows背景中的系統顏色
- 4. GD顏色替換
- 5. 替換顏色C#
- 6. PatchCollection的Matplotlib顏色條替換顏色
- 7. Qt:如何設置QPushButton的背景顏色爲系統顏色?
- 8. Android系統顏色常量
- 9. iOS 11.x系統顏色
- 10. 刪除系統顏色TcxDBColorCombobox
- 11. WPF系統主題顏色
- 12. 替換系統庫
- 13. 使用javascript將css系統顏色轉換爲十六進制?
- 14. 匹配windows系統顏色:淺色
- 15. 警告的「系統」顏色(紅色)
- 16. 將顏色代碼替換爲顏色名稱的腳本?
- 17. jQuery全局顏色替換
- 18. 用rmagick替換顏色
- 19. 用RabbitMQ替換MSMQ系統
- 20. L系統:替換順序
- 21. PHP替換路線系統
- 22. Imagick將SVG轉換爲PNG - 將顏色替換爲黑色和白色
- 23. 系統顏色中的微件背景顏色?
- 24. 更改系統托盤顏色
- 25. 寫在android系統與背景顏色
- 26. 獲取系統顯示顏色設置
- 27. 系統顏色列表屬性
- 28. 安裝系統顏色以一個LinearGradientBrush
- 29. aspNetDisabled類默認系統顏色
- 30. 創建您自己的系統顏色
是的,如果你想改變屬性你必須「重繪」角色。 –