我有一个Delphi程序,我必须转换为c#。我完成了大部分转换,但遇到了VarArrayCreate的几个挑战。
我所拥有的是:Line:= VarArrayCreate([0,1],varVariant);
我似乎无法找出VarArrayCreate的转换或替代品。 我知道c#中的对象可以用于Variant替换,但上面让我卡住了。
任何帮助都会很棒。
我在下面添加了Delphi代码我对程序“TForm1.Button3Click(Sender:TObject)感兴趣;程序:
unit Unit1;
(*------------------------------------------------------------------------------
DX Atlas Automation demo #2 (early binding)
Make sure that DX Atlas is installed.
Requires DxAtlas_TLB. You can either generate this file in Delphi
(Project -> Import Type Library -> DxAtlas) or use the one included
with this demo.
http://www.dxatlas.com
------------------------------------------------------------------------------*)
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OleServer, StdCtrls, DxAtlas_TLB, ActiveX, AxCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
CheckBox1: TCheckBox;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private declarations }
public
Atlas: IAtlas;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
//------------------------------------------------------------------------------
// Start DX Atlas
//------------------------------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
//connect to Dx Atlas on program startup
try
Atlas := CoAtlas.Create;
except on E: Exception do
begin
ShowMessage('Cannot connect to DX Atlas: ' + E.Message);
Application.Terminate;
end;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
var
WorkArea: TRect;
begin
//get Desktop work area dimensions
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
//form placement
Top := WorkArea.Top;
Left := WorkArea.Left;
Height := WorkArea.Bottom - WorkArea.Top;
//atlas placement
//stop repainting
Atlas.Map.BeginUpdate;
//place window
Atlas.Top := Top;
Atlas.Left := Left + Width;
Atlas.Width := WorkArea.Right - Left - Width;
Atlas.Height := Height;
//hide prefixes
Atlas.Map.PrefixesVisible := false;
//now allow repainting
Atlas.Map.EndUpdate;
//show the Atlas window
Atlas.Visible := true;
end;
//------------------------------------------------------------------------------
// Points
//------------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
Pt, Points: OleVariant;
i: integer;
Layer: ICustomLayer;
begin
Randomize;
//create Variant array for data
Points := VarArrayCreate([0, 999], varVariant);
//fill the array with random points
for i:=0 to 999 do
begin
//each point is a variant array with 2 elements
Pt := VarArrayCreate([0,1], varVariant);
//point coordinates are random (decimal degrees)
Pt[0] := Random(360) - 180; //longitude
Pt[1] := Random(180) - 90; //latitude
//add point to the data array
Points[i] := Pt;
end;
//show data on the map
Atlas.Map.BeginUpdate;
with Atlas.Map do
try
Projection := PRJ_RECTANGULAR;
Dimmed := false;
CustomLayers.Clear;
//add new custom layer
Layer := CustomLayers.Add(LK_POINTS);
with Layer do
begin
//set layer attributes
PenColor := clBlue;
BrushColor := clLime;
PointSize := 2;
//set data
SetData(Points);
end;
finally
EndUpdate;
end;
end;
//------------------------------------------------------------------------------
// Labels
//------------------------------------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
var
//Lb: Variant;
Labels: Variant;
i: integer;
Layer: ICustomLayer;
begin
Randomize;
Labels := VarArrayCreate([0, 999], varVariant);
for i:=0 to 999 do
begin
//each label is a variant array of 3 Variants
Labels[i] := VarArrayOf([Random(360) - 180, //longitude
Random(180) - 90, //latitude
Format(' LABEL #%d ', [i])]); //label text
//alternate way of creating and filling the array
{
Lb := VarArrayCreate([0,2], varVariant);
Lb[0] := Random(360) - 180;
Lb[1] := Random(180) - 90;
Lb[2] := Format(' Label #%d ', [i]);
Labels[i] := Lb;
}
end;
Atlas.Map.BeginUpdate;
with Atlas.Map do
try
Projection := PRJ_RECTANGULAR;
Dimmed := false;
CustomLayers.Clear;
Layer := CustomLayers.Add(LK_LABELS);
with Layer do
begin
LabelsTransparent := CheckBox1.Checked;
//label BG if not transparent
BrushColor := clAqua;
//font attributes
with (Font as IFont) do
begin
Put_Name('Courier New');
Put_Italic(true);
Put_Size(9);
//Put_Name('Small fonts');
//Put_Size(5);
end;
//font color
PenColor := clBlue;
//data
SetData(Labels);
end;
finally
EndUpdate;
end;
end;
//------------------------------------------------------------------------------
// Lines
//------------------------------------------------------------------------------
procedure TForm1.Button3Click(Sender: TObject);
var
Pt, Line, Meridians, Parallels: OleVariant;
i, j: integer;
begin
//generate meridians
Meridians := VarArrayCreate([0, 7], varVariant);
for i:=0 to 7 do
begin
Line := VarArrayCreate([0, 36], varVariant);
for j:=0 to 36 do
begin
Pt := VarArrayCreate([0, 1], varVariant);
Pt[0] := i*45 - 180;
Pt[1] := j*5 - 90;
Line[j] := Pt;
end;
Meridians[i] := Line;
end;
//generate parallels
Parallels := VarArrayCreate([0, 2], varVariant);
for i:=0 to 2 do
begin
Line := VarArrayCreate([0, 72], varVariant);
for j:=0 to 72 do
begin
Pt := VarArrayCreate([0, 1], varVariant);
Pt[0] := j*5 - 180;
Pt[1] := i*45 - 45;
Line[j] := Pt;
end;
Parallels[i] := Line;
end;
//show on the map
Atlas.Map.BeginUpdate;
with Atlas.Map do
try
Projection := PRJ_AZIMUTHAL;
Dimmed := false;
CenterLatitude := 43;
CenterLongitude := -79;
CustomLayers.Clear;
//show meridians
with CustomLayers.Add(LK_LINES) do
begin
PenColor := clBlue;
SetData(Meridians);
end;
//show parallels
with CustomLayers.Add(LK_LINES) do
begin
PenColor := clRed;
SetData(Parallels);
end;
finally
EndUpdate;
end;
end;
//------------------------------------------------------------------------------
// Area
//------------------------------------------------------------------------------
procedure TForm1.Button4Click(Sender: TObject);
var
Pt, Area, Areas: OleVariant;
i: integer;
begin
//single area
Areas := VarArrayCreate([0, 0], varVariant);
//generate area data
Area := VarArrayCreate([0, 72], varVariant);
for i:=0 to 72 do
begin
Pt := VarArrayCreate([0, 1], varVariant);
Pt[0] := -79 + 20 * cos(i*5/180*Pi);
Pt[1] := 43 + 20 * sin(i*5/180*Pi);
Area[i] := Pt;
end;
Areas[0] := Area;
//show on the map
Atlas.Map.BeginUpdate;
with Atlas.Map do
try
Projection := PRJ_RECTANGULAR;
Dimmed := true;
CustomLayers.Clear;
with CustomLayers.Add(LK_AREAS) do
begin
AreaBrightness := 12; //0..15, 15=max
SetData(Areas);
end;
finally
EndUpdate;
end;
end;
//------------------------------------------------------------------------------
// Glyphs
//------------------------------------------------------------------------------
procedure TForm1.Button5Click(Sender: TObject);
var
Glyphs: Variant;
i: integer;
Layer: ICustomLayer;
begin
Randomize;
//create array of Variants
Glyphs := VarArrayCreate([0,333], varVariant);
//each element of the array is a variant array with 3 elements
for i:=0 to 333 do
Glyphs[i] := VarArrayOf([Random(360)-180, //longitude -180..180
Random(180)-90, //latitude -90..90
Random(10)]); //image index 0..9
Atlas.Map.BeginUpdate;
with Atlas.Map do
try
Projection := PRJ_RECTANGULAR;
Dimmed := false;
//delete all layers
CustomLayers.Clear;
//add layer
Layer := CustomLayers.Add(LK_GLYPHS);
//Glyphs.bmp is a bitmap 160x16 that contains 10 glyphs, 16x16 each
//the color of lower left pixel (clFuchsia) is considered transparent
//the hot spot of the glyph is at (1, 15).
Layer.LoadGlyphsFromFile(ExtractFilePath(ParamStr(0)) + 'Glyphs.bmp', 1, 15);
//send locations to the layer
Layer.SetData(Glyphs);
finally
//now allow repainting
EndUpdate;
end;
end;
//------------------------------------------------------------------------------
// Great Circle paths
//------------------------------------------------------------------------------
procedure TForm1.Button6Click(Sender: TObject);
var
Pt, Line, Lines: Variant;
i, j: integer;
begin
//generate an array of Great Circle paths
Lines := VarArrayCreate([0, 33], varVariant);
for i:=0 to 33 do
begin
//a Great Circle path is defined by its end points
Line := VarArrayCreate([0, 1], varVariant);
Line[0] := VarArrayOf([-79, 43 {Toronto}]);
Line[1] := VarArrayOf([Random(360) - 180, Random(180) - 90]);
//add path to the array
Lines[i] := Line;
end;
//show paths on the map
Atlas.Map.BeginUpdate;
with Atlas.Map do
try
Projection := PRJ_RECTANGULAR;
Dimmed := false;
CustomLayers.Clear;
with CustomLayers.Add(LK_LINES) do
begin
PenColor := clBlue;
SetData(Lines);
end;
finally
EndUpdate;
end;
//Note that Delphi automatically releases the variant arrays when they go out of scope.
//In other languages you may have to release them explicitly.
end;
end.
麦克
答案 0 :(得分:3)
你的例子中的VarArrayCreate调用是创建一个由索引为零并以索引1结尾的2个元素的数组。
C#等价物是这样的:
object[] Line;
Line = new object[2];
答案 1 :(得分:1)
或许应该提到varArray创建variant数据类型的数组,这与普通类型完全不同。它在内存中创建一个无法与对象实例(AFAIK)进行比较的结构。期望将其存储为相互链接(通过指针)的节点列表。但是,Delphi变体结构与Microsoft自己的存储格式相同,这意味着您可以调用winapi来实现相同的功能。
如果你还没有解决它,我会看看.NET内部的COM支持库。可能在“System.Runtime.InteropServices”下。或者查看Delphi中的variants.pas单元,看看他们调用的WinAPI函数。
答案 2 :(得分:1)
private void _showPoints()
{
object[] pt = new object[2];
object[] points = new object[4];
for (int i = 0; i < 3; i++)
{
pt[0] = _dx[i, 0];
pt[1] = _dx[i, 1];
points[i] = pt;
}
_aquaPoints.SetData(points);
}
上面是Alex的VB代码中的ShowPoints方法的示例。它也适用于转换正在转换的Delphi代码...
对象是C#中最接近变体的东西。
答案 3 :(得分:0)
你可以制作一个“普通”数组......
MyType[] Line = new MyType[2];
或通用名单......
List<MyType> Line = new List<MyType>(); // list is empty, still have to add n elements
Line.Add( new MyType() );
Line.Add( new MyType() );
你走哪条路取决于你需要什么。如果您需要一个在程序运行时动态增长的“数组”,请使用通用List。如果没有,请使用数组。
现在,要记住的是,其中任何一个都是基于0的 - 不像Delphi那样随意从N开始。
现在,如果需要,可以使用HashTable
或Dictionary
来模拟。