T-Rex / wxModularApp

Cross-Platform Modular Application (Main app + plugins) example for C++/wxWidgets
29 stars 17 forks source link

Unable to add resources in the dll #6

Open sohaibimran-lm opened 3 years ago

sohaibimran-lm commented 3 years ago

Hi T-Rex, I successfully used your example to generate a GUI from dll. It worked really well. But apart from generating a GUI from dll I had to add resources to the dll itself. In my scenario I had to add some buttons with bitmaps. So what I simply did was I added an icon in the resource file of SampleGuiPlugin1 like this

SampleGuiPlugin1.rc icon_up ICON "icon_up.ico"

Placed this icon into right path and set the icon as bitmap to a button like this

SampleGuiPluginWindow1.cpp itemButton5->SetBitmap(wxICON(icon_up));

and built the dll once again. But here after running ModulatHost.exe, the icon was not added in the bitmap button.

I simply replaced the icon_up with a standard icon provided by wxWidgets like:

SampleGuiPluginWindow1.cpp itemButton5->SetBitmap(wxICON(wxICON_SMALL_FILE));

This added fine I could see the icon in the button.

After doing a lot of research on wxForums and wxWidgets mailing list all of them suggested that this problem is happening because the dll is not initializing the wxWidgets seperately. They told that in my case the dll is only able to access resources of the .exe and that is because wxWidgets is initialized from there. They pointed me towards the sample that generates dll and told to follow that example.

https://forums.wxwidgets.org/viewtopic.php?f=23&t=48199&p=205440#p205440 and

Screenshot from 2021-04-29 11-32-36

So I think this project wont be able to add resources from the dll in this state. It needs some tweaking

T-Rex commented 3 years ago

It's not an issue of this sample app. if you want to use the plugins, you have to use a single instance of wxWidgets which gets shared between the DLLs and the App. You should not call wxSetInstance() inside the DLL if you want GUI controls. You can actually try by yourself, in case if you get the desired logic + GUI from DLL working, you can submit a pull request or suggest a patch. Also, if you want your app be cross-platform, you'd better consider using images/icons or other assets from files.

T-Rex commented 3 years ago

As an option, under Windows you can use Windows-specific API to load the image from resources, then pass HICON or HBITMAP to wxIcon or wxBitmap as a source.

sohaibimran-lm commented 3 years ago

As an option, under Windows you can use Windows-specific API to load the image from resources, then pass HICON or HBITMAP to wxIcon or wxBitmap as a source.

Thanks for your suggestion. I think I would be trying this approach. I will share the code if I am able to do that here. Any links to this specific approach would be very helpful.

sohaibimran-lm commented 3 years ago

It's not an issue of this sample app. if you want to use the plugins, you have to use a single instance of wxWidgets which gets shared between the DLLs and the App. You should not call wxSetInstance() inside the DLL if you want GUI controls. You can actually try by yourself, in case if you get the desired logic + GUI from DLL working, you can submit a pull request or suggest a patch.

I think I understand this and even if I try, I think it won't work until I initialize the wxWidgets separately inside dll just as dll sample has done. Can you tell what difference does it make by using libs to make a dll. Or making a dll as you have made?

Also, if you want your app be cross-platform, you'd better consider using images/icons or other assets from files.

Can you suggest what files can help in this case? I am a bit unaware of this scenario.

T-Rex commented 3 years ago

Can you tell what difference does it make by using libs to make a dll. Or making a dll as you have made?

When you compile wxWidgets as static lib and then use it for building the DLL, then every DLL and the EXE itself will have its own copy of wxWidgets with its own message loop, resources and other logic which runs under the hood. And in this case you will not be able to host a window/control from one instance of wxWidgets in the window/control from another instamnce (at least in a normal wxWidgets way of doing this). This will be like you are running 2+ separate wxWidgets-based apps. So, if you want to have GUI from plugins, you need a single instance of wxWigdtes. And this is done by building the DLL version of wxWidgets and linking agains it. In this case the single instance of wxWidgets will be shared between the plugins and host app (as it is done in this sample).

Can you suggest what files can help in this case? I am a bit unaware of this scenario.

You can create an assets subdirectory near your app's EXE file, specify the Working Directory in Debug section of VS project to $(TargetDir), put PNG or ICO files with your icons into this assets directory and use the relative paths for loading the images and bitmaps.

sohaibimran-lm commented 3 years ago

You can create an assets subdirectory near your app's EXE file, specify the Working Directory in Debug section of VS project to $(TargetDir), put PNG or ICO files with your icons into this assets directory and use the relative paths for loading the images and bitmaps.

Thank you for the suggestion. In fact thanks for every thing