//
// Copyright(C) 1999-2003 toShay Consulting
// All rights reserved.
//
// toShay Consulting grants you ("Licensee") a non-exclusive, royalty free,
// licence to use, modify and redistribute this software in source and binary
// code form, provided that i) this copyright notice and licence appear on all
// copies of the software; and ii) Licensee does not utilize the software in a
// manner which is disparaging to toShay Consulting.
//
// This software is provided "as is" without a warranty of any kind. All
// express or implied conditions, representations and warranties, including
// any implied warranty of merchantability, fitness for a particular purpose
// or non-infringement, are hereby excluded. toShay Consulting and its licensors
// shall not be liable for any damages suffered by licensee as a result of
// using, modifying or distributing the software or its derivatives. In no
// event will toShay Consulting be liable for any lost revenue, profit or data,
// or for direct, indirect, special, consequential, incidental or punitive
// damages, however caused and regardless of the theory of liability, arising
// out of the use of or inability to use software, even if toShay Consulting
// has been advised of the possibility of such damages.
//
// This software is not designed or intended for use in on-line control of
// aircraft, air traffic, aircraft navigation or aircraft communications; or in
// the design, construction, operation or maintenance of any nuclear
// facility. Licensee represents and warrants that it will not use or
// redistribute the Software for such purposes.
//
///////////////////////////////////////////////////////////////////////////////
// Strings used in saving and restoring window position information
// in the Registry.
const CString cs_RegEntry = "Settings";
const CString cs_RegKey = "WindowPlacement";
// const CString cs_RegFormat = "%ld,%ld,%ld,%d,%d,%d,%d,%d,%d,%d,%d";
/// <summary>
/// CWindowPosition is a Singleton class for saving and restoring the position of a
/// window to a well-known location in the system registry. It can be used as a
/// drop-in module and requires only a few calls in the correct location to be
/// effective. Unfortunately it cannot be done with a single line in the source
/// since this would require depending on destructors firing at the right time,
/// and for most applications, by the time the destructor is called for this class,
/// there is no window left to query for its position information. So, to use
/// this class, instantiate it somewhere convenient while starting your application.
///
/// If you prefer to have a more human readable form of the window position in the
/// registry, use the cs_RegFormat variable above and the WriteProfileString and
/// GetProfileString code below.
///
/// Here are the steps necessary for a complete implementation in a dialog application.
/// First, make sure that you have set a registry key for your application. This is
/// typically done in the InitInstance() method of the application.
///
/// BOOL CWindowPositionApp::InitInstance()
/// {
/// // Standard initialization
/// .
/// . Other initialization code here
/// .
/// // Start WindowPlacement code block
/// {
/// // Set the registry key. Otherwise application settings will be placed
/// // in an INI file in the Windows folder.
/// SetRegistryKey("WindowPositionApp");
/// }
/// // End WindowPlacement code block
///
/// // For a dialog application the creation of the dialog is here
/// CMyDialog dlg;
/// dlg.DoModal();
/// .
/// . Other code here
/// .
///
/// // Since the dialog has been closed, return FALSE so that we exit the
/// // application, rather than start the application's message pump.
/// return FALSE;
/// }
///
/// // Include the window position header file
/// #include "WindowPosition.h"
///
/// class CMyDialog : public CDialog
/// {
/// private:
/// // Create the window position object and make it private
/// CWindowPosition m_WindowPosition;
///
/// // Construction
/// public:
/// CMyDialog(CWnd* pParent = NULL); // standard constructor
///
/// .
/// . Other code here
/// .
/// };
///
/// // Constructor
/// CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
/// : CDialog(CMyDialog::IDD, pParent),
/// m_WindowPosition(this)
/// {
/// .
/// . Other constructor code here
/// .
/// }
///
/// BOOL CMyDialog::OnInitDialog()
/// {
/// CDialog::OnInitDialog();
/// .
/// .
/// .
/// // Start WindowPlacement code block
/// {
/// // Be sure to set the registry key in the main application module.
/// // Otherwise application settings will be placed in an INI file in the
/// // Windows folder.
///
/// // Set the pointer to the window whose position is to be saved/restored.
/// // You can also initialize it in the constructor if you wish. Microsoft
/// // issues a 'warning C4355: 'this' : used in base member initializer list'
/// // if you do so, but it works nontheless. We'll set it explicitly here.
/// m_WindowPosition.SetPositionWnd(this);
/// // Restore the window position, if previously saved.
/// m_WindowPosition.SetWindowPlacement();
/// }
/// // End WindowPlacement code block
///
/// // TODO: Add extra initialization here
///
/// return TRUE; // return TRUE unless you set the focus to a control
/// }
///
/// // Override DestroyWindow() for a dialog application.
/// BOOL CMyDialog::DestroyWindow()
/// {
/// m_WindowPosition.SaveWindowPlacement();
/// return CDialog::DestroyWindow();
/// }
///
/// </summary>
class CWindowPosition
{
private:
CWnd* m_pPositionWnd;
public:
CWindowPosition(CWnd* pPositionWnd = NULL) :
m_pPositionWnd(pPositionWnd)
{
};
virtual ~CWindowPosition()
{
};
// The singleton
static CWindowPosition& Instance()
{
static CWindowPosition theOnlyWindowPosition;
return theOnlyWindowPosition;
};
void SetPositionWnd(CWnd* pPositionWnd)
{
Instance().m_pPositionWnd = pPositionWnd;
};
void SaveWindowPlacement()
{
// Save the last window size and position
WINDOWPLACEMENT wndpl;
if (Instance().m_pPositionWnd && Instance().m_pPositionWnd->GetWindowPlacement(&wndpl))
{
CWinApp* pApp = AfxGetApp();
ASSERT(pApp);
/*
CString strWP;
strWP.Format(cs_RegFormat,
wndpl.flags,
wndpl.length,
wndpl.showCmd,
wndpl.ptMaxPosition.x,
wndpl.ptMaxPosition.y,
wndpl.ptMinPosition.x,
wndpl.ptMinPosition.y,
wndpl.rcNormalPosition.left,
wndpl.rcNormalPosition.top,
wndpl.rcNormalPosition.right,
wndpl.rcNormalPosition.bottom);
pApp->WriteProfileString(cs_RegEntry, cs_RegKey, strWP);
*/
if (pApp)
{
pApp->WriteProfileBinary(cs_RegEntry, cs_RegKey, (BYTE*)&wndpl, sizeof(wndpl));
}
}
};
void SetWindowPlacement()
{
CWinApp* pApp = AfxGetApp();
if (pApp)
{
/*
WINDOWPLACEMENT wndpl;
CString strWP;
strWP = pApp->GetProfileString(cs_RegEntry, cs_RegKey, NULL);
if (!strWP.IsEmpty())
{
sscanf(strWP, cs_RegFormat,
&wndpl.flags,
&wndpl.length,
&wndpl.showCmd,
&wndpl.ptMaxPosition.x,
&wndpl.ptMaxPosition.y,
&wndpl.ptMinPosition.x,
&wndpl.ptMinPosition.y,
&wndpl.rcNormalPosition.left,
&wndpl.rcNormalPosition.top,
&wndpl.rcNormalPosition.right,
&wndpl.rcNormalPosition.bottom);
Instance().m_pPositionWnd->SetWindowPlacement(&wndpl);
}
*/
WINDOWPLACEMENT* pwndpl;
BYTE* pb = NULL;
UINT nLen = 0;
if (pApp && pApp->GetProfileBinary(cs_RegEntry, cs_RegKey, &pb, &nLen))
{
pwndpl = reinterpret_cast<WINDOWPLACEMENT*>(pb);
Instance().m_pPositionWnd->SetWindowPlacement(pwndpl);
free(pb);
}
}
};
};