Click here to Skip to main content
15,891,920 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all, hopefully someone will be able to help :)

I've managed to get the following code to "work".
My problem, however, is the icon file which is created from the resource, is missing the first 22 bytes.
Apart from the missing bytes, the rest of the file is OK (but obviously not a valid nor working icon).
(I checked by viewing original icon and new icon in a HEX editor.)

The size of the original Icon is 1,150 bytes. So, I double checked what dwSizeRes is actually finding.
The size dwSizeRes is returning, is only 1,128 bytes.

The resource is being correctly shown as the compiled applications Icon, so has been included into the project correctly.

I'm still somewhat new to C++, so it may be something silly that I'm overlooking.

If anyone would be able to hint at or tell me where I'm going wrong, I'd be very grateful.

Thanks in advance,
Gremz.


#include <windows.h>
#include <fstream>

int main () 
{
      HGLOBAL hResourceLoaded;      // handle to loaded resource
   HRSRC hRes;                  // handle/ptr. to res. info.
   char *lpResLock;            // pointer to resource data
   DWORD dwSizeRes;
   
   // find location of the resource and get handle to it
   hRes = FindResource( GetModuleHandle(NULL), MAKEINTRESOURCE(1), RT_ICON );

   // loads the specified resource into global memory.
   hResourceLoaded = LoadResource( NULL, hRes );

   // get a pointer to the loaded resource!
   lpResLock = (char*)LockResource( hResourceLoaded );

   // determine the size of the resource, so we know how much to write out to file 
   dwSizeRes = SizeofResource( NULL, hRes );

   // for testing, check if hRes is being populated.
      if(hRes==NULL){
	   printf("hRes not being populated.");
   }
   else{
   // if populated, all is well
   std::cout << dwSizeRes; // double check what dwSizeRes is saying the size is
   std::ofstream outputFile("c:\\test.ico", std::ios::binary);

   outputFile.write((const char*)lpResLock, dwSizeRes);
   outputFile.close();
   }

	}
Posted
Updated 22-Jul-11 0:45am
v5

You cannot load a resource into your application and then write it to a file in this way, as an icon resource and an icon file are not exactly the same thing. The icon file contains header information which is not part of the actual resource, so what you get loaded into memory is not the complete file. Take a look here[^] for more information about icon structures.
 
Share this answer
 
Comments
Gremz 22-Jul-11 9:16am    
Ahh, thank you Richard.
I had a feeling it may have been "dropping" the header information, but it's great to know exactly why & what's happening :)
Bits or bytes ? Did you debug and check the byte array you're writing to disk ?
 
Share this answer
 
Comments
Gremz 21-Jul-11 20:44pm    
Ah yes, bytes, sorry. Will update that now.
Debug, yes. No errors came up at all.

I'm not exactly sure how to check the byte array, though :(
Christian Graus 21-Jul-11 20:47pm    
You can type it in to the immediate window and see what the bytes are, there's also a memory watcher that gives you a hex editor.
Gremz 21-Jul-11 21:00pm    
Cheers Christian, shall do some research into it now :)
Gremz 22-Jul-11 6:23am    
OK, I've worked out what's happening, but not why or how to get around it.

The size of the original Icon is 1,150 bytes.
So, I double checked what dwSizeRes is actually finding.

std::cout <<dwSizeRes;

The size dwSizeRes is returning, is only 1,128 bytes.

Could this mean that the Icon didn't actually add to the project correctly..?
Ok, thanks to Richard's information, I've managed to find a way around it of sorts. Posting it here in case others have the same issue.

If the Icon is to be used for both the application and to be extracted to a *.ico file you will need to include the Icon as both an ICON and RCDATA.
ICON means it can still be used for the application's Icon.
RCDATA will load the Icon as just data, so it won't "strip" the header information :)

So changes to my original code:

hRes = FindResource( GetModuleHandle(NULL), MAKEINTRESOURCE(1), RT_RCDATA );

And in the *.rc file add another line with it changed from ICON to RCDATA.


Thanks everyone for your help.
It's truly great to have a place like codeproject to ask questions and not worry about being flamed etc :)
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900