喫茶XRAYトップページ

[スレッド全体
]

[11605] Re4:リソースのビットマップ取得返信 削除
2017/11/27 (月) 19:08:09 Mr.XRAY
ところで参考までに,
掲示板のレスで

http://www.geocities.jp/asumaroyuumaro/program/tips/BitmapResource.html

のリンクがあります.
もちろん,このコードでリソースのビットマップが取得できます.
しかし,BPL のコンポーネントのビットマップは取得できません.

リソースを列挙する時の,以下のコードがミソなんです.
(MSDN の記事をそのまま Delphi のコードにしただけですが)

        //リソース名のチェック
        //上位WORD(2バイト)が 0ならIDは数値.それ以外は文字列のポインタ
        if HiWord(Cardinal(lpszName)) = 0 then begin
          LResIDStr := IntToStr(Cardinal(lpszName));
        end else begin
          LResIDStr := lpszName;
        end;

それと上の Asuyu さんのコードでは,列挙した後,
目的のリソース ID のビットマップの検索に再度 EnumResourceNames を実行していますが,
これをしなくてもリソースID が分かっていれば,
記事に掲載している以下のコードで取得できます.

        if LItemInt < 0 then begin
          LBitmap.LoadFromResourceName(LhModule, LItemStr);;
        end else begin
          LBitmap.LoadFromResourceID(LhModule, LItemInt);
        end;

このあたりは,私も同じようなことよくやってしまっています.
サンプルを書いて実行して,後になって気づくことがあります.
つまり,新規に記事を掲載ていたがかの時はまだダウンロードしない方がいいです.
しばらくは細かい修正しています.


[11606] Re5:リソースのビットマップ取得返信 削除
2017/11/27 (月) 19:25:18 Mr.XRAY
> もちろん,このコードでリソースのビットマップが取得できます.
> しかし,BPL のコンポーネントのビットマップは取得できません.


もし,質問した方が,Asuyu さんのコードで実際にテストしたけど,
ビットマップが取得できなかった,という反応を示したのあれば,
なら,とレスしようとは思ったのですが,

しかし,それ以前の問題,あるいは問題は別にあるようです.


[11607] Re5:リソースのビットマップ取得返信 削除
2017/11/28 (火) 08:23:54 おかぽん
▼ Mr.XRAYさん
> しかし,BPL のコンポーネントのビットマップは取得できません.
が〜ん・・・

近い環境ということで、Delphi6で試してみたのですが、以下のほぼ丸コピー
動いています。
なぜだろう?

bplのフルパスを格納したEdit1: TEdit
EnumResourceNames でビットマップリソース名を列挙する ListBoxNames:TListBox
リソースビットマップを表示するImageRes: TImage

var
  hHandle: THandle;
  hBmp: HBitmap;
  tagBmp :tagBitmap;
  newBmp: TBitmap;
  memDC :HDC;
begin
  if ListBoxNames.ItemIndex < 0 then begin

  end
  else begin
    //ロード
    hHandle :=LoadLibrary(PChar(Edit1.Text));
    if hHandle <> 0 then begin
      //Bitmapリソース検索
      hBmp := LoadImage(hHandle, MakeIntResource(PChar(ListBoxNames.Items[ListBoxNames.ItemIndex])), IMAGE_BITMAP,
                       0, 0, 0);
      try
        if hBmp <> 0 then begin

          //ビットマップ情報を取得
          GetObject(hBmp, Sizeof(tagBmp), @tagBmp);
          newBmp := TBitmap.Create;
          try
            newBmp.Width := tagBmp.bmWidth;
            newBmp.Height := tagBmp.bmHeight;

            //TBitmap互換のメモリデバイスコンテキストを生成
            memDC :=CreateCompatibleDC(newBmp.Canvas.Handle);
            try
              SelectObject(memDC, hBmp);
              //ビットマップにコピー
              BitBlt(newBmp.Canvas.Handle, 0, 0, tagBmp.bmWidth, tagBmp.bmHeight,
                     memDC, 0, 0, SRCCOPY);
              //Imageにコピー
              ImageRes.Picture.Bitmap.Assign(newBmp);
            finally
              DeleteDC(memDC);
            end;
          finally
            newBmp.Free;
          end;
        end;
      finally
        DeleteObject(hBmp);
      end;
      //解放
      FreeLibrary(hHandle);
    end;
  end;
end;


[11609] Re6:リソースのビットマップ取得返信 削除
2017/11/28 (火) 09:03:46 Mr.XRAY
▼ おかぽんさん

> 近い環境ということで、Delphi6で試してみたのですが、以下のほぼ丸コピー
> 動いています。
> なぜだろう?


が〜ん・・・
Asuyu さんゴメンナサイ.名誉棄損で訴えないでね.
Asuyu の場合,EnumResourceNames のコールバック関数内で
目的の ID のビットマップを検出しているからですね.
元々 EnumResourceNames のコールバック内で列挙しているわけですから,
可能なわけです.
大変失礼しました.


[11611] Re7:リソースのビットマップ取得返信 削除
2017/11/28 (火) 09:38:59 Mr.XRAY
▼ おかぽんさん
>
> > 近い環境ということで、Delphi6で試してみたのですが、以下のほぼ丸コピー
> > 動いています。
> > なぜだろう?
>
> が〜ん・・・
> Asuyu さんゴメンナサイ.名誉棄損で訴えないでね.
> Asuyu の場合,EnumResourceNames のコールバック関数内で
> 目的の ID のビットマップを検出しているからですね.
> 元々 EnumResourceNames のコールバック内で列挙しているわけですから,
> 可能なわけです.
> 大変失礼しました.


あっ,これまた失礼しましたる
おかぽんさんのコードはEnumReourceNames のコールバック内ではないてずね.
Delphi 6 で動作確認しました.
hell32.dll はビットマップの取得はできませんでした.
また,Delphi XE では列挙はできますが,
TListBox の Item を選択すると何故か例外発生.
ただし,Delphi XE の IDE から実行する場合に dclstd60.bpl を対象にすると
正常に動作します.
う〜む何故だ.


[11612] Re8:リソースのビットマップ取得返信 削除
2017/11/28 (火) 09:51:11 Mr.XRAY
> う〜む何故だ.

はい分かりました.

Delphi XE では LoadLibrary ではなく LoadLibraryEx を使用すると
正常に動作します.

LoadLibraryEx のフラグに LOAD_LIBRARY_AS_DATAFILE を指定します.
フラグの値を 0 にすると LoadLibrary と同じになります.


[11613] Re9:リソースのビットマップ取得返信 削除
2017/11/28 (火) 10:39:18 Mr.XRAY
> LoadLibraryEx のフラグに LOAD_LIBRARY_AS_DATAFILE を指定します.
> フラグの値を 0 にすると LoadLibrary と同じになります.


ついでに説明しておきますと,
BPL ファイルというのは DLL と同じです.
しかし,Delphi 専用でしかも Delphi のバージョン依存です.

バージョン依存ですから Delphi 6 で作成した EXE では LoadLibrary で
Delphi 6 用の BPL は読み込めますが,Delphi XE の BPL は読み込めないわけです.
LoadLibraryEx で DATAFILE を指定して読み込めば読み込めることになります

参考記事
[005_フォームを実装した実行時パッケージの作成]
http://mrxray.on.coocan.jp/Delphi/plSamples/005_FormInPackage.htm


[11614] Re9:リソースのビットマップ取得返信 削除
2017/11/28 (火) 12:45:08 おかぽん
▼ Mr.XRAYさん
いつもながら仕事が早い。

> LoadLibraryEx のフラグに LOAD_LIBRARY_AS_DATAFILE を指定します.
> フラグの値を 0 にすると LoadLibrary と同じになります.

しかし、そんなところによく気がつきます。
まず、LoadLibraryExなんて、使おうとも思いません。
BPLなんて、単に拡張子が違うだけのDLLって認識なので、関数の呼び出しは
ともかく、リソースの一つや二つ、Loadできれば一緒だろと(^^;)



[11616] Re10:リソースのビットマップ取得返信 削除
2017/11/28 (火) 13:46:17 Mr.XRAY
▼ おかぽんさん

> しかし、そんなところによく気がつきます。

いや,その,これはですね.MSDN の記事そのままです.
掲載しているサンプルコードもそうですが,
ネットで検索すると,同じようなのがいくつかあります.
おそらく,誰かが最初にやったのをまた誰かがというのがありますよね.

最近,えっと... あっそうそう,インストールされている .NET Framework
なんかも,ネットうえにサンプルコードが結構ありました.
私は MSDN 説明記事にしたがってコーディングしました.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82