2017-09-11 26 views
2

私は2つのコンポーネントが、私は次のスクリプトを使用してGraphContour.resファイルに配置された同じPNGリソースを使用するDelphiのパッケージを書いたDelphiのパッケージにリソースを含めますGraphContour.rc:が正しく

GRAPH_CONTOUR RCDATA GraphContour.png 

コンポーネントの両方の装置が{$R GraphContour.res}ディレクティブ、コンポーネントの作業が含まれるが、私は、コンパイラの警告が出た場合:

[dcc32 Hint] H2161 Warning: Duplicate resource: Type 10 (RCDATA), ID GRAPH_CONTOUR; File C:\Borland\Components\MyControls\GraphContour.res resource kept; file C:\Borland\Components\MyControls\GraphContour.res resource discarded.

私はDPKファイルにそれを置く台から{$R GraphContour.res}ディレクティブを削除する場合:

{$R *.res} 
{$R GraphContour.res} 

警告が離れて行く、私はパッケージをコンパイルすることができ、リソースは設計時に示されますが、実行時にされています私はエラーを取得する:

Project ComponentTest.exe raised exception class EResNotFound with message 'Resource GRAPH_CONTOUR not found'.

これら2つのコントロールの1からのコードのビット:

procedure TMyDisplay.CreateWnd(); 
var png: TPngImage; 
begin 
    inherited; 
    //...................... 
    png := TPngImage.Create; 
    try 
    png.LoadFromResourceName(HInstance, 'GRAPH_CONTOUR'); //Error is here 
    _knob.Center.Picture.Graphic := png; 
    finally 
    png.Free(); 
    end; 
    //...................... 
end; 

バイナリビューアでBPLファイルを調べたところ、GRAPH_CONTOUR文字列名があることがわかりました。

HInstanceの代わりにFindClassHInstanceを使用しようとしました。それは助けになりませんでした。

png.LoadFromResourceName(FindClassHInstance(Self.ClassType), 'GRAPH_CONTOUR'); 

リソースをBPLに正しく組み込むにはどうすればいいですか?ここで

更新

私はリソースの可用性をチェックするために使用されるテストアプリケーションです:

program Loadres; 

uses Winapi.Windows; 

procedure PrintLastError(); 
var 
    cchMsg, code: Cardinal; 
    buf: array[0..512] of WideChar; 
begin 
    code := GetLastError(); 
    cchMsg := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS, 
    nil, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @buf, SizeOf(buf), nil); 
    MessageBoxW(0, @buf, 'Error', MB_ICONERROR); 
end; 

var 
    hm, hResInfo, hResData, hPngFile: NativeUInt; 
    rp: Pointer; 
    wb, rs: Cardinal; 

begin 
    hm := LoadLibrary('C:\Documents and Settings\All Users\Documents\Embarcadero\Studio\17.0\Bpl\MyControls.bpl'); 
    if hm = 0 then begin PrintLastError(); Exit; end; 
    try 
    hResInfo := FindResource(hm, 'GRAPH_CONTOUR', RT_RCDATA); 
    if hResInfo = 0 then begin PrintLastError(); Exit; end; 
    hResData := LoadResource(hm, hResInfo); 
    if hResData = 0 then begin PrintLastError(); Exit; end; 
    rs := SizeofResource(hm, hResInfo); 
    rp := LockResource(hResData); 
    try 
     hPngFile := CreateFile('TheContour.png', GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 
     FILE_ATTRIBUTE_NORMAL, 0); 
     try 
     WriteFile(hPngFile, rp^, rs, wb, nil); 
     finally 
     CloseHandle(hPngFile); 
     end; 
    finally 
     UnlockResource(hResData); 
    end; 
    finally 
    FreeLibrary(hm); 
    end; 
end. 

これは、リソースを見つけ、適切なリソースのサイズを報告し、ファイルにリソースを書き込みます。ファイルは元のファイルと一致します。

+0

'FindClassHInstance'は正常に動作します。それを使用するコードは表示されません。また、TMyDisplayがどこにあるのかもわかりません。 2つのコントロールを持つパッケージでは?この場合、 'HInstance'は正しいでしょう。 –

+0

だからHInstanceは正しい –

+0

いくつかのデバッグを試してください。 Windows APIメソッドを使用してリソースを検索します。エラーが発生した場合は、エラーコードを確認してください。最終的に、モジュールにそのタイプと名前のリソースがないと確信するようになります。 –

答えて

3

実行したデバッグに基づいて、実行可能プログラムがランタイムパッケージを使用していないという問題があります。代わりに、ソースファイルを実行可能ファイルに直接コンパイルします。それらはもはやリソースをリンクしないので、実行可能ファイルには存在しません。

いくつかのオプション:

  1. 使用ランタイムパッケージ。これにより、現在のパッケージをデザイン時パッケージとランタイムパッケージに分割する必要が生じる場合があります。
  2. リソースを別のユニットに配置します(コードは必要ありません。リンクする必要があるリソースのみ)。あなたのデザインパッケージと実行可能ファイルにそのユニットを含めます。コンポーネントソースファイルがそのリソースユニットを使用するように手配すれば、リソースを必要とするすべてのモジュールに強制的に組み込まれます。
+2

デザイン時にフォームや他のデザインサーフェスに追加できるようにコンポーネントをIDEに登録する必要がある場合は、それらをデザインタイムパッケージにコンパイルしてIDEに登録する必要があります。実行時には、ソースファイルを直接実行するか、ランタイムパッケージにリンクするかのいずれかを行うことができます。後者の場合、ランタイムパッケージとデザインタイムパッケージの両方が必要になります。後者は、前者を要求する(依存する)。これは重要なトピックですが、実際にはSOのコメントによる文書化に立ち向かうことはありません! –