Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Is there a way to embed resources (such as icons, dialogs) in a c++ (Win32 API) static library?
My purpose is to embed an icon in the static library in a way that functions that use LoadIcon will work as if it was a normal .exe so the main application can only link to the static library and include a header file, with no requirement to add other files such as .rc files, or .ico files, etc.
Clearly the main application who uses the static library doesn't have this resource so LoadIcon will fail, however I was wondering if there is a workaround to make it work. A static array with the icon data can work as long as the standard API calls (such as LoadIcon) will work.

What I have tried:

Reading about similar questions and solutions, however I couldn't find any example of dynamically loading static data into memory and associating this block of memory so it can be used by LoadIcon as if there is a resource.
Posted
Updated 31-Mar-17 7:45am

I am posting an answer because after some research I found a way. Using my method, an icon can be used as an integral part of a static library and such library can be used by any type of application, including a console one (which doesn't have any resource segment whatsoever).

1. Icon is converted to a static array of BYTE. bin2c can be used for that.

2. Data is converted into a HICON handle. Here is how I have done that:

C++
HICON GetIcon()
{ 
   DWORD dwTmp;
   int offset;
   HANDLE hFile;
   HICON hIcon = NULL;
   offset = LookupIconIdFromDirectoryEx(s_byIconData, TRUE, 0, 0, LR_DEFAULTCOLOR);
   if (offset != 0)
   {
      hIcon = CreateIconFromResourceEx(s_byIconData + offset, 0, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
   }
   return hIcon;  
}


3. GetIcon is used instead of LoadIcon.
Instead of calling:

C++
m_hIcon = ::LoadIcon(hInstanceIcon, MAKEINTRESOURCE(pXMB->nIcon));

I call
C++
m_hIcon = GetIcon()


To test it, I created a Console application and a new static library. I added to the static library the XMessageBox - A reverse-engineered MessageBox()[^] class which allows using a custom icon.
The Console application just calls a function located at the static library and the icon is displayed!

See also: How to embed resources in a Static Library[^]
 
Share this answer
 
v2
You might have a look at this SO thread:
visual c++ - VC++ resources in a static library - Stack Overflow[^].

Especially the second solution looks interesting (I have never done such so far). That solution is also referenced at Linking resources from a static library | Tech Leaves[^].
 
Share this answer
 
Comments
Michael Haephrati 30-Mar-17 10:09am    
I read them but we wish to deploy 2 files: .lib and .h. These solutions require deploying the .rc file and having whoever uses our static library to link / include it as well.
Jochen Arndt 30-Mar-17 10:20am    
Then there is no solution from my point of view.
The SO thread covers it all.

If you are strictly limited to a lib and header file, you must store the data as binary arrays and provide helper functions to load them like resources as mentioned in the thread.

If you can accept a third file I would put the resources into a DLL. That can be referenced using a
#pragma comment(lib, ...)
within the static library.
The static library can also load the DLL and provide a function to return the module handle.
Michael Haephrati 30-Mar-17 10:48am    
"If you are strictly limited to a lib and header file, you must store the data as binary arrays and provide helper functions to load them like resources as mentioned in the thread." - Yes. that's the solution I am looking for (the icon can be converted to a static array using bin2c), however the icon should then be available the same way a standard icon would be, so LoadIcon would work with this memory based icon

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