When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

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.
Sridhar@Work
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 221
Joined: Fri Jan 08, 2021 8:19 am

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by Sridhar@Work »

doublemax wrote: Thu Jun 23, 2022 12:30 pm Once again: How is the bitmap displayed? The automatic only works for controls that take a wxBitmapBundle as parameter, e.g. a wxStaticBitmap. It won't work if you draw a wxBitmap yourself onto a wxDC.
It is displayed properly and not blurred. The size at 100% is same as size at 200% i.e. both have 600x90 pixels dimensions at all dpi's.
We are using wxStaticBitmap but wxBitmapBundle is not used. We are not doing any custom draw functions. It is done by calling wxBITMAP_PNG()
the image is loaded from resource file using the identifier.
Sridhar@Work
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 221
Joined: Fri Jan 08, 2021 8:19 am

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by Sridhar@Work »

Sridhar@Work wrote: Thu Jun 23, 2022 11:49 am
doublemax@work wrote: Wed Jun 22, 2022 7:20 am JFYI, if one wants to be sure which DPI-aware mode an application is using (if any), I always recommend using Task Manager: In its Details tab, make sure that column "DPI Awareness" is displayed, and it contains "Per-Monitor (v2)" and not just "Per-Monitor" for the application.
Thank you. I will look into this and update the thread.
There is a third party application exe (java application) which internally dynamically loads our wxwidgets UI dll and launches the dialog in a separate thread. So when I view the DPI awareness in the process, it shows "System" under the java application exe. Maybe it is for the process and not the thread dialog inside it. I might be able to view the DPI aware of the thread inside it. Maybe I will have to use process explorer (exe) instead of Task Manager?
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by doublemax »

Sridhar@Work wrote: Fri Jun 24, 2022 5:04 am There is a third party application exe (java application) which internally dynamically loads our wxwidgets UI dll and launches the dialog in a separate thread.
Maybe you should have mentioned that earlier? By default the DLL inherits the DPI awareness of the parent executable.

https://docs.microsoft.com/en-us/window ... plications
I have no experience with this, so i can't answer any questions about it.
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by PB »

I don't think Process Explorer shows DPI-awareness per thread anywhere.

As doublemax said, you probably need to query your thread DPI-awareness via Windows API to see if the manifest is in effect (and is correct). FWIW, it could be done simply by using my https://github.com/PBfordev/wxsysinfoframe, as seen here https://raw.githubusercontent.com/PBfor ... s/misc.png.

But once again, are we still sure that the issue here is DPI-awareness? wxBITMAP_PNG() and similar are not really suitable for HiDPI, as they do not support multiple resolutions...
Sridhar@Work
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 221
Joined: Fri Jan 08, 2021 8:19 am

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by Sridhar@Work »

PB wrote: Fri Jun 24, 2022 7:18 am I don't think Process Explorer shows DPI-awareness per thread anywhere.

As doublemax said, you probably need to query your thread DPI-awareness via Windows API to see if the manifest is in effect (and is correct). FWIW, it could be done simply by using my https://github.com/PBfordev/wxsysinfoframe, as seen here https://raw.githubusercontent.com/PBfor ... s/misc.png.

But once again, are we still sure that the issue here is DPI-awareness? wxBITMAP_PNG() and similar are not really suitable for HiDPI, as they do not support multiple resolutions...
Thank you. I will definitely query that in code and check if something is not set internally.

I was using 3.1.6 using wxBITMAP_PNG() without adding any wx.rc to add wxwidgets dpiaware manifest to so that UI to auto scale without any issues.
The issue got reported when I upgraded the code from 3.1.6 to 3.1.7. So surely something in 3.1.7 is changed w.r.t DPI aware code that is causing this issue or maybe do I have to use wxBitmapBundle and not wxBITMAP_PNG() - is this the issue?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by ONEEYEMAN »

Hi,
In 3.1.7 you need to use wxBitmapBundle.
Is there a reason you don't want to?

Thank you.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: When upgrade code from wxwidgets 3.1.6 to 3.1.7, auto scaling at higher DPI doesn't work using wxBITMAP_PNG()

Post by PB »

Obviously, the signature of wxStaticBitmap methods changed between 3.1.6 and 3.1.7, the latter using wxBitmapBundle where the former had wxBitmap.

As I was still not sure what is the issue, I tried comparing 3.1.6, 3.1.7, and a week old GIT master.

I had 100x100 px PNG bitmap, loaded from resource to wxStaticBitmap in a PMv2 DPI-aware application on Win10 21H2 system where the primary monitor is at 125%DPI and the secondary one unscaled.

The bitmap in wxStaticBitmap did not change size in any version, i.e., I could not observe any difference.

Code (uses default wxStaticBitmap ScaleMode)

Code: Select all

#include <wx/wx.h>
#include <wx/statbmp.h>

class MyFrame : public wxFrame
{
public:
    MyFrame () : wxFrame(nullptr, wxID_ANY, "Test")
    {
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

        wxBitmap bmp = wxBITMAP_PNG(mybitmap);
        m_staticBmp = new wxStaticBitmap(this, wxID_ANY, bmp);
        m_staticBmp->SetBackgroundColour(*wxRED);
        mainSizer->Add(m_staticBmp, wxSizerFlags(1).Expand());

        wxTextCtrl* logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));
        mainSizer->Add(logCtrl, wxSizerFlags(1).Expand());

        SetSizer(mainSizer);

        wxLogMessage("wxWidgets version: %s", wxVERSION_NUM_DOT_STRING);
        LogBitmapSize(bmp, "PNG resource bitmap");

        Bind(wxEVT_DPI_CHANGED, [this](wxDPIChangedEvent& e) { e.Skip(); LogBitmapSize(m_staticBmp->GetBitmap(), "wxStaticBitmap bitmap");});

        CallAfter([this] { LogBitmapSize(m_staticBmp->GetBitmap(), "wxStaticBitmap bitmap");} );
    }

private:
    wxStaticBitmap* m_staticBmp;

    void LogBitmapSize(const wxBitmap& bmp, const wxString& bmpIdent)
    {
        const wxSize size = bmp.GetSize();

        wxLogMessage("%s size: %d x %d", bmpIdent, size.x, size.y);
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        wxInitAllImageHandlers();
        (new MyFrame())->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);
Resource file (wxUSE_RC_MANIFEST and wxUSE_DPI_AWARE_MANIFEST=2 are set in the resource compiler definitions in the MSVS project)

Code: Select all

#include "wx/msw/wx.rc"

MYBITMAP RCDATA "mybitmap.png"
When wxStaticBitmap was allowed to expand, in all versions the control expanded but the bitmap remained centered at the original size.

I did not measure if the bitmap displayed is actually 100x100, I blindly trusted what wxWidgets reported. It is also possible that wxStaticBitmap returns the bitmap used when constructing it and not the one it is actually using, but...

EDIT
I tried changing my DPI scaling from 125% to 200%. After doing this, the bitmap from wxStaticBitmap resizes from 100x100 to 200x200, the scaling is probably done in some steps, e.g. integer multiplies only. Still, the bitmap scaled in all three wxWidgets versions the same.
Attachments
mybitmap.png
mybitmap.png (400 Bytes) Viewed 321 times
Post Reply