Honor monitor layout and DPI changes when persisting window placement

This commit is contained in:
Simon Rozman 2018-09-11 15:32:06 +02:00
parent 1b11ccf4a2
commit 5a912ebcc6
9 changed files with 552 additions and 124 deletions

View File

@ -26,6 +26,7 @@
<ClCompile Include="..\src\stdafx.cpp"> <ClCompile Include="..\src\stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader> <PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\tlwgeom.cpp" />
<ClCompile Include="..\src\url.cpp" /> <ClCompile Include="..\src\url.cpp" />
<ClCompile Include="..\src\valhex.cpp" /> <ClCompile Include="..\src\valhex.cpp" />
<ClCompile Include="..\src\valnet.cpp" /> <ClCompile Include="..\src\valnet.cpp" />
@ -40,7 +41,8 @@
<ClInclude Include="..\include\wxex\hex.h" /> <ClInclude Include="..\include\wxex\hex.h" />
<ClInclude Include="..\include\wxex\object.h" /> <ClInclude Include="..\include\wxex\object.h" />
<ClInclude Include="..\include\wxex\persist\auimanager.h" /> <ClInclude Include="..\include\wxex\persist\auimanager.h" />
<ClInclude Include="..\include\wxex\persist\dialog.h" /> <ClInclude Include="..\include\wxex\persist\toplevel.h" />
<ClInclude Include="..\include\wxex\private\tlwgeom.h" />
<ClInclude Include="..\include\wxex\url.h" /> <ClInclude Include="..\include\wxex\url.h" />
<ClInclude Include="..\include\wxex\valhex.h" /> <ClInclude Include="..\include\wxex\valhex.h" />
<ClInclude Include="..\include\wxex\valnet.h" /> <ClInclude Include="..\include\wxex\valnet.h" />

View File

@ -23,6 +23,9 @@
<Filter Include="Header Files\aui"> <Filter Include="Header Files\aui">
<UniqueIdentifier>{be99b1e7-e013-4c69-8966-6b34932a1711}</UniqueIdentifier> <UniqueIdentifier>{be99b1e7-e013-4c69-8966-6b34932a1711}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\private">
<UniqueIdentifier>{e7ddefe0-5d58-4fda-943c-717689ad974c}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\stdafx.cpp"> <ClCompile Include="..\src\stdafx.cpp">
@ -55,6 +58,9 @@
<ClCompile Include="..\src\framemanager.cpp"> <ClCompile Include="..\src\framemanager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\tlwgeom.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\stdafx.h"> <ClInclude Include="..\src\stdafx.h">
@ -81,21 +87,30 @@
<ClInclude Include="..\include\wxex\persist\auimanager.h"> <ClInclude Include="..\include\wxex\persist\auimanager.h">
<Filter>Header Files\persist</Filter> <Filter>Header Files\persist</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\persist\dialog.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\valhex.h"> <ClInclude Include="..\include\wxex\valhex.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\url.h"> <ClInclude Include="..\include\wxex\url.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\object.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\valnet.h"> <ClInclude Include="..\include\wxex\valnet.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\aui\framemanager.h"> <ClInclude Include="..\include\wxex\aui\framemanager.h">
<Filter>Header Files\aui</Filter> <Filter>Header Files\aui</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\object.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\private\tlwgeom.h">
<Filter>Header Files\private</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\persist\toplevel.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\locale\wxExtend.pot"> <None Include="..\locale\wxExtend.pot">

View File

@ -23,6 +23,9 @@
<Filter Include="Header Files\aui"> <Filter Include="Header Files\aui">
<UniqueIdentifier>{be99b1e7-e013-4c69-8966-6b34932a1711}</UniqueIdentifier> <UniqueIdentifier>{be99b1e7-e013-4c69-8966-6b34932a1711}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\private">
<UniqueIdentifier>{e7ddefe0-5d58-4fda-943c-717689ad974c}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\stdafx.cpp"> <ClCompile Include="..\src\stdafx.cpp">
@ -55,6 +58,9 @@
<ClCompile Include="..\src\framemanager.cpp"> <ClCompile Include="..\src\framemanager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\tlwgeom.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\stdafx.h"> <ClInclude Include="..\src\stdafx.h">
@ -81,15 +87,15 @@
<ClInclude Include="..\include\wxex\persist\auimanager.h"> <ClInclude Include="..\include\wxex\persist\auimanager.h">
<Filter>Header Files\persist</Filter> <Filter>Header Files\persist</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\persist\dialog.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\valhex.h"> <ClInclude Include="..\include\wxex\valhex.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\url.h"> <ClInclude Include="..\include\wxex\url.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\object.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\valnet.h"> <ClInclude Include="..\include\wxex\valnet.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -99,6 +105,12 @@
<ClInclude Include="..\include\wxex\object.h"> <ClInclude Include="..\include\wxex\object.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\private\tlwgeom.h">
<Filter>Header Files\private</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\persist\toplevel.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\locale\wxExtend.pot"> <None Include="..\locale\wxExtend.pot">

View File

@ -20,6 +20,12 @@
<Filter Include="Header Files\persist"> <Filter Include="Header Files\persist">
<UniqueIdentifier>{33d4709f-47d3-42c1-9562-bc4743799b49}</UniqueIdentifier> <UniqueIdentifier>{33d4709f-47d3-42c1-9562-bc4743799b49}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\aui">
<UniqueIdentifier>{be99b1e7-e013-4c69-8966-6b34932a1711}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\private">
<UniqueIdentifier>{e7ddefe0-5d58-4fda-943c-717689ad974c}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\stdafx.cpp"> <ClCompile Include="..\src\stdafx.cpp">
@ -52,6 +58,9 @@
<ClCompile Include="..\src\framemanager.cpp"> <ClCompile Include="..\src\framemanager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\tlwgeom.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\stdafx.h"> <ClInclude Include="..\src\stdafx.h">
@ -78,9 +87,6 @@
<ClInclude Include="..\include\wxex\persist\auimanager.h"> <ClInclude Include="..\include\wxex\persist\auimanager.h">
<Filter>Header Files\persist</Filter> <Filter>Header Files\persist</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\persist\dialog.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\valhex.h"> <ClInclude Include="..\include\wxex\valhex.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -93,6 +99,18 @@
<ClInclude Include="..\include\wxex\valnet.h"> <ClInclude Include="..\include\wxex\valnet.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\aui\framemanager.h">
<Filter>Header Files\aui</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\object.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\private\tlwgeom.h">
<Filter>Header Files\private</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\persist\toplevel.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\locale\wxExtend.pot"> <None Include="..\locale\wxExtend.pot">
@ -188,9 +206,4 @@
<Filter>Resource Files\Localization</Filter> <Filter>Resource Files\Localization</Filter>
</POCompile> </POCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\res\wxExtend.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project> </Project>

View File

@ -20,6 +20,12 @@
<Filter Include="Header Files\persist"> <Filter Include="Header Files\persist">
<UniqueIdentifier>{33d4709f-47d3-42c1-9562-bc4743799b49}</UniqueIdentifier> <UniqueIdentifier>{33d4709f-47d3-42c1-9562-bc4743799b49}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\aui">
<UniqueIdentifier>{be99b1e7-e013-4c69-8966-6b34932a1711}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\private">
<UniqueIdentifier>{e7ddefe0-5d58-4fda-943c-717689ad974c}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\stdafx.cpp"> <ClCompile Include="..\src\stdafx.cpp">
@ -52,6 +58,9 @@
<ClCompile Include="..\src\framemanager.cpp"> <ClCompile Include="..\src\framemanager.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\tlwgeom.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\stdafx.h"> <ClInclude Include="..\src\stdafx.h">
@ -78,9 +87,6 @@
<ClInclude Include="..\include\wxex\persist\auimanager.h"> <ClInclude Include="..\include\wxex\persist\auimanager.h">
<Filter>Header Files\persist</Filter> <Filter>Header Files\persist</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\persist\dialog.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\valhex.h"> <ClInclude Include="..\include\wxex\valhex.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -94,8 +100,17 @@
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\aui\framemanager.h"> <ClInclude Include="..\include\wxex\aui\framemanager.h">
<Filter>Header Files\aui</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\object.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\wxex\private\tlwgeom.h">
<Filter>Header Files\private</Filter>
</ClInclude>
<ClInclude Include="..\include\wxex\persist\toplevel.h">
<Filter>Header Files\persist</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\locale\wxExtend.pot"> <None Include="..\locale\wxExtend.pot">

View File

@ -1,106 +1,98 @@
/* /*
Copyright 2015-2018 Amebis Copyright 2015-2018 Amebis
Copyright 2016 GÉANT Copyright 2016 GÉANT
This file is part of wxExtend. This file is part of wxExtend.
wxExtend is free software: you can redistribute it and/or modify it wxExtend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
wxExtend is distributed in the hope that it will be useful, but wxExtend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with wxExtend. If not, see <http://www.gnu.org/licenses/>. along with wxExtend. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include "../common.h" #include "../common.h"
#include "../private/tlwgeom.h"
#include <wx/persist.h>
#include <wx/persist/toplevel.h> #include <wx/persist.h>
#include <wx/persist/window.h> #include <wx/persist/toplevel.h>
#include <wx/dialog.h> #include <wx/persist/window.h>
#include <wx/toplevel.h>
/// \addtogroup wxExtend
/// @{ /// \addtogroup wxExtend
/// @{
///
/// `wxPersistentDialog` kind for persistent storage ///
/// /// Supports saving/restoring wxTopLevelWindow state
#define wxPERSIST_DIALOG_KIND "Dialog" ///
class wxPersistentTLWEx :
/// public wxPersistentWindow<wxTopLevelWindow>,
/// Supports saving/restoring wxDialog state private wxTopLevelWindow::GeometrySerializer
/// {
class wxPersistentDialog : public:
public wxPersistentWindow<wxDialog>, ///
private wxTopLevelWindow::GeometrySerializer /// Constructs a persistent dialog object
{ ///
public: wxPersistentTLWEx(wxTopLevelWindow *mgr) : wxPersistentWindow<wxTopLevelWindow>(mgr)
/// {
/// Constructs a persistent dialog object }
///
wxPersistentDialog(wxDialog *mgr) : wxPersistentWindow<wxDialog>(mgr) ///
{ /// \returns `wxT(wxPERSIST_TLW_KIND)`
} ///
virtual wxString GetKind() const wxOVERRIDE
/// {
/// \returns `wxT(wxPERSIST_DIALOG_KIND)` return wxT(wxPERSIST_TLW_KIND);
/// }
virtual wxString GetKind() const wxOVERRIDE
{ ///
return wxT(wxPERSIST_DIALOG_KIND); /// Saves dialog state
} ///
virtual void Save() const wxOVERRIDE
/// {
/// Saves dialog state const wxTopLevelWindow * const wnd = Get();
///
virtual void Save() const wxOVERRIDE wxTLWGeometryEx geom;
{ if (geom.GetFrom(wnd))
const wxDialog * const wnd = Get(); geom.Save(*this);
}
// Code copied from wxPersistentTLW::Save()
wnd->SaveGeometry(*this); ///
} /// Restores dialog state
///
/// virtual bool Restore() wxOVERRIDE
/// Restores dialog state {
/// wxTopLevelWindow * const wnd = Get();
virtual bool Restore() wxOVERRIDE
{ wxTLWGeometryEx geom;
wxDialog * const wnd = Get(); if (!geom.Restore(*this))
return false;
return wnd->RestoreToGeometry(*this);
} return geom.ApplyTo(wnd);
}
private:
wxDECLARE_NO_COPY_CLASS(wxPersistentDialog); private:
wxDECLARE_NO_COPY_CLASS(wxPersistentTLWEx);
private:
virtual bool SaveField(const wxString& name, int value) const wxOVERRIDE private:
{ virtual bool SaveField(const wxString& name, int value) const wxOVERRIDE
return SaveValue(name, value); {
} return SaveValue(name, value);
}
virtual bool RestoreField(const wxString& name, int* value) wxOVERRIDE
{ virtual bool RestoreField(const wxString& name, int* value) wxOVERRIDE
return RestoreValue(name, value); {
} return RestoreValue(name, value);
}; }
};
/// /// @}
/// wxDialog's instantiation of wxCreatePersistentObject template
///
inline wxPersistentObject *wxCreatePersistentObject(wxDialog *mgr)
{
return new wxPersistentDialog(mgr);
}
/// @}

View File

@ -0,0 +1,346 @@
/*
Copyright 2015-2018 Amebis
Copyright 2016 GÉANT
This file is part of wxExtend.
wxExtend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
wxExtend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with wxExtend. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <wx/dynlib.h>
#include <wx/private/tlwgeom.h>
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif
/// \addtogroup wxExtend
/// @{
///
/// `wxPersistentDialog` kind for persistent storage
///
#define wxPERSIST_TLW_MONITOR_X "xmon"
#define wxPERSIST_TLW_MONITOR_Y "ymon"
#define wxPERSIST_TLW_MONITOR_W "wmon"
#define wxPERSIST_TLW_MONITOR_H "hmon"
#define wxPERSIST_TLW_DPI_HORZ "xdpi"
#define wxPERSIST_TLW_DPI_VERT "ydpi"
class wxTLWGeometryEx : public wxTLWGeometryBase
{
public:
wxTLWGeometryEx()
{
wxZeroMemory(m_placement);
m_placement.length = sizeof(m_placement);
wxZeroMemory(m_mntinfo);
m_mntinfo.cbSize = sizeof(m_mntinfo);
m_dpiHorz = USER_DEFAULT_SCREEN_DPI;
m_dpiVert = USER_DEFAULT_SCREEN_DPI;
}
virtual bool Save(const Serializer& ser) const wxOVERRIDE
{
// For compatibility with the existing saved positions/sizes, use the
// same keys as the generic version (which was previously used under
// MSW too).
// Normal position and size.
const RECT& rc = m_placement.rcNormalPosition;
if (!ser.SaveField(wxPERSIST_TLW_X, rc.left) ||
!ser.SaveField(wxPERSIST_TLW_Y, rc.top) ||
!ser.SaveField(wxPERSIST_TLW_W, rc.right - rc.left) ||
!ser.SaveField(wxPERSIST_TLW_H, rc.bottom - rc.top))
return false;
// Maximized/minimized state.
UINT show = m_placement.showCmd;
if (!ser.SaveField(wxPERSIST_TLW_MAXIMIZED, show == SW_SHOWMAXIMIZED))
return false;
if (!ser.SaveField(wxPERSIST_TLW_ICONIZED, show == SW_SHOWMINIMIZED))
return false;
// Maximized window position.
const POINT pt = m_placement.ptMaxPosition;
if (!ser.SaveField(wxPERSIST_TLW_MAX_X, pt.x) ||
!ser.SaveField(wxPERSIST_TLW_MAX_Y, pt.y))
return false;
// We don't currently save the minimized window position, it doesn't
// seem useful for anything and is probably just a left over from
// Windows 3.1 days, when icons were positioned on the desktop instead
// of being located in the taskbar.
// Monitor position and size.
const RECT& rcMon = m_mntinfo.rcWork;
if (!ser.SaveField(wxPERSIST_TLW_MONITOR_X, rcMon.left) ||
!ser.SaveField(wxPERSIST_TLW_MONITOR_Y, rcMon.top) ||
!ser.SaveField(wxPERSIST_TLW_MONITOR_W, rcMon.right - rcMon.left) ||
!ser.SaveField(wxPERSIST_TLW_MONITOR_H, rcMon.bottom - rcMon.top))
return false;
// DPI.
if (!ser.SaveField(wxPERSIST_TLW_DPI_HORZ, m_dpiHorz) ||
!ser.SaveField(wxPERSIST_TLW_DPI_VERT, m_dpiVert))
return false;
return true;
}
virtual bool Restore(Serializer& ser) wxOVERRIDE
{
// Normal position and size.
wxRect r;
if (!ser.RestoreField(wxPERSIST_TLW_X, &r.x) ||
!ser.RestoreField(wxPERSIST_TLW_Y, &r.y) ||
!ser.RestoreField(wxPERSIST_TLW_W, &r.width) ||
!ser.RestoreField(wxPERSIST_TLW_H, &r.height))
return false;
wxCopyRectToRECT(r, m_placement.rcNormalPosition);
// Maximized/minimized state.
//
// Note the special case of SW_MINIMIZE: while GetWindowPlacement()
// returns SW_SHOWMINIMIZED when the window is iconized, we restore it
// as SW_MINIMIZE as this is what the code in wxTLW checks to determine
// whether the window is supposed to be iconized or not.
//
// Just to confuse matters further, note that SW_MAXIMIZE is exactly
// the same thing as SW_SHOWMAXIMIZED.
int tmp;
UINT& show = m_placement.showCmd;
if (ser.RestoreField(wxPERSIST_TLW_MAXIMIZED, &tmp) && tmp)
show = SW_MAXIMIZE;
else if (ser.RestoreField(wxPERSIST_TLW_ICONIZED, &tmp) && tmp)
show = SW_MINIMIZE;
else
show = SW_SHOWNORMAL;
// Maximized window position.
if (ser.RestoreField(wxPERSIST_TLW_MAX_X, &r.x) &&
ser.RestoreField(wxPERSIST_TLW_MAX_Y, &r.y))
{
m_placement.ptMaxPosition.x = r.x;
m_placement.ptMaxPosition.y = r.y;
} else {
m_placement.ptMaxPosition.x = -1;
m_placement.ptMaxPosition.y = -1;
}
m_placement.ptMinPosition.x = -1;
m_placement.ptMinPosition.y = -1;
// Monitor position and size.
wxRect rmon;
if (!ser.RestoreField(wxPERSIST_TLW_MONITOR_X, &rmon.x) ||
!ser.RestoreField(wxPERSIST_TLW_MONITOR_Y, &rmon.y) ||
!ser.RestoreField(wxPERSIST_TLW_MONITOR_W, &rmon.width) ||
!ser.RestoreField(wxPERSIST_TLW_MONITOR_H, &rmon.height))
return false;
wxCopyRectToRECT(rmon, m_mntinfo.rcWork);
// DPI.
if (!ser.RestoreField(wxPERSIST_TLW_DPI_HORZ, &r.x) ||
!ser.RestoreField(wxPERSIST_TLW_DPI_VERT, &r.y))
return false;
m_dpiHorz = r.x;
m_dpiVert = r.y;
return true;
}
virtual bool GetFrom(const wxTopLevelWindow* tlw) wxOVERRIDE
{
WXHWND hWnd = GetHwndOf(tlw);
if (!::GetWindowPlacement(hWnd, &m_placement))
{
wxLogLastError(wxS("GetWindowPlacement"));
return false;
}
HMONITOR hMonitor = ::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
wxASSERT_MSG(hMonitor, wxT("error locating monitor"));
if (!::GetMonitorInfo(hMonitor, &m_mntinfo))
{
wxLogLastError(wxS("GetMonitorInfo"));
return false;
}
GetDPI(hWnd, &m_dpiHorz, &m_dpiVert) || GetDPI(hMonitor, &m_dpiHorz, &m_dpiVert);
return true;
}
virtual bool ApplyTo(wxTopLevelWindow* tlw) wxOVERRIDE
{
// There is a subtlety here: if the window is currently hidden,
// restoring its geometry shouldn't show it, so we must use SW_HIDE as
// show command, but showing it later should restore it to the correct
// state, so we need to remember it in wxTLW itself. And even if it's
// currently shown, we still need to update its show command, so that
// it matches the real window state after SetWindowPlacement() call.
tlw->MSWSetShowCommand(m_placement.showCmd);
if (!tlw->IsShown())
{
m_placement.showCmd = SW_HIDE;
}
// Get monitor to restore window to.
HMONITOR hMonitor = ::MonitorFromRect(&m_mntinfo.rcWork, MONITOR_DEFAULTTONEAREST);
wxASSERT_MSG(hMonitor, wxT("error locating monitor"));
MONITORINFO mntinfo;
mntinfo.cbSize = sizeof(mntinfo);
if (!::GetMonitorInfo(hMonitor, &mntinfo))
{
wxLogLastError(wxS("GetMonitorInfo"));
return false;
}
UINT dpiHorz, dpiVert;
GetDPI(hMonitor, &dpiHorz, &dpiVert);
SIZE
sizeWorkPrev = {
m_mntinfo.rcWork.right - m_mntinfo.rcWork.left,
m_mntinfo.rcWork.bottom - m_mntinfo.rcWork.top
},
sizeWork = {
mntinfo.rcWork.right - mntinfo.rcWork.left,
mntinfo.rcWork.bottom - mntinfo.rcWork.top
};
//
// Project the coordinates:
// - Position relative to monitor working area center.
// - Scale according to DPI.
//
if (m_placement.ptMaxPosition.x != -1 && m_placement.ptMaxPosition.y != -1) {
m_placement.ptMaxPosition.x = wxMulDivInt32(m_placement.ptMaxPosition.x - m_mntinfo.rcWork.left, sizeWork.cx, sizeWorkPrev.cx) + mntinfo.rcWork.left;
m_placement.ptMaxPosition.y = wxMulDivInt32(m_placement.ptMaxPosition.y - m_mntinfo.rcWork.top, sizeWork.cy, sizeWorkPrev.cy) + mntinfo.rcWork.top;
}
SIZE sizeWndPrev, sizeWnd;
HWND hWnd = GetHwndOf(tlw);
if (tlw->GetWindowStyle() & wxRESIZE_BORDER) {
sizeWndPrev.cx = m_placement.rcNormalPosition.right - m_placement.rcNormalPosition.left;
sizeWndPrev.cy = m_placement.rcNormalPosition.bottom - m_placement.rcNormalPosition.top;
sizeWnd.cx = wxMulDivInt32(sizeWndPrev.cx, dpiHorz, m_dpiHorz);
sizeWnd.cy = wxMulDivInt32(sizeWndPrev.cy, dpiVert, m_dpiVert);
} else {
// The window is not resizable. Do not change its size.
WINDOWPLACEMENT placement = { sizeof(placement) };
if (!::GetWindowPlacement(hWnd, &placement))
{
wxLogLastError(wxS("GetWindowPlacement"));
return false;
}
SIZE size = {
placement.rcNormalPosition.right - placement.rcNormalPosition.left,
placement.rcNormalPosition.bottom - placement.rcNormalPosition.top
};
UINT dpiWndHorz, dpiWndVert;
GetDPI(hWnd, &dpiWndHorz, &dpiWndVert) || GetDPI(::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &dpiWndHorz, &dpiWndVert);
sizeWndPrev.cx = wxMulDivInt32(size.cx, m_dpiHorz, dpiWndHorz);
sizeWndPrev.cy = wxMulDivInt32(size.cy, m_dpiVert, dpiWndVert);
sizeWnd.cx = wxMulDivInt32(size.cx, dpiHorz, dpiWndHorz);
sizeWnd.cy = wxMulDivInt32(size.cy, dpiVert, dpiWndVert);
}
m_placement.rcNormalPosition.left = wxMulDivInt32(m_placement.rcNormalPosition.left + sizeWndPrev.cx / 2 - m_mntinfo.rcWork.left, sizeWork.cx, sizeWorkPrev.cx) + mntinfo.rcWork.left - sizeWnd.cx / 2;
m_placement.rcNormalPosition.top = wxMulDivInt32(m_placement.rcNormalPosition.top + sizeWndPrev.cy / 2 - m_mntinfo.rcWork.top, sizeWork.cy, sizeWorkPrev.cy) + mntinfo.rcWork.top - sizeWnd.cy / 2;
m_placement.rcNormalPosition.right = m_placement.rcNormalPosition.left + sizeWnd.cx;
m_placement.rcNormalPosition.bottom = m_placement.rcNormalPosition.top + sizeWnd.cy;
if (!::SetWindowPlacement(hWnd, &m_placement))
{
wxLogLastError(wxS("SetWindowPlacement"));
return false;
}
return true;
}
private:
static bool GetDPI(HWND hWnd, UINT *dpiHorz, UINT *dpiVert)
{
wxASSERT(dpiHorz);
wxASSERT(dpiVert);
#if wxUSE_DYNLIB_CLASS
typedef HRESULT(WINAPI *GetDpiForWindow_t)(HWND);
static GetDpiForWindow_t s_pfnGetDpiForWindow = NULL;
if (!s_pfnGetDpiForWindow && s_dllUser32.IsLoaded())
s_pfnGetDpiForWindow = (GetDpiForWindow_t)s_dllUser32.GetSymbol(wxT("GetDpiForWindow"));
if (s_pfnGetDpiForWindow) {
*dpiHorz = *dpiVert = s_pfnGetDpiForWindow(hWnd);
return true;
}
#endif
*dpiHorz = *dpiVert = USER_DEFAULT_SCREEN_DPI;
return false;
}
static bool GetDPI(HMONITOR hMonitor, UINT *dpiHorz, UINT *dpiVert)
{
wxASSERT(dpiHorz);
wxASSERT(dpiVert);
#if wxUSE_DYNLIB_CLASS
enum MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
};
typedef HRESULT(WINAPI *GetDpiForMonitor_t)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *);
static GetDpiForMonitor_t s_pfnGetDpiForMonitor = NULL;
if (!s_pfnGetDpiForMonitor) {
if (s_dllShCore.IsLoaded())
s_pfnGetDpiForMonitor = (GetDpiForMonitor_t)s_dllShCore.GetSymbol(wxT("GetDpiForMonitor"));
}
if (s_pfnGetDpiForMonitor) {
s_pfnGetDpiForMonitor(hMonitor, MDT_DEFAULT, dpiHorz, dpiVert);
return true;
}
#endif
*dpiHorz = *dpiVert = USER_DEFAULT_SCREEN_DPI;
return false;
}
private:
WINDOWPLACEMENT m_placement;
MONITORINFO m_mntinfo;
UINT m_dpiHorz;
UINT m_dpiVert;
#if wxUSE_DYNLIB_CLASS
static wxDynamicLibrary s_dllUser32;
static wxDynamicLibrary s_dllShCore;
#endif
};

View File

@ -26,6 +26,9 @@
#include "../include/wxex/aui/framemanager.h" #include "../include/wxex/aui/framemanager.h"
#include "../include/wxex/persist/auimanager.h"
#include "../include/wxex/persist/toplevel.h"
#include "../include/wxex/appbar.h" #include "../include/wxex/appbar.h"
#include "../include/wxex/comutils.h" #include "../include/wxex/comutils.h"
#include "../include/wxex/crypto.h" #include "../include/wxex/crypto.h"
@ -37,3 +40,5 @@
#include "../include/wxex/xml.h" #include "../include/wxex/xml.h"
#include "../include/wxex/common.h" #include "../include/wxex/common.h"
#include "../include/wxex/private/tlwgeom.h"

28
src/tlwgeom.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
Copyright 2015-2018 Amebis
Copyright 2016 GÉANT
Based on code written by Jeffrey Richter.
This file is part of wxExtend.
wxExtend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
wxExtend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with wxExtend. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
#if wxUSE_DYNLIB_CLASS
wxDynamicLibrary wxTLWGeometryEx::s_dllUser32(wxT("user32.dll"));
wxDynamicLibrary wxTLWGeometryEx::s_dllShCore(wxT("shcore.dll"));
#endif