diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 193682e6d7..f6bc5a4a93 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -895,9 +895,9 @@ public: void SetDropEffect( wxDragResult effect ) { m_dropEffect = effect; } wxDragResult GetDropEffect() const { return m_dropEffect; } // for plaforms (currently only OSX) that support Drag/Drop insertion of items, - // this is the proposed child index for the insertion - void SetProposedDropIndex(int index) { m_proposedDropIndex = index; } - int GetProposedDropIndex() const { return m_proposedDropIndex;} + // this is the proposed child index for the insertion + void SetProposedDropIndex(int index) { m_proposedDropIndex = index; } + int GetProposedDropIndex() const { return m_proposedDropIndex;} #endif // wxUSE_DRAG_AND_DROP virtual wxEvent *Clone() const wxOVERRIDE { return new wxDataViewEvent(*this); } diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index 6742e048ba..b6fc60857e 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -316,6 +316,8 @@ protected: virtual void DoEnableSystemTheme(bool enable, wxWindow* window) wxOVERRIDE; + void OnDPIChanged(wxDPIChangedEvent& event); + public: // utility functions not part of the API // returns the "best" width for the idx-th column diff --git a/include/wx/generic/srchctlg.h b/include/wx/generic/srchctlg.h index 79151ea5af..a123fcfab3 100644 --- a/include/wx/generic/srchctlg.h +++ b/include/wx/generic/srchctlg.h @@ -206,6 +206,8 @@ protected: void OnSize( wxSizeEvent& event ); + void OnDPIChanged(wxDPIChangedEvent& event); + bool HasMenu() const { #if wxUSE_MENUS diff --git a/include/wx/msw/bmpcbox.h b/include/wx/msw/bmpcbox.h index b6d5a47998..d71fc8d728 100644 --- a/include/wx/msw/bmpcbox.h +++ b/include/wx/msw/bmpcbox.h @@ -104,6 +104,7 @@ protected: WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const wxOVERRIDE; virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *item) wxOVERRIDE; virtual bool MSWOnMeasure(WXMEASUREITEMSTRUCT *item) wxOVERRIDE; + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; // Event handlers void OnSize(wxSizeEvent& event); diff --git a/include/wx/msw/checklst.h b/include/wx/msw/checklst.h index 8fa50253ba..91180c6a3e 100644 --- a/include/wx/msw/checklst.h +++ b/include/wx/msw/checklst.h @@ -81,6 +81,8 @@ protected: ProcessCommand(event); } + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; + wxSize DoGetBestClientSize() const wxOVERRIDE; wxDECLARE_EVENT_TABLE(); diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h index 3ba0175320..3c910e325e 100644 --- a/include/wx/msw/listbox.h +++ b/include/wx/msw/listbox.h @@ -181,6 +181,8 @@ protected: return wxSize(w, h); } + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; + // free memory (common part of Clear() and dtor) void Free(); diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index da1cb79063..f35585d58f 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -394,6 +394,10 @@ protected: virtual void DoSetToolTip(wxToolTip *tip) wxOVERRIDE; #endif // wxUSE_TOOLTIPS + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; + + void OnDPIChanged(wxDPIChangedEvent& event); + wxSize MSWGetBestViewRect(int x, int y) const; // Implement base class pure virtual methods. diff --git a/include/wx/msw/private/dpiaware.h b/include/wx/msw/private/dpiaware.h new file mode 100644 index 0000000000..8467ef3b30 --- /dev/null +++ b/include/wx/msw/private/dpiaware.h @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/private/dpiaware.h +// Purpose: AutoSystemDpiAware class +// Author: Maarten Bent +// Created: 2016-10-06 +// Copyright: (c) Maarten Bent +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_DPI_AWARE_H_ +#define _WX_MSW_DPI_AWARE_H_ + +#ifndef WX_PRECOMP + #include "wx/msw/missing.h" +#endif + +#include "wx/dynlib.h" + +#if wxUSE_DYNLIB_CLASS + +namespace wxMSWImpl +{ + +// ---------------------------------------------------------------------------- +// Temporarily change the DPI Awareness context to System +// ---------------------------------------------------------------------------- + +class AutoSystemDpiAware +{ + #define WXDPI_AWARENESS_CONTEXT_UNAWARE ((WXDPI_AWARENESS_CONTEXT)-1) + #define WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((WXDPI_AWARENESS_CONTEXT)-2) + typedef WXDPI_AWARENESS_CONTEXT + (WINAPI *SetThreadDpiAwarenessContext_t)(WXDPI_AWARENESS_CONTEXT); + +public: + AutoSystemDpiAware() + : m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE), + m_pfnSetThreadDpiAwarenessContext((SetThreadDpiAwarenessContext_t)-1) + { + if ( m_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1) + { + wxLoadedDLL dllUser32("user32.dll"); + wxDL_INIT_FUNC(m_pfn, SetThreadDpiAwarenessContext, dllUser32); + } + + if ( m_pfnSetThreadDpiAwarenessContext ) + { + m_prevContext = m_pfnSetThreadDpiAwarenessContext( + WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + } + + } + + ~AutoSystemDpiAware() + { + if ( m_pfnSetThreadDpiAwarenessContext ) + { + m_pfnSetThreadDpiAwarenessContext(m_prevContext); + } + } + +private: + WXDPI_AWARENESS_CONTEXT m_prevContext; + + SetThreadDpiAwarenessContext_t m_pfnSetThreadDpiAwarenessContext; +}; + +#else // !wxUSE_DYNLIB_CLASS + +// Just a stub to avoid littering the code with wxUSE_DYNLIB_CLASS checks. +class AutoSystemDpiAware { }; + +#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS + +} // namespace wxMSWImpl + +#endif // _WX_MSW_DPI_AWARE_H_ diff --git a/include/wx/msw/spinctrl.h b/include/wx/msw/spinctrl.h index c81ed26665..2152ca828d 100644 --- a/include/wx/msw/spinctrl.h +++ b/include/wx/msw/spinctrl.h @@ -131,6 +131,7 @@ protected: virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) wxOVERRIDE; virtual bool MSWOnScroll(int orientation, WXWORD wParam, WXWORD pos, WXHWND control) wxOVERRIDE; + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; // handle processing of special keys void OnChar(wxKeyEvent& event); diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h index 5ef3128a7c..f7be3725be 100644 --- a/include/wx/msw/textctrl.h +++ b/include/wx/msw/textctrl.h @@ -240,6 +240,8 @@ protected: virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const wxOVERRIDE; #if wxUSE_RICHEDIT + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; + // Apply the character-related parts of wxTextAttr to the given selection // or the entire control if start == end == -1. // diff --git a/include/wx/msw/toolbar.h b/include/wx/msw/toolbar.h index ba3581515b..1fa4a5260b 100644 --- a/include/wx/msw/toolbar.h +++ b/include/wx/msw/toolbar.h @@ -139,6 +139,9 @@ protected: // set native toolbar padding void MSWSetPadding(WXWORD padding); + void RealizeHelper(); + void OnDPIChanged(wxDPIChangedEvent& event); + // the big bitmap containing all bitmaps of the toolbar buttons WXHBITMAP m_hBitmap; diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index eeca2d15b3..11a654429d 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -261,6 +261,7 @@ protected: // return true if the key was processed, false otherwise bool MSWHandleSelectionKey(unsigned vkey); + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; // data used only while editing the item label: wxTextCtrl *m_textCtrl; // text control in which it is edited diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index c15d582cca..b879d3e7d8 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -763,7 +763,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l wxDataViewTextRenderer *tr = new wxDataViewTextRenderer( "string", wxDATAVIEW_CELL_INERT ); wxDataViewColumn *column0 = - new wxDataViewColumn( "title", tr, 0, 200, wxALIGN_LEFT, + new wxDataViewColumn( "title", tr, 0, FromDIP(200), wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE ); m_ctrl[Page_Music]->AppendColumn( column0 ); #if 0 @@ -776,10 +776,10 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l tr = new wxDataViewTextRenderer( "string", wxDATAVIEW_CELL_EDITABLE ); wxDataViewColumn *column1 = - new wxDataViewColumn( "artist", tr, 1, 150, wxALIGN_LEFT, + new wxDataViewColumn( "artist", tr, 1, FromDIP(150), wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE ); - column1->SetMinWidth(150); // this column can't be resized to be smaller + column1->SetMinWidth(FromDIP(150)); // this column can't be resized to be smaller m_ctrl[Page_Music]->AppendColumn( column1 ); // column 2 of the view control: @@ -788,7 +788,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l new wxDataViewSpinRenderer( 0, 2010, wxDATAVIEW_CELL_EDITABLE, wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); wxDataViewColumn *column2 = - new wxDataViewColumn( "year", sr, 2, 60, wxALIGN_LEFT, + new wxDataViewColumn( "year", sr, 2, FromDIP(60), wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE ); m_ctrl[Page_Music]->AppendColumn( column2 ); @@ -802,19 +802,19 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l new wxDataViewChoiceRenderer( choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); wxDataViewColumn *column3 = - new wxDataViewColumn( "rating", c, 3, 100, wxALIGN_LEFT, + new wxDataViewColumn( "rating", c, 3, FromDIP(100), wxALIGN_LEFT, wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE ); m_ctrl[Page_Music]->AppendColumn( column3 ); // column 4 of the view control: - m_ctrl[Page_Music]->AppendProgressColumn( "popularity", 4, wxDATAVIEW_CELL_INERT, 80 ); + m_ctrl[Page_Music]->AppendProgressColumn( "popularity", 4, wxDATAVIEW_CELL_INERT, FromDIP(80) ); // column 5 of the view control: MyCustomRenderer *cr = new MyCustomRenderer(wxDATAVIEW_CELL_ACTIVATABLE); wxDataViewColumn *column5 = - new wxDataViewColumn( "custom", cr, 5, -1, wxALIGN_LEFT, + new wxDataViewColumn( "custom", cr, 5, wxCOL_WIDTH_DEFAULT, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE ); column5->SetBitmap(wxArtProvider::GetBitmap(wxART_INFORMATION, wxART_MENU)); m_ctrl[Page_Music]->AppendColumn( column5 ); @@ -900,7 +900,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l lc->AppendColumn(colRadio, "bool"); lc->AppendTextColumn( "Text" ); - lc->AppendProgressColumn( "Progress" )->SetMinWidth(100); + lc->AppendProgressColumn( "Progress" )->SetMinWidth(FromDIP(100)); wxVector data; for (unsigned int i=0; i<10; i++) @@ -957,17 +957,17 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l MultiLineCustomRenderer *tr = new MultiLineCustomRenderer(); wxDataViewColumn *column0 = - new wxDataViewColumn("title", tr, 0, 200, wxALIGN_LEFT, + new wxDataViewColumn("title", tr, 0, FromDIP(200), wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); m_ctrl[Page_VarHeight]->AppendColumn(column0); // column 1 of the view control: tr = new MultiLineCustomRenderer(); wxDataViewColumn *column1 = - new wxDataViewColumn("artist", tr, 1, 150, wxALIGN_LEFT, + new wxDataViewColumn("artist", tr, 1, FromDIP(150), wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE); - column1->SetMinWidth(150); // this column can't be resized to be smaller + column1->SetMinWidth(FromDIP(150)); // this column can't be resized to be smaller m_ctrl[Page_VarHeight]->AppendColumn(column1); } break; diff --git a/samples/toolbar/toolbar.cpp b/samples/toolbar/toolbar.cpp index 6ade05c7d2..0c42388dac 100644 --- a/samples/toolbar/toolbar.cpp +++ b/samples/toolbar/toolbar.cpp @@ -307,7 +307,7 @@ bool MyApp::OnInit() // Create the main frame window MyFrame* frame = new MyFrame((wxFrame *) NULL, wxID_ANY, "wxToolBar Sample", - wxPoint(100, 100), wxSize(650, 350)); + wxPoint(100, 100), wxDefaultSize); frame->Show(true); @@ -440,7 +440,7 @@ void MyFrame::PopulateToolbar(wxToolBarBase* toolBar) // adding a combo to a vertical toolbar is not very smart if ( !toolBar->IsVertical() ) { - wxComboBox *combo = new wxComboBox(toolBar, ID_COMBO, wxEmptyString, wxDefaultPosition, wxSize(100,-1) ); + wxComboBox *combo = new wxComboBox(toolBar, ID_COMBO, wxEmptyString, wxDefaultPosition, FromDIP(wxSize(100,-1)) ); combo->Append("This"); combo->Append("is a"); combo->Append("combobox with extremely, extremely, extremely, extremely long label"); @@ -652,6 +652,8 @@ MyFrame::MyFrame(wxFrame* parent, sizer->Add(m_extraToolBar, 0, wxEXPAND, 0); #endif sizer->Add(m_textWindow, 1, wxEXPAND, 0); + + SetInitialSize(FromDIP(wxSize(650, 350))); } MyFrame::~MyFrame() @@ -891,7 +893,7 @@ void MyFrame::OnToggleSearch(wxCommandEvent& WXUNUSED(event)) if ( !m_searchTool ) { wxSearchCtrl * const srch = new wxSearchCtrl(tb, wxID_ANY, "needle"); - srch->SetMinSize(wxSize(80, -1)); + srch->SetMinSize(FromDIP(wxSize(80, -1))); m_searchTool = tb->AddControl(srch); } else // tool already exists diff --git a/src/common/bmpcboxcmn.cpp b/src/common/bmpcboxcmn.cpp index 1fa3c83ffa..103da719e1 100644 --- a/src/common/bmpcboxcmn.cpp +++ b/src/common/bmpcboxcmn.cpp @@ -68,7 +68,8 @@ void wxBitmapComboBoxBase::Init() void wxBitmapComboBoxBase::UpdateInternals() { - m_fontHeight = GetControl()->GetCharHeight() + EXTRA_FONT_HEIGHT; + m_fontHeight = GetControl()->GetCharHeight() + + GetControl()->FromDIP(EXTRA_FONT_HEIGHT); while ( m_bitmaps.GetCount() < GetItemContainer()->GetCount() ) m_bitmaps.Add( new wxBitmap() ); @@ -159,7 +160,9 @@ int wxBitmapComboBoxBase::DetermineIndent() if ( m_usedImgSize.x > 0 ) { - indent = m_usedImgSize.x + IMAGE_SPACING_LEFT + IMAGE_SPACING_RIGHT; + indent = m_usedImgSize.x + + GetControl()->FromDIP(IMAGE_SPACING_LEFT) + + GetControl()->FromDIP(IMAGE_SPACING_RIGHT); m_imgAreaWidth = indent; indent -= 3; @@ -214,9 +217,12 @@ void wxBitmapComboBoxBase::DrawItem(wxDC& dc, wxCoord w = bmp.GetWidth(); wxCoord h = bmp.GetHeight(); + const wxWindow* win = const_cast(this)->GetControl(); + const int imgSpacingLeft = win->FromDIP(IMAGE_SPACING_LEFT); + // Draw the image centered dc.DrawBitmap(bmp, - rect.x + (m_usedImgSize.x-w)/2 + IMAGE_SPACING_LEFT, + rect.x + (m_usedImgSize.x-w)/2 + imgSpacingLeft, rect.y + (rect.height-h)/2, true); } @@ -235,7 +241,8 @@ wxCoord wxBitmapComboBoxBase::MeasureItem(size_t WXUNUSED(item)) const return imgHeightArea > m_fontHeight ? imgHeightArea : m_fontHeight; } - return wxBCB_DEFAULT_ITEM_HEIGHT; + const wxWindow* win = const_cast(this)->GetControl(); + return win->FromDIP(wxBCB_DEFAULT_ITEM_HEIGHT); } #endif // wxBITMAPCOMBOBOX_OWNERDRAWN_BASED diff --git a/src/common/choiccmn.cpp b/src/common/choiccmn.cpp index 7018527266..5c17f9bc5e 100644 --- a/src/common/choiccmn.cpp +++ b/src/common/choiccmn.cpp @@ -107,7 +107,7 @@ wxChoiceBase::~wxChoiceBase() wxSize wxChoiceBase::DoGetBestSize() const { // a reasonable width for an empty choice list - wxSize best(80, -1); + wxSize best(FromDIP(80), -1); const unsigned int nItems = GetCount(); if ( nItems > 0 ) diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index 1ad0db9f63..4e87e9f75b 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -1374,7 +1374,7 @@ void wxComboCtrlBase::PositionTextCtrl( int textCtrlXAdjust, int textCtrlYAdjust wxSize wxComboCtrlBase::DoGetBestSize() const { - int width = m_text ? m_text->GetBestSize().x : 80; + int width = m_text ? m_text->GetBestSize().x : FromDIP(80); return GetSizeFromTextSize(width); } diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index 99f1e81532..540dc4042e 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -29,10 +29,9 @@ #include "wx/pen.h" #include "wx/region.h" #include "wx/log.h" + #include "wx/window.h" #endif -#include "wx/display.h" - #ifdef __WXMSW__ #include "wx/msw/enhmeta.h" #endif @@ -624,7 +623,7 @@ void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY) { if ( m_window ) { - const wxSize ppi = wxDisplay(m_window).GetPPI(); + const wxSize ppi = m_window->GetDPI(); *dpiX = ppi.x; *dpiY = ppi.y; } diff --git a/src/generic/animateg.cpp b/src/generic/animateg.cpp index 1d95134114..c27fc524a9 100644 --- a/src/generic/animateg.cpp +++ b/src/generic/animateg.cpp @@ -327,7 +327,7 @@ wxSize wxAnimationCtrl::DoGetBestSize() const if (m_animation.IsOk() && !this->HasFlag(wxAC_NO_AUTORESIZE)) return m_animation.GetSize(); - return wxSize(100, 100); + return FromDIP(wxSize(100, 100)); } void wxAnimationCtrl::SetAnimation(const wxAnimation& animation) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index dcb6792ca5..bca358a7e0 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -193,7 +193,7 @@ int wxDataViewColumn::GetWidth() const switch ( m_width ) { case wxCOL_WIDTH_DEFAULT: - return wxDVC_DEFAULT_WIDTH; + return wxWindow::FromDIP(wxDVC_DEFAULT_WIDTH, m_owner); case wxCOL_WIDTH_AUTOSIZE: wxCHECK_MSG( m_owner, wxDVC_DEFAULT_WIDTH, "no owner control" ); @@ -709,8 +709,7 @@ public: bool Cleared(); void Resort() { - if ( m_rowHeightCache ) - m_rowHeightCache->Clear(); + ClearRowHeightCache(); if (!IsVirtualList()) { @@ -718,6 +717,11 @@ public: } UpdateDisplay(); } + void ClearRowHeightCache() + { + if ( m_rowHeightCache ) + m_rowHeightCache->Clear(); + } SortOrder GetSortOrder() const { @@ -1188,7 +1192,8 @@ wxSize wxDataViewTextRenderer::GetSize() const return GetTextExtent(m_text); } else - return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); + return GetView()->FromDIP(wxSize(wxDVC_DEFAULT_RENDERER_SIZE, + wxDVC_DEFAULT_RENDERER_SIZE)); } // --------------------------------------------------------- @@ -1251,7 +1256,8 @@ wxSize wxDataViewBitmapRenderer::GetSize() const else if (m_icon.IsOk()) return wxSize( m_icon.GetWidth(), m_icon.GetHeight() ); - return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); + return GetView()->FromDIP(wxSize(wxDVC_DEFAULT_RENDERER_SIZE, + wxDVC_DEFAULT_RENDERER_SIZE)); } // --------------------------------------------------------- @@ -2770,11 +2776,8 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData } else { - if ( m_rowHeightCache ) - { - // specific position (row) is unclear, so clear whole height cache - m_rowHeightCache->Clear(); - } + // specific position (row) is unclear, so clear whole height cache + ClearRowHeightCache(); wxDataViewTreeNode *parentNode = FindNode(parent); @@ -3039,8 +3042,7 @@ bool wxDataViewMainWindow::Cleared() m_selection.Clear(); m_currentRow = (unsigned)-1; - if ( m_rowHeightCache ) - m_rowHeightCache->Clear(); + ClearRowHeightCache(); if (GetModel()) { @@ -5107,6 +5109,7 @@ void wxDataViewMainWindow::UpdateColumnSizes() wxIMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase); wxBEGIN_EVENT_TABLE(wxDataViewCtrl, wxDataViewCtrlBase) EVT_SIZE(wxDataViewCtrl::OnSize) + EVT_DPI_CHANGED(wxDataViewCtrl::OnDPIChanged) wxEND_EVENT_TABLE() wxDataViewCtrl::~wxDataViewCtrl() @@ -5251,6 +5254,28 @@ void wxDataViewCtrl::OnSize( wxSizeEvent &WXUNUSED(event) ) } } +void wxDataViewCtrl::OnDPIChanged(wxDPIChangedEvent& event) +{ + if ( m_clientArea ) + { + m_clientArea->ClearRowHeightCache(); + m_clientArea->SetRowHeight(m_clientArea->GetDefaultRowHeight()); + } + + for ( unsigned i = 0; i < m_cols.size(); ++i ) + { + int minWidth = m_cols[i]->GetMinWidth(); + if ( minWidth > 0 ) + minWidth = minWidth * event.GetNewDPI().x / event.GetOldDPI().x; + m_cols[i]->SetMinWidth(minWidth); + + int width = m_cols[i]->WXGetManuallySetWidth(); + if ( width > 0 ) + width = width * event.GetNewDPI().x / event.GetOldDPI().x; + m_cols[i]->SetWidth(width); + } +} + void wxDataViewCtrl::SetFocus() { if (m_clientArea) diff --git a/src/generic/spinctlg.cpp b/src/generic/spinctlg.cpp index feef3a6c5f..b49c5db77b 100644 --- a/src/generic/spinctlg.cpp +++ b/src/generic/spinctlg.cpp @@ -298,7 +298,14 @@ void wxSpinCtrlGenericBase::DoMoveWindow(int x, int y, int width, int height) wxControl::DoMoveWindow(x, y, width, height); // position the subcontrols inside the client area - wxSize sizeBtn = m_spinButton->GetSize(); + + // Use GetBestSize instead of GetSize to get the size of the spin control. + // This fixes a problem on wxMSW when the size is set after a DPI change. + // GetSize returns the old, invalid, size. GetBestSize will return the size + // that the control should be. Normally, GetBestSize and GetSize should + // always return the same value because the size of the spinButton never + // changes. + wxSize sizeBtn = m_spinButton->GetBestSize(); wxCoord wText = width - sizeBtn.x - MARGIN; m_textCtrl->SetSize(0, 0, wText, height); diff --git a/src/generic/srchctlg.cpp b/src/generic/srchctlg.cpp index 88091fd239..583c6fd710 100644 --- a/src/generic/srchctlg.cpp +++ b/src/generic/srchctlg.cpp @@ -248,6 +248,7 @@ wxEND_EVENT_TABLE() wxBEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase) EVT_SEARCH_CANCEL(wxID_ANY, wxSearchCtrl::OnCancelButton) EVT_SIZE(wxSearchCtrl::OnSize) + EVT_DPI_CHANGED(wxSearchCtrl::OnDPIChanged) wxEND_EVENT_TABLE() wxIMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase); @@ -1234,6 +1235,11 @@ void wxSearchCtrl::OnSize( wxSizeEvent& WXUNUSED(event) ) LayoutControls(); } +void wxSearchCtrl::OnDPIChanged(wxDPIChangedEvent &WXUNUSED(event)) +{ + RecalcBitmaps(); +} + #if wxUSE_MENUS void wxSearchCtrl::PopupSearchMenu() diff --git a/src/msw/anybutton.cpp b/src/msw/anybutton.cpp index e74c535b90..76021aa0ae 100644 --- a/src/msw/anybutton.cpp +++ b/src/msw/anybutton.cpp @@ -431,7 +431,7 @@ wxSize wxMSWButton::IncreaseToStdSizeAndCache(wxControl *btn, const wxSize& size // // Note that we intentionally don't use GetDefaultSize() here, because // it's inexact -- dialog units depend on this dialog's font. - const wxSize sizeDef = btn->ConvertDialogToPixels(wxSize(50, 14)); + const wxSize sizeDef = btn->ConvertDialogToPixels(btn->FromDIP(wxSize(50, 14))); sizeBtn.IncTo(sizeDef); } diff --git a/src/msw/bmpcbox.cpp b/src/msw/bmpcbox.cpp index 6f1b9bd0e1..1d8fc3fa7b 100644 --- a/src/msw/bmpcbox.cpp +++ b/src/msw/bmpcbox.cpp @@ -39,8 +39,6 @@ #include "wx/odcombo.h" -#define IMAGE_SPACING_CTRL_VERTICAL 7 // Spacing used in control size calculation - // ============================================================================ // implementation @@ -129,6 +127,7 @@ void wxBitmapComboBox::RecreateControl() // mouse-wheel behaviour. // wxString value = GetValue(); + int selection = GetSelection(); wxPoint pos = GetPosition(); wxSize size = GetSize(); size.y = GetBestSize().y; @@ -212,6 +211,8 @@ void wxBitmapComboBox::RecreateControl() // Revert the old string value if ( !HasFlag(wxCB_READONLY) ) ChangeValue(value); + else if ( selection != wxNOT_FOUND ) + SetSelection(selection); // If disabled we'll have to disable it again after re-creating if ( !IsEnabled() ) @@ -409,7 +410,7 @@ int wxBitmapComboBox::DoInsertItems(const wxArrayStringsAdapter & items, bool wxBitmapComboBox::OnAddBitmap(const wxBitmap& bitmap) { - if ( wxBitmapComboBoxBase::OnAddBitmap(bitmap) ) + if ( wxBitmapComboBoxBase::OnAddBitmap(bitmap) || !GetCount() ) { // Need to recreate control for a new measureitem call? int prevItemHeight = ::SendMessage(GetHwnd(), CB_GETITEMHEIGHT, 0, 0); @@ -532,4 +533,13 @@ bool wxBitmapComboBox::MSWOnMeasure(WXMEASUREITEMSTRUCT *item) return true; } +void wxBitmapComboBox::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxComboBox::MSWUpdateFontOnDPIChange(newDPI); + + UpdateInternals(); + + RecreateControl(); +} + #endif // wxUSE_BITMAPCOMBOBOX diff --git a/src/msw/checklst.cpp b/src/msw/checklst.cpp index 753bccc335..911dd1cb86 100644 --- a/src/msw/checklst.cpp +++ b/src/msw/checklst.cpp @@ -255,7 +255,20 @@ bool wxCheckListBox::MSWOnMeasure(WXMEASUREITEMSTRUCT *item) } return false; - } +} + +void wxCheckListBox::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxCheckListBoxBase::MSWUpdateFontOnDPIChange(newDPI); + + wxSize size = wxRendererNative::Get().GetCheckBoxSize(this); + size.x += 2 * CHECKMARK_EXTRA_SPACE + CHECKMARK_LABEL_SPACE; + + for ( unsigned int i = 0; i < GetCount(); ++i ) + { + GetItem(i)->SetMarginWidth(size.GetWidth()); + } +} // check items // ----------- diff --git a/src/msw/colordlg.cpp b/src/msw/colordlg.cpp index ab9a671525..4eaf44f255 100644 --- a/src/msw/colordlg.cpp +++ b/src/msw/colordlg.cpp @@ -40,6 +40,7 @@ #include "wx/scopeguard.h" #include "wx/msw/private.h" +#include "wx/msw/private/dpiaware.h" #include #include @@ -216,6 +217,8 @@ int wxColourDialog::ShowModal() gs_activeDialog = this; wxON_BLOCK_EXIT_NULL(gs_activeDialog); + wxMSWImpl::AutoSystemDpiAware dpiAwareness; + // do show the modal dialog if ( !::ChooseColor(&chooseColorStruct) ) { diff --git a/src/msw/datetimectrl.cpp b/src/msw/datetimectrl.cpp index e1a3cd9534..604c2dcf0c 100644 --- a/src/msw/datetimectrl.cpp +++ b/src/msw/datetimectrl.cpp @@ -112,50 +112,37 @@ wxDateTime wxDateTimePickerCtrl::GetValue() const wxSize wxDateTimePickerCtrl::DoGetBestSize() const { - // Since Vista, the control can compute its best size itself, just ask it. - wxSize size; - if ( wxGetWinVersion() >= wxWinVersion_Vista ) - { - SIZE idealSize; + // Do not use DateTime_GetIdealSize / DTM_GETIDEALSIZE. It returns + // incorrect sizes after the DPI of the window has changed. For every DPI + // change, the returned size is 4 pixels higher, even if the DPI is + // lowered. - // Work around https://bugs.winehq.org/show_bug.cgi?id=44680 by - // checking for the return value: even if all "real" MSW systems do - // support this message, Wine does not, even when it's configured to - // return Vista or later version to the application. - if ( ::SendMessage(m_hWnd, DTM_GETIDEALSIZE, 0, (LPARAM)&idealSize) ) - { - size = wxSize(idealSize.cx, idealSize.cy); - } - } + wxClientDC dc(const_cast(this)); - if ( !size.x || !size.y ) - { - wxClientDC dc(const_cast(this)); - - // Use the same native format as the underlying native control. + // Use the same native format as the underlying native control. #if wxUSE_INTL - wxString s = wxDateTime::Now().Format(wxLocale::GetOSInfo(MSWGetFormat())); + wxString s = wxDateTime::Now().Format(wxLocale::GetOSInfo(MSWGetFormat())); #else // !wxUSE_INTL - wxString s("XXX-YYY-ZZZZ"); + wxString s("XXX-YYY-ZZZZ"); #endif // wxUSE_INTL/!wxUSE_INTL - // the best size for the control is bigger than just the string - // representation of the current value because the control must accommodate - // any date and while the widths of all digits are usually about the same, - // the width of the month string varies a lot, so try to account for it - s += wxS("W"); + // the best size for the control is bigger than just the string + // representation of the current value because the control must accommodate + // any date and while the widths of all digits are usually about the same, + // the width of the month string varies a lot, so try to account for it + s += wxS("W"); - size = dc.GetTextExtent(s); + wxSize size = dc.GetTextExtent(s); - // account for the drop-down arrow or spin arrows - size.x += wxSystemSettings::GetMetric(wxSYS_HSCROLL_ARROW_X, m_parent); - } + // Account for the drop-down arrow or spin arrows. + size.x += wxSystemSettings::GetMetric(wxSYS_HSCROLL_ARROW_X, m_parent); - // We need to account for the checkbox, if we have one, ourselves as - // DTM_GETIDEALSIZE doesn't seem to take it into account, at least under - // Windows 7. + int scrollY = wxSystemSettings::GetMetric(wxSYS_HSCROLL_ARROW_Y, m_parent); + size.y = wxMax(size.y, scrollY); + + // We need to account for the checkbox, if we have one. if ( MSWAllowsNone() ) - size.x += 3*GetCharWidth(); + size.x += 3 * GetCharWidth(); // In any case, adjust the height to be the same as for the text controls. size.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(size.y); diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index ec0529c47d..737b001439 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -47,6 +47,7 @@ #include "wx/scopeguard.h" #include "wx/tokenzr.h" #include "wx/modalhook.h" +#include "wx/msw/private/dpiaware.h" // ---------------------------------------------------------------------------- // constants @@ -375,6 +376,12 @@ void wxFileDialog::MSWOnTypeChange(WXHWND WXUNUSED(hDlg), int nFilterIndex) // err is filled with the CDERR_XXX constant static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err) { + // Extra controls do not handle per-monitor DPI, fall back to system DPI + // so entire file-dialog is resized. + wxScopedPtr dpiAwareness; + if ( of->Flags & OFN_ENABLEHOOK ) + dpiAwareness.reset(new wxMSWImpl::AutoSystemDpiAware()); + if ( style & wxFD_SAVE ? GetSaveFileName(of) : GetOpenFileName(of) ) return true; diff --git a/src/msw/fontdlg.cpp b/src/msw/fontdlg.cpp index 610b2c21b1..06b73674ac 100644 --- a/src/msw/fontdlg.cpp +++ b/src/msw/fontdlg.cpp @@ -37,6 +37,7 @@ #endif #include "wx/fontutil.h" +#include "wx/msw/private/dpiaware.h" #include #include @@ -149,6 +150,8 @@ int wxFontDialog::ShowModal() chooseFontStruct.Flags = flags; + wxMSWImpl::AutoSystemDpiAware dpiAwareness; + if ( ChooseFont(&chooseFontStruct) != 0 ) { wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors); diff --git a/src/msw/gauge.cpp b/src/msw/gauge.cpp index ac03441790..af7cefdee5 100644 --- a/src/msw/gauge.cpp +++ b/src/msw/gauge.cpp @@ -122,9 +122,9 @@ wxSize wxGauge::DoGetBestSize() const // the smaller one. if (HasFlag(wxGA_VERTICAL)) - return ConvertDialogToPixels(wxSize(8, 107)); + return ConvertDialogToPixels(FromDIP(wxSize(8, 107))); else - return ConvertDialogToPixels(wxSize(107, 8)); + return ConvertDialogToPixels(FromDIP(wxSize(107, 8))); } // ---------------------------------------------------------------------------- diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 25dcc7f632..68ee831c55 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -124,6 +124,7 @@ protected: virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO) wxOVERRIDE; + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; private: // override MSW-specific methods needed for new control @@ -324,6 +325,16 @@ wxSize wxMSWHeaderCtrl::DoGetBestSize() const return wxSize(wxDefaultCoord, wpos.cy); } +void wxMSWHeaderCtrl::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxControl::MSWUpdateFontOnDPIChange(newDPI); + + if ( wxMSWHeaderCtrlCustomDraw * customDraw = GetCustomDraw() ) + { + customDraw->m_attr.SetFont(m_font); + } +} + // ---------------------------------------------------------------------------- // wxMSWHeaderCtrl columns managements // ---------------------------------------------------------------------------- @@ -701,7 +712,7 @@ bool wxMSWHeaderCtrl::SetFont(const wxFont& font) if ( wxMSWHeaderCtrlCustomDraw* customDraw = GetCustomDraw() ) { - customDraw->m_attr.SetFont(font); + customDraw->m_attr.SetFont(m_font); } return true; diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index 02f2ecb9e5..128f679d2c 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -190,6 +190,14 @@ WXDWORD wxListBox::MSWGetStyle(long style, WXDWORD *exstyle) const return msStyle; } +void wxListBox::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxListBoxBase::MSWUpdateFontOnDPIChange(newDPI); + + if ( m_font.IsOk() ) + SetFont(m_font); +} + void wxListBox::OnInternalIdle() { wxWindow::OnInternalIdle(); @@ -695,22 +703,22 @@ bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) bool wxListBox::SetFont(const wxFont &font) { + wxListBoxBase::SetFont(font); + if ( HasFlag(wxLB_OWNERDRAW) ) { const unsigned count = m_aItems.GetCount(); for ( unsigned i = 0; i < count; i++ ) - m_aItems[i]->SetFont(font); + m_aItems[i]->SetFont(m_font); // Non owner drawn list boxes update the item height on their own, but // we need to do it manually in the owner drawn case. wxClientDC dc(this); - dc.SetFont(font); + dc.SetFont(m_font); SendMessage(GetHwnd(), LB_SETITEMHEIGHT, 0, dc.GetCharHeight() + 2 * LISTBOX_EXTRA_SPACE); } - wxListBoxBase::SetFont(font); - return true; } diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index d1508e1f39..aa5afe781c 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -265,6 +265,7 @@ private: wxBEGIN_EVENT_TABLE(wxListCtrl, wxListCtrlBase) EVT_PAINT(wxListCtrl::OnPaint) EVT_CHAR_HOOK(wxListCtrl::OnCharHook) + EVT_DPI_CHANGED(wxListCtrl::OnDPIChanged) wxEND_EVENT_TABLE() // ============================================================================ @@ -319,6 +320,9 @@ bool wxListCtrl::Create(wxWindow *parent, if ( InReportView() ) MSWSetExListStyles(); + if ( HasFlag(wxLC_LIST) ) + m_colCount = 1; + return true; } @@ -421,6 +425,47 @@ WXDWORD wxListCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const return wstyle; } +void wxListCtrl::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxListCtrlBase::MSWUpdateFontOnDPIChange(newDPI); + + for ( int i = 0; i < GetItemCount(); i++ ) + { + wxMSWListItemData *data = MSWGetItemData(i); + if ( data && data->attr && data->attr->HasFont() ) + { + wxFont f = data->attr->GetFont(); + f.WXAdjustToPPI(newDPI); + SetItemFont(i, f); + } + } + + if ( m_headerCustomDraw && m_headerCustomDraw->m_attr.HasFont() ) + { + wxItemAttr item(m_headerCustomDraw->m_attr); + wxFont f = item.GetFont(); + f.WXAdjustToPPI(newDPI); + item.SetFont(f); + + // reset the item attribute first so wxListCtrl::SetHeaderAttr + // will detect the font change + SetHeaderAttr(wxItemAttr()); + SetHeaderAttr(item); + } +} + +void wxListCtrl::OnDPIChanged(wxDPIChangedEvent &event) +{ + const int numCols = GetColumnCount(); + for ( int i = 0; i < numCols; ++i ) + { + int width = GetColumnWidth(i); + if ( width > 0 ) + width = width * event.GetNewDPI().x / event.GetOldDPI().x; + SetColumnWidth(i, width); + } +} + #if WXWIN_COMPATIBILITY_3_0 // Deprecated void wxListCtrl::UpdateStyle() @@ -632,11 +677,16 @@ bool wxListCtrl::SetHeaderAttr(const wxItemAttr& attr) // Don't just reset the font if no font is specified, as the header // uses the same font as the listview control and not the ugly // default GUI font by default. - const wxFont& font = attr.HasFont() ? attr.GetFont() : GetFont(); - - // We need to tell the header about its new font to let it compute - // its new height. - wxSetWindowFont(hwndHdr, font); + if ( attr.HasFont() ) + { + wxSetWindowFont(hwndHdr, attr.GetFont()); + } + else + { + // make sure m_font is valid before using its HFONT reference + SetFont(GetFont()); + wxSetWindowFont(hwndHdr, m_font); + } } // Refreshing the listview makes it notice the change in height of its @@ -953,6 +1003,13 @@ bool wxListCtrl::SetItem(wxListItem& info) data->attr->AssignFrom(attrNew); else data->attr = new wxItemAttr(attrNew); + + if ( data->attr->HasFont() ) + { + wxFont f = data->attr->GetFont(); + f.WXAdjustToPPI(GetDPI()); + data->attr->SetFont(f); + } } } diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index 9372afbd29..6645283603 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -550,8 +550,8 @@ wxRendererMSW::DrawTitleBarBitmap(wxWindow *win, wxSize wxRendererMSW::GetCheckBoxSize(wxWindow* win) { - // Even though we don't use the window in this implementation, still check - // that it's valid to avoid surprises when using themes. + // We must have a valid window in order to return the size which is correct + // for the display this window is on. wxCHECK_MSG( win, wxSize(0, 0), "Must have a valid window" ); return wxSize(wxGetSystemMetrics(SM_CXMENUCHECK, win), diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index 6f1e8c7864..f76ad61968 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -223,6 +223,14 @@ void wxSpinCtrl::OnKillFocus(wxFocusEvent& event) event.Skip(); } +void wxSpinCtrl::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxSpinButton::MSWUpdateFontOnDPIChange(newDPI); + + if ( m_font.IsOk() ) + wxSetWindowFont(GetBuddyHwnd(), m_font); +} + void wxSpinCtrl::OnSetFocus(wxFocusEvent& event) { // when we get focus, give it to our buddy window as it needs it more than @@ -577,7 +585,8 @@ bool wxSpinCtrl::SetFont(const wxFont& font) return false; } - wxSetWindowFont(GetBuddyHwnd(), GetFont()); + if ( m_font.IsOk() ) + wxSetWindowFont(GetBuddyHwnd(), m_font); return true; } diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 7b138bc75f..9118db73bd 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -2633,6 +2633,16 @@ wxMenu *wxTextCtrl::MSWCreateContextMenu() return m; } +void wxTextCtrl::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + // Don't do anything for the rich edit controls, they (somehow?) update + // their appearance on their own and changing their HFONT, as the base + // class version does, would reset all the styles used by them when the DPI + // changes, which is unwanted. + if ( !IsRich() ) + wxTextCtrlBase::MSWUpdateFontOnDPIChange(newDPI); +} + // ---------------------------------------------------------------------------- // EN_LINK processing // ---------------------------------------------------------------------------- diff --git a/src/msw/toolbar.cpp b/src/msw/toolbar.cpp index dc9c50fcd8..8f03aee595 100644 --- a/src/msw/toolbar.cpp +++ b/src/msw/toolbar.cpp @@ -38,6 +38,8 @@ #include "wx/region.h" #include "wx/dcmemory.h" #include "wx/control.h" + #include "wx/choice.h" + #include "wx/combobox.h" #include "wx/app.h" // for GetComCtl32Version #include "wx/image.h" #include "wx/stattext.h" @@ -127,6 +129,7 @@ wxBEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged) EVT_ERASE_BACKGROUND(wxToolBar::OnEraseBackground) + EVT_DPI_CHANGED(wxToolBar::OnDPIChanged) wxEND_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -1001,7 +1004,7 @@ bool wxToolBar::Realize() // Strangely, toolbar expects bitmaps with transparency to not // be premultiplied, unlike most of the rest of win32. Without this // conversion, e.g. antialiased lines would be subtly, but - // noticeably misrendered. + // noticeably misrendered. hBitmap = wxDIB(bitmap.ConvertToImage(), wxDIB::PixelFormat_NotPreMultiplied).Detach(); } @@ -1895,6 +1898,57 @@ void wxToolBar::OnEraseBackground(wxEraseEvent& event) #endif // wxHAS_MSW_BACKGROUND_ERASE_HOOK } +void wxToolBar::RealizeHelper() +{ + Realize(); +} + +void wxToolBar::OnDPIChanged(wxDPIChangedEvent& event) +{ + // Manually scale the size of the controls. Even though the font has been + // updated, the internal size of the controls does not. + const float scaleFactor = (float)event.GetNewDPI().y / event.GetOldDPI().y; + + wxToolBarToolsList::compatibility_iterator node; + for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) + { + wxToolBarTool* const tool = static_cast(node->GetData()); + if ( !tool->IsControl() ) + continue; + + if ( wxControl* const control = tool->GetControl() ) + { + const wxSize oldSize = control->GetSize(); + wxSize newSize = oldSize * scaleFactor; + + // Use the best height for choice-based controls. + // Scaling the current size does not work, because the control + // automatically increases size when the font-size increases. + if ( wxDynamicCast(control, wxComboBox) || + wxDynamicCast(control, wxChoice) ) + { + const wxSize bestSize = control->GetBestSize(); + newSize.y = bestSize.y; + } + + control->SetSize(newSize); + } + + if ( wxStaticText* const staticText = tool->GetStaticText() ) + { + // Use the best size for the label + staticText->SetSize(staticText->GetBestSize()); + } + } + + // Use CallAfter because creating the toolbar directly sometimes doesn't + // work. E.g. when switching from 125% to 150%. All the sizes are set + // correctly, but after all dpi events are handled, 5px of the toolbar are + // gone and a dark-gray bar appears. After resizing the window, the gray + // bar disapears as well. + CallAfter(&wxToolBar::RealizeHelper); +} + bool wxToolBar::HandleSize(WXWPARAM WXUNUSED(wParam), WXLPARAM WXUNUSED(lParam)) { // wait until we have some tools diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 8080f7cc03..12dd26bc36 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -1253,7 +1253,9 @@ void wxTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font) attr = it->second; } - attr->SetFont(font); + wxFont f = font; + f.WXAdjustToPPI(GetDPI()); + attr->SetFont(f); // Reset the item's text to ensure that the bounding rect will be adjusted // for the new font. @@ -2270,6 +2272,17 @@ bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id_) return true; } +void wxTreeCtrl::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + wxTreeCtrlBase::MSWUpdateFontOnDPIChange(newDPI); + + for ( wxMapTreeAttr::const_iterator it = m_attrs.begin(); it != m_attrs.end(); ++it ) + { + if ( it->second->HasFont() ) + SetItemFont(it->first, it->second->GetFont()); + } +} + bool wxTreeCtrl::MSWIsOnItem(unsigned flags) const { unsigned mask = TVHT_ONITEM; diff --git a/src/msw/window.cpp b/src/msw/window.cpp index e00ac4b25f..a4e2e0c5f4 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -4830,7 +4830,7 @@ wxSize wxWindowMSW::GetDPI() const if ( !dpi.x || !dpi.y ) { - WindowHDC hdc(GetHwnd()); + WindowHDC hdc(hwnd); dpi.x = ::GetDeviceCaps(hdc, LOGPIXELSX); dpi.y = ::GetDeviceCaps(hdc, LOGPIXELSY); } diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 7840ef29a9..a369de8a37 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -3808,7 +3808,7 @@ void wxRichTextCtrl::OnDropFiles(wxDropFilesEvent& event) wxSize wxRichTextCtrl::DoGetBestSize() const { - return wxSize(10, 10); + return FromDIP(wxSize(10, 10)); } // ----------------------------------------------------------------------------