2016-09-16 10 views
0

したがって、dllファイルから画像リソースを読み込もうとします。これを行うには、このメソッドを作成しました。LoadImageによって返されたハンドルでImage.FromHBitmapを呼び出すとGDI +エラーが発生する

static Bitmap GetImageResource(IntPtr handle, string resourceId) 
{ 
    IntPtr img_ptr = NativeMethods.LoadImage(handle, "#" + resourceId, IMAGE_ICON, 16, 16, 0); 

    if (img_ptr == IntPtr.Zero) 
     throw new System.ComponentModel.Win32Exception((int)NativeMethods.GetLastError()); 

    return Image.FromHbitmap(img_ptr); 
} 

ハンドルとリソースIDを指定して、dllから画像リソースをロードします。 this question I asked yesterdayによれば、私はidに#を付ける必要があります。今LoadImageによって返されたハンドルはもはやゼロではない、私は Image.FromHbitmapを使用して、このハンドルからビットマップ画像を作成しようとすると、しかし、私はSystem.Runtime.InteropServices.ExternalException一般的なエラーがGDI +

を発生

を言ってます(または似たようなもの、私は英語でメッセージを受け取っていません)。

私はすでにthisthisの質問を読んだけど、助けにはなりませんでした。

これはなぜですか?それはネイティブDLL(ではないアセンブリ)である場合は、あなたの代わりに相互運用機能を使用する必要があります

public static Bitmap getBitmapFromAssemblyPath(string assemblyPath, string resourceId) { 
    Assembly assemb = Assembly.LoadFrom(assemblyPath); 
    Stream stream = assemb.GetManifestResourceStream(resourceId); 
    Bitmap bmp = new Bitmap(stream); 
    return bmp; 
} 

:DLLは.NETアセンブリである場合は事前に感謝

+0

これは完全に正常です。イメージではなくアイコンを読み込んでいます。代わりにIcon.FromHandle()を使用してください。 Iconオブジェクトを再度使用できないことが確認されたら、DestroyIconでアイコンをもう一度破棄する必要があります。 –

答えて

0

することは、あなたがそうのように、Assembly.GetManifestResourceStreamを呼び出すことができます。あなたはソリューションhereを持っており、次のようにまとめることができます。

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags); 

[DllImport("kernel32.dll")] 
static extern IntPtr FindResource(IntPtr hModule, int lpID, string lpType); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo); 

[DllImport("kernel32.dll", SetLastError=true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool FreeLibrary(IntPtr hModule); 

static const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002; 

public static Bitmap getImageFromNativeDll(string dllPath, string resourceName, int resourceId) { 
    Bitmap bmp = null; 
    IntPtr dllHandle = LoadLibraryEx(dllPath, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE); 
    IntPtr resourceHandle = FindResource(dllHandle, resourceId, resourceName); 
    uint resourceSize = SizeofResource(dllHandle, resourceHandle); 
    IntPtr resourceUnmanagedBytesPtr = LoadResource(dllHandle, resourceHandle); 

    byte[] resourceManagedBytes = new byte[resourceSize]; 
    Marshal.Copy(resourceUnmanagedBytesPtr, resourceManagedBytes, 0, (int)resourceSize); 
    using (MemoryStream m = new MemoryStream(resourceManagedBytes)) { 
     bmp = (Bitmap)Bitmap.FromStream(m); 
    } 

    FreeLibrary(dllHandle); 

    return bmp; 
} 

んが、エラー処理が追加されなかった、これはない生産対応コードです。

注:アイコンが必要な場合は、あなたがストリームを受信アイコンコンストラクタ使用することができます。

using (MemoryStream m = new MemoryStream(resourceManagedBytes)) { 
     bmp = (Icon)new Icon(m); 
    } 

をそして、あなたはそれに応じて戻り値の型を変更する必要があります。

+0

正確に 'bptr'とは何ですか? –

+1

タイプミス。私は適切な変数名でコードを変更しました。 –

+0

私はリソースのIDしか持っていませんが、 'resourceName'パラメータにはどうすればいいですか? –

関連する問題