我已经编写了这个小程序来演示WriteConsoleOutput。只要我使用静态数组,一切都可以正常工作。
但是如果我更改CI的声明
来自
CI: array of array of CHAR_INFO;
收件人
CI: array [0 .. 80, 0 .. 25] of CHAR_INFO;
当然要初始化它:
SetLength(Ci, 80, 25);
那我只能在屏幕上弄垃圾了。
uses
Winapi.Windows,
System.Console,
System.Diagnostics,
System.SysUtils;
var
CH: THandle;
// CI: array of array of CHAR_INFO;
CI: array [0 .. 80, 0 .. 25] of CHAR_INFO;
Character, Attribute: Integer;
X, Y: COORD;
z: SMALL_RECT;
i, j: Integer;
StopWatch: TStopwatch;
begin
CH := CreateFile('CONOUT$', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
X.X := high(CI) - low(CI);
X.Y := high(CI[high(CI)]) - low(CI[high(CI)]);
Y.X := 0;
Y.Y := 0;
z.Left := low(CI);
z.Top := low(CI[low(CI)]);
z.Right := high(CI);
z.Bottom := high(CI[low(CI)]);
StopWatch := TStopwatch.StartNew;
for Character := 65 to 65 + 26 - 1 do
for Attribute := 0 to 15 - 1 do
begin
for i := low(CI) to high(CI) do
for j := low(CI[i]) to high(CI[i]) do
begin
CI[i, j].UnicodeChar := Char(Character);
CI[i, j].Attributes := Attribute;
CI[i, j].AsciiChar := AnsiChar(Character);
end;
WriteConsoleOutput(CH, @CI, X, Y, z);
end;
StopWatch.Stop;
Console.Title := StopWatch.ElapsedMilliseconds.ToString;
Console.ReadLine;
end.
Ps。该示例使用 DelphiConsole
更新
有了MBo给出的答案,我将代码更改为以下内容:
uses
Winapi.Windows,
System.Console,
System.Diagnostics,
System.SysUtils;
var
CH: THandle;
CI: array of CHAR_INFO;
Character, Attribute: Integer;
X, Y: COORD;
Z: SMALL_RECT;
i, j: Integer;
StopWatch: TStopwatch;
begin
CH := CreateFile('CONOUT$', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
X.X := 80;
X.Y := 25;
Y.X := 0;
Y.Y := 0;
Z.Left := Y.X;
Z.Top := Y.Y;
Z.Right := X.X;
Z.Bottom := X.Y;
SetLength(CI, X.X * X, Y);
StopWatch := TStopwatch.StartNew;
for Character := 65 to 65 + 26 - 1 do
for Attribute := 0 to 15 - 1 do
begin
for i := 0 to X.X * X.Y do
begin
CI[i].UnicodeChar := Char(Character);
CI[i].Attributes := Attribute;
CI[i].AsciiChar := AnsiChar(Character);
end;
WriteConsoleOutput(CH, CI, X, Y, Z);
end;
StopWatch.Stop;
Console.Title := StopWatch.ElapsedMilliseconds.ToString;
Console.ReadLine;
end.
答案 0 :(得分:3)
静态数组占据连续的内存区域,@CI
参数是数组内容的地址。
但是动态数组已经是指针,因此@CI
是指向数据的指针的地址,而不是数据的地址。要在类似情况下使用一维动态数组,可以使用@A[0]
技巧。
但是,此外-二维动态数组不会占用连续的内存区域,因此您没有机会在此处使用它。
但是您可以将2D数据重新打包为长度为80*25
的1D动态数组,并使用上述语法。 y行和x列的屏幕元素的表达式为CI[y * screenwidth + x]