Reputation: 5047
I've searched a lot, but I couldn't find how to load a resource which ID is a string. The tutorial Here is good, but doesn't do that. Does someone know how to make it? Here's my structure. I want to load the pngs.
And the code:
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);
[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);
const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
void LoadSkin() {
IntPtr hMod = LoadLibraryEx(@"C:\Users\myuser\Desktop\skin.dll", IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
IntPtr hRes = FindResource(hMod, "BACK.PNG", "23");
MessageBox.Show(hRes.ToString()); // <- 0 here.
uint size = SizeofResource(hMod, hRes);
IntPtr pt = LoadResource(hMod, hRes);
Bitmap bmp;
byte[] bPtr = new byte[size];
Marshal.Copy(pt, bPtr, 0, (int) size);
using (MemoryStream m = new MemoryStream(bPtr))
bmp = (Bitmap) Bitmap.FromStream(m);
}
EDIT:
Fixed it. The problem was in the declaration of FindResource. For my case the correct one was:
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr FindResource(IntPtr hModule, string lpName, uint lpType);
Upvotes: 2
Views: 2361
Reputation: 941990
@"C:\Users\myuser\Desktop\skin.dll"
Clearly the DLL could not be loaded. Get a better diagnostic by writing it like this:
IntPtr hMod = LoadLibraryEx(@"C:\Users\myuser\Desktop\skin.dll", IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
if (hMod == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
The default constructor for the Win32Exception class already takes care of digging up the Marshal.GetLastWin32Error() error code and generating the appropriate message for it.
File not found is likely here. You have to watch out for the Desktop folder, the shell doesn't actually show the content of the c:\users\yourname\desktop folder, you get a blend of several folders. This blending doesn't happen when you refer to the folder in your code. One possible location for the file is c:\users\public\desktop. Solve this problem the right way, ensure that the DLL is located in the same directory as your main EXE. Project + Add Existing Item, navigate to the DLL so it is added to your project. Select it and set the Copy to Output Directory property to "Copy if newer".
After edit: the resource type argument could be trouble too. Either use "#23" or declare the argument type as integer so you can pass 23.
Upvotes: 2