Perhaps instead of hard-coding the values, you could use the way described in the second post I linked. Possibility of these values changing in future Windows versions aside, I would not be surprised if these values were noticeably different when using large DPI scaling such as 200%.
EDIT
Just for the future reference, this seems to work fine
Code: Select all
#include <wx/wx.h>
#include <wx/display.h>
#ifdef __WXMSW__
#include <dwmapi.h> // needs also to link with dwmapi.lib
#endif // __WXMSW__
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(nullptr, wxID_ANY, _("Test"))
{
wxPanel* mainPanel = new wxPanel(this);
wxBoxSizer* mainPanelSizer = new wxBoxSizer(wxVERTICAL);
wxButton* button = new wxButton(mainPanel, wxID_ANY, "Fit to Screen");
button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::FitToScreen, this);
mainPanelSizer->Add(button, wxSizerFlags().Border().CenterHorizontal());
wxTextCtrl* logCtrl = new wxTextCtrl(mainPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxTE_RICH2 | wxTE_READONLY);
wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));
wxLog::DisableTimestamp();
mainPanelSizer->Add(logCtrl, wxSizerFlags().Proportion(1).Expand().Border());
mainPanel->SetSizer(mainPanelSizer);
}
private:
static wxString wxRectTowxString(const wxRect& r)
{
return wxString::Format(_("(left, top; right, bottom): %d, %d; %d, %d"),
r.GetLeft(), r.GetTop(), r.GetRight(), r.GetBottom());
}
void FitToScreen(wxCommandEvent&)
{
const wxDisplay display(wxDisplay::GetFromWindow(this));
if ( !display.IsOk() )
{
wxLogError("Could not create wxDisplay from this window.");
return;
}
const wxRect displayClientRect(display.GetClientArea());
wxRect windowRect(displayClientRect);
wxLogMessage("%s (%dx%d DPI) client rect %s", display.GetName(),
display.GetPPI().GetWidth(), display.GetPPI().GetHeight(),
wxRectTowxString(displayClientRect));
#ifdef __WXMSW__
// based on the code from https://stackoverflow.com/a/34143777/7267315
RECT dwmRect;
if ( SUCCEEDED(::DwmGetWindowAttribute(GetHWND(), DWMWA_EXTENDED_FRAME_BOUNDS,
&dwmRect, sizeof(dwmRect))) )
{
wxRect borders;
wxRect windowRectAdjusted(GetRect());
borders.SetLeft(dwmRect.left - windowRectAdjusted.GetLeft());
borders.SetTop(dwmRect.top - windowRectAdjusted.GetTop());
borders.SetRight(windowRectAdjusted.GetRight() - dwmRect.right);
borders.SetBottom(windowRectAdjusted.GetBottom() - dwmRect.bottom);
wxLogMessage("Window invisible borders %s", wxRectTowxString(borders));
windowRectAdjusted = windowRect;
windowRectAdjusted.Offset(-borders.GetLeft(), -borders.GetTop());
windowRectAdjusted.SetWidth(windowRect.GetWidth() + borders.GetLeft() + borders.GetRight());
windowRectAdjusted.SetHeight(windowRect.GetHeight() + borders.GetTop() + borders.GetBottom());
wxLogMessage("Adjusted fit-to-screen window rect %s", wxRectTowxString(windowRectAdjusted));
windowRect = windowRectAdjusted;
}
#endif // __WXMSW__
SetSize(windowRect);
}
};
class MyApp : public wxApp
{
public:
bool OnInit() override
{
(new MyFrame())->Show();
return true;
}
}; wxIMPLEMENT_APP(MyApp);;
Regarding the difference with DPI scaling:
Code: Select all
\\.\DISPLAY1 (120x120 DPI) client rect (left, top; right, bottom): 0, 0; 2559, 1338
Window invisible borders (left, top; right, bottom): 8, 0; 7, 7
Adjusted fit-to-screen window rect (left, top; right, bottom): -8, 0; 2566, 1345
\\.\DISPLAY2 (96x96 DPI) client rect (left, top; right, bottom): -1680, 195; -1, 1204
Window invisible borders (left, top; right, bottom): 7, 0; 6, 6
Adjusted fit-to-screen window rect (left, top; right, bottom): -1687, 195; 5, 1210
so the difference could be noticeable with higher differences in DPI scalings when hard-coded borders are used...
You can also see (for \\.\DISPLAY2) that for the display client rect neither top nor left are always 0, if one has multiple displays (which is nowadays very common).