Adding resources in .dll

159 views
Skip to first unread message

Sohaib Imran

unread,
Apr 8, 2021, 6:16:15 AM4/8/21
to wx-users
Hello,
I am a beginner in wxWidgets. I am using windows and visual studio for development of my applications. Recently I was asked to convert my .exe application to a dll so that another .exe can load it as a plugin.
The application that I made had an icon and various buttons that had loaded bitmaps to them. All the bitmaps were set using resources.rc file where I declared all the bitmaps in resources like this

"sample.rc"
application      ICON            "application.ico"
button1            ICON            "button1.bmp"
and in my code where I set these


btnMyButton->SetBitmap(wxICON(button1));

The application loaded all the icons correctly in the .exe of the app. But when I converted my application to a dll (to be used as a plugin) all the icons were disappeared. My buttons did not load the bitmaps. My frame was icon less. In the host .exe the error message was
Can't load bitmap 'button1.bmp' from resources! Check .rc file
So my question is

How can we include the resources in the dll so that when it is loaded as plugin from a different .exe it loads all the icons and bitmaps if any correctly.

Any suggestions or links would also be appreciated

Vadim Zeitlin

unread,
Apr 8, 2021, 8:27:43 AM4/8/21
to wx-u...@googlegroups.com
On Thu, 8 Apr 2021 03:16:15 -0700 (PDT) Sohaib Imran wrote:

SI> Hello,
SI> I am a beginner in wxWidgets. I am using windows and visual studio for
SI> development of my applications. Recently I was asked to convert my .exe
SI> application to a dll so that another .exe can load it as a plugin.

Just a warning: this is usually not completely trivial to do,
independently of the problem with the resources, because you need to decide
who is running the main event loop, the application or the DLL.

SI> The application that I made had an icon and various buttons that had loaded
SI> bitmaps to them. All the bitmaps were set using resources.rc file where I
SI> declared all the bitmaps in resources like this
SI>
SI> "sample.rc"
SI> application ICON "application.ico"
SI> button1 ICON "button1.bmp"
SI> and in my code where I set these
SI>
SI> btnMyButton->SetBitmap(wxICON(button1));
SI>
SI> The application loaded all the icons correctly in the .exe of the app. But
SI> when I converted my application to a dll (to be used as a plugin) all the
SI> icons were disappeared. My buttons did not load the bitmaps. My frame was
SI> icon less. In the host .exe the error message was
SI> Can't load bitmap 'button1.bmp' from resources! Check .rc file
SI> So my question is
SI>
SI> How can we include the resources in the dll so that when it is loaded as
SI> plugin from a different .exe it loads all the icons and bitmaps if any
SI> correctly.

You need to initialize wxWidgets correctly from the DLL, so that it uses
the DLL instance handle and not the application one. You seem to be
initializing it from the application instead and this is not going to work
for many other reasons unless the DLL and the application use exactly the
same wxWidgets version -- which is not something you can usually guarantee
for a plugin.

There are 2 solutions that work:

1. If the application doesn't use wxWidgets, the DLL can statically link
with its own copy of wxWidgets. It will initialize it using its own
instance handle from its DllMain().

2. If both the application and the DLL use wxWidgets, then you must use
the same wxWidgets DLL in both of them.

The first case is simpler, so if you can, try doing it like this.

Good luck,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

PB

unread,
Apr 8, 2021, 11:04:50 AM4/8/21
to wx-users
(I already wrote basically the same as an answer on wxForum)

wxWidgets initialization stuff aside, let's assume both the plugin DLL and application EXE correctly use the same wxWidgets DLL.

How can such a plugin DLL access its own icon resources with wxIcon? wxIconResource handler uses wxGetInstance() to access the resources (i.e., the EXE's HINSTANCE here), so I do not see any way to use the plugin DLL's HINSTANCE?

OTOH, I have always believed wxICON() suboptimal, as it cannot use multiple icon resolutions, which Windows then can use in addition to the icon being displayed in a frame (e.g., switching tasks, task bar) instead of scaling them. That's why I recommended using wxIconBundle instead, which (since 3.1.1) allows using a custom HINSTANCE.

Regards,
PB

Vadim Zeitlin

unread,
Apr 8, 2021, 5:38:21 PM4/8/21
to wx-u...@googlegroups.com
On Thu, 8 Apr 2021 08:04:50 -0700 (PDT) PB wrote:

P> How can such a plugin DLL access its own icon resources with wxIcon?
P> wxIconResource handler uses wxGetInstance() to access the resources (i.e.,
P> the EXE's HINSTANCE here),

It should be the DLL HINSTANCE if wx was initialized by the DLL, I think.
In the worst case, wxSetInstance() can be called directly to set the right
instance handle.

P> OTOH, I have always believed wxICON() suboptimal, as it cannot use multiple
P> icon resolutions, which Windows then can use in addition to the icon being
P> displayed in a frame (e.g., switching tasks, task bar) instead of scaling
P> them. That's why I recommended using wxIconBundle instead, which (since
P> 3.1.1) allows using a custom HINSTANCE.

Yes, this is definitely a very good point.

Regards,

Sohaib Imran

unread,
Apr 12, 2021, 2:08:59 AM4/12/21
to wx-users
Thanks a lot for the explanation. Thanks PB for helping me both at the forum and here it really means a lot.
 
Sorry because I am a beginner it seems a little complex to me.  From your explanations, please correct me if I have understood something wrong.

P> How can such a plugin DLL access its own icon resources with wxIcon?
P> wxIconResource handler uses wxGetInstance() to access the resources (i.e.,
P> the EXE's HINSTANCE here),

Even if we use same versions of wxWidgets DLLs for building the EXE and the plugin, we cannot use wxIcon for accessing plugins resources because wxIcon uses wxGetInstance that only access the HINSTANCEs (resources) of the EXE and not the plugin?

V> It should be the DLL HINSTANCE if wx was initialized by the DLL, I think.
V> In the worst case, wxSetInstance() can be called directly to set the right
V> instance handle

So it all depends upon from where wx is initialized? If it is initialized from the DLL it will use the DLL HINSTANCE but if it is initialized by the EXE it will use the EXE HINSTANCE?

In the example -> samples/dll project I set the icon in the my_dll's project (by adding resource .rc file to that project) and it worked fine (the icon was set) is it because the example has initialized everything rightly and I am not initializing my plugin (dll) correctly?

Thanks in advance.
You guys are such a nice community.

PB

unread,
Apr 12, 2021, 1:48:58 PM4/12/21
to wx-users
TBH, I know little about plugin stuff.

Be it as it may, if the application executable and a plugin DLL share the same instance of the wxWidgets DLL, wxWidgets is probably going to be initialized from the executable and using the executable's HINSTANCE to access resources.

If a plugin DLL has its own separate (or only) instance of wxWidgets, as it is done in the dll sample, DLL's HINSTANCE is going to be used and as you saw, everything works out of the box.

Vadim Zeitlin

unread,
Apr 12, 2021, 3:38:19 PM4/12/21
to wx-u...@googlegroups.com
On Sun, 11 Apr 2021 23:08:59 -0700 (PDT) Sohaib Imran wrote:

SI> Even if we use same versions of wxWidgets DLLs for building the EXE and the
SI> plugin, we cannot use wxIcon for accessing plugins resources because wxIcon
SI> uses wxGetInstance that only access the HINSTANCEs (resources) of the EXE
SI> and not the plugin?

You can use plugin DLL resources if you tell wxWidgets to use its
HINSTANCE, which is what happens if you initialize wx from this DLL. But
you indeed can't use both the EXE and the plugin DLL resources if you use
the same wx DLL from both of them.

If you really need to do it, the simplest solution might be to call
::LoadIcon() itself, passing it the correct HINSTANCE, and then use
wxIcon::CreateFromHICON().

SI> So it all depends upon from where wx is initialized? If it is initialized
SI> from the DLL it will use the DLL HINSTANCE but if it is initialized by the
SI> EXE it will use the EXE HINSTANCE?

Yes, when you initialize it from the DLL you usually call wxEntryStart()
yourself and you should pass it the DLL HINSTANCE in this case (as you
don't have any other one, anyhow).

SI> In the example -> samples/dll project I set the icon in the my_dll's
SI> project (by adding resource .rc file to that project) and it worked fine
SI> (the icon was set) is it because the example has initialized everything
SI> rightly and I am not initializing my plugin (dll) correctly?

Yes, the sample has a comment about passing the correct HINSTANCE to
wxEntry(). The same thing applies to wxEntryStart().

krishnaLee

unread,
Apr 13, 2021, 2:10:09 AM4/13/21
to wx-u...@googlegroups.com
I know little about windows resource file althrough I am a windows user,
If I were you, May be I will convert all the icons to C arrray, such as:

static const char* my_xpm_icon_buffer[]=
{
 .........................
 .........................
 .........................
}

the wxWidgets can handle xpm_image buffer, so it's really simple, 
then you can include it in your code file and do whatever you want.


thanks.

Krishna.

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
 
To unsubscribe, send email to wx-users+u...@googlegroups.com
or visit http://groups.google.com/group/wx-users
---
You received this message because you are subscribed to the Google Groups "wx-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wx-users+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-users/2350c2b6-1012-44db-ad6d-bc5014dc1e90n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages