Fix refreshing display information in wxMSW in some special cases
Passing screen HDC to EnumDisplayMonitors() doesn't work if we do it while a UAC prompt is shown or during log-off process, so change the code enumerating the displays to use monitor-appropriate HDC instead. This fixes the problem with losing display information entirely if WM_SETTINGSCHANGE was generated when showing UAC prompt, as it happens when "automatic background color" option is set under Windows 10.
This commit is contained in:
@@ -594,10 +594,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"));
|
||||||
}
|
}
|
||||||
@@ -607,13 +607,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