  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| [C#/C] How to use icon resource?
I'm writing a C# plugin for a C app, which has well defined API's, structures, etc. I'm trying to figure out how to use a icon / image resource in my C# project and properly convert it to the C struct.
For example, the C struct I have to use is: c code:struct medium_entry { unsigned int struct_size;
char *medium; char *description; int allows_accounts; int allows_connections;
ttkCallback callback; void *data;
unsigned char *png_image_32; unsigned int png_image_32_len; unsigned char *png_image_16; unsigned int png_image_16_len; };
Here is the C# representation of that struct: cs code: [StructLayoutAttribute( LayoutKind.Sequential )] public class medium_entry { /// unsigned int public uint struct_size;
/// char* [MarshalAsAttribute( UnmanagedType.LPStr )] public string medium;
/// char* [MarshalAsAttribute( UnmanagedType.LPStr )] public string description;
/// ttkCallback public ttkCallback callback;
/// void* public System.IntPtr data;
/// unsigned char* [MarshalAsAttribute( UnmanagedType.LPStr )] public string png_image_32;
/// unsigned int public uint png_image_32_len;
/// unsigned char* [MarshalAsAttribute( UnmanagedType.LPStr )] public string png_image_16;
/// unsigned int public uint png_image_16_len;
public medium_entry_t() { this.struct_size = (uint)Marshal.SizeOf( typeof( medium_entry ) ); } }
What is the correct way to take an image and store it in the C# struct, in the png_image_16 field? What exactly does the C FindResource / MAKEINTRESOURCE functions do?
-- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
  PetePuma How many lumps do you want Premium,MVM join:2002-06-13 Arlington, VA | My guess is that the png_image_16 and png_image_32 aren't strings but are arrays of bytes, and that you'll have to marshal them as something different. |
|
 dave Premium,MVM join:2000-05-04 not in ohio
·Verizon Online DSL
| reply to USR56K FindResource looks for the specified resource in the resource section of the specified module.
When you link an image, it can have a 'resource section'. The running program accesses those resources with FindResource or LoadResource. As far as the API is concerned, they're just bits.
Resources can be identified by integer code or string name. There is however one API to load the resource regardless of whether it's identified by integer or string. The MAKEINTRESOURCE macro just does some nasty typecasting so that the integer value looks like a string pointer as far as the compiler is concerned; it may not be much more complicated than
#define MAKEINTRESOURCE(X) ((const TCHAR*)(X))
The API then has a convention that 'addresses' less than some limit are in fact integer resource ids.
It's a load easier to use LoadIcon than the generic LoadResource. |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| reply to USR56K Alright, but how to I convert that to what needs to be done in C#? The following code appears to properly load my embedded resource and convert it to some sort of string, but it doesn't work in the C application I'm targeting. I'm not sure what the string is suppose to look like that the C struct uses to validate it's correct.
cs code: //broken System.Reflection.Assembly thisExe; thisExe = System.Reflection.Assembly.GetExecutingAssembly(); //string[] resources = thisExe.GetManifestResourceNames(); System.IO.Stream fs = thisExe.GetManifestResourceStream( "Plugin.Resources.online_16x16.png" ); System.IO.BinaryReader br = new System.IO.BinaryReader( fs ); MediumEntry.png_image_16 = Encoding.ASCII.GetString( br.ReadBytes( (int)fs.Length ) ); MediumEntry.png_image_16_len = (uint)MediumEntry.png_image_16.Length;
-- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
 Graycode
join:2006-04-17
·net2phone
| reply to USR56K
said by USR56K : I don't see these 2 C structure members represented in the C# version. |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| reply to USR56K Type-o on my part -- I've removed a bunch of the structure's repetitive fields from my posting. There are a LOT of allow_XXXX fields.
Anyways they're: cs code:/// int public bool allows_accounts; /// int public bool allows_connections;
-- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
 dave Premium,MVM join:2000-05-04 not in ohio
·Verizon Online DSL
| reply to USR56K Sorry, I don't speak C#.
Though the call to Encoding.ASCII.GetString looks like you're feeding random non-ASCII byte data through something that would treat it as a text string, and that doesn't seem right.
I am hereby rather confused. Since your aim in life seems to be to end up with a pointer-to-some-bytes, do you want to be messing around with 'resources' in the first place? An icon resource, for example, allows you to use the resource editor to operate on the icon as a picture, place the icon in your .EXE file, to use LoadIcon on it, and you end up with an icon handle that you can pass to the GDI functions that deal with icons. The system is expressly designed to make this look like a sort of 'icon object' and not a bunch o' bytes.
So what is your actual starting point supposed to be? |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| said by dave :So what is your actual starting point supposed to be? Well basically I have a C# project and am trying to use as much native C# functionality as possible. That being the case, I was planning on using the C# way of doing resources, as in using them embedded. Since the C struct I have to deal with, doesn't obviously work with C# embedded resources, I'm trying to find a way to convert/use it instead.
I've already found plenty of guides on how to load resources from assemblies into C#, via P/Invoke and LoadResource/Makeresource, etc. But thats not the direction I want to go. -- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
 dave Premium,MVM join:2000-05-04 not in ohio | OK, fair enough.
At this point you need someone who can give you some C# advice. |
|
  nirvansk815 Premium join:2001-06-18 Rancho Cucamonga, CA clubs: | reply to USR56K Try going here and downloading resourcer. It might help with the resource files. -- There's so much to be thankful for...How can anyone be sad? |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| reply to USR56K Any else have an idea, how I would load an image from my C# assembly (yes, already know about GetManifestResourceStream) and then store it in the png_image_16 field? Should png_image_16 really be an IntPtr instead of String? -- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
  PetePuma How many lumps do you want Premium,MVM join:2002-06-13 Arlington, VA | I think it should be an IntPtr -- I think they are using a char array as a byte array, which may contain embedded zeros. Converting it to a string likely truncates the icon well before the end of its data stream. |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
edit: May 3rd, @10:56PM
| said by PetePuma :I think it should be an IntPtr -- I think they are using a char array as a byte array, which may contain embedded zeros. I'm thinking you're right.
Now the question becomes, how do I implement the C# equivalent of this C code? c code: HRSRC ImageRes; data *medium_entry; // the structure given by the app HMODULE hInstance; // the handle of your DLL instance, passed in through DLLMain
ImageRes = FindResource(hInstance, MakeIntResource(102), 'PNG'); data->png_image_32 = LockResource(LoadResource(hInstance, ImageRes)); data->png_image_32_len = SizeOfResource(hInstance, ImageRes);
I'm trying to stay away from P/Invoking all of those commands to load up raw icon/png/etc files. Would really rather just use native C# code as much as possible.
-- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
  PetePuma How many lumps do you want Premium,MVM join:2002-06-13 Arlington, VA | You might not have a choice. There are not native implementations of everything in the Win32 API. |
|
  USR56K
join:2000-05-20 Seattle, WA clubs: | reply to USR56K Ok. But how do I load an image stored in my C# binary and use FindResource, LockResource, and SizeOfResource? |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| reply to USR56K Hmm well I tried using the LockBits thing, but the image doesn't show up in my C app, so I assume something isn't working quite right.
cs code:Bitmap bmp = null; System.IO.Stream imgStream = thisExe.GetManifestResourceStream( "Plugin.Resources.online_16x16.png" );
bmp = Bitmap.FromStream( imgStream ) as Bitmap; if ( !( null == bmp ) ) { Rectangle rect = new Rectangle( 0, 0, bmp.Width, bmp.Height ); BitmapData bmpData = bmp.LockBits( rect, ImageLockMode.ReadOnly, bmp.PixelFormat ); MediumEntry.png_image_16 = bmpData.Scan0; MediumEntry.png_image_16_len = (uint)imgStream.Length;
// Unlock the bits. bmp.UnlockBits( bmpData ); }
-- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|
  nirvansk815 Premium join:2001-06-18 Rancho Cucamonga, CA clubs:
·Charter Pipeline
| »www.codeproject.com/KB/dotnet/em···ces.aspx
Maybe this guy knows? -- There's so much to be thankful for...How can anyone be sad? |
|
  USR56K
join:2000-05-20 Seattle, WA clubs: | Doubt it. That only deals with embedded resources on .NET projects. Not the issues of using one in unmanaged code. |
|
  nirvansk815 Premium join:2001-06-18 Rancho Cucamonga, CA clubs:
·Charter Pipeline
| Does it have to be C#? Why not use C++/CLI and use the unmanaged code directly?
»www.codeproject.com/KB/mcpp/quic···.aspx#A9
»www.codeproject.com/KB/mcpp/whycppcli.aspx -- There's so much to be thankful for...How can anyone be sad? |
|
  USR56K
join:2000-05-20 Seattle, WA clubs:
·Charter Pipeline
| said by nirvansk815 :Does it have to be C#? Why not use C++/CLI and use the unmanaged code directly? The whole program/plugin I'm writing? Because there is an existing framework I started with and am expanding, which is already done in C#. Too much has been accomplished so far to go back to square 1 with C++/CLI. Additionally, I'm implementing the Facebook Developer Toolkit in my app, which too is C#.
This image problem is my last major hurtle at the moment. I've considered using a pure C++ dll with the sole purpose of loading images (from its native C+++ resources). But that is really 'clunky' and not ideal. There just MUST be some way to accomplish whats needed to make this work. -- If it's not on Google, then it doesn't exist.
**DC++ FAQ** |
|