- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
尝试使用 SetConsoleScreenBufferSize
但失败并显示“句柄无效”。在最后一个错误。将发布所有代码,但这里有一些要点:
使用它来调整缓冲区大小:
int TGHandleResizeEvent(struct TGHandle *tgHandle, INPUT_RECORD record) {
if (record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
WINDOW_BUFFER_SIZE_RECORD size = record.Event.WindowBufferSizeEvent;
sizeTGDrawBuffer(&tgHandle->drawBuffer, size.dwSize.X, size.dwSize.Y);
clearTGDrawBuffer(&tgHandle->drawBuffer);
COORD bufferNewSize = {
size.dwSize.X,
size.dwSize.Y
};
return SetConsoleScreenBufferSize(&tgHandle->screenBufferHandle, bufferNewSize);
}
}
使用它来分配句柄:
struct TGHandle TG() {
struct TGHandle tgHandle;
tgHandle.screenBufferHandle = CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CONSOLE_TEXTMODE_BUFFER,
NULL
);
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(tgHandle.screenBufferHandle, &info);
tgHandle.drawBuffer = createTGDrawBuffer(info.dwSize.X, info.dwSize.Y);
// Create the input buffer
tgHandle.inputBufferSize = 32;
tgHandle.inputBuffer = malloc(sizeof(INPUT_RECORD) * tgHandle.inputBufferSize);
// Hook up the input handle
tgHandle.inputHandle = GetStdHandle(STD_INPUT_HANDLE);
return tgHandle;
}
这里是完整的代码。
#ifndef TG_H
#define TG_H
#include <Windows.h>
#include <memory.h>
#define FOREGROUND_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
#define BACKGROUND_WHITE BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
// A drawing buffer, for general purposes
struct TGDrawBuffer {
COORD size;
CHAR_INFO *buffer;
};
struct TGDrawBuffer createTGDrawBuffer(int, int); // Function to allocate a drawing buffer
void sizeTGDrawBuffer(struct TGDrawBuffer*, int, int); // Resize a draw buffer
void clearTGDrawBuffer(struct TGDrawBuffer*); // Fill a buffer with blank cells
void TGDrawPixel(struct TGDrawBuffer*, int, int, CHAR_INFO); // Draw to a single cell on the buffer
void TGDrawAttribute(struct TGDrawBuffer*, int, int, int); // Modify a single attribute. X, Y, Attr
void TGDrawCharInfoString(struct TGDrawBuffer*, int, int, CHAR_INFO*, int); // X, Y, string, int. Draws to max X
CHAR_INFO* TGCharToCharInfo(char*, int); // Convert basic characters to CHAR_INFO. String, length.
void TGDrawString(struct TGDrawBuffer*, int, int, char*, int); // X, Y, string, length. Draws to max X
void freeTGDrawBuffer(struct TGDrawBuffer*); // Function to de-allocate a drawing buffer
int CharInfoStrlen(CHAR_INFO*); // Get length of a CHAR_INFO as if it were a string
// Essentially a drawing context to the screen
struct TGHandle {
HANDLE screenBufferHandle, inputHandle;
struct TGDrawBuffer drawBuffer;
INPUT_RECORD *inputBuffer;
int inputBufferSize;
};
struct TGHandle TG(); // Initialization function, which returns a drawing context to the screen
void useTGHandle(struct TGHandle*); // Make a screen drawing context active
void updateTGHandle(struct TGHandle*); // Displays what has been drawn
void setTGHandleCursorVisibility(struct TGHandle*, int); // True / False
int getTGInput(struct TGHandle*, INPUT_RECORD*, int); // Fill input into a buffer
int getTGNextInput(struct TGHandle*, INPUT_RECORD*); // Get a single INPUT_RECORD or return false
int TGHandleResizeEvent(struct TGHandle*, INPUT_RECORD); // Resize is not handled automatically
#endif
#include "tg.h"
#include <string.h>
struct TGDrawBuffer createTGDrawBuffer(int width, int height) {
struct TGDrawBuffer tgDrawBuffer;
tgDrawBuffer.buffer = NULL; // Init the buffer to NULL
sizeTGDrawBuffer(&tgDrawBuffer, width, height);
return tgDrawBuffer;
}
void sizeTGDrawBuffer(struct TGDrawBuffer* drawBuffer, int width, int height) {
// Using free/ malloc here because we aren't interested in retaining data
if (drawBuffer->buffer) {
free(drawBuffer->buffer);
}
drawBuffer->buffer = malloc(sizeof(CHAR_INFO) * (width * height));
// Copy the size to the buffer record
drawBuffer->size.X = width;
drawBuffer->size.Y = height;
}
void clearTGDrawBuffer(struct TGDrawBuffer *tgBuffer) {
int i = 0, limit = tgBuffer->size.X * tgBuffer->size.Y;
// Create a blank CHAR_INFO
CHAR_INFO clearChar;
clearChar.Char.AsciiChar = ' ';
clearChar.Char.UnicodeChar = ' ';
clearChar.Attributes = FOREGROUND_WHITE; // Would be confusing without this
// Set everything to that buffer
while (i < limit) {
tgBuffer->buffer[i] = clearChar;
i++;
}
}
void TGDrawPixel(struct TGDrawBuffer *tgBuffer, int x, int y, CHAR_INFO character) {
tgBuffer->buffer[(tgBuffer->size.X * y) + x] = character;
}
void TGDrawAttribute(struct TGDrawBuffer *tgBuffer, int x, int y, int attr) {
tgBuffer->buffer[(tgBuffer->size.X * y) + x].Attributes = attr;
}
void TGDrawCharInfoString(struct TGDrawBuffer *tgDrawBuffer, int x, int y, CHAR_INFO *string, int length) {
int charsToWrite = length;
int distanceToEnd = (tgDrawBuffer->size.Y - 1) - y;
if (distanceToEnd < charsToWrite)
distanceToEnd = charsToWrite;
int startPos = x + (tgDrawBuffer->size.X * y);
int i = 0;
while (i < distanceToEnd) {
tgDrawBuffer->buffer[startPos + x] = string[i];
i++;
}
}
CHAR_INFO* TGCharToCharInfo(char* string, int length) {
if (length == -1)
length = strlen(string);
// TODO
}
void TGDrawString(struct TGDrawBuffer *tgDrawBuffer, int x, int y, char *string, int length) {
int charsToWrite = length;
int distanceToEnd = (tgDrawBuffer->size.Y - 1) - y;
if (distanceToEnd < charsToWrite)
charsToWrite = distanceToEnd;
int startPos = x + (tgDrawBuffer->size.X * y);
int i = 0;
while (i < charsToWrite) {
tgDrawBuffer->buffer[startPos + i].Char.AsciiChar = string[i];
tgDrawBuffer->buffer[startPos + i].Char.UnicodeChar = string[i];
i++;
}
}
void freeTGDrawBuffer(struct TGDrawBuffer *drawBuffer) {
free(drawBuffer->buffer);
}
struct TGHandle TG() {
struct TGHandle tgHandle;
tgHandle.screenBufferHandle = CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CONSOLE_TEXTMODE_BUFFER,
NULL
);
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(tgHandle.screenBufferHandle, &info);
tgHandle.drawBuffer = createTGDrawBuffer(info.dwSize.X, info.dwSize.Y);
// Create the input buffer
tgHandle.inputBufferSize = 32;
tgHandle.inputBuffer = malloc(sizeof(INPUT_RECORD) * tgHandle.inputBufferSize);
// Hook up the input handle
tgHandle.inputHandle = GetStdHandle(STD_INPUT_HANDLE);
return tgHandle;
}
void useTGHandle(struct TGHandle *tgHandle) {
SetConsoleActiveScreenBuffer(tgHandle->screenBufferHandle);
// Update the buffer sizes
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(tgHandle->screenBufferHandle, &info);
sizeTGDrawBuffer(&tgHandle->drawBuffer, info.dwSize.X, info.dwSize.Y);
clearTGDrawBuffer(&tgHandle->drawBuffer);
}
void updateTGHandle(struct TGHandle *tgHandle) {
COORD size = { tgHandle->drawBuffer.size.X, tgHandle->drawBuffer.size.Y }; // Buffer size
COORD pos = { 0, 0 }; // Start of the buffer coord
SMALL_RECT rect = {
.Left = 0,
.Top = 0,
.Right = size.X - 1,
.Bottom = size.Y - 1
}; // Rect to draw to on destination
WriteConsoleOutput(
tgHandle->screenBufferHandle,
tgHandle->drawBuffer.buffer,
size,
pos,
&rect
);
}
void setTGHandleCursorVisibility(struct TGHandle *tgHandle, int visible) {
// Copy the already-available cursor info
CONSOLE_CURSOR_INFO info;
GetConsoleCursorInfo(tgHandle->screenBufferHandle, &info);
// Modify the cursor visibility
info.bVisible = visible;
SetConsoleCursorInfo(tgHandle->screenBufferHandle, &info);
}
// You should be able to use a TGHandle's input buffer rather than creating your own
// for maximum memory conservation
int getTGInput(struct TGHandle *tgHandle, INPUT_RECORD *inputBuffer, int max) {
int availableRecords;
GetNumberOfConsoleInputEvents(tgHandle->inputHandle, &availableRecords);
int amountToRead = max;
if (availableRecords < max) {
amountToRead = availableRecords;
}
int numberRead;
ReadConsoleInput(
tgHandle->inputHandle,
inputBuffer,
amountToRead,
&numberRead
);
return numberRead;
}
// This function should be pretty performant if someone would not like to use
// the above function and mess around with buffers.
// Input record info: https://learn.microsoft.com/en-us/windows/console/input-record-str
int getTGNextInput(struct TGHandle *tgHandle, INPUT_RECORD *record) {
int availableRecords;
GetNumberOfConsoleInputEvents(tgHandle->inputHandle, &availableRecords);
if (availableRecords == 0) {
return 0;
}
ReadConsoleInput(
tgHandle->inputHandle,
tgHandle->inputBuffer,
1,
&availableRecords
);
*record = tgHandle->inputBuffer[0];
return 1;
}
int TGHandleResizeEvent(struct TGHandle *tgHandle, INPUT_RECORD record) {
if (record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
WINDOW_BUFFER_SIZE_RECORD size = record.Event.WindowBufferSizeEvent;
sizeTGDrawBuffer(&tgHandle->drawBuffer, size.dwSize.X, size.dwSize.Y);
clearTGDrawBuffer(&tgHandle->drawBuffer);
COORD bufferNewSize = {
size.dwSize.X,
size.dwSize.Y
};
return SetConsoleScreenBufferSize(&tgHandle->screenBufferHandle, bufferNewSize);
}
}
#include "tg.h"
#include <time.h>
#include <stdio.h>
void getMessageAsStr(char *buf) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0,
buf, 256, NULL);
}
int main() {
// Error buffer
char buf[256];
// Create a drawing context to the screen
struct TGHandle context = TG();
useTGHandle(&context);
setTGHandleCursorVisibility(&context, 0); // Hide the cursor of course
struct TGDrawBuffer *buffer = &context.drawBuffer;
// Create a CHAR_INFO to draw with
CHAR_INFO info;
info.Attributes = BACKGROUND_BLUE | FOREGROUND_WHITE;
info.Char.AsciiChar = ' ';
info.Char.UnicodeChar = ' ';
INPUT_RECORD input;
const int STRING_BUF_SIZE = 64;
char *fpsCountBuffer = malloc(sizeof(char) * STRING_BUF_SIZE);
long start, end;
start = QueryPerformanceCounter(&start);
int running = 1;
while (running) {
// Start off with a nice clean slate
//clearTGDrawBuffer(buffer);
// Collect input to react to resize
while (getTGNextInput(&context, &input)) {
if (input.EventType == WINDOW_BUFFER_SIZE_EVENT) {
if (!TGHandleResizeEvent(&context, input)) {
OutputDebugString("Couldn't resize:\n");
getMessageAsStr(buf);
OutputDebugString(buf);
}
}
}
// Draw line along top and bottom
int i = 0;
while (i < buffer->size.X) {
TGDrawPixel(buffer, i, 0, info);
TGDrawPixel(buffer, i, buffer->size.Y - 1, info);
i++;
}
i = 0;
// Draw vertical lines
while (i < buffer->size.Y) {
TGDrawPixel(buffer, 0, i, info);
TGDrawPixel(buffer, buffer->size.X - 1, i, info);
i++;
}
// FPS count!
// Get time elapsed in millis
QueryPerformanceCounter(&end);
long fps = 1000000 / (end - start);
// Put it into the screen buffer
snprintf(fpsCountBuffer, STRING_BUF_SIZE, "Running at %ldhz, %dx%d", fps, buffer->size.X, buffer->size.Y);
TGDrawString(buffer, 1, 1, fpsCountBuffer, strlen(fpsCountBuffer));
start = end;
updateTGHandle(&context);
}
}
最佳答案
一发帖就发现了。您可以看到我正在获取 TGHandleResizeEvent
中句柄的指针 location:
return SetConsoleScreenBufferSize(&tgHandle->screenBufferHandle, bufferNewSize);
事实上,这是一个无效句柄。更正后的代码:
return SetConsoleScreenBufferSize(tgHandle->screenBufferHandle, bufferNewSize);
关于c - 句柄无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55464847/
我有一个接受以下参数的函数: int setvalue(void (*)(void *)); 为了满足参数:void (*)(void *),我创建了这样一个函数: static void *
我有以下代码: typedef void VOID; int f(void); int g(VOID); 在 C 中编译得很好(在 Fedora 10 上使用 gcc 4.3.2)。与 C++ 编译的
这个问题已经有答案了: Is f(void) deprecated in modern C and C++? [duplicate] (6 个回答) 已关闭 7 年前。 B.A.T.M.A.N./A.
我在 ASP.NET Core 3.1 项目上有以下 Identity Server 4 配置: services .AddIdentityServer(y => { y.Events.R
我们有一个 O365 租户,一切都是开箱即用的。租户放置在德国云中,而不是全局 (office.de) 中。我们还开发了一个 Office 插件,使用 OAuth 2.0 授权访问共享点。首先,我们向
我有一个如下所示的路由 routes.MapRoute( name: "Default", url: "{controller}/{action}/{i
我正在尝试使用 OAuth2.0 访问 google 文档。我已经从 Google API 控制台获取了客户端 ID 和 key 。但是当我运行这段代码时,我收到了异常。如果我遗漏了什么,有人可以建议
此代码有效: let mut b: Vec = Vec::with_capacity(a.len()); for val in a.iter() { b.push(val); } 此代码不起作
使用 client_credintials 授权类型请求 EWS oauth2 v2.0 的访问 token 时出现错误。 https://login.microsoftonline.com/tena
我通过 Java 应用程序使用 Google 电子表格时遇到了问题。我创建了应用程序,该应用程序运行了 1 年多,没有任何问题,我什至在 Create Spreadsheet using Google
如何创建 匹配所有无效 Base64 字符的正则表达式?我在堆栈上找到了 [^a-zA-Z0-9+/=\n\r].*$ 但是当我尝试时我得到了带有 - 符号的结果字符串.我根本不知道正则表达式,任何人
我从 Gitlab CI/CD Pipelines 获得错误信息:yaml invalid。问题是由 .gitlab-ci.yml 脚本的第五行引起的: - 'ssh deployer@gita
我有 3 个数据源,设置如下: @Configuration @Component public class DataSourceConfig { @Bean("foo") @Conf
你好,我想用bulkCreate ex 插入数据: [ { "typeId": 5, "devEui": "0094E796CBFCFEF9", "application_name": "Pressu
UIApplicationExitsOnSuspend 不会强制我的应用程序退出。我已经清理过目标、删除了应用程序、重建并重新安装了很多次。 我确实需要退出我的应用程序。 最佳答案 您是否链接了 SD
在 iPhone 配置门户上,显示我的 iPhone 团队配置配置文件无效。有一个“由 Xcode 管理”文本。 “续订”按钮被禁用。 我该如何解决这个问题?谢谢 最佳答案 使用 Xcode 3.2.
好的,所以今天我用我们的“实时”数据库中的新信息更新了我的数据库……从那时起,我的一个表格就出现了问题。如果您需要任何代码,请告诉我,我将对其进行编辑并发布所需的代码... 我有一个报告表格,其中有一
我有一个结构体,其中有一个元素表示为 void (*func)(); 我知道 void 指针通常用于函数指针,但我似乎无法定义该函数。我不断收到取消引用指向不完整类型的指针。我用谷歌搜索了一下但没有结
我正在尝试使用 Coldfusion 9 从 ning 网络获取凭证,所以首先这是测试 api 的 curl 语法: curl -k https://external.ningapis.com/xn/
这个问题已经有答案了: Does C have references? (2 个回答) 已关闭 4 年前。 我正在学习 C 语言引用,这是我的代码: #include int main(void)
我是一名优秀的程序员,十分优秀!