Reputation: 331
If I build my application and link against a resource file that is not using a HiDPI aware manifest then everything works correctly but the fonts are, as one would expect, pixelated. However, once I link with a HiDPI aware resource file then the controls are not resized proportionally with their associated text. Please see the following screenshots.
The image above shows the test wxFrame being rendered without a HiDPI aware resource file. The monitor scaling was 200%. As you can see, the wxFrame has rendered correctly.
The image above shows the test wxFrame being rendered without a HiDPI aware resource file. The monitor scaling was 350%. As you can see, (aside from the blurry text) the wxFrame has rendered correctly..
The image above shows the test wxFrame being rendered with a HiDPI aware resource file. The monitor scaling was 200%. As you can see, the wxFrame has rendered badly. This wxFrame renders correctly at 100% scale.
Here is a minimal fully functional code sample to demonstrate my problem.
#include <wx/wx.h>
#include <wx/frame.h>
#include <wx/sizer.h>
#include <wx/button.h>
class HiDPI_Test: public wxFrame
{
public:
HiDPI_Test() :
wxFrame(NULL, wxID_ANY, "HiDPI Test")
{
wxBoxSizer *sizer_master = new wxBoxSizer(wxHORIZONTAL);
m_btn_1 = new wxButton(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_btn_1->SetMinSize(wxSize(-1, 30));
m_btn_1->SetMaxSize(wxSize(120, 30));
m_btn_1->SetLabel("Button Label Test");
m_btn_2 = new wxButton(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_btn_2->SetMinSize(wxSize(-1, 30));
m_btn_2->SetMaxSize(wxSize(120, 30));
m_btn_2->SetLabel("Button Label Test");
sizer_master->Add(m_btn_1, 0, wxALL | wxEXPAND, 0);
sizer_master->Add(m_btn_2, 0, wxALL | wxEXPAND, 0);
this->SetSizerAndFit(sizer_master);
this->Layout();
this->Centre(wxBOTH);
}
private:
wxButton *m_btn_1, *m_btn_2;
};
class HiDPI: public wxApp
{
public:
bool OnInit() override
{
HiDPI_Test *mainApp = new HiDPI_Test();
mainApp->Show();
return true;
}
};
wxIMPLEMENT_APP(HiDPI);
The calls to SetMinSize() and SetMaxSize() are vital to my overall UI design.
I built the wxWidgets resource file by using the following:
windres --use-temp-file -ires.rc -ores.o -I/home/user/resource -DwxUSE_DPI_AWARE_MANIFEST=2
I then pass the resulting object file to the linker when building my application.
It's important to add that my application renders correctly on wxWidgets/GTK3 (Linux) and wxWidgets macOS/Cocoa. That is to say, it works correctly (without pixelated fonts) on macOS and Linux at any scale value.
Does anybody have any idea why my application is not rendering correctly when I use a HiDPI aware resource file on Windows 10?
Upvotes: 2
Views: 575
Reputation: 22743
It's a pretty bad idea to use sizes in pixels in general, as this doesn't take the current font size into account, and so using dialog units or just the result of GetTextExtent("something") would be better.
But if you absolutely want to use pixels, you need to at least convert them to the proper units using FromDIP()
, see HiDPI overview in the manual for more information.
And if you use
m_btn_1->SetMinSize(FromDIP(wxSize(-1, 30)));
m_btn_1->SetMaxSize(FromDIP(wxSize(120, 30)));
your code works as expected in 200% scaling, at least with the current master (I think that this should work with 3.1.5 too, but there have been tons of high DPI-related improvements since then, so I strongly recommend using master/3.1.6 when it is released soon if you care about high DPI support).
Upvotes: 4