要把数据库中的图像字段显示到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.
解决方案 »
- 窗口调
- 請教TFileStream裁剪文件簡單的方法
- 如何在不导入类型库的情况下调用COM对象?
- 如何限定一个Edit1里只能输入数字?并且当长度小于N时显示一个对话框?我的代码错在哪里?
- 如何显示NAME,存储ID
- 大虾们向小弟推荐一本用delphi开发corba的书吧
- 怎样在MDI上放置按钮控件?最后40分了...
- 高分求救!怎么样往表中添加记录??在线等候......
- 将数据库转到Excel中去,当某一字段(为字符型)的内容是'0001'时,到Excel后变成了'1',有源码分析。
- Delphi 中如何制作平面按钮?
- Delphi 是否可以动态调用 WebServices
- 使用ADOQuery在ACCESS中 动态建表 SQL语句报错 哪位高手指教一下
var
o:olevariant;
begin
......
o:=cds1.DataRequest(VarArrayOf(['TN_TechPhoto','TechPhoto','00386']));
......
end;