Merge branch 'msw-display-refresh'
Fixes for display information refreshing under MSW. See https://github.com/wxWidgets/wxWidgets/pull/1282
This commit is contained in:
@@ -81,6 +81,9 @@ public:
|
|||||||
void OnLeftClick(wxMouseEvent& event);
|
void OnLeftClick(wxMouseEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Fill m_book with the information about all the displays.
|
||||||
|
void PopuplateWithDisplayInfo();
|
||||||
|
|
||||||
#if wxUSE_DISPLAY
|
#if wxUSE_DISPLAY
|
||||||
// convert video mode to textual description
|
// convert video mode to textual description
|
||||||
wxString VideoModeToText(const wxVideoMode& mode);
|
wxString VideoModeToText(const wxVideoMode& mode);
|
||||||
@@ -233,6 +236,11 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
|
|||||||
|
|
||||||
// create child controls
|
// create child controls
|
||||||
m_book = new wxBookCtrl(this, wxID_ANY);
|
m_book = new wxBookCtrl(this, wxID_ANY);
|
||||||
|
PopuplateWithDisplayInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::PopuplateWithDisplayInfo()
|
||||||
|
{
|
||||||
const size_t countDpy = wxDisplay::GetCount();
|
const size_t countDpy = wxDisplay::GetCount();
|
||||||
for ( size_t nDpy = 0; nDpy < countDpy; nDpy++ )
|
for ( size_t nDpy = 0; nDpy < countDpy; nDpy++ )
|
||||||
{
|
{
|
||||||
@@ -426,16 +434,8 @@ void MyFrame::OnLeftClick(wxMouseEvent& event)
|
|||||||
|
|
||||||
void MyFrame::OnDisplayChanged(wxDisplayChangedEvent& event)
|
void MyFrame::OnDisplayChanged(wxDisplayChangedEvent& event)
|
||||||
{
|
{
|
||||||
// update the current mode text
|
m_book->DeleteAllPages();
|
||||||
for ( size_t n = 0; n < m_book->GetPageCount(); n++ )
|
PopuplateWithDisplayInfo();
|
||||||
{
|
|
||||||
wxStaticText *label = wxDynamicCast(m_book->GetPage(n)->
|
|
||||||
FindWindow(Display_CurrentMode),
|
|
||||||
wxStaticText);
|
|
||||||
if ( label )
|
|
||||||
label->SetLabel(VideoModeToText(wxDisplay(n).GetCurrentMode()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxLogStatus(this, "Display resolution was changed.");
|
wxLogStatus(this, "Display resolution was changed.");
|
||||||
|
|
||||||
|
@@ -198,10 +198,6 @@ public:
|
|||||||
DoRefreshMonitors();
|
DoRefreshMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when we receive WM_SETTINGCHANGE to refresh the list of monitor
|
|
||||||
// handles.
|
|
||||||
static void RefreshMonitors() { ms_factory->InvalidateCache(); }
|
|
||||||
|
|
||||||
// Declare the second argument as int to avoid problems with older SDKs not
|
// Declare the second argument as int to avoid problems with older SDKs not
|
||||||
// declaring MONITOR_DPI_TYPE enum.
|
// declaring MONITOR_DPI_TYPE enum.
|
||||||
typedef HRESULT (WINAPI *GetDpiForMonitor_t)(HMONITOR, int, UINT*, UINT*);
|
typedef HRESULT (WINAPI *GetDpiForMonitor_t)(HMONITOR, int, UINT*, UINT*);
|
||||||
@@ -221,15 +217,9 @@ private:
|
|||||||
// return wxNOT_FOUND if not found
|
// return wxNOT_FOUND if not found
|
||||||
int FindDisplayFromHMONITOR(HMONITOR hmon) const;
|
int FindDisplayFromHMONITOR(HMONITOR hmon) const;
|
||||||
|
|
||||||
// Update m_displays array, used by RefreshMonitors().
|
// Update m_displays array, used initially and by InvalidateCache().
|
||||||
void DoRefreshMonitors();
|
void DoRefreshMonitors();
|
||||||
|
|
||||||
|
|
||||||
// The unique factory being used (as we don't have direct access to the
|
|
||||||
// global factory pointer in the common code so we just duplicate this
|
|
||||||
// variable (also making it of correct type for us) here).
|
|
||||||
static wxDisplayFactoryMSW* ms_factory;
|
|
||||||
|
|
||||||
// The pointer to GetDpiForMonitorPtr(), retrieved on demand, and the
|
// The pointer to GetDpiForMonitorPtr(), retrieved on demand, and the
|
||||||
// related data, including the DLL containing the function that we must
|
// related data, including the DLL containing the function that we must
|
||||||
// keep loaded.
|
// keep loaded.
|
||||||
@@ -285,7 +275,6 @@ private:
|
|||||||
wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMSW);
|
wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMSW);
|
||||||
};
|
};
|
||||||
|
|
||||||
wxDisplayFactoryMSW* wxDisplayFactoryMSW::ms_factory = NULL;
|
|
||||||
wxDisplayFactoryMSW::GetDpiForMonitorData
|
wxDisplayFactoryMSW::GetDpiForMonitorData
|
||||||
wxDisplayFactoryMSW::ms_getDpiForMonitorData;
|
wxDisplayFactoryMSW::ms_getDpiForMonitorData;
|
||||||
|
|
||||||
@@ -535,7 +524,8 @@ bool wxDisplayMSW::ChangeMode(const wxVideoMode& mode)
|
|||||||
LRESULT APIENTRY
|
LRESULT APIENTRY
|
||||||
wxDisplayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
wxDisplayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if ( msg == WM_SETTINGCHANGE || msg == WM_DISPLAYCHANGE )
|
if ( (msg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA) ||
|
||||||
|
msg == WM_DISPLAYCHANGE )
|
||||||
{
|
{
|
||||||
wxDisplay::InvalidateCache();
|
wxDisplay::InvalidateCache();
|
||||||
|
|
||||||
@@ -547,12 +537,6 @@ wxDisplayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
wxDisplayFactoryMSW::wxDisplayFactoryMSW()
|
wxDisplayFactoryMSW::wxDisplayFactoryMSW()
|
||||||
{
|
{
|
||||||
// This is not supposed to happen with the current code, the factory is
|
|
||||||
// implicitly a singleton.
|
|
||||||
wxASSERT_MSG( !ms_factory, wxS("Using more than one factory?") );
|
|
||||||
|
|
||||||
ms_factory = this;
|
|
||||||
|
|
||||||
m_hiddenHwnd = NULL;
|
m_hiddenHwnd = NULL;
|
||||||
m_hiddenClass = NULL;
|
m_hiddenClass = NULL;
|
||||||
|
|
||||||
@@ -592,8 +576,6 @@ wxDisplayFactoryMSW::~wxDisplayFactoryMSW()
|
|||||||
ms_getDpiForMonitorData.UnloadIfNecessary();
|
ms_getDpiForMonitorData.UnloadIfNecessary();
|
||||||
ms_getDpiForMonitorData.m_initialized = false;
|
ms_getDpiForMonitorData.m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_factory = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -613,10 +595,10 @@ void wxDisplayFactoryMSW::DoRefreshMonitors()
|
|||||||
{
|
{
|
||||||
m_displays.clear();
|
m_displays.clear();
|
||||||
|
|
||||||
// We need to pass a valid HDC here in order to get valid hdcMonitor in our
|
// Note that we pass NULL as first parameter here because using screen HDC
|
||||||
// callback.
|
// doesn't work reliably: notably, it doesn't enumerate any displays if
|
||||||
ScreenHDC dc;
|
// this code is executed while a UAC prompt is shown or during log-off.
|
||||||
if ( !::EnumDisplayMonitors(dc, NULL, MultimonEnumProc, (LPARAM)this) )
|
if ( !::EnumDisplayMonitors(NULL, NULL, MultimonEnumProc, (LPARAM)this) )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("EnumDisplayMonitors"));
|
wxLogLastError(wxT("EnumDisplayMonitors"));
|
||||||
}
|
}
|
||||||
@@ -626,13 +608,24 @@ void wxDisplayFactoryMSW::DoRefreshMonitors()
|
|||||||
BOOL CALLBACK
|
BOOL CALLBACK
|
||||||
wxDisplayFactoryMSW::MultimonEnumProc(
|
wxDisplayFactoryMSW::MultimonEnumProc(
|
||||||
HMONITOR hMonitor, // handle to display monitor
|
HMONITOR hMonitor, // handle to display monitor
|
||||||
HDC hdcMonitor, // handle to monitor-appropriate device context
|
HDC /* hdcMonitor */, // handle to monitor-appropriate device context:
|
||||||
|
// not set due to our use of EnumDisplayMonitors(NULL, ...)
|
||||||
LPRECT WXUNUSED(lprcMonitor), // pointer to monitor intersection rectangle
|
LPRECT WXUNUSED(lprcMonitor), // pointer to monitor intersection rectangle
|
||||||
LPARAM dwData) // data passed from EnumDisplayMonitors (this)
|
LPARAM dwData) // data passed from EnumDisplayMonitors (this)
|
||||||
{
|
{
|
||||||
wxDisplayFactoryMSW *const self = (wxDisplayFactoryMSW *)dwData;
|
wxDisplayFactoryMSW *const self = (wxDisplayFactoryMSW *)dwData;
|
||||||
|
|
||||||
self->m_displays.push_back(wxDisplayInfo(hMonitor, wxGetHDCDepth(hdcMonitor)));
|
WinStruct<MONITORINFOEX> monInfo;
|
||||||
|
if ( !::GetMonitorInfo(hMonitor, &monInfo) )
|
||||||
|
{
|
||||||
|
wxLogLastError(wxT("GetMonitorInfo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
HDC hdcMonitor = ::CreateDC(NULL, monInfo.szDevice, NULL, NULL);
|
||||||
|
const int hdcDepth = wxGetHDCDepth(hdcMonitor);
|
||||||
|
::DeleteDC(hdcMonitor);
|
||||||
|
|
||||||
|
self->m_displays.push_back(wxDisplayInfo(hMonitor, hdcDepth));
|
||||||
|
|
||||||
// continue the enumeration
|
// continue the enumeration
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Reference in New Issue
Block a user