////////////////////////////////////////////////////////////////
// CNGWindowPlacement Copyright 1996 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
#include "StdAfx.h"
#include "NGWindowPlacement.h"
/////////////////////////////////////////////////////////////////////////////
// Helpers for saving/restoring window state
// (taken from the MFC SuperPad sample)
static TCHAR szSection[] = _T("Settings");
static TCHAR szWindowPos[] = _T("WindowPos");
static TCHAR szFormat[] = _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
NGLIB_EXT_API BOOL ReadWindowPlacement(LPWINDOWPLACEMENT pwp)
{
CString strBuffer = AfxGetApp()->GetProfileString(szSection, szWindowPos);
if (strBuffer.IsEmpty())
return FALSE;
WINDOWPLACEMENT wp;
int nRead = sscanf(strBuffer, szFormat,
&wp.flags, &wp.showCmd,
&wp.ptMinPosition.x, &wp.ptMinPosition.y,
&wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
&wp.rcNormalPosition.left, &wp.rcNormalPosition.top,
&wp.rcNormalPosition.right, &wp.rcNormalPosition.bottom);
if (nRead != 10)
return FALSE;
wp.length = sizeof wp;
*pwp = wp;
return TRUE;
}
// Write a window placement to settings section of app's ini file
NGLIB_EXT_API void WriteWindowPlacement(LPWINDOWPLACEMENT pwp)
{
TCHAR szBuffer[sizeof(_T("-32767"))*8 + sizeof(_T("65535"))*2];
sprintf(szBuffer, szFormat,
pwp->flags, pwp->showCmd,
pwp->ptMinPosition.x, pwp->ptMinPosition.y,
pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
pwp->rcNormalPosition.left, pwp->rcNormalPosition.top,
pwp->rcNormalPosition.right, pwp->rcNormalPosition.bottom);
AfxGetApp()->WriteProfileString(szSection, szWindowPos, szBuffer);
}
BOOL CNGWindowPlacement::ParsePlacementString(const CString& sBuffer)
{
if (!sBuffer.IsEmpty())
{
int nRead = sscanf( sBuffer,
szFormat,
&flags,
&showCmd,
&ptMinPosition.x, &ptMinPosition.y,
&ptMaxPosition.x, &ptMaxPosition.y,
&rcNormalPosition.left, &rcNormalPosition.top,
&rcNormalPosition.right, &rcNormalPosition.bottom);
if (10 == nRead)
return TRUE;
}
return FALSE;
}
CString CNGWindowPlacement::BuildPlacementString(void)
{
TCHAR szBuffer[sizeof(_T("-32767"))*8 + sizeof(_T("65535"))*2];
sprintf( szBuffer,
szFormat,
flags, showCmd,
ptMinPosition.x, ptMinPosition.y,
ptMaxPosition.x, ptMaxPosition.y,
rcNormalPosition.left, rcNormalPosition.top,
rcNormalPosition.right, rcNormalPosition.bottom);
return szBuffer;
}
CNGWindowPlacement::CNGWindowPlacement()
{
// Note: "length" is inherited from WINDOWPLACEMENT
length = sizeof(WINDOWPLACEMENT);
}
CNGWindowPlacement::~CNGWindowPlacement()
{
}
//////////////////
// Restore window placement from profile key
//
BOOL CNGWindowPlacement::Restore(LPCSTR lpKeyName, CWnd* pWnd)
{
if (GetProfileWP(lpKeyName))
{
// Only restore if window intersects the screen.
//
CRect rcTemp, rcScreen(0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
if (!::IntersectRect(&rcTemp, &rcNormalPosition, &rcScreen))
return FALSE;
pWnd->SetWindowPlacement(this); // set placement
return TRUE;
}
return FALSE;
}
//////////////////
// Get window placement from profile.
//
BOOL CNGWindowPlacement::GetProfileWP(LPCSTR lpKeyName)
{
CWinApp *pApp = AfxGetApp();
ASSERT_VALID(pApp);
CString sBuffer = AfxGetApp()->GetProfileString(lpKeyName, szWindowPos);
if (ParsePlacementString(sBuffer))
return TRUE;
return FALSE;
}
////////////////
// Save window placement in app profile
//
BOOL CNGWindowPlacement::Save(LPCSTR lpKeyName, CWnd* pWnd)
{
pWnd->GetWindowPlacement(this);
return WriteProfileWP(lpKeyName);
}
//////////////////
// Write window placement to app profile
//
BOOL CNGWindowPlacement::WriteProfileWP(LPCSTR lpKeyName)
{
CString sBuffer = BuildPlacementString();
if (!sBuffer.IsEmpty())
{
AfxGetApp()->WriteProfileString(lpKeyName, szWindowPos, sBuffer);
return TRUE;
}
return FALSE;
}
// The ugly casts are required to help the VC++ 3.0 compiler decide which
// operator<< or operator>> to use. If you're using VC++ 4.0 or later, you
// can delete this stuff.
//
#if (_MSC_VER < 1000) // 1000 = VC++ 4.0
#define UINT_CAST (LONG)
#define UINT_CASTREF (LONG&)
#else
#define UINT_CAST
#define UINT_CASTREF
#endif
//////////////////
// Write window placement to archive
// WARNING: archiving functions are untested.
//
CArchive& operator<<(CArchive& ar, const CNGWindowPlacement& wp)
{
ar << UINT_CAST wp.length;
ar << UINT_CAST wp.flags;
ar << UINT_CAST wp.showCmd;
ar << wp.ptMinPosition;
ar << wp.ptMaxPosition;
ar << wp.rcNormalPosition;
return ar;
}
//////////////////
// Read window placement from archive
// WARNING: archiving functions are untested.
//
CArchive& operator>>(CArchive& ar, CNGWindowPlacement& wp)
{
ar >> UINT_CASTREF wp.length;
ar >> UINT_CASTREF wp.flags;
ar >> UINT_CASTREF wp.showCmd;
ar >> wp.ptMinPosition;
ar >> wp.ptMaxPosition;
ar >> wp.rcNormalPosition;
return ar;
}