SetBackgroundBitmap results in white background

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
GamerX
Earned a small fee
Earned a small fee
Posts: 17
Joined: Wed Oct 20, 2021 3:06 pm

SetBackgroundBitmap results in white background

Post by GamerX »

Compiler: Microsoft Visual Studio Community 2019 Version 16.11.5
wxWidgets: Compiled https://github.com/wxWidgets/wxWidgets/ ... 7398875681 with MT and MTd as static x64 lib
Platform: Windows 10 Home Build 19043 x64

When I call SetBackgroundBitmap, all it does is make the background white instead of gray, my bitmap is not applied. There is no runtime error or warning about the bitmap being not loaded either (which I do get if I specify a non existent bitmap). The bitmap has a resolution of 1280x720 and is not transparent.
Thanks again for the help.

Code: Select all

// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/valgen.h>
#include <wx/custombgwin.h>

class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
    wxString Title = "wxTest";
    MyFrame();
private:

    wxDECLARE_EVENT_TABLE();
};
class MyControlPanel : public wxCustomBackgroundWindow<wxPanel>
{
public:
    wxBitmap Wallpaper00 = wxBitmap(L"IDB_WALLPAPER00", wxBITMAP_TYPE_BMP_RESOURCE);
    MyControlPanel(wxWindow* parent);
private:
};

wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)

wxEND_EVENT_TABLE()

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
    MyFrame* frame = new MyFrame();
    frame->Show(true);
    return true;
}
MyFrame::MyFrame()
    : wxFrame()
{
    Create(NULL, wxID_ANY, Title);
    SetSizeHints(wxSize(1280, 720), wxSize(1280, 720));
    MyControlPanel* ControlPanel = new MyControlPanel(this);
}

MyControlPanel::MyControlPanel(wxWindow* parent)
    : wxCustomBackgroundWindow<wxPanel>()
{
    Create(parent, wxID_ANY);
    SetBackgroundBitmap(Wallpaper00);
}
My .rc file:

Code: Select all

#include "wx/msw/wx.rc"

/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

IDB_WALLPAPER00         BITMAP                  "res\\bmp\\wallpaper_00.bmp"

IDB_WALLPAPER01         BITMAP                  "res\\bmp\\wallpaper_01.bmp"

IDB_WALLPAPER02         BITMAP                  "res\\bmp\\wallpaper_02.bmp"

IDB_WALLPAPER03         BITMAP                  "res\\bmp\\wallpaper_03.bmp"

IDB_WALLPAPER04         BITMAP                  "res\\bmp\\wallpaper_04.bmp"

IDB_WALLPAPER05         BITMAP                  "res\\bmp\\wallpaper_05.bmp"

IDB_WALLPAPER06         BITMAP                  "res\\bmp\\wallpaper_06.bmp"

IDB_WALLPAPER07         BITMAP                  "res\\bmp\\wallpaper_07.bmp"

IDB_WALLPAPER08         BITMAP                  "res\\bmp\\wallpaper_08.bmp"

IDB_WALLPAPER09         BITMAP                  "res\\bmp\\wallpaper_09.bmp"

IDB_WALLPAPER10         BITMAP                  "res\\bmp\\wallpaper_10.bmp"

IDB_WALLPAPER11         BITMAP                  "res\\bmp\\wallpaper_11.bmp"

IDB_WALLPAPER12         BITMAP                  "res\\bmp\\wallpaper_12.bmp"


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
MAINICON                ICON                    "res\\ico\\MAINICON.ico"
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

I know you said you do not get an error when loading a bitmap. Still, I would start checking if its IsOk() returns true.

I also find the way you initialize member variables odd, but I guess that should work.
GamerX
Earned a small fee
Earned a small fee
Posts: 17
Joined: Wed Oct 20, 2021 3:06 pm

Re: SetBackgroundBitmap results in white background

Post by GamerX »

PB wrote: Thu Oct 21, 2021 5:10 pm I know you said you do not get an error when loading a bitmap. Still, I would start checking if its IsOk() returns true.

I also find the way you initialize member variables odd, but I guess that should work.
Yeah I just did some temporary code here for testing purposes. Wallpaper00.IsOk() returns true. Do I need to call some special function after SetBackgroundBitmap to refresh the panel?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

Disclaimer: I have never used wxCustomBackgroundWindow.

I tried running a test with your code but for simplicity sake using

Code: Select all

wxArtProvider::GetBitmap(wxART_ERROR)
as the bitmap. Worked as expected.

Then I tried using a bitmap from resource, with size of about 800x600 resulting into a white window just as you. I thought it may be due to large image size, but even when scaling the bitmap to 40x40 (same as the one from wxArtProvider), the result was the same.

I have no idea what is going on. Perhaps someone else will.

BTW, which wxWidgets version are you running? EDIT Tried with 3.0.5 to check if it is not a regression (due to recent bitmap changes), same result.
GamerX
Earned a small fee
Earned a small fee
Posts: 17
Joined: Wed Oct 20, 2021 3:06 pm

Re: SetBackgroundBitmap results in white background

Post by GamerX »

I´ll try your method then (if it´s not too complex for loading my wallpapers). As written in my initial post, I compiled the wxWidgets source code from github with the following last commit as I cloned the repo: https://github.com/wxWidgets/wxWidgets/ ... 7398875681
with MT and MTd as a static x64 lib.

Edit: So from the documentation, it seems that wxBitmap is the recommended way for loading a bitmap from resources. When tracing the code, it even correctly extracted the resolution of the loaded bitmap, so I have no idea why this won´t work, maybe it´s some super obvious oversight on my end.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

I do not think wxWidgets build has anything to do with that. I am using 64-bit Debug DLL with dynamic CRT, BTW.

I did some more tests and found out that it works for another bitmap.

The other bitmap is the non-working BMP saved as a PNG, which I added to my resource as

Code: Select all

IDB_WALLPAPER01 RCDATA "wallpaper_01.png"
When running the modified code with

Code: Select all

MyControlPanel::MyControlPanel(wxWindow* parent)
    : wxCustomBackgroundWindow<wxPanel>()
{
    wxInitAllImageHandlers();

    Create(parent, wxID_ANY);

    if ( wxMessageBox("Press 'Yes' to use BMP or 'No' to use PNG", "Select", wxYES_NO) == wxYES )
        Wallpaper00 = wxBITMAP(IDB_WALLPAPER00);
    else
        Wallpaper00 = wxBITMAP_PNG(IDB_WALLPAPER01);

    wxLogMessage("depth = %d bpp, DIB = %s, alpha = %s",
        Wallpaper00.GetDepth(), Wallpaper00.IsDIB() ? "Yes" : "No", Wallpaper00.HasAlpha() ? "Yes" : "No");

    SetBackgroundBitmap(Wallpaper00);
}
There is a difference between the working (PNG) and non-working (BMP) bitmaps: the former has the depth of 24 bpp and is a DIB, while the latter has 32 bpp and is not a DIB.

As no such limitation is documented I would consider this a bug.

And being you, having such horrible first experiences with wxWidgets, I would reconsider using it (not only because this). ;)
Last edited by PB on Thu Oct 21, 2021 6:55 pm, edited 2 times in total.
User avatar
doublemax
Moderator
Moderator
Posts: 19117
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackgroundBitmap results in white background

Post by doublemax »

I looked into the code for wxCustomBackgroundWindow, and under Windows it uses platform specific code, it creates a GDI brush directly from the bitmap. I can only guess, but maybe because the bitmap data lies inside the resource (= inside the executable) that it's somehow locked and can't be used that way?

Unfortunately wxBitmap has no Clone() method, try converting the bitmap to wxImage and back and check if it makes any difference.

Apart from that, follow PBs suggestion and use PNGs.
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

doublemax wrote: Thu Oct 21, 2021 6:54 pm I can only guess, but maybe because the bitmap data lies inside the resource (= inside the executable) that it's somehow locked and can't be used that way?
I tried that before when testing for image size with

Code: Select all

Wallpaper00 = wxBitmap(Wallpaper00.ConvertToImage().Scale(48, 48));
and without success.
User avatar
doublemax
Moderator
Moderator
Posts: 19117
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackgroundBitmap results in white background

Post by doublemax »

Hmm, ok. Then the only option left would be DIB vs DDB?
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

doublemax wrote: Thu Oct 21, 2021 6:57 pm Hmm, ok. Then the only option left would be DIB vs DDB?
I guess so, but as I wrote above, I would consider this a bug or a limitation that ought to be documented.

TBH I consider wxCustomBackgroundWindow a fringe class, probably not used much. It does not even have different modes for drawing the bitmap besides tiling it...
User avatar
doublemax
Moderator
Moderator
Posts: 19117
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackgroundBitmap results in white background

Post by doublemax »

After tracing through the code: For some reason loading with wxBITMAP_TYPE_BMP_RESOURCE forces the creation of a mask for the bitmap.

Calling Wallpaper00.SetMask(NULL) fixes this.

Don't ask me why...
Use the source, Luke!
GamerX
Earned a small fee
Earned a small fee
Posts: 17
Joined: Wed Oct 20, 2021 3:06 pm

Re: SetBackgroundBitmap results in white background

Post by GamerX »

I really appreciate all the suggestions guys, I wanted to give wxWidgets a try because I already tried out:
1) WinUI3 (still lacks some important features, cannot be easily deployed as a single exe)
2) Win32 (too cumbersome to get complex transparency controls done without flickering, tbh it even flickered with normal controls despite trying double buffering and what not)

And now I thought that wxWidgets would provide an experience similar to Win32, but with more options for handling stuff automatically, like background images (yeah, that PNG or mask fix method works for SetBackgroundBitmap, but the function doesn´t even align the image properly, it just tiles it, size cannot be specified either....) and transparent controls without flickering (looking good on that end so far).

So, I assume wxWidgets does not have any functionality that could get done what I want easily, right?
I basically want a C++ GUI that fulfills this:
1) A single .exe, all dependencies statically linked into it, CLOSED SOURCE, no license required (unlike what e.g. QT demands)
2) The GUI layout being: a custom "status" bar at the top, followed by a panel with controls below it, the panel has cycling background wallpapers, the controls have transparency and show the wallpaper behind them, the controls have a way to disable the annoying focus rectangle which just looks outdated on native win32, the controls don´t flicker (not even when the wallpaper is changed mid runtime).
3) What I definitely do not care about is crossplatform portability, my only target is Windows (and I´m even willing to sacrifice backwards compatibility with older Windows versions like 7 and 8 ).
4) What I definitely also want is PM DPI Awareness V2.

So, if you guys are telling me I´m not gonna be happy with wxWidgets, I would really gladly take your advice as to what C++ GUI framework makes the most sense in my situation. I know you´re way more experienced than me in that regard, so I would be very happy about suggestions. I´m sorry if my question is too much off topic.
Last edited by GamerX on Thu Oct 21, 2021 7:25 pm, edited 1 time in total.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

doublemax wrote: Thu Oct 21, 2021 7:15 pm After tracing through the code: For some reason loading with wxBITMAP_TYPE_BMP_RESOURCE forces the creation of a mask for the bitmap.

I considered testing also for a mask, but got lazy thinking that the mask would not survive converting to wxImage and back. Apparently it does.
User avatar
doublemax
Moderator
Moderator
Posts: 19117
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackgroundBitmap results in white background

Post by doublemax »

GamerX wrote: Thu Oct 21, 2021 7:23 pm 1) A single .exe, all dependencies statically linked into it, CLOSED SOURCE, no license required (unlike what e.g. QT demands)
No problem.
2) The GUI layout being: a custom "status" bar at the top, followed by a panel with controls below it, the panel has cycling background wallpapers, the controls have transparency and show the wallpaper behind them, the controls have a way to disable the annoying focus rectangle which just looks outdated on native win32, the controls don´t flicker (not even when the wallpaper is changed mid runtime).
As wxWidgets uses native controls where ever possible, this is your first show-stopper. You won't get semi-transparent controls over any background. You'd need custom controls for that. As long as they're only buttons, it should be easy. The more controls you need, the more of a hazzle it will become.
So, if you guys are telling me I´m not gonna be happy with wxWidgets, I would really gladly take your advice as to what C++ GUI framework makes the most sense in my situation. I know you´re way more experienced than me in that regard, so I would be very happy about suggestions.
Honestly, Qt is the only mature alternative.

If you could live without the "single exe", i'd use web technologies here (Electron, basically a Chrome bundled with your app). https://www.electronjs.org/
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: SetBackgroundBitmap results in white background

Post by PB »

GamerX wrote: Thu Oct 21, 2021 7:23 pm So, if you guys are telling me I´m not gonna be happy with wxWidgets
Firstly, I do not mean to bash wxWidgets.

That said, its biggest limitations from my viewpoint:
1. Uses Win32 API on Windows. This API is abandoned by MS, see no support for dark mode. OTOH, there is no real alternative there.
2. Very low bus factor.
3. Basically non-existent ecosystem, for example no decent maintained chart control with wxWindows licence.

There are others, such as the project being chronically understaffed resulting into late/little support for the greatest and latest stuff (e.g., GTK4) or just its inherent philosophy of using native controls whenever possible, resulting in limitations and inconsistencies for the same control between platforms, or inability to be skinned.

wxWidgets still has its uses but one has to be aware of its limitation and pick the right library for the job.

Qt aside, for example, (and if you need C++ which may not be the best idea in 2021) it seems that libraries such Dear ImGUI are currently popular. I am sure that it too has its limitations (aside from not looking "native", which some may consider a pro) but as usual, the grass is always greener on the other side. I think it has permissive license, assume it supports DPI awareness (it's 2021 FFS), but have no idea whether it allows static linking. TBH, IMO not having static linking is no big deal, as long as you can just install all required DLLs into your executable folder.
Last edited by PB on Thu Oct 21, 2021 7:47 pm, edited 1 time in total.
Post Reply