将多个BMP文件合成一个文件里,并根据另一个文件的索引号读出相应的图片 ( 积分: 100 )

  • 主题发起人 主题发起人 别长江
  • 开始时间 开始时间

别长江

Unregistered / Unconfirmed
GUEST, unregistred user!
如题:
创建两个文件,一个是存贮图片信息的. *.WIL文件,另一个是存取相应的索引信息. *.WIX
将选中的BMP文件添加到WIL文件里,并在WIX文件里创建索引.以后可在根据WIX索引地址找到WIL文件里对应的图片信息,并在IMAGE控件里显示出来.
 
如题:
创建两个文件,一个是存贮图片信息的. *.WIL文件,另一个是存取相应的索引信息. *.WIX
将选中的BMP文件添加到WIL文件里,并在WIX文件里创建索引.以后可在根据WIX索引地址找到WIL文件里对应的图片信息,并在IMAGE控件里显示出来.
 
用结构化存储技术可以实现你的要求。我写一个类,关有demo。 什么给你呢?
 
俺把类与demo贴上来, 呵呵,给分吧 [:D]
//-----------------------------------------------------------------------------
//类
unit DocStorageUnit;

interface

uses
Windows, SysUtils, Classes, Forms, ActiveX, AxCtrls;

type
TDocStorage=class
private
FSavePath: string; //保存路径
FStgName: string; //保存的文件名(*.stg)
FStgModeSave: integer;
FStgModeRead: integer;
FStgRoot: IStorage;
public
property SavePath: string read FSavePath ;
property StgName: string read FStgName;
property StgModeSave: integer read FStgModeSave ;
property StgModeRead: integer read FStgModeRead ;

constructor Create(path: string; AStgName: string);
destructor Destory;

function GetResList(var RList: TStringList): Boolean;
function Read(stmName: string): Boolean;
function Save(stmName: string): Boolean;
function Delete(stmName: string): Boolean;
end;

implementation

//==============================================================================

{=== TStgStorge ===}

constructor TDocStorage.Create(path: string; AStgName: string);
begin
inherited Create;

FSavePath:=path; //保存的路径
if FSavePath[length(FSavePath)]<>'/' then
FSavePath:=FSavePath+'/';

FStgName:= FSavePath+ AStgName; //保存的文件名(完整路径)

FStgModeSave:=STGM_CREATE+STGM_READWRITE+STGM_SHARE_EXCLUSIVE;
FStgModeRead:=STGM_READWRITE+STGM_SHARE_EXCLUSIVE; //读写+独占方式

if not FileExists(FStgName) then begin //文件不存在则创建一个
StgCreateDocfile(StringToOleStr(FStgName), FStgModeSave, 0, FStgRoot);

end
else begin
StgOpenStorage(StringToOleStr(FStgName), nil, FStgModeRead, nil, 0, FStgRoot);

end; //end if
end;


destructor TDocStorage.Destory ;
begin

inherited;
end;

//返回文件中的资源列表
function TDocStorage.GetResList(var RList: TStringList): Boolean;
var
EnumStatStg: IEnumStatStg;
StatStg: TStatStg;
iHRESULT: HRESULT;
s: string;
begin
Result:=False;
iHRESULT:=FStgRoot.EnumElements(0, nil, 0, EnumStatStg);


if iHRESULT=S_OK then begin
while EnumStatStg.Next(1, StatStg, nil) = S_OK do begin
s:=StatStg.pwcsName;
RList.Add(s);
end; //end while
Result:=True;
s:='';
end
else if iHRESULT=STG_E_INSUFFICIENTMEMORY then begin
s:='Error: STG_E_INSUFFICIENTMEMORY' +#13#10#13
+'The enumerator object could not be created due to lack of memory';
end
else if iHRESULT=STG_E_INVALIDPARAMETER then begin
s:='Error: STG_E_INVALIDPARAMETER'+#13#10#13
+'One of the parameters was not valid.';
end//end if
//else if iHRESULT=STG_E_REVERTED then begin
else begin
s:='Error: STG_E_REVERTED'+#13#10#13
+'the object has been invalidated by a revert operation above it in the transaction tree.';
end;

if s<>'' then
Application.MessageBox(PChar(s),PChar('Error'),MB_ICONERROR+MB_OK) ;
end;


function TDocStorage.Read(stmName: string): Boolean;
var
EnumStatStg: IEnumStatStg;
StatStg: TStatStg;
stmData: IStream;
OleStream: TOleStream;
LoadStream: TMemoryStream;
begin
Result:=False;

if FStgRoot.EnumElements(0, nil, 0, EnumStatStg)=S_OK then begin
Result:=True;
while EnumStatStg.Next(1, StatStg, nil) = S_OK do begin
if StatStg.pwcsName=stmName then begin
if FileExists(FSavePath+'Stg_'+stmName) then
DeleteFile(FSavePath+'Stg_'+stmName);

FStgRoot.OpenStream(StatStg.pwcsName, nil, FStgModeRead, 0, stmData);
OleStream:=TOleStream.Create(stmData);

LoadStream:=TMemoryStream.Create;
LoadStream.Size:=0;
LoadStream.CopyFrom(OleStream, OleStream.Size);
LoadStream.SaveToFile(FSavePath+'Stg_'+stmName);
LoadStream.Free;

OleStream.Free;
break;
end;
end; //end while
end; //end if 1
end;


function TDocStorage.Save(stmName: string): Boolean;
var
EnumStatStg: IEnumStatStg;
StatStg: TStatStg;
stmData: IStream;
OleStream: TOleStream;
LoadStream: TMemoryStream;
isFind: Boolean;
s: string;
begin
Result:=False;

//判断是否已经存在对应资源名称
isFind:=False;
if FStgRoot.EnumElements(0, nil, 0, EnumStatStg)=S_OK then begin
while EnumStatStg.Next(1, StatStg, nil) = S_OK do begin
if StatStg.pwcsName=stmName then begin
isFind:=True;
break;
end;
end; //end while
end; //end if 1

if isFind then begin
s:='资源文件中已存在该文件名称! ';
Application.MessageBox(PChar(s),PChar('Warning'),MB_OK+MB_ICONSTOP) ;
exit;
end;

//保存文件
LoadStream:= TMemoryStream.Create ;
LoadStream.LoadFromFile(FSavePath + stmName);
LoadStream.Position:=0;
FStgRoot.CreateStream(StringToOleStr(stmName), FStgModeSave, 0, 0, stmData);
OleStream:=TOleStream.Create(stmData);
OleStream.CopyFrom(LoadStream, LoadStream.Size);
OleStream.Free;
LoadStream.Free;
Result:=True;
end;

function TDocStorage.Delete(stmName: string): Boolean;
begin
Result:=False;

if FStgRoot.DestroyElement(StringToOleStr(stmName))=S_OK then
Result:=True;
end;

//==============================================================================
end.

//---------------------------------------------------------------------------

//调用示例
var
iDocStorage: TDocStorage;
RList: TStringList;
begin
iDocStorage:=TDocStorage.Create('d:/','Data.stg') ;//保存路径,与文件名

iDocStorage.Save('a.jpg'); //d:/ 目录文件下的一文件(a.jpg文件保存到 data.stg中)

iDocStorage.Read('a.jpg'); //data.stg中读出a.jpg,并保存为stg_a.jpg

RList:=TStringList.Create ; //列表data.stg中的资源目录,如果是多级的,请自己改一下
iDocStorage.GetResList(RList);
showmessage(RList.Text );
RList.Free ;

iDocStorage.Free ;
end;
 
TO:楼上的谢谢:
邮箱地址是:bcj1983@163.com
给我发一份好吗?
 
这个用结构化储存不好呀!
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
902
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部