要把数据库中的图像字段显示到image1中,执行cds1.Data:=cds1.DataRequest(VarArrayOf(['TN_TechPhoto','TechPhoto','00386']));的时候报错,我到事件内跟踪了,执行都正确,返回的olevariant我保存到文件也没问题,就是当DataSetProvider1DataRequest这个事件结束就会出现标题所示错误。
下附完整源码,数据库字段是image类型,经测试取字段数据没问题。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ADODB, Provider, DB, DBClient, ExtCtrls, StdCtrls, jpeg;type
TByteArray = array of byte;
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
cds1: TClientDataSet;
DataSetProvider1: TDataSetProvider;
ADOQuery1: TADOQuery;
procedure Button1Click(Sender: TObject);
function DataSetProvider1DataRequest(Sender: TObject; Input: OLEVariant):
OLEVariant;
private
procedure LoadPicFromDB(fn:string;jpgimg:TImage);
procedure OleVariantToStream(var Input: OleVariant; Stream: TStream);
function StreamToOleVariant(Stream: TStream; Count: Integer): OleVariant;
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
cds1.Open;
cds1.Data:=cds1.DataRequest(VarArrayOf(['TN_TechPhoto','TechPhoto','00386']));
// ShowMessage('cao');
if not VarIsNull(cds1.Data) then
LoadPicFromDB('TechPhoto',Image1)
else
Image1.Picture.Graphic:=nil;
end;function TForm1.DataSetProvider1DataRequest(Sender: TObject; Input:
OLEVariant): OLEVariant;
var
Ms:TMemoryStream;
procedure savetofile(pbuf:OleVariant);
var
p: Pointer;
fs:TFileStream;
nSize:Integer;
begin
nSize := VarArrayHighBound(pBuf, 1) - VarArrayLowBound(pBuf, 1) + 1;
fs := TFileStream.Create('d:\abc', fmCreate or fmOpenWrite);
try
p := VarArrayLock(pBuf);
try
fs.Seek(0, soFromBeginning);
fs.WriteBuffer(p^, nSize);
finally
VarArrayUnLock(pBuf);
end;
finally
fs.Free;
end;
end;
begin
ms:=TMemoryStream.Create;
with ADOQuery1 do
begin
Close;
sql.Clear;
sql.Add('select '+Input[1]+' as tu from '+input[0]+' where FactoryStyle='+QuotedStr(input[2]));
open;
if recordcount=1 then
begin
TBlobField(FieldByName('tu')).SaveToStream(ms);
Result:=StreamToOleVariant(ms,ms.Size);
end
else
Result:=NULL;
end;
ms.free;
savetofile(Result);
end;procedure TForm1.LoadPicFromDB(fn: string; jpgimg: TImage);
var
Ms:TMemoryStream;
jpg:Tjpegimage;
o:OleVariant;
begin
Ms:=TMemoryStream.Create;
jpg:=TJPEGImage.Create;
o:=cds1.Data;
OleVariantToStream(o,Ms);
Ms.Position :=0;
Jpg.LoadFromStream(Ms);
jpgimg.Picture.Assign(Jpg);
Ms.Free;
jpg.free;
end;procedure TForm1.OleVariantToStream(var Input: OleVariant;
Stream: TStream);
var
pBuf: Pointer;
begin
pBuf := VarArrayLock(Input);
Stream.Write(TByteArray(pBuf^), Length(TByteArray(Input)));
VarArrayUnlock(Input);
end;function TForm1.StreamToOleVariant(Stream: TStream;
Count: Integer): OleVariant;
var
pBuf: Pointer;
begin
Result:=VarArrayCreate([0,Count-1],varByte);
pBuf:=VarArrayLock(Result);
Stream.Position:=0;
Stream.Read(TByteArray(pBuf^),Length(TByteArray(Result)));
VarArrayUnlock(Result);
end;end.
下附完整源码,数据库字段是image类型,经测试取字段数据没问题。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ADODB, Provider, DB, DBClient, ExtCtrls, StdCtrls, jpeg;type
TByteArray = array of byte;
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
cds1: TClientDataSet;
DataSetProvider1: TDataSetProvider;
ADOQuery1: TADOQuery;
procedure Button1Click(Sender: TObject);
function DataSetProvider1DataRequest(Sender: TObject; Input: OLEVariant):
OLEVariant;
private
procedure LoadPicFromDB(fn:string;jpgimg:TImage);
procedure OleVariantToStream(var Input: OleVariant; Stream: TStream);
function StreamToOleVariant(Stream: TStream; Count: Integer): OleVariant;
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
cds1.Open;
cds1.Data:=cds1.DataRequest(VarArrayOf(['TN_TechPhoto','TechPhoto','00386']));
// ShowMessage('cao');
if not VarIsNull(cds1.Data) then
LoadPicFromDB('TechPhoto',Image1)
else
Image1.Picture.Graphic:=nil;
end;function TForm1.DataSetProvider1DataRequest(Sender: TObject; Input:
OLEVariant): OLEVariant;
var
Ms:TMemoryStream;
procedure savetofile(pbuf:OleVariant);
var
p: Pointer;
fs:TFileStream;
nSize:Integer;
begin
nSize := VarArrayHighBound(pBuf, 1) - VarArrayLowBound(pBuf, 1) + 1;
fs := TFileStream.Create('d:\abc', fmCreate or fmOpenWrite);
try
p := VarArrayLock(pBuf);
try
fs.Seek(0, soFromBeginning);
fs.WriteBuffer(p^, nSize);
finally
VarArrayUnLock(pBuf);
end;
finally
fs.Free;
end;
end;
begin
ms:=TMemoryStream.Create;
with ADOQuery1 do
begin
Close;
sql.Clear;
sql.Add('select '+Input[1]+' as tu from '+input[0]+' where FactoryStyle='+QuotedStr(input[2]));
open;
if recordcount=1 then
begin
TBlobField(FieldByName('tu')).SaveToStream(ms);
Result:=StreamToOleVariant(ms,ms.Size);
end
else
Result:=NULL;
end;
ms.free;
savetofile(Result);
end;procedure TForm1.LoadPicFromDB(fn: string; jpgimg: TImage);
var
Ms:TMemoryStream;
jpg:Tjpegimage;
o:OleVariant;
begin
Ms:=TMemoryStream.Create;
jpg:=TJPEGImage.Create;
o:=cds1.Data;
OleVariantToStream(o,Ms);
Ms.Position :=0;
Jpg.LoadFromStream(Ms);
jpgimg.Picture.Assign(Jpg);
Ms.Free;
jpg.free;
end;procedure TForm1.OleVariantToStream(var Input: OleVariant;
Stream: TStream);
var
pBuf: Pointer;
begin
pBuf := VarArrayLock(Input);
Stream.Write(TByteArray(pBuf^), Length(TByteArray(Input)));
VarArrayUnlock(Input);
end;function TForm1.StreamToOleVariant(Stream: TStream;
Count: Integer): OleVariant;
var
pBuf: Pointer;
begin
Result:=VarArrayCreate([0,Count-1],varByte);
pBuf:=VarArrayLock(Result);
Stream.Position:=0;
Stream.Read(TByteArray(pBuf^),Length(TByteArray(Result)));
VarArrayUnlock(Result);
end;end.
var
o:olevariant;
begin
......
o:=cds1.DataRequest(VarArrayOf(['TN_TechPhoto','TechPhoto','00386']));
......
end;