呵呵,搞定!
这是由于Pascal语法本身的问题造成的。TLogPalette的定义如下:
PLogPalette = ^TLogPalette;
TLogPalette = packed record
palVersion: Word;
palNumEntries: Word;
palPalEntry: array[0..0] of TPaletteEntry;
end;
palPalEntry定义为长度为1的数组,所以当数组元素引用超过此范围时
Range Check就会报错。Delphi的解决方案如下,定义了一个TMaxLogPalette:
PMaxLogPalette = ^TMaxLogPalette;
TMaxLogPalette = packed record
palVersion: Word;
palNumEntries: Word;
palPalEntry: array [Byte] of TPaletteEntry;
end;
注意这里的palPalEntry为可变数组,所以使用这个结构不会有Range Checking
的问题,当然先要分配内存,CreatePalette的时候还要把PMaxLogPalette 强制
转换为PLogPalette。VCL的源代码中Graphics单元里创建Palette就是这么做的。
新的范例如下:
procedure TForm1.Button1Click(Sender: TObject);
var
x,y : integer;
BitMap : TBitMap;
lplogpal
MaxLogPalette;//pointer of TMaxLogPalette
p
ByteArray;
begin
BitMap := TBitMap.create;
Bitmap.Width:=256;
Bitmap.Height:=256;
Bitmap.PixelFormat:= pf8bit;
GetMem(lpLogPal,sizeof(TLOGPALETTE) + ((255) * sizeof(TPALETTEENTRY)));
lpLogPal.palVersion := $0300;
lpLogPal.palNumEntries := 256;
for x := 0 to 255 do
begin
lpLogPal.palPalEntry[x].peRed := x;//没问题了!
lpLogPal.palPalEntry[x].peGreen := x;
lpLogPal.palPalEntry[x].peBlue := x;
end;
Bitmap.Palette := CreatePalette(pLogPalette(lpLogPal)^);//要转换
FreeMem(lpLogPal,sizeof(TLOGPALETTE) + ((255) * sizeof(TPALETTEENTRY)));
for y := 0 to BitMap.Height -1 do
begin
P := BitMap.ScanLine[y];
for x := 0 to BitMap.Width -1 do
P[x] := Byte(x*y);//这里不类型转换一下也会Range Checking错
end;
canvas.draw(0,0,BitMap);//form.canvas, just for a look
end;
给~~分~~吧~~~~@_@