16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"リソースから LoadFromStream"
この発言に対し以下のコメントが寄せられています
#00983 もろぼし☆らむ さん RE:リソースから LoadFromStream
タイトル:リソースにバイナリファイルを付けて LoadFromStream で
読み込む
動作テスト:Delphi5
先日、生データの入ったファイルをリソースとして実行ファイルに
リンクして、このデータを TStream として読み出すコードを書いた
ので、サンプルにまとめ直してみました。
【生データファイルをリソースにする】
【リソースに TStream を被せる】
【TStream を被せたストリームの使用例】
この順番で書きます。
【生データファイルをリソースにする】
まず、バイナリファイルをリソースとして実行ファイルに貼り付け
ます。例えば、SAMPLE.RC というテキストファイルを作り、以下の一
行を書き込みます。
RID_SAMPLE RCDATA "SAMPLE.DAT"
このファイル(SAMPLE.RC)を Delphi5 のプロジェクトに追加しま
す。追加手順はマニュアルを参照してください。Delphi4 以前ではリ
ソースを別途コンパイルして *.RES ファイルにしてからユニットに
{$R SAMPLE.RES} を記述してリンクします。
これでプロジェクトをメイクすれば実行ファイルにリソースが付き
ます。
【リソースに TStream を被せる】
次にオリジナル形式(バイナリ)のリソースを Stream として読む
ためのクラスを準備します。
type
// 既存のメモリを Stream として読むクラス
TMemoryReader = class(TStream)
FMemory: Pointer;
FSize: Longint;
FPosition: Longint;
public
constructor Create(AMemory: Pointer; ASize: Longint);
// TStream から少なくとも下記の3関数をオーバーライドします
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
end;
// リソースを Stream として読むクラス
TResourceReader = class(TMemoryReader)
public
constructor Create(AInst: HINSTANCE; AName: string);
end;
{ TMemoryReader }
constructor TMemoryReader.Create(AMemory: Pointer; ASize: Longint);
begin
inherited Create;
FMemory := AMemory;
FSize := ASize;
FPosition := 0;
end;
function TMemoryReader.Read(var Buffer; Count: Longint): Longint;
begin
// 読み込み超過の防止
if (FPosition + Count) > FSize then
Result := FSize - FPosition
else
Result := Count;
// 読み込み
CopyMemory(@Buffer, Pointer(Longint(FMemory) + FPosition), Result);
// ポジションの変更
Inc(FPosition, Result);
end;
function TMemoryReader.Write(const Buffer; Count: Longint): Longint;
begin
// とりあえずこの例では書き込み禁止にしておきます
Result := 0;
end;
function TMemoryReader.Seek(Offset: Longint; Origin: Word): Longint;
begin
// ポジションの移動
case Origin of
soFromBeginning: FPosition := Offset;
soFromCurrent: Inc(FPosition, Offset);
soFromEnd: FPosition := FSize - Offset;
end;
// ポジションの値を有効範囲内に収める
if FPosition < 0 then FPosition := 0
else if FPosition > FSize then FPosition := FSize;
Result := FPosition;
end;
{ TResourceReader }
constructor TResourceReader.Create(AInst: HINSTANCE; AName: string);
var
ResInfo: HRSRC;
Data: HGLOBAL;
AMemory: Pointer;
ASize: Longint;
begin
// リソースをメモリ化して TMemoryReader のコンストラクタに渡す
ResInfo := FindResource(AInst, PChar(AName), RT_RCDATA);
Data := LoadResource(AInst, ResInfo);
AMemory := LockResource(Data);
ASize := SizeOfResource(AInst, ResInfo);
inherited Create(AMemory, ASize);
end;
【TStream を被せたストリームの使用例】
使用例は、
var
Reader: TResourceReader;
begin
Reader := TResourceReader.Create(SysInit.HInstance, 'RID_SAMPLE');
Reader.ReadComponent(ListView1);
// それから
Bitmap.LoadFromStream(Reader);
// Bitmapを生リソースにするのも何ですが(^^;
Reader.Free;
end;
のようになります。
1999/11/02、河邦 正(GCC02240@nifty.com)
(http://member.nifty.ne.jp/kht0000/、NIFTY外へ私作Componentの
公開用)
Original document by 河邦 正 氏 ID:(GCC02240)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|